Commit Graph

2670 Commits

Author SHA1 Message Date
Scott Idem
219f0a6507 Bug fix for when a POC is signed in. Also adjusted style to make the button more obvious. 2026-06-23 13:27:17 -04:00
Scott Idem
7ccc199b1d refactor(src): normalize component naming conventions (Group 2 cleanup)
pres_mgmt route: 8 co-located component files had no prefix, inconsistent
with every other module in the codebase. Renamed to ae_comp__* convention:
  event_page_menu, locations_page_menu, location_page_menu, location_view,
  presenter_page_menu, presenter_view, session_page_menu, session_view.
  Each had exactly one importer — import paths updated.

leads route: ae_tab__ prefix was unique to this module. The 3 active tab
files renamed to ae_comp__tab_* (ae_comp__tab_add, ae_comp__tab_start,
ae_comp__tab_manage). Three unused files (ae_tab__add_search_scan,
ae_tab__lead_list, ae_tab__list) had zero importers and were removed.

PascalCase import bindings (AE_Record_Controls, AE_AITools, AE_Object_Flags)
left unchanged — Svelte requires capitalized component names in templates;
this is a style-only concern and not worth touching without a broader
component naming convention decision.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:49:08 -04:00
Scott Idem
b1c2438867 refactor(src): root-level clutter cleanup (Group 4)
- Move 10 theme CSS files from src/ root to src/styles/ — update app.css
  @import paths from ./ae-*.css to ./styles/ae-*.css. Keeps src/ root tidy
  without changing how the themes are bundled.
- Trash aeclci_v1.css — not imported anywhere, dead file.
- Move pwa_install.svelte.ts from lib/pwa/ (single-file dir) into lib/elements/
  alongside element_pwa_install_prompt.svelte; update 2 imports.
- Move src/types/temporary-svelte-augments.d.ts into src/lib/types/ (canonical
  type location); trash empty src/types/ dir.
- idaa/clear-caches/ route slug NOT renamed — URL is embedded in Novi portal
  iframe config; requires coordinated portal update outside this repo.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:39:17 -04:00
Scott Idem
7fa9e107b8 refactor(src): resolve orphaned/misplaced files (Group 3 cleanup)
Five Svelte components removed from ae_core/ (data/logic lib dir) and moved
to elements/ where reusable UI components live:
  ae_comp__hosted_files_download_button, ae_comp__hosted_files_upload,
  ae_comp__hosted_files_clip_video, ae_comp__hosted_files_clip_video_li,
  ae_comp__site_config_editor — all import paths updated.

ae_core__organization.ts deleted — zero importers, dead code.

ae_events/types/ae_badge_template_cfg.ts promoted to ae_events root and
renamed ae_events__badge_template_cfg.ts (follows module naming convention);
types/ subdir removed.

ae_events/badges/css/ badge layout CSS files moved to elements/styles/
(the dedicated styles dir); badges/ subdir removed.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:33:58 -04:00
Scott Idem
ba07ec6313 fix(tests): update stale $lib/api/api import in unit test
Missed by the earlier refactor sed (which only ran over src/); the mock
path in create_event_badge.spec.ts still pointed to the old $lib/api/api.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:26:08 -04:00
Scott Idem
4d6dd980c2 refactor(src): consolidate duplicate lib directories (Group 1 cleanup)
Three pairs of duplicate/split directories collapsed into their canonical homes:

- src/lib/api/ → src/lib/ae_api/: api.ts moved alongside the individual
  api_*.ts files it aggregates; all 85 import lines updated across the codebase.

- src/lib/utils/ → src/lib/ae_utils/: ae_string_snippets.ts and utils.ts
  moved; one import updated (ae_stores.ts). utils.ts had no importers.

- src/lib/ae_elements/ → src/lib/elements/: AE_AITools, AE_Object_Flags,
  AE_Record_Controls moved and renamed to snake_case (ae_ai_tools.svelte,
  ae_object_flags.svelte, ae_record_controls.svelte); 6 import paths updated.
  Local binding names left unchanged for a separate Group 2 pass.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:22:10 -04:00
Scott Idem
3f73fc059e fix(sw): guard navigator.serviceWorker access before feature check; fix EOF newline
Accessing navigator.serviceWorker.controller before the 'serviceWorker' in navigator
guard would throw a TypeError on browsers without SW support. Moved the guard into
the had_controller expression so the property is never accessed on unsupported browsers.

