@hasna/recordings 0.3.13 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +223 -37
  2. package/bun.lock +37 -38
  3. package/dist/cli/index.js +1884 -615
  4. package/dist/cli/macos-shortcut.d.ts +2 -2
  5. package/dist/db/database.d.ts.map +1 -1
  6. package/dist/db/pg-migrations.d.ts.map +1 -1
  7. package/dist/db/recordings.d.ts +6 -0
  8. package/dist/db/recordings.d.ts.map +1 -1
  9. package/dist/http/client.d.ts +183 -22
  10. package/dist/http/client.d.ts.map +1 -1
  11. package/dist/index.d.ts +3 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2858 -2288
  14. package/dist/lib/audio-artifact-storage.d.ts +98 -0
  15. package/dist/lib/audio-artifact-storage.d.ts.map +1 -0
  16. package/dist/lib/capture-probe.d.ts +3 -3
  17. package/dist/lib/capture-probe.d.ts.map +1 -1
  18. package/dist/lib/config.d.ts.map +1 -1
  19. package/dist/lib/local-opt-in.d.ts +132 -0
  20. package/dist/lib/local-opt-in.d.ts.map +1 -0
  21. package/dist/lib/macos-bundle.d.ts +1 -1
  22. package/dist/lib/persistence-probe.d.ts +56 -17
  23. package/dist/lib/persistence-probe.d.ts.map +1 -1
  24. package/dist/lib/transcriber.d.ts.map +1 -1
  25. package/dist/mcp/index.d.ts.map +1 -1
  26. package/dist/mcp/index.js +1689 -456
  27. package/dist/sdk/index.d.ts +13 -5
  28. package/dist/sdk/index.d.ts.map +1 -1
  29. package/dist/sdk/index.js +904 -1
  30. package/dist/sdk/resolve.d.ts +53 -0
  31. package/dist/sdk/resolve.d.ts.map +1 -0
  32. package/dist/sdk/v1.generated.d.ts +6 -0
  33. package/dist/sdk/v1.generated.d.ts.map +1 -1
  34. package/dist/server/client-ip.d.ts +39 -0
  35. package/dist/server/client-ip.d.ts.map +1 -0
  36. package/dist/server/cloud-config.d.ts +12 -0
  37. package/dist/server/cloud-config.d.ts.map +1 -1
  38. package/dist/server/cloud-readiness.d.ts.map +1 -1
  39. package/dist/server/cloud.d.ts +20 -2
  40. package/dist/server/cloud.d.ts.map +1 -1
  41. package/dist/server/index.js +566 -284
  42. package/dist/server/migrate-command.d.ts +1 -1
  43. package/dist/server/migrate-command.d.ts.map +1 -1
  44. package/dist/server/openapi.d.ts +21 -0
  45. package/dist/server/openapi.d.ts.map +1 -1
  46. package/dist/server/repo.d.ts.map +1 -1
  47. package/dist/server/serve.d.ts.map +1 -1
  48. package/dist/storage.d.ts +2 -2
  49. package/dist/storage.d.ts.map +1 -1
  50. package/dist/storage.js +1334 -871
  51. package/dist/store.d.ts +12 -3
  52. package/dist/store.d.ts.map +1 -1
  53. package/dist/types/index.d.ts +15 -0
  54. package/dist/types/index.d.ts.map +1 -1
  55. package/package.json +9 -8
  56. package/packaging/macos/build_release_pkg.sh +3 -3
  57. package/packaging/macos/managed_bootstrap.sh +4 -4
  58. package/packaging/macos/scripts/postinstall +2 -2
  59. package/packaging/macos/scripts/preinstall +2 -2
  60. package/scripts/build_companion_cli.sh +7 -1
  61. package/scripts/install_macos_app.sh +27 -24
  62. package/scripts/macos_artifact.ts +20 -16
  63. package/scripts/migrate.ts +4 -20
  64. package/scripts/smoke_macos_app.sh +21 -21
  65. package/src/native/Recordings/App/ContentView.swift +53 -68
  66. package/src/native/Recordings/App/MenuBarStatusView.swift +171 -61
  67. package/src/native/Recordings/App/RecordWorkspaceView.swift +47 -449
  68. package/src/native/Recordings/App/RecorderSettingsView.swift +75 -0
  69. package/src/native/Recordings/App/RecordingDetailView.swift +3 -4
  70. package/src/native/Recordings/App/RecordingsApp.swift +185 -9
  71. package/src/native/Recordings/App/RecordingsListView.swift +60 -112
  72. package/src/native/Recordings/App/RecordingsStore.swift +124 -109
  73. package/src/native/Recordings/App/Theme.swift +73 -61
  74. package/src/native/Recordings/Package.swift +1 -0
  75. package/src/native/Recordings/RecordingsLib/CaptureMonitor.swift +65 -0
  76. package/src/native/Recordings/RecordingsLib/Info.plist +3 -3
  77. package/src/native/Recordings/RecordingsLib/OpenAIAPIKeyStore.swift +75 -21
  78. package/src/native/Recordings/RecordingsLib/Recording.swift +14 -2
  79. package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +316 -34
  80. package/src/native/Recordings/RecordingsLib/RecordingGlassBackground.swift +34 -0
  81. package/src/native/Recordings/RecordingsLib/RecordingProvider.swift +102 -0
  82. package/src/native/Recordings/RecordingsLib/RecordingsCLI.swift +17 -10
  83. package/src/native/Recordings/RecordingsLib/ServiceAPIConfiguration.swift +107 -0
  84. package/src/native/Recordings/RecordingsLib/ServiceConnectionView.swift +76 -0
  85. package/src/native/Recordings/RecordingsLib/SettingsView.swift +45 -149
  86. package/src/native/Recordings/RecordingsLib/SettingsWindowController.swift +48 -0
  87. package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +13 -4
  88. package/src/native/Recordings/RecordingsTests/OpenAIAPIKeyStoreTests.swift +43 -38
  89. package/src/native/Recordings/RecordingsTests/RecorderSurfaceTests.swift +60 -0
  90. package/src/native/Recordings/RecordingsTests/RecordingDateTests.swift +26 -0
  91. package/src/native/Recordings/RecordingsTests/RecordingProviderTests.swift +195 -0
  92. package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +1 -1
  93. package/src/native/Recordings/RecordingsTests/RecordingStartTimingTests.swift +30 -0
  94. package/src/native/Recordings/RecordingsTests/ServiceAPIConfigurationTests.swift +75 -0
  95. package/src/native/Recordings/RecordingsTests/SettingsWindowControllerTests.swift +28 -0
  96. package/src/native/Recordings/Updater/BootstrapPreflight/BootstrapPreflightMain.swift +1 -1
  97. package/src/native/Recordings/Updater/Broker/ApplicationNamespace.swift +2 -2
  98. package/src/native/Recordings/Updater/Broker/BrokerMain.swift +1 -1
  99. package/src/native/Recordings/Updater/Broker/CanonicalTreeCopy.swift +1 -1
  100. package/src/native/Recordings/Updater/Broker/InstallJournal.swift +1 -1
  101. package/src/native/Recordings/Updater/BrokerTests/ActivationRecoveryPolicyTests.swift +2 -2
  102. package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +1 -1
  103. package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +2 -2
  104. package/src/native/Recordings/build.sh +6 -6
  105. package/src/native/Recordings/App/SidebarView.swift +0 -212
