@hasna/recordings 0.3.13 → 0.5.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 (148) hide show
  1. package/README.md +279 -43
  2. package/bun.lock +37 -38
  3. package/contracts/v1/fixtures.json +1206 -0
  4. package/dist/cli/index.js +1909 -619
  5. package/dist/cli/macos-shortcut.d.ts +2 -2
  6. package/dist/contracts/hosted-v1.d.ts +105 -0
  7. package/dist/contracts/hosted-v1.d.ts.map +1 -0
  8. package/dist/contracts/hosted-v1.js +41 -0
  9. package/dist/contracts/stream-v1.d.ts +117 -0
  10. package/dist/contracts/stream-v1.d.ts.map +1 -0
  11. package/dist/contracts/stream-v1.js +35 -0
  12. package/dist/db/database.d.ts.map +1 -1
  13. package/dist/db/pg-migrations.d.ts.map +1 -1
  14. package/dist/db/recordings.d.ts +6 -0
  15. package/dist/db/recordings.d.ts.map +1 -1
  16. package/dist/hosted/index.d.ts +58 -0
  17. package/dist/hosted/index.d.ts.map +1 -0
  18. package/dist/hosted/index.js +266 -0
  19. package/dist/hosted/transport.d.ts +36 -0
  20. package/dist/hosted/transport.d.ts.map +1 -0
  21. package/dist/hosted-v1-aavn7ktb.js +4114 -0
  22. package/dist/hosted-v1-gdr9extc.js +84 -0
  23. package/dist/http/client.d.ts +183 -22
  24. package/dist/http/client.d.ts.map +1 -1
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2879 -2288
  28. package/dist/lib/audio-artifact-storage.d.ts +98 -0
  29. package/dist/lib/audio-artifact-storage.d.ts.map +1 -0
  30. package/dist/lib/capture-probe.d.ts +3 -3
  31. package/dist/lib/capture-probe.d.ts.map +1 -1
  32. package/dist/lib/config.d.ts.map +1 -1
  33. package/dist/lib/local-opt-in.d.ts +132 -0
  34. package/dist/lib/local-opt-in.d.ts.map +1 -0
  35. package/dist/lib/macos-bundle.d.ts +1 -1
  36. package/dist/lib/persistence-probe.d.ts +56 -17
  37. package/dist/lib/persistence-probe.d.ts.map +1 -1
  38. package/dist/lib/transcriber.d.ts.map +1 -1
  39. package/dist/mcp/index.d.ts.map +1 -1
  40. package/dist/mcp/index.js +1713 -459
  41. package/dist/sdk/index.d.ts +13 -5
  42. package/dist/sdk/index.d.ts.map +1 -1
  43. package/dist/sdk/index.js +904 -1
  44. package/dist/sdk/resolve.d.ts +53 -0
  45. package/dist/sdk/resolve.d.ts.map +1 -0
  46. package/dist/sdk/v1.generated.d.ts +6 -0
  47. package/dist/sdk/v1.generated.d.ts.map +1 -1
  48. package/dist/server/client-ip.d.ts +39 -0
  49. package/dist/server/client-ip.d.ts.map +1 -0
  50. package/dist/server/cloud-config.d.ts +12 -0
  51. package/dist/server/cloud-config.d.ts.map +1 -1
  52. package/dist/server/cloud-readiness.d.ts.map +1 -1
  53. package/dist/server/cloud.d.ts +20 -2
  54. package/dist/server/cloud.d.ts.map +1 -1
  55. package/dist/server/index.js +590 -287
  56. package/dist/server/migrate-command.d.ts +1 -1
  57. package/dist/server/migrate-command.d.ts.map +1 -1
  58. package/dist/server/openapi.d.ts +21 -0
  59. package/dist/server/openapi.d.ts.map +1 -1
  60. package/dist/server/repo.d.ts.map +1 -1
  61. package/dist/server/serve.d.ts.map +1 -1
  62. package/dist/storage.d.ts +2 -2
  63. package/dist/storage.d.ts.map +1 -1
  64. package/dist/storage.js +1358 -874
  65. package/dist/store.d.ts +12 -3
  66. package/dist/store.d.ts.map +1 -1
  67. package/dist/types/index.d.ts +15 -0
  68. package/dist/types/index.d.ts.map +1 -1
  69. package/docs/hosted-sdk.md +71 -0
  70. package/docs/wire-contracts.md +24 -0
  71. package/package.json +33 -11
  72. package/packaging/macos/build_release_pkg.sh +3 -3
  73. package/packaging/macos/managed_bootstrap.sh +4 -4
  74. package/packaging/macos/scripts/postinstall +2 -2
  75. package/packaging/macos/scripts/preinstall +2 -2
  76. package/scripts/build_companion_cli.sh +7 -1
  77. package/scripts/ci-linux-suite.ts +23 -13
  78. package/scripts/install_macos_app.sh +27 -24
  79. package/scripts/macos_artifact.ts +60 -49
  80. package/scripts/migrate.ts +4 -20
  81. package/scripts/native/prebuilds/darwin-universal/recordings_fs_guard.node +0 -0
  82. package/scripts/native/recordings_fs_guard.c +36 -4
  83. package/scripts/native-core-receipt.py +171 -0
  84. package/scripts/native_fs_guard.ts +2 -0
  85. package/scripts/release-suite-gate.ts +227 -150
  86. package/scripts/resolve_tailscale_cli.sh +24 -3
  87. package/scripts/smoke_macos_app.sh +21 -21
  88. package/src/native/Recordings/App/ContentView.swift +53 -68
  89. package/src/native/Recordings/App/MenuBarStatusView.swift +171 -61
  90. package/src/native/Recordings/App/RecordWorkspaceView.swift +47 -449
  91. package/src/native/Recordings/App/RecorderSettingsView.swift +75 -0
  92. package/src/native/Recordings/App/RecordingDetailView.swift +3 -4
  93. package/src/native/Recordings/App/RecordingsApp.swift +185 -9
  94. package/src/native/Recordings/App/RecordingsListView.swift +60 -112
  95. package/src/native/Recordings/App/RecordingsStore.swift +124 -109
  96. package/src/native/Recordings/App/Theme.swift +73 -61
  97. package/src/native/Recordings/Package.swift +1 -0
  98. package/src/native/Recordings/RecordingsLib/BlockingOperation.swift +29 -0
  99. package/src/native/Recordings/RecordingsLib/CaptureMonitor.swift +65 -0
  100. package/src/native/Recordings/RecordingsLib/Info.plist +3 -3
  101. package/src/native/Recordings/RecordingsLib/OpenAIAPIKeyStore.swift +75 -21
  102. package/src/native/Recordings/RecordingsLib/ProjectStore.swift +4 -4
  103. package/src/native/Recordings/RecordingsLib/Recording.swift +14 -2
  104. package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +539 -89
  105. package/src/native/Recordings/RecordingsLib/RecordingGlassBackground.swift +34 -0
  106. package/src/native/Recordings/RecordingsLib/RecordingPasteTarget.swift +114 -0
  107. package/src/native/Recordings/RecordingsLib/RecordingProvider.swift +112 -0
  108. package/src/native/Recordings/RecordingsLib/RecordingsCLI.swift +17 -10
  109. package/src/native/Recordings/RecordingsLib/ServiceAPIConfiguration.swift +107 -0
  110. package/src/native/Recordings/RecordingsLib/ServiceConnectionView.swift +76 -0
  111. package/src/native/Recordings/RecordingsLib/SettingsView.swift +45 -149
  112. package/src/native/Recordings/RecordingsLib/SettingsWindowController.swift +48 -0
  113. package/src/native/Recordings/RecordingsTests/BlockingOperationTests.swift +85 -0
  114. package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +454 -76
  115. package/src/native/Recordings/RecordingsTests/OpenAIAPIKeyStoreTests.swift +43 -38
  116. package/src/native/Recordings/RecordingsTests/PipeClosureFixture.swift +215 -0
  117. package/src/native/Recordings/RecordingsTests/ProjectStoreTests.swift +10 -10
  118. package/src/native/Recordings/RecordingsTests/RecorderSurfaceTests.swift +60 -0
  119. package/src/native/Recordings/RecordingsTests/RecordingDateTests.swift +26 -0
  120. package/src/native/Recordings/RecordingsTests/RecordingEngineDeliveryTests.swift +1 -1
  121. package/src/native/Recordings/RecordingsTests/RecordingFrozenPasteTargetTests.swift +50 -0
  122. package/src/native/Recordings/RecordingsTests/RecordingPasteTargetTrackerTests.swift +48 -0
  123. package/src/native/Recordings/RecordingsTests/RecordingProviderTests.swift +308 -0
  124. package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +1 -1
  125. package/src/native/Recordings/RecordingsTests/RecordingStartTimingTests.swift +123 -21
  126. package/src/native/Recordings/RecordingsTests/ServiceAPIConfigurationTests.swift +75 -0
  127. package/src/native/Recordings/RecordingsTests/SettingsWindowControllerTests.swift +28 -0
  128. package/src/native/Recordings/RecordingsTests/TestHomeDirectory.swift +5 -1
  129. package/src/native/Recordings/Updater/BootstrapPreflight/BootstrapPreflightMain.swift +1 -1
  130. package/src/native/Recordings/Updater/Broker/ApplicationNamespace.swift +2 -2
  131. package/src/native/Recordings/Updater/Broker/BrokerMain.swift +1 -1
  132. package/src/native/Recordings/Updater/Broker/CanonicalTreeCopy.swift +1 -1
  133. package/src/native/Recordings/Updater/Broker/InstallJournal.swift +1 -1
  134. package/src/native/Recordings/Updater/BrokerTests/ActivationRecoveryPolicyTests.swift +2 -2
  135. package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +1 -1
  136. package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +2 -2
  137. package/src/native/Recordings/build.sh +8 -7
  138. package/dist/__tests__/helpers/installer-guard-execution.d.ts +0 -22
  139. package/dist/__tests__/helpers/installer-guard-execution.d.ts.map +0 -1
  140. package/dist/__tests__/helpers/installer-preflight.d.ts +0 -22
  141. package/dist/__tests__/helpers/installer-preflight.d.ts.map +0 -1
  142. package/dist/__tests__/helpers/native-fs-guard.d.ts +0 -2
  143. package/dist/__tests__/helpers/native-fs-guard.d.ts.map +0 -1
  144. package/dist/__tests__/helpers/source-assertions.d.ts +0 -171
  145. package/dist/__tests__/helpers/source-assertions.d.ts.map +0 -1
  146. package/dist/__tests__/preload.d.ts +0 -2
  147. package/dist/__tests__/preload.d.ts.map +0 -1
  148. package/src/native/Recordings/App/SidebarView.swift +0 -212
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Artifact kit for recording audio — the object-store half of the storage
3
+ * layer, modelled on the shared kit pattern first shipped for skills bundles
4
+ * (hasna/apps#1639, apps/skills/src/server/artifact-storage.ts).
5
+ *
6
+ * One class, `AudioArtifactStorage`, has two modes:
7
+ * • db/local-only — no bucket configured: `usesS3` is false, every method is
8
+ * a no-op returning null, and recordings keep the historical behaviour of
9
+ * `audio_path`-only provenance on the recording machine.
10
+ * • s3 — a bucket is configured (env `HASNA_RECORDINGS_S3_BUCKET` /
11
+ * `RECORDINGS_S3_BUCKET`): audio bytes are placed as a content-addressed
12
+ * object `recordings/<recording_id>/<sha256>.<ext>` (prefix configurable
13
+ * via `HASNA_RECORDINGS_S3_PREFIX`), and the row records the object key,
14
+ * the digest and the byte size.
15
+ *
16
+ * The key is content-addressed: the digest is part of the key, so re-uploading
17
+ * the same bytes is idempotent (identical key, identical object) and a wrong
18
+ * digest can never be stored because only a verified lowercase hex sha-256 is
19
+ * accepted into a key. The recording id segment is structural — one recording
20
+ * never shares a key with another, and a bucket policy or lifecycle rule can
21
+ * key on it.
22
+ *
23
+ * The S3 client is injectable (`client` option) so tests can stand in an
24
+ * in-memory bucket exactly like the skills kit tests do. Credentials are
25
+ * never read here: the AWS SDK resolves them from the ambient environment /
26
+ * instance role at send time.
27
+ */
28
+ import { GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
29
+ /** Default object-key prefix; matches the issue's `recordings/<id>/<sha256>.<ext>` layout. */
30
+ export declare const DEFAULT_S3_PREFIX = "recordings";
31
+ /** The slice of the AWS client the storage uses; injectable so tests can stand in an in-memory bucket. */
32
+ export interface S3ClientLike {
33
+ send(command: PutObjectCommand | GetObjectCommand): Promise<{
34
+ Body?: unknown;
35
+ }>;
36
+ }
37
+ export interface AudioArtifactStorageOptions {
38
+ bucket?: string;
39
+ prefix?: string;
40
+ region?: string;
41
+ /** Overrides the real S3 client (tests). Ignored when no bucket is configured. */
42
+ client?: S3ClientLike;
43
+ }
44
+ /** What a successful upload wrote, for the row link. */
45
+ export interface UploadedAudioRef {
46
+ objectKey: string;
47
+ sha256: string;
48
+ bytes: number;
49
+ }
50
+ /** RFC-ish content type for a file extension; unknown extensions fall back to application/octet-stream. */
51
+ export declare function contentTypeForExtension(extension: string): string;
52
+ export declare class AudioArtifactStorage {
53
+ private bucket?;
54
+ private prefix;
55
+ private s3?;
56
+ constructor(options?: AudioArtifactStorageOptions);
57
+ get usesS3(): boolean;
58
+ /**
59
+ * Content-addressed object key for a recording's audio:
60
+ * `<prefix>/<recordingId>/<sha256>.<extension>`. The digest is the whole
61
+ * name — there is no caller-supplied path component to sanitise, only a
62
+ * digest to refuse if it is not one, and an extension to bound.
63
+ */
64
+ objectKeyFor(recordingId: string, sha256: string, extension: string): string;
65
+ /**
66
+ * Upload one audio file as a content-addressed object.
67
+ *
68
+ * Returns null when no bucket is configured (local-only mode) or when the
69
+ * file cannot be read — in which case nothing is written and nothing was
70
+ * lost. Throws only on a genuine storage failure, which the caller decides
71
+ * how softly to treat.
72
+ */
73
+ uploadAudio(recordingId: string, audioPath: string): Promise<UploadedAudioRef | null>;
74
+ /**
75
+ * Read an uploaded object back, for anywhere-any-machine playback.
76
+ *
77
+ * Returns null when no bucket is configured or the object does not exist.
78
+ * The caller checks the digest when it needs proof of identity.
79
+ */
80
+ readAudio(objectKey: string): Promise<Uint8Array | null>;
81
+ }
82
+ /**
83
+ * Resolve the kit from the environment. The bucket comes from
84
+ * HASNA_RECORDINGS_S3_BUCKET (preferred, matches the hosted service env
85
+ * naming) or RECORDINGS_S3_BUCKET; the prefix defaults to "recordings" and the
86
+ * region to AWS_REGION, then us-east-1.
87
+ */
88
+ export declare function resolveAudioArtifactStorage(env?: NodeJS.ProcessEnv | Record<string, string | undefined>, client?: S3ClientLike): AudioArtifactStorage;
89
+ /**
90
+ * The creation-time hook: upload a recording's audio when a bucket is
91
+ * configured, and NEVER let a storage failure take the recording down with it.
92
+ * The row already exists by the time this runs; a failed or unconfigured
93
+ * upload leaves the historical `audio_path` provenance in place and returns
94
+ * null. This is the deliberate fail-soft contract of the app-side fix — the
95
+ * hosted service's fail-closed rule is an infra-side concern (hasna/apps#1645).
96
+ */
97
+ export declare function uploadAudioAtCreation(recordingId: string, audioPath: string | null | undefined, storage?: AudioArtifactStorage): Promise<UploadedAudioRef | null>;
98
+ //# sourceMappingURL=audio-artifact-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-artifact-storage.d.ts","sourceRoot":"","sources":["../../src/lib/audio-artifact-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAA2B,MAAM,oBAAoB,CAAC;AAQjG,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAE9C,0GAA0G;AAC1G,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAYD,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAC,CAAe;gBAEd,OAAO,GAAE,2BAAgC;IAQrD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;;;OAKG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAM5E;;;;;;;OAOG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgB3F;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACzE,MAAM,CAAC,EAAE,YAAY,GACpB,oBAAoB,CAKtB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,oBAAoD,GAC5D,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAclC"}
@@ -118,7 +118,7 @@ export interface CaptureProbeSubject {
118
118
  * Name whose Microphone grant this probe actually exercises.
119
119
  *
120
120
  * macOS attributes microphone access to the RESPONSIBLE process — for a CLI that
121
- * is the terminal application (or sshd), never HasnaRecordings.app. So a silent probe
121
+ * is the terminal application (or sshd), never Hasna Recordings.app. So a silent probe
122
122
  * means "the thing running this command has no grant", which is a different
123
123
  * finding, with a different fix, from "the app has no grant". Reporting the one
124
124
  * as the other is how a diagnostic sends someone to the wrong settings pane.
@@ -141,7 +141,7 @@ export interface MicrophoneGrantInstruction {
141
141
  /** The bundle that must receive the grant, or null when none was found. */
142
142
  bundle_path: string | null;
143
143
  bundle_identifier: string;
144
- /** Every HasnaRecordings.app on disk — more than one makes the grant ambiguous. */
144
+ /** Every Hasna Recordings.app on disk — more than one makes the grant ambiguous. */
145
145
  candidate_bundle_paths: string[];
146
146
  /** Ordered steps, already naming the pane, the section and the bundle. */
147
147
  steps: string[];
@@ -197,7 +197,7 @@ export declare function classifyPermissionState(permissionState: string): Permis
197
197
  export declare function microphoneGrantInstruction(options: {
198
198
  /** Path the installer treats as canonical. */
199
199
  installedAppPath?: string | null;
200
- /** Other HasnaRecordings.app bundles found on disk (e.g. legacy install sites). */
200
+ /** Other Hasna Recordings.app bundles found on disk (e.g. legacy install sites). */
201
201
  otherAppPaths?: string[];
202
202
  /**
203
203
  * Whether the app has ever prompted. `unknown` means the TCC state could not
@@ -1 +1 @@
1
- {"version":3,"file":"capture-probe.d.ts","sourceRoot":"","sources":["../../src/lib/capture-probe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capture-probe.d.ts","sourceRoot":"","sources":["../../src/lib/capture-probe.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAW9E,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,8BAA8B,iBAAiB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,yBAAyB,CAAC;AAE3E,eAAO,MAAM,cAAc,EAAE,gBAkC5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA+HhE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAoC9E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK/D;AAaD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,GAAE,kBAA2B,GACpC,kBAAkB,CAMpB;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,gBAAgB,EACxB,wBAAwB,UAAO,GAC9B,gBAAgB,CAoBlB;AA0BD,wBAAgB,UAAU,IAAI,MAAM,CAyBnC;AA2ID,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiB5D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAW9E,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,8BAA8B,iBAAiB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,yBAAyB,CAAC;AAE3E,eAAO,MAAM,cAAc,EAAE,gBAqC5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAsJhE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAoC9E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK/D;AAaD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,GAAE,kBAA2B,GACpC,kBAAkB,CAMpB;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,gBAAgB,EACxB,wBAAwB,UAAO,GAC9B,gBAAgB,CAoBlB;AA0BD,wBAAgB,UAAU,IAAI,MAAM,CAyBnC;AAqFD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiB5D"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * The routing preamble every surface runs before the credential chain: "did the
3
+ * environment configure a Recordings authority, and if not, did the operator
4
+ * ask for the on-box store?"
5
+ *
6
+ * It lives in one leaf module because the CLI, the MCP server and the SDK all
7
+ * have to answer identically — a second spelling is a second thing that can
8
+ * drift — and because the SDK must be able to ask without pulling the CLI's
9
+ * transport module (and its transitive world) into a zero-dependency bundle.
10
+ * Its only import is the env-key derivation from @hasna/contracts, so the NAMES
11
+ * it looks for are the resolver's own rather than a copy that can fall behind.
12
+ *
13
+ * ORDER, AND WHY IT IS THIS WAY ROUND. A configured environment outranks the
14
+ * opt-in: a run with `HASNA_RECORDINGS_API_KEY` set goes hosted, and a
15
+ * half-configured one fails loudly, rather than quietly serving a different
16
+ * dataset because a stale `HASNA_RECORDINGS_LOCAL` was lying around. But when
17
+ * the environment configures nothing, the opt-in is answered WITHOUT calling
18
+ * the resolver — so no Keychain item and no credential file is read — which is
19
+ * what lets a scrubbed test environment physically cannot reach the shared
20
+ * store, now that a credential can arrive from somewhere an env dictionary
21
+ * cannot blank.
22
+ *
23
+ * THE RECORDINGS CARVE. `@hasna/contracts` treats the unprefixed
24
+ * `RECORDINGS_API_URL` / `RECORDINGS_API_KEY` pair as the legacy aliases of the
25
+ * canonical `HASNA_RECORDINGS_*` pair (silent, one release). In THIS package
26
+ * those two unprefixed names are already spoken for by an older contract:
27
+ * `RECORDINGS_API_KEY` is the OpenAI transcription-key override
28
+ * (`src/lib/config.ts`, marked with the credential-seam waiver), and the
29
+ * unprefixed URL form was never part of the hosted contract either. An OpenAI
30
+ * key must never be handed to the resolver as a Hasna service credential — it
31
+ * would authenticate to the fleet gateway as the wrong principal — so both
32
+ * unprefixed names are carved OUT of the environment before the resolver sees
33
+ * it AND out of the authority-intent check (an operator combining
34
+ * `HASNA_RECORDINGS_LOCAL=1` with a plain `RECORDINGS_API_KEY` for the local
35
+ * store must still land on the local store). The canonical
36
+ * `HASNA_RECORDINGS_*` pair is the only env spelling the hosted contract
37
+ * accepts.
38
+ */
39
+ import type { CredentialChainOptions } from "@hasna/contracts/client";
40
+ /** The deliberate unhosted opt-in, canonical name first. */
41
+ export declare const RECORDINGS_LOCAL_OPT_IN_ENV_KEYS: readonly ["HASNA_RECORDINGS_LOCAL", "RECORDINGS_LOCAL"];
42
+ export type RecordingsLocalOptInEnv = Record<string, string | undefined>;
43
+ /** True when the operator deliberately asked for the unhosted local store. */
44
+ export declare function isRecordingsLocalOptIn(env?: RecordingsLocalOptInEnv): boolean;
45
+ /** Every env name that can configure a Recordings authority or credential, resolver-derived. */
46
+ export declare function recordingsAuthorityEnvKeys(): string[];
47
+ /**
48
+ * Does the ENVIRONMENT itself configure a Recordings authority or credential?
49
+ *
50
+ * Deliberately narrower than "does a credential resolve": answering it must not
51
+ * touch the Keychain or the filesystem, because doing so would defeat the
52
+ * isolation the opt-in short-circuit exists to provide. It reads the env
53
+ * dictionary and nothing else.
54
+ *
55
+ * A DECLARED-BUT-BLANK variable counts as absent HERE — a blank has always been
56
+ * this package's spelling for "not configured", and helpers in the wild blank
57
+ * rather than delete. It is NOT absent once we do go hosted: the resolver
58
+ * refuses a blank loudly rather than falling through to another identity, which
59
+ * is the behaviour that matters at that point.
60
+ */
61
+ export declare function hasRecordingsEnvAuthorityIntent(env?: RecordingsLocalOptInEnv): boolean;
62
+ /** True when this environment should be served by the on-box SQLite store. */
63
+ export declare function selectsRecordingsLocalStore(env?: RecordingsLocalOptInEnv): boolean;
64
+ /**
65
+ * The environment as the resolver should see it: every authority/credential
66
+ * variable that is DECLARED BUT BLANK removed, plus the two carved unprefixed
67
+ * names this package reserves for its older contract (`RECORDINGS_API_KEY` is
68
+ * the OpenAI transcription-key override; the unprefixed URL form was never a
69
+ * hosted-contract spelling).
70
+ *
71
+ * A blank has always been this package's spelling for "not configured" — it is
72
+ * how fixture helpers scrub an inherited environment, and how consumer fixtures
73
+ * in other repos still write it. @hasna/contracts takes the opposite and, for
74
+ * its purposes, correct view: a declared-but-blank credential is a
75
+ * misconfiguration it refuses loudly rather than resolving around, because a
76
+ * blank that fell through would authenticate as a different principal than the
77
+ * operator named.
78
+ *
79
+ * Both are right at their own layer, and the mismatch is not hypothetical: an
80
+ * environment carrying a real `HASNA_RECORDINGS_API_KEY` alongside a blank
81
+ * legacy alias — the exact shape a scrubbed-then-overridden fixture produces —
82
+ * is a complete, unambiguous configuration that would otherwise be refused for
83
+ * the alias nobody set. Normalising here keeps "blank means unset" true at the
84
+ * Recordings seam while leaving the resolver's stricter rule intact for
85
+ * everything it does receive: a value that is present is still policed, and
86
+ * two aliases that actually disagree still refuse.
87
+ *
88
+ * The carved names are removed whenever present, blank or not: they configure
89
+ * nothing on this package's hosted contract, and a value in them must never
90
+ * reach the resolver as a Hasna credential.
91
+ */
92
+ export declare function recordingsResolverEnv<T extends RecordingsLocalOptInEnv>(env: T): T;
93
+ /** The env object and credential options a Recordings surface hands @hasna/contracts. */
94
+ export interface RecordingsResolverInputs<T extends RecordingsLocalOptInEnv> {
95
+ /** The environment with every declared-but-blank authority variable removed. */
96
+ env: T;
97
+ /** The chain options, with the Keychain tier's ambient gate already decided. */
98
+ credentials: CredentialChainOptions;
99
+ }
100
+ /**
101
+ * Build the resolver's inputs: the normalised environment AND the credential
102
+ * options that keep the machine's Keychain tier reachable across it.
103
+ *
104
+ * WHY THIS IS NOT JUST {@link recordingsResolverEnv}. Blanking a variable and
105
+ * deleting it are not the same operation to @hasna/contracts, because dropping
106
+ * a key forces us to hand the resolver a COPY, and the resolver gates its
107
+ * ambient tiers on OBJECT IDENTITY (`env === process.env`, or the registry
108
+ * symbol its own snapshot carries). A copy is, by that test, a caller-built
109
+ * world — the hermetic seam — so the Keychain is outside it and tier 3 turns
110
+ * itself off. Silently: there is no error, no warning and no diagnostic,
111
+ * because from the resolver's side nothing went wrong.
112
+ *
113
+ * The consequence is the one failure this whole ruling exists to prevent. On a
114
+ * station whose Keychain holds `hasna.credentials.recordings.api-key`, ONE
115
+ * declared-but-blank authority variable — any name in
116
+ * {@link recordingsAuthorityEnvKeys}, canonical or carved; the shape a scrubbed
117
+ * fixture leaves behind — dropped the run from the Keychain identity to
118
+ * whatever came next: to `~/.hasna/recordings/config/credentials`, a DIFFERENT
119
+ * principal, with no notice; or, with nothing on disk, to a bare
120
+ * REMOTE_API_CONFIG_MISSING on a station that is in fact configured. A
121
+ * deliberate tier must never fall through to another identity, so the gate is
122
+ * decided HERE, on the original env, and carried across the copy as the
123
+ * documented `keychain.enabled` control rather than being left to an identity
124
+ * test the copy cannot pass.
125
+ *
126
+ * An explicit `enabled` from the caller still wins, and an injected `run`
127
+ * (which @hasna/contracts already treats as "enabled") is left alone, so the
128
+ * hermetic seam tests rely on is untouched. When there is nothing to remove
129
+ * the inputs pass through by identity, exactly as before.
130
+ */
131
+ export declare function recordingsResolverInputs<T extends RecordingsLocalOptInEnv>(env: T, credentials?: CredentialChainOptions): RecordingsResolverInputs<T>;
132
+ //# sourceMappingURL=local-opt-in.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-opt-in.d.ts","sourceRoot":"","sources":["../../src/lib/local-opt-in.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAQH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,4DAA4D;AAC5D,eAAO,MAAM,gCAAgC,yDAGnC,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEzE,8EAA8E;AAC9E,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,uBAAqC,GACzC,OAAO,CAIT;AAeD,gGAAgG;AAChG,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CASrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,GAAG,GAAE,uBAAqC,GACzC,OAAO,CAIT;AAED,8EAA8E;AAC9E,wBAAgB,2BAA2B,CACzC,GAAG,GAAE,uBAAqC,GACzC,OAAO,CAET;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,uBAAuB,EACrE,GAAG,EAAE,CAAC,GACL,CAAC,CAYH;AA+BD,yFAAyF;AACzF,MAAM,WAAW,wBAAwB,CAAC,CAAC,SAAS,uBAAuB;IACzE,gFAAgF;IAChF,GAAG,EAAE,CAAC,CAAC;IACP,gFAAgF;IAChF,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,uBAAuB,EACxE,GAAG,EAAE,CAAC,EACN,WAAW,GAAE,sBAA2B,GACvC,wBAAwB,CAAC,CAAC,CAAC,CAS7B"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Canonical macOS bundle identity for HasnaRecordings.app.
2
+ * Canonical macOS bundle identity for Hasna Recordings.app.
3
3
  *
4
4
  * Why this module exists at all, rather than the constant living next to its first caller:
5
5
  * three branches in the #24-#29 queue each introduced their own copy of this literal —
@@ -1,3 +1,4 @@
1
+ import { type RecordsClientResolveOptions } from "../http/client.js";
1
2
  import { type Store } from "../store.js";
2
3
  import type { RecordingsConfig } from "../types/index.js";
3
4
  /**
@@ -5,13 +6,13 @@ import type { RecordingsConfig } from "../types/index.js";
5
6
  *
6
7
  * A transcript is only "recorded" once it is durably stored, and this package
7
8
  * has TWO stores behind one interface (src/store.ts): on-box SQLite and the
8
- * server's `/v1` HTTP API. Which one is active is decided entirely by the
9
- * environmentthe presence of HASNA_RECORDINGS_API_URL +
10
- * HASNA_RECORDINGS_API_KEY is itself the signal to use the API, with no
11
- * variable set explicitly to make it visible.
9
+ * server's `/v1` HTTP API. Which one is active is decided by the
10
+ * @hasna/contracts resolver a resolved credential (Keychain, disk or env)
11
+ * points at the hosted API, nothing resolved points nowhere until the
12
+ * deliberate `HASNA_RECORDINGS_LOCAL=1` opt-in selects the on-box file.
12
13
  *
13
14
  * `check` never reported which store it had resolved. That blind spot is not
14
- * theoretical: on an affected fleet Mac those two variables are set in the
15
+ * theoretical: on an affected fleet Mac the hosted API pair was set in the
15
16
  * LAUNCHD USER SESSION, so every process in the session inherits them — the GUI
16
17
  * app, its CLI helper, and any ssh shell alike. Writes go to the API while
17
18
  * ~/.hasna/recordings/recordings.db sits frozen at the row count it held when the
@@ -27,26 +28,40 @@ import type { RecordingsConfig } from "../types/index.js";
27
28
  * probe must round-trip against the ACTIVE store, never against whichever one is
28
29
  * easier to open.
29
30
  */
30
- /** The name we report when the transport came from URL+key presence alone. */
31
- export declare const AUTO_FLIP_MODE_SOURCE = "auto:api-url+api-key";
31
+ /**
32
+ * The name we report when the credential came from the process-env tier, where
33
+ * a shell export is a snapshot that a rotation cannot heal until the shell
34
+ * exits.
35
+ */
36
+ export declare const ENV_CREDENTIAL_MODE_SOURCE = "env";
32
37
  /**
33
38
  * Strip credentials out of a URL before it is printed anywhere.
34
39
  *
35
- * `toV1BaseUrl` clears the query and fragment but preserves userinfo, so a
36
- * configured `https://svc:PASSWORD@host` reaches every reporter in this module
37
- * intact stdout, the `--json` payload, and two warning strings. This module
38
- * exists to make the store visible; leaking a password while doing it would be a
39
- * worse bug than the one it fixes.
40
+ * The @hasna/contracts resolver REFUSES an authority URL that carries userinfo,
41
+ * so a configured `https://svc:PASSWORD@host` never reaches the transport or
42
+ * this module's reporters on its way to failure. This boundary exists as
43
+ * defense-in-depth for every other URL-shaped string a reporter can receive
44
+ * a fake Store's `baseUrl` in diagnostics, a server-supplied URL in a future
45
+ * report — and to make the redaction property testable without a resolution.
40
46
  *
41
- * Applied at the reporting boundary rather than in `toV1BaseUrl` itself, so the
47
+ * Applied at the reporting boundary rather than in the URL normaliser, so the
42
48
  * URL the transport actually requests is left exactly as configured.
43
49
  */
44
50
  export declare function safeBaseUrl(baseUrl: string | null): string | null;
45
51
  export interface ActiveStoreDescription {
46
- transport: "sqlite" | "http";
47
52
  /**
48
- * What decided the transport: an env var NAME, `auto:api-url+api-key`, or
49
- * `default`. Never a value these variables hold credentials.
53
+ * Which store this process would read and write: `"sqlite"` only under the
54
+ * deliberate local opt-in, `"http"` when the resolver succeeded, and
55
+ * `"none"` when the resolver REFUSED — a hosted run with no credential has
56
+ * no active store at all, and the diagnostic says so instead of reporting
57
+ * the on-box file as live (fail loud, hasna/apps#1720).
58
+ */
59
+ transport: "sqlite" | "http" | "none";
60
+ /**
61
+ * What decided the transport: `"local-opt-in"`, `"unresolved"`, or an env
62
+ * key NAME / Keychain item reference / file PATH / `"default"` as the
63
+ * @hasna/contracts chain reported the credential and the authority. Never a
64
+ * value — these variables hold credentials.
50
65
  */
51
66
  mode_source: string;
52
67
  /** `<url>/v1` when routed to the API, else null. Carries no credential. */
@@ -80,7 +95,31 @@ export declare function localStoreIsBehindSchema(dbPath: string): boolean | null
80
95
  * Report which store this process would read and write, and whether a second,
81
96
  * stale dataset is sitting next to it.
82
97
  */
83
- export declare function describeActiveStore(config: RecordingsConfig, env?: NodeJS.ProcessEnv | Record<string, string | undefined>): ActiveStoreDescription;
98
+ export declare function describeActiveStore(config: RecordingsConfig, env?: NodeJS.ProcessEnv | Record<string, string | undefined>, options?: RecordsClientResolveOptions): ActiveStoreDescription;
99
+ /**
100
+ * True when the resolver REFUSED: nothing resolved and the on-box store was
101
+ * not opted in. The one predicate `check` keys both its exit code and its
102
+ * glyph off, so a future renderer cannot turn a fail-closed report green
103
+ * without also changing the exit contract.
104
+ */
105
+ export declare function activeStoreFailClosed(description: ActiveStoreDescription): boolean;
106
+ /** The glyph palette `check` supplies; injected so the mapping stays testable. */
107
+ export interface StoreLinePalette {
108
+ pass: (text: string) => string;
109
+ warn: (text: string) => string;
110
+ fail: (text: string) => string;
111
+ }
112
+ /**
113
+ * The ONE rendered line for the active store — `check` keys its glyph,
114
+ * wording and (via {@link activeStoreFailClosed}) its exit code off this, so
115
+ * the text surface and the exit contract cannot drift apart:
116
+ *
117
+ * - unresolved refusal -> fail line naming the refusal and whether the on-box
118
+ * file was present but NOT opened (or absent);
119
+ * - deliberate local opt-in -> pass line naming the file;
120
+ * - hosted resolution -> pass line naming the resolver's sources.
121
+ */
122
+ export declare function describeActiveStoreLine(description: ActiveStoreDescription, paint: StoreLinePalette): string;
84
123
  export interface PersistenceProbeResult {
85
124
  /**
86
125
  * True ONLY when a write was performed and read back. Never true for a skip.
@@ -1 +1 @@
1
- {"version":3,"file":"persistence-probe.d.ts","sourceRoot":"","sources":["../../src/lib/persistence-probe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"persistence-probe.d.ts","sourceRoot":"","sources":["../../src/lib/persistence-probe.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"transcriber.d.ts","sourceRoot":"","sources":["../../src/lib/transcriber.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAM/E,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAcD,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,wEAAwE;IACxE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,IAAI,EAAE,eAAe,GAAG,aAAa,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAU9B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC;IACvC,qEAAqE;IACrE,aAAa,CAAC,EAAE,wBAAwB,CAAC;CACrC,GACL,OAAO,CAAC,qBAAqB,CAAC,CA6ChC;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,mBAAmB,CAAC,CA4B9B;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6C9B;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAM5D"}
1
+ {"version":3,"file":"transcriber.d.ts","sourceRoot":"","sources":["../../src/lib/transcriber.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAM/E,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAeD,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,wEAAwE;IACxE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,IAAI,EAAE,eAAe,GAAG,aAAa,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAU9B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC;IACvC,qEAAqE;IACrE,aAAa,CAAC,EAAE,wBAAwB,CAAC;CACrC,GACL,OAAO,CAAC,qBAAqB,CAAC,CA6ChC;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,mBAAmB,CAAC,CA4B9B;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6C9B;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAM5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgCpE,wBAAgB,WAAW,IAAI,SAAS,CAo1BvC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCpE,wBAAgB,WAAW,IAAI,SAAS,CAo1BvC"}