Also adds the missing trailing newline to core__export.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:09:21 -04:00
Scott Idem
6c822bc466 docs: add mistake #19 — optional TypeScript params break vite build SSR
Documents the param?: Type pattern that esbuild mishandles in .svelte
files (strips the type but leaves ?, producing invalid JavaScript). Adds
the full write-up to REFERENCE__Common_Agent_Mistakes.md and a summary
entry #10 to BOOTSTRAP__AI_Agent_Quickstart.md §7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 19:04:52 -04:00
Scott Idem
3bc93857dd fix(build): replace optional TypeScript params to fix SSR build
esbuild strips ': Type' from 'param?: Type' but leaves 'param?' in the
output, which is invalid JavaScript and causes Rollup to fail during the
Vite SSR build. Changed all 5 occurrences across source files from
'param?: Type' to 'param: Type | undefined = undefined', preserving the
same optional semantics while producing valid JavaScript after stripping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:56:51 -04:00
Scott Idem
8062006a21 fix(docker): copy scripts/ before npm install; skip postinstall in deploy stage
The postinstall hook (scripts/postinstall.mjs) runs during `npm install`, but the
Dockerfile only copied package*.json before that step, so the script wasn't present.

- Copy scripts/ alongside package*.json in the builder stage.
- Add --ignore-scripts to the deploy-stage npm install: flowbite-svelte is a
  devDependency and won't be installed there, so the postinstall patch is irrelevant
  and the script file won't be available in that stage anyway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:39:06 -04:00