package/README.md CHANGED
@@ -13,26 +13,58 @@ npm install -g @hasna/recordings
13
13
 
14
14
  ## macOS App
15
15
 
16
- Recordings ships a **full native macOS app** (SwiftUI, macOS 26 / Liquid Glass) with a
17
- companion menu-bar control. It opens to a **Recordings workspace**: a narrow violet
18
- Liquid-Glass sidebar (Workspace · Library · Projects · Modes · Machines) beside one
19
- continuous canvas with the record hero, transcript library, and detail view. The menu bar
20
- provides recording controls and access to the main window while it is in the background.
21
-
22
- - **Record** — large push-to-talk / dictation / command hero with live transcription,
23
- duration, the active project, and a "just now" strip. Global shortcut (default F5, or
24
- hold fn) works while the window is in the background.
25
- - **Library** every past transcript (read straight from the active local or HTTP Store
26
- the CLI and MCP write), searchable and filterable by project, mode, and machine, with a
27
- detail pane (copy, paste-into-front-app, audio playback, metadata).
28
- - **Projects** app projects are registered through the same canonical Store before a
29
- recording can reference them, preserving referential integrity on either store.
30
- - **Settings** (⌘,) OpenAI key, language, recording shortcut, permissions, projects,
31
- and voice shortcuts.
16
+ **Hasna Recordings** is a native macOS 26 app with a companion menu bar control.
17
+ The app opens a compact glass recorder with a microphone/stop/play control and timer.
18
+ The clock opens searchable history and the gear opens Settings inside the same retained app window. A shared title bar and back navigation keep the recorder, transcripts, and settings together. The recorder uses a compact 224 × 244 point layout; normal interface text uses macOS-sized 11–13 point type. Glass backgrounds use one live native blur per surface, with matching translucent controls.
19
+ A floating transcription bar shows live words, the microphone waveform, pause/resume,
20
+ playback, and an Auto-paste switch. Recent pastes show delivery evidence from this session.
21
+ There is no sidebar or project UI. New app recordings are unassigned; existing recordings and their metadata
22
+ are preserved.
23
+
24
+ - Click Record, or hold the global shortcut (F5 by default).
25
+ - Click the clock or press **⌘L** for recordings; select a row to read its transcript.
26
+ Audio playback is available when its file is retained on this Mac.
27
+ - Press **⇧⌘B** for the floating transcription bar, or choose **Keep bar visible** from
28
+ the menu bar’s More menu. Its play control opens Recent pastes.
29
+ - Pause/resume from the bar or the recorder’s context menu. Paused microphone samples
30
+ are excluded from the transcript and recording duration.
31
+ - Turn **Auto-paste** off to keep transcripts available without typing into another app.
32
+ Recordings still save through the configured API. Clearing Recent pastes only clears
33
+ this session’s delivery list; it does not delete recordings.
34
+ - Open **Settings** (⌘,), then **API & Advanced…** to configure the service connection,
35
+ transcription cleanup, shortcuts, and permissions. The input follows the macOS default
36
+ microphone; audio remains uncompressed 24 kHz PCM.
37
+
38
+ New installations default to dictation. Question and edit-command detection is
39
+ optional in Settings; enabling it can add a model request before delivery. For
40
+ verbatim dictation with the shortest delivery path, keep intent detection off and
41
+ set Transcription Cleanup to Raw (Off). Settled realtime text can paste while the API save
42
+ continues in the background. Capture shutdown runs off the UI thread, and the
43
+ recording panel avoids animated glass so rendering does not stall live transcription.
44
+
45
+ In **Settings → API & Advanced… → General → Recordings API**, enter your API URL and service key,
46
+ then choose **Save Connection** and **Test Connection**. There is no compiled-in API
47
+ hostname. Both a service prefix such as `https://api.example.com/recordings` and its
48
+ versioned form `https://api.example.com/recordings/v1/` work; requests append the
49
+ resource to exactly one `/v1`. The service key stays in macOS Keychain, scoped to the
50
+ normalized endpoint, and is separate from the OpenAI transcription key.
51
+
52
+ An explicitly configured launch environment takes precedence over saved connection
53
+ settings: `HASNA_RECORDINGS_API_URL` plus the existing Hasna credential chain, or
54
+ `HASNA_RECORDINGS_CLIENT_STORE=sqlite` for an intentional local store. The native app
55
+ passes the connection to its embedded CLI, so recording persistence, history, and
56
+ deletion use the same API client as the CLI and MCP. No local fallback is selected
57
+ when an API connection is missing or fails.
58
+
59
+ The bundle filename is **Hasna Recordings.app** for both full and menu bar builds.
60
+ Older unspaced bundles remain discoverable as legacy installations. The managed
61
+ updater's canonical path is part of its immutable cohort; an existing cohort bound
62
+ to the old filename requires managed reprovisioning before receiving bundles under
63
+ the new name. This change does not rename an already installed managed app.
32
64
 
33
65
  The app embeds a same-version `recordings` CLI as its data layer, so the CLI, MCP, and app
34
66
  share one store without depending on a possibly stale global CLI installation. Production
35
- release installs use a one-time managed bootstrap at `/Applications/HasnaRecordings.app`; later
67
+ release installs use a one-time managed bootstrap at `/Applications/Hasna Recordings.app`; later
36
68
  release updates replace only that app through the installed root-owned broker.
37
69
 
38
70
  ```bash
@@ -62,7 +94,7 @@ recordings app status # show install state
62
94
  recordings app snapshot # write ./desktop-snapshot.png for local UI debugging
63
95
  # From this repository, optionally choosing another output path:
64
96
  bun run desktop:snapshot -- /tmp/recordings-desktop.png
65
- /Applications/HasnaRecordings.app/Contents/Helpers/recordings-update-client status
97
+ "/Applications/Hasna Recordings.app/Contents/Helpers/recordings-update-client" status
66
98
 
67
99
  # Release builds run only as the isolated _recordingsbuild account. Provision these first:
68
100
  # - /private/var/recordings-build owned by _recordingsbuild, mode 0700, beneath a
@@ -165,13 +197,13 @@ recordings app install \
165
197
  swift test # run the native test suite
166
198
  ```
167
199
 
168
- The production release location is `/Applications/HasnaRecordings.app`. The managed bootstrap installs
200
+ The production release location is `/Applications/Hasna Recordings.app`. The managed bootstrap installs
169
201
  one signed/notarized PKG exactly once, including the root broker, no-login verifier, launchd policy,
170
202
  release key, and initial app. That root cohort is intentionally immutable:
171
203
  `lifecycle=bootstrap-v1-app-updates-only`,
172
204
  `root_maintenance_supported=false`, and `key_rotation_supported=false`. Subsequent release
173
205
  envelopes must bind the exact installed broker/verifier cohort, protocol version, and pinned key
174
- epoch, and may replace only `/Applications/HasnaRecordings.app`. A second bootstrap PKG, a broker or
206
+ epoch, and may replace only `/Applications/Hasna Recordings.app`. A second bootstrap PKG, a broker or
175
207
  verifier mismatch, a broker-protocol incompatibility, or a key-epoch change fails before app
176
208
  activation with `unsupported_lifecycle`. Root updater maintenance and release-key rotation require a
177
209
  separate managed reprovisioning lifecycle; the current tooling does not run Installer or overwrite
@@ -227,7 +259,7 @@ private, fsynced root journal and anti-rollback state recover interrupted app re
227
259
  next install attempt.
228
260
 
229
261
  The explicit `local-only` development path remains separate and installs
230
- `~/Applications/HasnaRecordings.app`; it never provisions or imitates the production root cohort.
262
+ `~/Applications/Hasna Recordings.app`; it never provisions or imitates the production root cohort.
231
263
  For a station-specific deployment, pass `--expected-hostname` so the installer proves the live
232
264
  short hostname before taking a lock or mutating state while the release artifact itself remains
233
265
  fleet-distributable. Obtain `AUTHENTICATED_MANIFEST_SHA256` from independently authenticated
@@ -285,7 +317,7 @@ The app's **Transcription Cleanup** setting controls the same post-processing pi
285
317
  the CLI and MCP server. Use **Raw** to keep verbatim text only, **Auto** to clean up only
286
318
  when trigger phrases or instruction patterns are detected, or **Always** to run the
287
319
  transcriber cleanup prompt for every recording. Global cleanup instructions can be set in
288
- Settings, and project-specific instructions are appended when a project is active.
320
+ Settings. The native app applies only those global instructions.
289
321
 
290
322
  The native app uses OpenAI realtime transcription for the stop-and-paste path: settled
291
323
  `gpt-realtime-whisper` text is saved and pasted immediately, while full-file