Scott Idem
9c30d4618a fix(build): postinstall script patches flowbite-svelte TypeScript optional params
flowbite-svelte ships TypeScript optional-param syntax (x?: string, event?: MouseEvent,
date?: Date) in its dist .svelte files. Vite's esbuild dep pre-bundler processes these
files (via dist/*/index.js re-exports) and fails with "Unexpected '?'" parse errors
whenever the lockfile changes and the dep cache is rebuilt.

- Add scripts/postinstall.mjs: patches 4 specific TypeScript signatures in
  CommandPalette.svelte, ScrollSpy.svelte, and Datepicker.svelte after every npm install.
  Patches are idempotent and targeted — only the ?-in-param-position syntax is removed;
  optional-chaining (?.) in function bodies is untouched.
- Add "postinstall" script to package.json to run it automatically.
- Upgrade flowbite-svelte 1.31.0 → 1.33.1 (both have the same issue; 1.33.1 is current).
- npm update now works without breaking the dev server.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:33:53 -04:00
Scott Idem
99c4934045 I think this works a little more now. 2026-06-22 18:06:51 -04:00
Scott Idem
309d04cb0a This is working if you just do an install? Not an update yet. 2026-06-22 17:54:13 -04:00
Scott Idem
69dd102e93 Working package updates? 2026-06-22 16:30:58 -04:00
Scott Idem
ea3b60c819 More package updates. No issues so far. 2026-06-22 15:59:36 -04:00
Scott Idem
21f3192fa7 Testing more package updates. 2026-06-22 15:50:22 -04:00
Scott Idem
cf9975f50f fix(sw): skip controllerchange reload on first activation
The reload should only fire when an existing SW is replaced by a new one
(old → new), not when the SW activates for the first time on a fresh page
load (null → first). The spurious reload on fresh loads was caused by
checking unconditionally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:26:48 -04:00
Scott Idem
677ec9d918 feat(build): inject build time and version into health endpoint
Vite define injects __BUILD_TIME__ and __BUILD_VERSION__ at build time
so /health returns the exact timestamp and package version of the running
build — useful for verifying deploys without guessing what changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:13:04 -04:00
Scott Idem
0cd008af73 New version of updated packages that should work well. 2026-06-22 14:03:00 -04:00
Scott Idem
f029c323f5 fix(build): remove flowbite-svelte from optimizeDeps.exclude
The previous session added flowbite-svelte to optimizeDeps.exclude to
fix an esbuild TypeScript syntax error with 1.33.1. But tailwindcss 4.3+
is now stricter: when a style virtual module fails to load (which happens
when the package is excluded from pre-bundling), tailwindcss receives the
raw .svelte file content — including TypeScript — and rejects it with
"Invalid declaration: Side".

With flowbite-svelte 1.31.0, only Drawer and Modal are imported. Neither
their dist files nor their transitive deps have TypeScript optional-param
syntax (?: ) that would cause esbuild to fail. Safe to remove the exclusion.

Updated the comment to explain when/why to re-add it if upgrading.

Dev server: clean start, HTTP 200 ✔  |  npm run build ✔

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 13:57:29 -04:00
Scott Idem
fff4178265 So far this round of updates is working. Still testing... 2026-06-22 13:24:12 -04:00
Scott Idem
f9a7d0bbde Package updates that are working well. 2026-06-22 13:17:26 -04:00
Scott Idem
c750625e8f fix(build): roll back broken packages, pin tailwindcss 4.3.1 only
npm update (c4d4d2bde) silently upgraded @sveltejs/kit (2.53→2.66),
rollup (4.59→4.62), and svelte (5.53→5.56) together, which caused the
SSR production build to fail: rollup received raw .svelte files without
vite-plugin-svelte transforming them (non-deterministic, race condition).

Fix: restore stable package-lock from 468ed61b3, then selectively update
only tailwindcss and its ecosystem (4.2.1→4.3.1) to resolve DEP0205.
Align @tailwindcss/vite constraint to ^4.3.0 to match.

Also adds flowbite-svelte to optimizeDeps.exclude — it ships TypeScript
optional-param syntax in compiled .svelte dist files that esbuild rejects
during dependency pre-bundling (will matter when flowbite-svelte updates).

Build tested: npm run build ✔  |  svelte-check: 0 errors 0 warnings ✔

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 13:12:33 -04:00
Scott Idem
c4d4d2bde0 Updating outdated packages 2026-06-22 12:42:10 -04:00
Scott Idem
bdebfffaf7 Update to Tailwind to get rid of a warning hopefully. 2026-06-22 12:38:55 -04:00
Scott Idem
39f2e6ccfa refactor(core): fix svelte-check errors and clean up ae_core_functions
- Fix two broken V1/V2 api calls (get_ae_obj_id_crud, update_ae_obj_id_crud)
  that no longer exist on the api object — replaced with V3 equivalents
- Comment out two dead/uncalled functions (load_ae_obj_id__site_domain,
  update_ae_obj_id_crud) and remove them from the export; pending full removal
- Extract download_export__obj_type into core__export.ts following the
  core__*.ts module convention

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 12:33:14 -04:00
Scott Idem
81874ffa5d fix(sw): complete cache-clearing + add controllerchange auto-reload
All cache-clearing buttons and the IDAA clear-caches page previously
cleared IDB/localStorage but left service worker registrations and Cache
Storage intact. On the next reload the SW re-served the old JS bundle,
leaving users stuck on stale code despite appearing to reload. This
caused recurring stale-state reports from IDAA and other clients for
4+ months.

Two gaps closed:
1. Every clear path (root page buttons, sys bar, help tech, idaa/clear-caches)
   now unregisters SW registrations and clears Cache Storage before touching
   IDB and localStorage. Order: SW → Cache Storage → IDB → localStorage.
2. Added controllerchange listener in +layout.svelte effect 4. When the new
   SW activates and calls clients.claim(), this listener reloads the page so
   open tabs run the new JS bundle instead of keeping old code in memory
   indefinitely. Without this, skipWaiting + clients.claim work correctly on
   the SW side but the page side never picks up the update.

Also added thorough code comments and updated REFERENCE__Common_Agent_Mistakes
(#15) and BOOTSTRAP doc (#8) to document the full root cause so this cannot
be silently re-broken by a future agent or refactor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 12:17:51 -04:00
Scott Idem
468ed61b39 Just a version bump because things very stable. 2026-06-18 19:26:13 -04:00
Scott Idem
31909c99fd docs: add multi-select / quick delete to files TODO
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:20:22 -04:00
Scott Idem
66c794ee53 fix(core): align menu + dashboard colors and order
Menu: Files moved between People and Data Stores; color tertiary (matches Users/People).
Dashboard: Sites secondary→primary, Files secondary→tertiary, Data Stores + Lookups surface→secondary. All cards now match menu color groupings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:19:39 -04:00
Scott Idem
dae610795b feat(core): add Files card to dashboard, fix card colors, expand per-page options
Dashboard: Users + People cards corrected to tertiary (matched menu);
Files card added between People and Data Stores using secondary (matched menu).
Files per-page options extended to 200/400/800/1000/1500/2000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:16:14 -04:00
Scott Idem
af636f5b53 fix(files): total size reflects displayed rows, not all loaded results
When orphan filter is active, total was summing all 50 loaded files
rather than the filtered subset shown in the table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:56:24 -04:00
Scott Idem
ed87d1c1ef docs: add agent messaging section to frontend bootstrap
Documents ae_send_message recipient names, the directory-name vs
recipient-name gotcha, and ae_inbox inbox defaults. Mirrors the
equivalent section added to the backend bootstrap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:21:42 -04:00
Scott Idem
b954f75b18 docs: mark hosted file backend tasks complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:19:07 -04:00
Scott Idem
5689bfebbc fix(files): use new backend action endpoints for event_file delete + orphan scan
DELETE /v3/action/event_file/{id} now handles full atomic cleanup (link
removal, physical file, hosted_file record) in one call — replaces the
multi-step Redis pre-warm workaround. orphan_scan endpoint replaces the
N+1 per-file /links fetch on the admin files page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:18:34 -04:00
Scott Idem
f93bca1bd4 docs: track backend-pending hosted file cleanup tasks
Two new items in DevOps & Backend: V3 CRUD regression fix for
event_file delete (delete_obj_template ignores cleanup params) and
orphan scan endpoint for hosted_file. Both logged after message to
backend agent 2026-06-18.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:14:14 -04:00
Scott Idem
f3c6580b69 fix(files): reliable hosted_file cleanup + orphan detection in /core/files/
Event file delete (Pres Mgmt):
- Re-implement cleanup using /links pre-fetch before delete_hosted_file calls.
  The /links endpoint calls get_id_random() per link which populates Redis.
  Without this, redis_lookup_id_random('event_file', id) raises 404 in the
  delete handler → silent skip → physical file never removed.
  Now mirrors the same pattern used by the /core/files/ admin page delete.

/core/files/ admin page:
- Add orphan check mode: "Check Orphans" button batch-fetches links for all
  visible results in parallel (reusing links_map cache), then filters table
  to show only files with zero links.
- Orphan files get a warning badge in the filename column.
- Results header toggles to show "N orphans of M" when filter is active.
- Unlink icon imported from lucide for orphan UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:02:04 -04:00
Scott Idem
94b3dd84af fix(files): actually delete physical files when removing event_file or hosted_file
event_file delete was broken since the module was first created (Oct 2024).
delete_ae_obj_id__event_file passed delete_hosted_file=true + rm_orphan=true to
the generic V3 CRUD endpoint, but delete_obj_template never handled those params —
it only did a raw sql_delete on the event_file row. The hosted_file_link record,
hosted_file DB record, and physical file on disk were never cleaned up.

Fix: call api.delete_hosted_file (the action endpoint) BEFORE deleting the
event_file record so the backend can still resolve link_to_id via Redis.
Pass link_to_type='event_file', link_to_id=event_file_id, rm_orphan=true,
method=delete. hosted_file_id is now an optional param on
delete_ae_obj_id__event_file; component passes event_file_obj.hosted_file_id.

Also fix hosted_file delete in /core/files/ admin page (same root cause):
load links first, then call delete_hosted_file for each link with correct
link_to_type/link_to_id_random and method=delete before removing the record.

Also: add clickable navigation links in the files admin link sub-row.
Direct types (event, journal, archive, post) resolve immediately; nested types
(event_session, event_location, event_presenter, journal_entry, etc.) fetch
their parent ID via the V3 CRUD endpoint and construct the correct route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 17:47:10 -04:00
Scott Idem
015a38fd14 feat(files): add Hosted Files admin page at /core/files/
- Search hosted files across all accounts (including disabled)
- Sortable columns, pagination, per-row delete, download, and SHA-256 copy
- Lazy-load file link records per row via /v3/action/hosted_file/{id}/links
- Fix delete to load links first, remove each via correct link_to_type/link_to_id_random,
  then hard-delete with method=delete and rm_orphan=true
- Remove Linked To and Group columns (moved Group/ForType to filter bar only)
- SHA-256 column now visible at lg breakpoint (was xl)
- Added /core/files nav link to /core layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 17:32:45 -04:00
Scott Idem
fa7889bd80 Added new clear IDB tables button to the AE system bar/menu. 2026-06-18 15:27:03 -04:00
Scott Idem
6222f7655d docs: update passcode security status and add async $effect guard pattern
- TODO__Agents.md: check off completed passcode JWT migration items;
  document the three remaining cleanup steps (deferred ~a few days)
- PROJECT__AE_Site_Passcode_Security.md: update status to active/cleanup-deferred,
  check off completed implementation checklist items
- GUIDE__SvelteKit2_Svelte5_DexieJS.md: add new section documenting the
  async-function-from-$effect guard-reset infinite loop pattern, with the
  real example from the passcode auth bug (2026-06-18)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 13:32:50 -04:00
Scott Idem
d939f3190d feat(security): implement API-verified passcode auth with JWT session
Passcodes are no longer compared locally against cached localStorage data.
Entry now POSTs to /v3/action/auth/authenticate_passcode; on success the
returned JWT (with per-role TTL) is stored in $ae_loc.jwt. Page-load
expiry check in +layout.ts resets access_type to anonymous when the JWT
has expired, targeting only auth_type='passcode' JWTs.

- Debounce (600 ms) auto-fires the check after typing stops; Enter key
  fires immediately as a secondary trigger — preserving the original UX
- Inline spinner and error message added to the passcode input
- Silent fallback to local comparison on network error or unresolved
  site_id (ghost), so IDAA staff and Electron/Launcher contexts are safe
- USE_API_PASSCODE_AUTH = true (active); local fallback retained while
  production is observed; site_access_code_kv cleanup deferred

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 13:32:44 -04:00
Scott Idem
e09757f2b1 chore: remove dead legacy CRUD API functions and helpers 2026-06-18 11:55:53 -04:00
Scott Idem
12f799b0d6 chore: add deprecation warnings for idaa_loc migration 2026-06-18 11:43:12 -04:00
Scott Idem
f603780e71 Fixing bug with random appended still 2026-06-18 09:32:46 -04:00
Scott Idem
7ef2b55af6 Fixing the permissions of things again. Yes. Some things are hidden by default for staff/trusted access differently than for admins/managers. Staff should use Edit Mode to see more details and edit things. 2026-06-18 09:19:30 -04:00
Scott Idem
2563307d71 fix(build): resolve store binding and linter warnings to harden build stability
- Removed invalid two-way bindings to read-only Dexie observables in the test page
- Fixed 'state_referenced_locally' warning in Field Editor by refactoring draft_value initialization
- Cleaned up empty else block in session list to resolve Vite build warning
- Verified successful production build and clean 'npm run check' output
2026-06-17 18:16:59 -04:00
Scott Idem
d06dcae94b feat(field-editor): modernize field editor with non-blocking modal and viewport clamping
- Completed rewrite of `element_ae_obj_field_editor.svelte` to Svelte 5 + Tailwind v4
- Set `display_modal = true`, `modal_blocking = false`, and `modal_placement = 'center'` as new defaults
- Implemented trigger-relative modal positioning with automatic viewport boundary clamping to prevent off-screen rendering
- Migrated all 12 call sites across core and events modules (Session, Presenter, Location, Exhibit, etc.)
- Removed legacy datetime-to-local manual conversion logic from views as the component now handles it natively
- Retired Skeleton-based legacy component
- Updated testing page and documentation to reflect the new standardized primitive
2026-06-17 18:01:08 -04:00
Scott Idem
ea413bbb9b style(core): enhance UI consistency, support dark mode, and reorder navigation
- Refactored core layout and dashboard to follow AE Firefly guidelines
- Added proper theme-aware backgrounds and transitioned to Skeleton v4 tokens
- Grouped navigation and cards by functional color (Teal: Infra, Indigo: Identity, Amber: Config)
- Reordered items to: Accounts, Sites, Users, People, Data Stores, Lookups, Addresses, Contacts
- Fixed color inconsistency for Activity Logs in dashboard vs navigation
- Enabled non-blocking modal mode for inline field editors in Data Stores table
2026-06-17 17:27:39 -04:00
Scott Idem
04205e4a63 feat(field-editor): add display_modal mode with placement, blocking toggle, and unsaved-changes guard
- New `display_modal` prop opens the edit panel as a native <dialog> anchored
  near the pencil trigger instead of shifting inline content
- `modal_placement` (center|above|below|left|right, default center) positions
  the dialog relative to the trigger via getBoundingClientRect + CSS transform
- `modal_blocking` (default true) toggles showModal() vs show(); non-modal
  mode adds a document pointerdown listener to close on outside click
- `cancel_edit()` now warns "Discard unsaved changes?" when draft differs from
  saved value (matches data store form behaviour); skips warning after a
  successful save
- Dialog background uses theme CSS vars directly (--color-surface-50/900) via
  :global CSS — Skeleton tonal presets are intentionally semi-transparent and
  rendered behind table content without explicit position:fixed + z-index
- Extracted edit panel to {#snippet edit_panel()} — shared by inline and
  dialog paths with no duplication
- data-stores table: all three inline field editors switched to display_modal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 17:21:17 -04:00