@@ -440,15 +472,52 @@ directly with API-key auth via
440
472
  [`@hasna/contracts`](https://www.npmjs.com/package/@hasna/contracts).
441
473
 
442
474
  The CLI and MCP client have exactly two stores and never open Postgres — they
443
- read the on-box `sqlite` file, or call the server's `/v1` HTTP API. The
444
- presence of BOTH `HASNA_RECORDINGS_API_URL` and `HASNA_RECORDINGS_API_KEY`
445
- selects the API; any other environment reads the on-box file. A partial setup
446
- (one of the two variables set) fails closed rather than silently reading the
447
- wrong dataset. The explicit `HASNA_RECORDINGS_CLIENT_STORE` switch (`sqlite` |
448
- `http`) wins over the auto-selection, so a configuration that sets it to
449
- `sqlite` keeps reading the local file even when the hosted pair is present.
450
- `RECORDINGS_API_KEY` is the OpenAI transcription-key override only and never
451
- selects client transport.
475
+ read the on-box `sqlite` file only when the deliberate unhosted opt-in
476
+ `HASNA_RECORDINGS_LOCAL=1` (alias `RECORDINGS_LOCAL=1`) selects it, or they
477
+ call the server's `/v1` HTTP API. Which one it is is decided by the ONE
478
+ credential resolver in [`@hasna/contracts`](https://www.npmjs.com/package/@hasna/contracts)
479
+ (resolved fresh on every call):
480
+
481
+ | tier | source |
482
+ | ---- | ------ |
483
+ | 1 | explicit `--api-key` / `--profile`, or `HASNA_RECORDINGS_API_KEY_OVERRIDE` / `HASNA_PROFILE` / `HASNA_RECORDINGS_API_KEY_REF` |
484
+ | 2 | the macOS Keychain item `hasna.credentials.recordings.api-key` (account `HASNA_STATION`, else `hostname -s`, else `$USER`) |
485
+ | 3 | `~/.hasna/recordings/config/credentials` (owner-only 0400/0600; `HASNA_HOME` / `HASNA_CONFIG_HOME` move the root) |
486
+ | 4 | `HASNA_RECORDINGS_API_KEY` — a legitimate tier, no deprecation notice |
487
+
488
+ The authority follows the same ladder — `HASNA_RECORDINGS_API_URL`, the
489
+ Keychain `api-url` item, the credentials file — and otherwise DEFAULTS to the
490
+ fleet gateway `https://api.hasna.com/recordings`, so a key alone is a complete
491
+ configuration. Retired inputs are gone: nothing reads the old fleet-env or
492
+ cloud credential directories, `~/.config/hasna` or `$XDG_CONFIG_HOME`, and no
493
+ `*_MODE` / `*_STORAGE_MODE` / `*_CLIENT_STORE` switch exists (the old
494
+ `HASNA_RECORDINGS_CLIENT_STORE` variable selects nothing any more).
495
+
496
+ **Fail closed.** Hosted mode with no credential exits non-zero with one
497
+ `REMOTE_API_*` line naming every tier that was consulted; there is no SQLite
498
+ fallback and no local-fallback event. The on-box file is reachable ONLY
499
+ through the explicit opt-in above, and an opted-in run reads neither the
500
+ Keychain nor any credential file. `RECORDINGS_API_KEY` remains the OpenAI
501
+ transcription-key override only — it is carved out of the resolver
502
+ environment and never selects or fails client transport.
503
+
504
+ The same gate runs before anything else connects: `recordings-mcp` refuses to
505
+ answer `initialize` (exit 1, first stderr line `ERROR: REMOTE_API_…`) when no
506
+ credential resolves and no opt-in is set, and `recordings check` renders
507
+ `✗ Active store: none — fail-closed (REMOTE_API_…); <db path> is present but
508
+ NOT opened` (or `absent`) and exits non-zero instead of displaying the on-box
509
+ file as the live store. With the opt-in set, `recordings-mcp` prints one
510
+ `recordings: LOCAL mode` line on stderr before serving the on-box store.
511
+
512
+ Native Settings saves new OpenAI transcription keys in macOS Keychain under
513
+ service `hasna.credentials.openai.api-key`, account `openai/api_key`. Finder
514
+ launches read that entry and pass it to the embedded helper in memory. Use
515
+ `RECORDINGS_OPENAI_API_KEY` for an explicit provider-key override, separate
516
+ from the Hasna service credential. The CLI no longer walks
517
+ `~/.secrets/**/*.env` for the OpenAI key (retired in the #1720 validation
518
+ wave): the declared stores are the env vars above, the config file, and the
519
+ macOS Keychain entry.
520
+
452
521
 
453
522
  ```bash
454
523
  recordings-serve --port 8874 # start the API
@@ -473,21 +542,70 @@ Env: `HASNA_RECORDINGS_DATABASE_URL` (PostgreSQL DSN — selects the
473
542
  `postgresql` backend) and `HASNA_RECORDINGS_API_SIGNING_KEY` (HMAC signing
474
543
  secret for API-key auth).
475
544
 
545
+ ### Production two-role deploy contract
546
+
547
+ The ECS deploy uses TWO database roles and TWO DSNs (the `migrate` one-shot
548
+ resolves `HASNA_RECORDINGS_MIGRATE_DATABASE_URL` /
549
+ `RECORDINGS_MIGRATE_DATABASE_URL`, falling back to the runtime DSN):
550
+
551
+ - **Migration / owner role** (e.g. `recordings_owner`) — runs the one-shot
552
+ `migrate` task and OWNS the schema. The task definition's
553
+ `HASNA_RECORDINGS_MIGRATE_DATABASE_URL` secret must point at this role's
554
+ DSN; the ECS execution role needs `secretsmanager:GetSecretValue` on that
555
+ secret.
556
+ - **Runtime role** (e.g. `recordings_app`) — the `DATABASE_URL` the serve
557
+ process reads. It must be STRICTLY DML-only; `recordings-serve` `/ready`
558
+ (and the migrate verb, when a dedicated migration DSN is configured)
559
+ enforce the least-privilege posture contract: no table/sequence ownership,
560
+ no `CREATE` on any schema, no `TEMPORARY` on the database, and exactly
561
+ these grants on the `public` schema:
562
+
563
+ | table | grants |
564
+ | --- | --- |
565
+ | `recordings` | SELECT, INSERT, DELETE |
566
+ | `recording_tags` | SELECT, INSERT |
567
+ | `agents` | SELECT, INSERT, UPDATE |
568
+ | `projects` | SELECT, INSERT, UPDATE |
569
+ | `feedback` | INSERT |
570
+ | `api_keys` | SELECT |
571
+ | `recording_idempotency` | SELECT, INSERT |
572
+
573
+ plus `USAGE` on schema `public`. A runtime role that owns tables (for
574
+ example because the migrate task ran DDL with the runtime DSN) makes
575
+ `/ready` return `503 {"error":"dependency unavailable"}` — the database is
576
+ healthy; the role posture is not. Remediate by re-owning the tables and
577
+ sequences to the owner role and granting the DML set above.
578
+
579
+ The table owner must also retain the privileges used by PostgreSQL's foreign
580
+ key cleanup: SELECT/UPDATE on `recording_idempotency.recording_id` and
581
+ SELECT/DELETE on `recording_tags`. Revoking the owner's DML privileges can
582
+ make recording deletion fail even when the runtime grants are correct.
583
+ Readiness checks both owner cleanup permissions. Restore these grants to the
584
+ affected table's owner; the runtime role remains SELECT/INSERT on both tables.
585
+
476
586
  ## SDK
477
587
 
478
588
  The typed `/v1` client is generated from the serve OpenAPI document
479
- (`bun run generate:sdk`):
589
+ (`bun run generate:sdk`). The resolver-backed factory resolves the credential
590
+ and authority through the same `@hasna/contracts` chain as the CLI, fresh on
591
+ every request, so a key rotation heals a client held open for hours:
480
592
 
481
593
  ```ts
482
- import { RecordingsV1Client } from "@hasna/recordings/sdk";
594
+ import { createRecordingsV1Client } from "@hasna/recordings/sdk";
483
595
 
484
- const client = new RecordingsV1Client({
485
- baseUrl: process.env.HASNA_RECORDINGS_API_URL!,
486
- apiKey: process.env.HASNA_RECORDINGS_API_KEY!,
487
- });
596
+ const client = createRecordingsV1Client(); // resolves through the chain
488
597
  const { recordings } = await client.listRecordings({ limit: 20 });
489
598
  ```
490
599
 
600
+ An explicit `baseUrl` pins the authority: with no `apiKey` beside it the
601
+ client sends NO credential at all (the ambient chain is never consulted), and
602
+ with one it sends exactly that key, every request. The unhosted local
603
+ `recordings-serve` (`http://localhost:8874`) is reachable only under
604
+ `HASNA_RECORDINGS_LOCAL=1` and prints one "LOCAL mode" line on stderr; every
605
+ other refusal throws `RECORDINGS_CREDENTIAL_MISSING`. The raw generated
606
+ constructor `new RecordingsV1Client({ baseUrl, apiKey })` still works for
607
+ explicit configurations.
608
+
491
609
  Useful agent tools include `recordings_status` for safe service/config diagnostics,
492
610
  `transcribe_audio`, `save_recording`, `list_recordings`, `search_recordings`,
493
611
  `register_agent`, `heartbeat`, and `set_focus`.
@@ -546,6 +664,74 @@ bundle is only as verified as the last macOS build.
546
664
 
547
665
  Data is stored in `~/.hasna/recordings/`.
548
666
 
667
+ ## Audio artifact upload (S3 via the artifact kit)
668
+
669
+ On `recordings record` / `recordings transcribe`, the audio is uploaded at
670
+ creation as a content-addressed object and the row records
671
+ `audio_object_key`, `audio_sha256` and `audio_bytes` (the local `audio_path`
672
+ stays as provenance). Without configuration, nothing changes: audio remains
673
+ local-only.
674
+
675
+ Environment:
676
+
677
+ - `HASNA_RECORDINGS_S3_BUCKET` (fallback `RECORDINGS_S3_BUCKET`) — the bucket
678
+ to upload into; unset/empty keeps the historical local-only behaviour.
679
+ - `HASNA_RECORDINGS_S3_PREFIX` (fallback `RECORDINGS_S3_PREFIX`) — object-key
680
+ prefix inside the bucket; defaults to `recordings`, so keys look like
681
+ `recordings/<recording_id>/<sha256>.<ext>`.
682
+ - `RECORDINGS_S3_REGION` (fallback `AWS_REGION`, then `us-east-1`) — the
683
+ region for the S3 client. Credentials are never read by the app: the AWS SDK
684
+ resolves them from the ambient environment or instance role at send time.
685
+
686
+ Upload failures never lose a recording: the row is still created and the
687
+ warning is logged, matching the fail-soft contract of the app-side fix.
688
+
549
689
  ## License
550
690
 
551
691
  Apache-2.0 -- see [LICENSE](LICENSE)
692
+
693
+ ## Reusing the native recorder
694
+
695
+ The Swift package at `src/native/Recordings` exports the `RecordingsLib` library.
696
+ A separate macOS application can depend on that package and reuse `RecordingEngine`
697
+ for real PCM capture, pause, meters, recording state, clipboard and verified paste:
698
+
699
+ ```swift
700
+ import RecordingsLib
701
+
702
+ let configuration = try RecordingEngineConfiguration(
703
+ isolatedHomePath: candidateStateHome.path,
704
+ preferencesSuiteName: "com.example.recorder.preferences"
705
+ )
706
+ let engine = RecordingEngine(configuration: configuration, transcriptionProvider: provider)
707
+ ```
708
+
709
+ The isolated initializer never installs global shortcuts or fn monitors and does
710
+ not read the legacy provider credentials, service URL, launch environment or CLI.
711
+ It rejects the installed recorder's home and preferences suite. Its audio and logs
712
+ live below `<isolatedHomePath>/.hasna/recordings`; preferences use only the named
713
+ suite. The original `RecordingEngine(homePath:installsGlobalHandlers:)` initializer
714
+ retains the legacy application's behavior.
715
+
716
+ Implement `RecordingTranscriptionProvider.makeSession(configuration:onPartialTranscript:)`
717
+ to create one session per recording. Construction must return promptly. Its
718
+ `appendPCM` method receives ordered 24 kHz mono PCM16LE chunks during recording;
719
+ paused samples are excluded. Publish partial callbacks as the complete current
720
+ transcript. `finish` receives the finalized WAV URL, duration, language and capture
721
+ ID, and returns `RecordingProviderResult`. `cancel` must safely interrupt a pending
722
+ connection or finish; any in-flight append must be ignored after cancellation.
723
+ Providers own their bounded networking queues and credential namespace. A local
724
+ file recognizer may ignore streaming chunks and recognize the WAV at finish.
725
+
726
+ Completed results appear in `recentTranscriptions` with `captureID` and `audioURL`
727
+ before automatic paste starts, allowing the consumer to persist them asynchronously.
728
+ This publication is not a storage acknowledgement; `persistedRecordingRevision`
729
+ continues to describe only legacy CLI persistence. Call `cancelRecording()` to
730
+ discard capture or cancel an isolated provider that is still finalizing.
731
+
732
+ Completed paste transactions publish `RecentPaste.captureID` and the typed
733
+ `deliveryStatus` (`confirmed`, `unconfirmed`, or `notDelivered`). A posted
734
+ keystroke is never a confirmed delivery. Pass a `captureID` to
735
+ `pasteIntoFrontApp` when manually pasting a saved recording. Early permission
736
+ or target failures remain visible in the engine status without a completed
737
+ transaction receipt.
package/bun.lock CHANGED
@@ -5,7 +5,8 @@
5
5
  "": {
6
6
  "name": "@hasna/recordings",
7
7
  "dependencies": {
8
- "@hasna/contracts": "0.14.1",
8
+ "@aws-sdk/client-s3": "^3.1007.0",
9
+ "@hasna/contracts": "1.0.2",
9
10
  "@hasna/events": "0.1.11",
10
11
  "@modelcontextprotocol/sdk": "^1.12.1",
11
12
  "chalk": "^5.4.1",
@@ -15,7 +16,7 @@
15
16
  "zod": "^3.24.2",
16
17
  },
17
18
  "devDependencies": {
18
- "@types/bun": "^1.2.5",
19
+ "@types/bun": "1.3.14",
19
20
  "@types/pg": "^8.11.11",
20
21
  "node-api-headers": "1.9.0",
21
22
  "typescript": "^5.8.2",
@@ -23,69 +24,67 @@
23
24
  },
24
25
  },
25
26
  "packages": {
26
- "@aws-sdk/client-secrets-manager": ["@aws-sdk/client-secrets-manager@3.1111.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/credential-provider-node": "^3.972.80", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/fetch-http-handler": "^5.6.13", "@smithy/node-http-handler": "^4.9.13", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-+OQYrSTkRJV826I4+PuXY+h6m1lqo5LTGtbPsJ5JWlpuYr+GY9vTyWO4qOoyUu+YnRqD5NTXSCQqmZXACJsYJg=="],
27
+ "@aws-sdk/checksums": ["@aws-sdk/checksums@3.1000.29", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Dtu0gr4dnATZAPwEYbpCsG+MpLM7OAliy2gTepEFQwl1vZ6DL3QMH2FveMa3HLvPsOdhJsPRB3KtxVhph9T75A=="],
27
28
 
28
- "@aws-sdk/core": ["@aws-sdk/core@3.977.8", "", { "dependencies": { "@aws-sdk/types": "^3.974.4", "@aws-sdk/xml-builder": "^3.972.39", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.31.1", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.16.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-7+Kcrkvrk9lM/m7jRhHpT4jCdvzGHsuaSRbF8TdzzkY1mRzp/Ogwf9c7H29k4gGhey0BBWhCWr16+t0J61gwmg=="],
29
+ "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1127.0", "", { "dependencies": { "@aws-sdk/checksums": "^3.1000.29", "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-node": "^3.972.82", "@aws-sdk/middleware-sdk-s3": "^3.972.75", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-0ZSAgmEda33xPqVPt+bx2KzrXV1cUCKRRVPGliLu+V7DzHPa04CqPSi1maGEM4O0LDP0iI6HRSW5ULloNwayNw=="],
29
30
 
30
- "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.68", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-Fo2RC5hZmEVhnVLMzNjYL6Iu78F4wDuaNtkgzRVU4DlUaFhcXxsnxWBOTH2drxZ59OHSipQ1LndfkCWPxGBJHA=="],
31
+ "@aws-sdk/core": ["@aws-sdk/core@3.977.9", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@aws-sdk/xml-builder": "^3.972.40", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.33.3", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-reqPFEQrZxDZpeGj4PFMepBeR5LGYHRqq/L0motTzgFkCRBA4rFdaVXDSLYyGHhxVz7sT2PDnPN9CluGSfgyJA=="],
31
32
 
32
- "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.69", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-AreCFzcB4kH2HF9031Ot0jSJr3KXvRg6e8uDeub20JEVdZU3Bv0sTq1plc7VsT3KiqutlzH7l0j50UcCWHUioA=="],
33
+ "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-H404B7dJl2mCrBqahDEYsanB0xhdDp6tXnXcTUnXmmpy2Q3J0Ho0bUajZ2jr/RdwzCyS59Gi8xXIFwPLGBl6Uw=="],
33
34
 
34
- "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.71", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/fetch-http-handler": "^5.6.13", "@smithy/node-http-handler": "^4.9.13", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-A8ObcqVmDMnk4F9NozZ7JwmUu9Q4xyBJkmyq1C5U+wNM9ht9J7+EuuyabsLWXZnOoTqFaJuYBYTKf5CTipkEjA=="],
35
+ "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-X98zYOrVOeuosCX+6ktf29FC2N2GHPLia7qv6mzPzTc+RPAuHWCDS++Z6JK7eGYqb/v6uaW7bAXaOvDBfol+0w=="],
35
36
 
36
- "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.14", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/credential-provider-env": "^3.972.69", "@aws-sdk/credential-provider-http": "^3.972.71", "@aws-sdk/credential-provider-login": "^3.972.76", "@aws-sdk/credential-provider-process": "^3.972.69", "@aws-sdk/credential-provider-sso": "^3.973.13", "@aws-sdk/credential-provider-web-identity": "^3.972.75", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-7c+Wti2LsERNWMfm7ySz3/6RPopFW3Nmn7s63Xpcq6R/tRuY5hpvkHA2xVgi5ukJbvok9l0IDtVEvqTtg+X7dw=="],
37
+ "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.15", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-login": "^3.972.77", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Rykg6s5ceBuynMOGWgoowO4N+27JfnqXAnVaSunZl0hOO1XodSrxGNz6sCEbnmS0lAfQZDKyb3fbr46gSuv6Sg=="],
37
38
 
38
- "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.76", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-LVixwOnEJfrrfKHeZjBA8pIMTZjNDq8ak8VpcoWUuCJDrSnBNU8POJksULMgvN089P0MXtQYH2Zs627/MK1K0g=="],
39
+ "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.77", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Jb59xfEISoN5mmbnA+HYqdtrSX3CgCtJoof+V5D8/TgUI56W63GEEd5Y58WijU3Ou6+WEgaLD1feVzaRXV5IDQ=="],
39
40
 
40
- "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.80", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.69", "@aws-sdk/credential-provider-http": "^3.972.71", "@aws-sdk/credential-provider-ini": "^3.973.14", "@aws-sdk/credential-provider-process": "^3.972.69", "@aws-sdk/credential-provider-sso": "^3.973.13", "@aws-sdk/credential-provider-web-identity": "^3.972.75", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-bE2qh8ww4iClO1jHsBXdOE8FUgzDbdxbyorNjSCoPSkQd51k3jODItuPZfuwcLHZqDXsH+bI4AMHhqtuyR7mSg=="],
41
+ "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.82", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-ini": "^3.973.15", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-znDkEOGXB8W3kG1LJUKP3foBZY/9qLM0eil/DxWXSp37XsdsRLQHE/d/OaCGGVgKpA6znR38h/+INk8do1FjiA=="],
41
42
 
42
- "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.69", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-9kpTNdZTrcqXTfhxM7fgl9Z68ek3Fu5oe3Yf+A/pJGibEqpgZxz2tSY7SinmyCIU2PJ+ygY4FPoBBnLpocMtrQ=="],
43
+ "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-2ry03fGRJr4sV3jI+ocjj5JqALnFD6ymM5KiNCDZMvq8bX2GSbE0vji4aM43TVCl2nXqqLRZaUxdq/KeWRAY4Q=="],
43
44
 
44
- "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.13", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/token-providers": "3.1111.0", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-Oc81qauMPzUoTnAS2YKpNwY6sY/LUyQTEeaf6yP197WMxkEBQfcKLR1MFpD7+pNTubXnfkH6gwpji+Gc7iyD2Q=="],
45
+ "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.14", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/token-providers": "3.1116.0", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-jkhg/8ocAAoc0RFyLMhCw+/zZh7gystQgd4F4hznNa8P4Cc501PQmxd+jGLiMHodPJ+7Zv/3znM62gZojyasmA=="],
45
46
 
46
- "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.75", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-YPN6uoGDgjjjeVFZrcOeCJqmB6zpXoeeNgIjqe+DexJaWqdjVfCCe+VAZwli9Z2h8KhFW8oxkO39emQ1tyz/Mw=="],
47
+ "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.76", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-d3AGyVu759PGr35mEB2s22xxlNEA5rpdxtSPJthfPFJvoQ8dt357iVPECqWfUxXp1toJAvKmbtcIYVGigaGsCA=="],
47
48
 
48
- "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1111.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/credential-provider-cognito-identity": "^3.972.68", "@aws-sdk/credential-provider-env": "^3.972.69", "@aws-sdk/credential-provider-http": "^3.972.71", "@aws-sdk/credential-provider-ini": "^3.973.14", "@aws-sdk/credential-provider-login": "^3.972.76", "@aws-sdk/credential-provider-node": "^3.972.80", "@aws-sdk/credential-provider-process": "^3.972.69", "@aws-sdk/credential-provider-sso": "^3.973.13", "@aws-sdk/credential-provider-web-identity": "^3.972.75", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-kon/lEuONhTw4F4nYo2mOlzi+2yWJyLWzyuTFK8bH0j5TG5fA/6B4y754ma6lvM9N2QNjhF9TG01kHO2eFYAcQ=="],
49
+ "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.75", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wMIsNumRVKaNMKhvU/s9VrdEwE8S6gSzXp4RygFG5BEMnGkkXf8cjh8zf7cKJBpUDpqTWqwbz5isEgp9rH6Lng=="],
49
50
 
50
- "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.43", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/signature-v4-multi-region": "^3.996.45", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/fetch-http-handler": "^5.6.13", "@smithy/node-http-handler": "^4.9.13", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-bit+VpqWNyi3wHxFoTsTliNXimCSL2r2OeDTm7ZrG+YsTZ2D7ofDJ6r/t9PVBn80i6/v0X2h9Tgw6QP2MAKfPw=="],
51
+ "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.44", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-NhEgryjlBF9w38ZXqGymQV28IhkYa1mKhlbYnqIis57AYwWGVYfUPgg/qC2rLRqOUfblxx++irvju10kVTa8Vw=="],
51
52
 
52
- "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.45", "", { "dependencies": { "@aws-sdk/types": "^3.974.4", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-bBuyztukzXq6plzFGHAWiQt0QXo+HL8b8lX5cFTzkez/74PtS1c0qPFCIVuHkyoT+miH2qOjAcm1/yoro2ESPA=="],
53
+ "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.46", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ=="],
53
54
 
54
- "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1111.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.8", "@aws-sdk/nested-clients": "^3.997.43", "@aws-sdk/types": "^3.974.4", "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-JfljgoVtl+s3Qy21n9a7Z48uCQaOXcN74KJ3TEQfPoB293GrXFSt6HSQJF1sTZ8c/5QedEvd3NjJQMO4u9qa5A=="],
55
+ "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1116.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-ygIivKqh8aHzNkucOCXHyIBgBpLPfrSI0mCqXF+vLBsPTUKqj0VSqAY0GFPe7lQl4HntjOcQ+KSyS7oUV2C54Q=="],
55
56
 
56
- "@aws-sdk/types": ["@aws-sdk/types@3.974.4", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-dSFDNG00MEz0/xl5gxL62giLd1iYyJsTxZ1I1DOj6lC+bbgLB4TRsYClJg3b62dhXT1uATzsTNXPnC+33EJV3A=="],
57
+ "@aws-sdk/types": ["@aws-sdk/types@3.974.5", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ=="],
57
58
 
58
- "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.39", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-FTti8DS5MMWXNUWiRwXAJeYS+0GHHiMy0+7XOhcwk63ILHmfS2UFy2z/HNpZCSOJJ3P3dnWY6hfYNW3DF0nXUA=="],
59
+ "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.40", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA=="],
59
60
 
60
61
  "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="],
61
62
 
62
- "@hasna/contracts": ["@hasna/contracts@0.14.1", "", { "dependencies": { "commander": "^13.1.0", "zod": "^3.25.76", "zod-to-json-schema": "^3.24.6" }, "peerDependencies": { "@hasna/secrets": "0.3.10" }, "bin": { "contracts": "dist/cli/index.js", "contracts-cli": "dist/cli/contracts-cli.js" } }, "sha512-aAh6st+k74Lk70rhkXTYyx4JILQHJFfAR88fgunc5tm3cF8jK772pqrFIL/cwp6b0++JzapTWFI87qsNn0dakA=="],
63
+ "@hasna/contracts": ["@hasna/contracts@1.0.2", "", { "dependencies": { "commander": "^13.1.0", "zod": "^3.25.76", "zod-to-json-schema": "^3.24.6" }, "peerDependencies": { "@hasna/secrets": "^0.3.10 || ^0.4.0" }, "optionalPeers": ["@hasna/secrets"], "bin": { "contracts": "dist/cli/index.js", "contracts-cli": "dist/cli/contracts-cli.js" } }, "sha512-Wq6ma5qR+ozmMabPZ1EyHb3TVRi37jYkrjiEmIpd6ZpTQY5H2gRept/e8kxlA/xOyxFN6bPhKcFQ7FmhuCpnwQ=="],
63
64
 
64
65
  "@hasna/events": ["@hasna/events@0.1.11", "", { "dependencies": { "commander": "^13.1.0" }, "bin": { "events": "dist/cli/index.js", "hasna-events": "dist/cli/index.js" } }, "sha512-X36W9TB8mKxtS5UeW1n2IlvW6nPUcoYCQWNMMV+/JM4YNzlnnk1FRm8Aay02tt1LjQOGICCHF3hz/l//EHEe+Q=="],
65
66
 
66
- "@hasna/secrets": ["@hasna/secrets@0.3.3", "", { "dependencies": { "@aws-sdk/client-secrets-manager": "^3.1008.0", "@aws-sdk/credential-providers": "^3.1008.0", "@hasna/events": "^0.1.16", "@modelcontextprotocol/sdk": "^1.27.1", "@smithy/core": "^3.25.1", "commander": "^13.1.0", "pg": "^8.20.0", "zod": "3.25.76" }, "peerDependencies": { "@hasna/contracts": "^0.13.1" }, "bin": { "secrets": "dist/index.js", "secrets-mcp": "dist/mcp-server.js", "secrets-serve": "dist/server/index.js" } }, "sha512-Gg9ZjrKXxLf8PhTLphzQBQU+JeDRDidzdoohYfD/Fxicf/c4nLtBnIvV0NzIhpYBnLjW4unN9TQu0LHUb0DTuA=="],
67
-
68
67
  "@hono/node-server": ["@hono/node-server@2.1.1", "", { "peerDependencies": { "hono": "^4" } }, "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg=="],
69
68
 
70
69
  "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.30.0", "", { "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA=="],
71
70
 
72
- "@smithy/core": ["@smithy/core@3.33.2", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CUGXpnPkVdjUCbix+83sWLW9VFgQOm44MDOx/ihITJMAnOZKvL8YYIc7DR9pP/tZ8CIRvMiON/TucvygqbHO3w=="],
71
+ "@smithy/core": ["@smithy/core@3.33.3", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg=="],
73
72
 
74
73
  "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.5.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg=="],
75
74
 
76
- "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.7.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-nZyWTmSpJEXl6VtWVMBJve/7x12DZu6sIX1z1a+ZMaHlQQRs9Zpu6NbTe/gmxYXVRpkjxyDYpZ5gx2IM6f/Wkw=="],
75
+ "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.8.0", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA=="],
77
76
 
78
- "@smithy/node-http-handler": ["@smithy/node-http-handler@4.11.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-avwAh9HM3h2lcfjvP3zYIZGf+XVgLQ91wOJ2qoFbNpW1UZeZb33aGlhTZvtkANHfcGhJroRY64525OjfgOg30g=="],
77
+ "@smithy/node-http-handler": ["@smithy/node-http-handler@4.12.1", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw=="],
79
78
 
80
- "@smithy/signature-v4": ["@smithy/signature-v4@5.7.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-P7Ki6px6OOrxVtx8K7nLmyx4SlXUW/uTKDdMG44UHefmPGSRMBKe2v+TM59WdLcpUIrBrnuCsIqiM2MbsZjmhw=="],
79
+ "@smithy/signature-v4": ["@smithy/signature-v4@5.7.3", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow=="],
81
80
 
82
- "@smithy/types": ["@smithy/types@4.17.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-FOKpVZob9MPTn2znRzGrnsMHv7BOsKVw3XiP/cOyYLDVZ9qKp4nifIiSCuUU/fIj5Vu0UOAxCFr+qRAtG0NUkA=="],
81
+ "@smithy/types": ["@smithy/types@4.18.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A=="],
83
82
 
84
83
  "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
85
84
 
86
- "@types/node": ["@types/node@26.2.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="],
85
+ "@types/node": ["@types/node@26.4.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA=="],
87
86
 
88
- "@types/pg": ["@types/pg@8.21.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-AYdtudzabjLZgVgRZmAnU8bAnVUXzuJX2IYHeSIiIHm68olD+LgQYCGWdtcNYnP0uq9c4S4NibVG3Ni7VbKW7Q=="],
87
+ "@types/pg": ["@types/pg@8.23.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A=="],
89
88
 
90
89
  "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
91
90
 
@@ -147,11 +146,11 @@
147
146
 
148
147
  "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
149
148
 
150
- "express-rate-limit": ["express-rate-limit@8.6.2", "", { "dependencies": { "debug": "^4.4.3", "ip-address": "^10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-YH4ru+eOJxQABscKFfRCy9R7x9QFGdezclVMwwgFFndzS2Xnm0uo6B0ABZsLhcpeptGv2qvuJVWlQr9gQZoC3A=="],
149
+ "express-rate-limit": ["express-rate-limit@8.7.0", "", { "dependencies": { "debug": "^4.4.3", "ip-address": "^10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g=="],
151
150
 
152
151
  "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
153
152
 
154
- "fast-uri": ["fast-uri@3.1.5", "", {}, "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw=="],
153
+ "fast-uri": ["fast-uri@3.1.7", "", {}, "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg=="],
155
154
 
156
155
  "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="],
157
156
 
@@ -171,7 +170,7 @@
171
170
 
172
171
  "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
173
172
 
174
- "hono": ["hono@4.13.2", "", {}, "sha512-JydRilDRkYBQMt9qR9U92mXxmbGqsqSn/IKOrh4e7/gEbn+0zSr8igTu0obwJoNGN4sez28DIql7FBHWydoJpA=="],
173
+ "hono": ["hono@4.13.7", "", {}, "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ=="],
175
174
 
176
175
  "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
177
176
 
@@ -179,7 +178,7 @@
179
178
 
180
179
  "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
181
180
 
182
- "ip-address": ["ip-address@10.5.0", "", {}, "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g=="],
181
+ "ip-address": ["ip-address@10.7.0", "", {}, "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA=="],
183
182
 
184
183
  "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
185
184
 
@@ -187,7 +186,7 @@
187
186
 
188
187
  "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
189
188
 
190
- "jose": ["jose@6.2.9", "", {}, "sha512-XrchZOFZUl/T3vTwRe8XK+cJrGtMF4th1ARnDfwbBXFKThGhlsxEE4Zu03AD/bjJSt/9jT/mxrOCkJWOg77aPA=="],
189
+ "jose": ["jose@6.2.12", "", {}, "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw=="],
191
190
 
192
191
  "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
193
192
 
@@ -205,7 +204,7 @@
205
204
 
206
205
  "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
207
206
 
208
- "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
207
+ "negotiator": ["negotiator@1.1.0", "", { "dependencies": { "content-type": "^2.1.0" } }, "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg=="],
209
208
 
210
209
  "node-api-headers": ["node-api-headers@1.9.0", "", {}, "sha512-2oNILP4jXwRB4ywnYKjVk1YyJ96n2D4EOVJO6S3oYZ5PtbJrw3Yt9TpAuX3nBLMuzn74rnfGQrv13pS9vC+YiA=="],
211
210
 
@@ -253,7 +252,7 @@
253
252
 
254
253
  "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
255
254
 
256
- "qs": ["qs@6.15.3", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="],
255
+ "qs": ["qs@6.16.0", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA=="],
257
256
 
258
257
  "range-parser": ["range-parser@1.3.0", "", {}, "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw=="],
259
258
 
@@ -311,10 +310,10 @@
311
310
 
312
311
  "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="],
313
312
 
314
- "@hasna/secrets/@hasna/events": ["@hasna/events@0.1.16", "", { "dependencies": { "commander": "^13.1.0" }, "bin": { "events": "dist/cli/index.js", "hasna-events": "dist/cli/index.js" } }, "sha512-HX66T8JljVOoE/Li8WKLUFVozg0GIdZmgBalScfBFW5Vru4IcVSTNs07TmYH3kIJUe5tylItTqwzc02nvjqbfw=="],
315
-
316
313
  "body-parser/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="],
317
314
 
315
+ "negotiator/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="],
316
+
318
317
  "type-is/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="],
319
318
  }
320
319
  }