@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/dist/store.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { Recording, CreateRecordingInput, RecordingFilter, Agent, Project } from "./types/index.js";
2
2
  import { type FeedbackInput } from "./db/feedback.js";
3
+ import { type RecordsClientResolveOptions } from "./http/client.js";
4
+ import { AudioArtifactStorage } from "./lib/audio-artifact-storage.js";
3
5
  export declare const APP = "recordings";
4
6
  export type { FeedbackInput } from "./db/feedback.js";
5
7
  export interface RecordingStats {
@@ -30,13 +32,20 @@ export interface Store {
30
32
  saveFeedback(input: FeedbackInput): Promise<void>;
31
33
  }
32
34
  export declare function countStoreRecordings(store: Store, filter?: RecordingFilter): Promise<number>;
35
+ /** Test helper: force the LocalStore's artifact kit (e.g. an in-memory bucket). */
36
+ export declare function __setLocalArtifactStorage(storage: AudioArtifactStorage | null): void;
37
+ /** Test helper: clear the artifact-storage override. */
38
+ export declare function __resetLocalArtifactStorage(): void;
33
39
  /**
34
40
  * Resolve the active Store from the environment. Cached per-process after first
35
41
  * resolution against `process.env`; pass an explicit `env` (e.g. in tests) to
36
- * bypass the cache. Throws if the cloud transport is requested but misconfigured
37
- * (URL/key mismatch) so callers never silently read the wrong dataset.
42
+ * bypass the cache. The hosted client re-resolves its credential on every
43
+ * request through the @hasna/contracts chain, so the cache never freezes a
44
+ * key. Throws a `REMOTE_API_*` failure when no credential resolves — the
45
+ * on-box file is reachable only through the explicit
46
+ * `HASNA_RECORDINGS_LOCAL=1` opt-in, never as a fallback.
38
47
  */
39
- export declare function getStore(env?: NodeJS.ProcessEnv | Record<string, string | undefined>): Store;
48
+ export declare function getStore(env?: NodeJS.ProcessEnv | Record<string, string | undefined>, options?: RecordsClientResolveOptions): Store;
40
49
  /** Test helper: clear the cached Store. */
41
50
  export declare function __resetStore(): void;
42
51
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACR,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUzF,eAAO,MAAM,GAAG,eAAe,CAAC;AAEhC,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,eAAe,CAAC,KAAK,EAAE,oBAAoB,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1F,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpD,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/D,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAChF,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAG7C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAClD,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAGjF,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAGnC,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AA4QD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,KAAK,EACZ,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAID;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,KAAK,CAMzG;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,12 @@
1
1
  export interface Recording {
2
2
  id: string;
3
3
  audio_path: string | null;
4
+ /** Object key of the uploaded audio in the configured artifact bucket, when the upload happened. */
5
+ audio_object_key: string | null;
6
+ /** Lowercase hex sha-256 of the uploaded audio bytes; content-addressed storage identity. */
7
+ audio_sha256: string | null;
8
+ /** Byte size of the uploaded audio object. */
9
+ audio_bytes: number | null;
4
10
  raw_text: string;
5
11
  processed_text: string | null;
6
12
  processing_mode: ProcessingMode;
@@ -24,6 +30,9 @@ export interface CreateRecordingInput {
24
30
  /** Stable caller-owned identity for retrying one logical recording create. */
25
31
  id?: string;
26
32
  audio_path?: string;
33
+ audio_object_key?: string;
34
+ audio_sha256?: string;
35
+ audio_bytes?: number;
27
36
  raw_text: string;
28
37
  processed_text?: string;
29
38
  processing_mode?: ProcessingMode;
@@ -93,6 +102,12 @@ export interface RecordingsConfig {
93
102
  db_path: string;
94
103
  audio_dir: string;
95
104
  max_recording_seconds: number;
105
+ /** Artifact bucket for uploaded audio (HASNA_RECORDINGS_S3_BUCKET / RECORDINGS_S3_BUCKET). Empty = local-only. */
106
+ s3_bucket: string;
107
+ /** Object-key prefix inside the bucket; defaults to "recordings" when the bucket is set. */
108
+ s3_prefix: string;
109
+ /** AWS region for the S3 client; defaults to AWS_REGION, then us-east-1. */
110
+ s3_region: string;
96
111
  config_warnings?: string[];
97
112
  }
98
113
  export interface TranscriptionResult {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/recordings",
3
- "version": "0.3.13",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Speech-to-text recording tool with MCP and CLI — records, transcribes, and optionally enhances text using AI",
6
6
  "repository": {
@@ -34,10 +34,10 @@
34
34
  "scripts": {
35
35
  "clean": "rm -rf dist",
36
36
  "build": "bun run clean && bun run build:cli && bun run build:mcp && bun run build:serve && bun run build:lib && tsc --emitDeclarationOnly --outDir dist",
37
- "build:cli": "bun build src/cli/index.ts --target=bun --outfile=dist/cli/index.js --external=commander --external=chalk --external=openai",
38
- "build:mcp": "bun build src/mcp/index.ts --target=bun --outfile=dist/mcp/index.js --external=@modelcontextprotocol/sdk --external=openai",
39
- "build:serve": "bun build src/server/index.ts --target=bun --outfile=dist/server/index.js --external=@modelcontextprotocol/sdk --external=@hasna/contracts --external=openai --external=pg",
40
- "build:lib": "bun build src/index.ts src/storage.ts src/sdk/index.ts --target=bun --outdir=dist --external=openai",
37
+ "build:cli": "bun build src/cli/index.ts --target=bun --outfile=dist/cli/index.js --external=commander --external=chalk --external=openai --external=@aws-sdk/client-s3",
38
+ "build:mcp": "bun build src/mcp/index.ts --target=bun --outfile=dist/mcp/index.js --external=@modelcontextprotocol/sdk --external=openai --external=@aws-sdk/client-s3",
39
+ "build:serve": "bun build src/server/index.ts --target=bun --outfile=dist/server/index.js --external=@modelcontextprotocol/sdk --external=@hasna/contracts --external=openai --external=pg --external=@aws-sdk/client-s3",
40
+ "build:lib": "bun build src/index.ts src/storage.ts src/sdk/index.ts --target=bun --outdir=dist --external=openai --external=@aws-sdk/client-s3",
41
41
  "build:native-fs-guard": "/bin/bash scripts/build_native_fs_guard.sh",
42
42
  "generate:sdk": "bun run scripts/generate-sdk.ts",
43
43
  "migrate": "bun run scripts/migrate.ts",
@@ -47,7 +47,7 @@
47
47
  "verify:ci-suite": "bun scripts/ci-linux-suite.ts --check",
48
48
  "verify:ci-suite:run": "bun scripts/ci-linux-suite.ts --verify-run",
49
49
  "verify:ci-native": "bun scripts/ci-native-build.ts",
50
- "test:gated": "bun scripts/ci-linux-suite.ts --check && RECORDINGS_TEST_TIMEOUT_MS=\"${RECORDINGS_TEST_TIMEOUT_MS:-120000}\" bun test --timeout \"$RECORDINGS_TEST_TIMEOUT_MS\" $(bun scripts/ci-linux-suite.ts --gated)",
50
+ "test:gated": "bun scripts/ci-linux-suite.ts --check && RECORDINGS_TEST_TIMEOUT_MS=\"${RECORDINGS_TEST_TIMEOUT_MS:-120000}\" bun test --timeout \"${RECORDINGS_TEST_TIMEOUT_MS:-120000}\" $(bun scripts/ci-linux-suite.ts --gated)",
51
51
  "test:vacuity-battery": "bun scripts/vacuity-manifest-gen.ts > \"${TMPDIR:-/tmp}/vacuity-corrupt-sites.tsv\" && bun scripts/vacuity-mutation-battery.ts \"${TMPDIR:-/tmp}/vacuity-corrupt-sites.tsv\"",
52
52
  "test:vacuity-battery:source": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/source-side.tsv",
53
53
  "test:vacuity-battery:chain": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/install-chain.tsv",
@@ -84,7 +84,8 @@
84
84
  "LICENSE"
85
85
  ],
86
86
  "dependencies": {
87
- "@hasna/contracts": "0.14.1",
87
+ "@aws-sdk/client-s3": "^3.1007.0",
88
+ "@hasna/contracts": "1.0.2",
88
89
  "@hasna/events": "0.1.11",
89
90
  "@modelcontextprotocol/sdk": "^1.12.1",
90
91
  "chalk": "^5.4.1",
@@ -94,7 +95,7 @@
94
95
  "zod": "^3.24.2"
95
96
  },
96
97
  "devDependencies": {
97
- "@types/bun": "^1.2.5",
98
+ "@types/bun": "1.3.14",
98
99
  "@types/pg": "^8.11.11",
99
100
  "node-api-headers": "1.9.0",
100
101
  "typescript": "^5.8.2"
@@ -224,7 +224,7 @@ case "$VERSION" in
224
224
  esac
225
225
  # The artifact basename is derived from the canonical bundle identity, never hardcoded:
226
226
  # build.sh emits ${APP_BASENAME}-${VERSION}-macos-${RELEASE_SUBTYPE} with APP_BASENAME
227
- # taken from the bundle name (currently HasnaRecordings.app). The legacy
227
+ # taken from the bundle name (currently Hasna Recordings.app). The legacy
228
228
  # Recordings-* form was dropped with the bundle rename and must not be re-required.
229
229
  [ -n "$APP" ] && [ -d "$APP" ] || { echo "Package app bundle path is missing or invalid." >&2; exit 2; }
230
230
  expected_basename="$(/usr/bin/basename "$APP" .app)-${VERSION}-macos-initial-bootstrap"
@@ -533,7 +533,7 @@ PACKAGE_BOOTSTRAP_ID="$(/usr/bin/uuidgen | /usr/bin/tr '[:upper:]' '[:lower:]')"
533
533
  "$SCRIPTS"
534
534
  require_no_extended_acl "$PACKAGE_STAGE_DIR"
535
535
 
536
- /usr/bin/ditto "$APP" "$ROOT/Applications/HasnaRecordings.app"
536
+ /usr/bin/ditto "$APP" "$ROOT/Applications/Hasna Recordings.app"
537
537
  /bin/cp "$BROKER" "$ROOT/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
538
538
  /bin/cp "$VERIFIER" "$ROOT/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier"
539
539
  /bin/cp "$PUBLIC_KEY" "$ROOT/Library/Application Support/Hasna/Recordings/Trust/envelope-keys/${KEY_EPOCH}.raw"
@@ -582,7 +582,7 @@ require_tree_without_extended_acl "$SCRIPTS"
582
582
  "$ROOT/Library/LaunchDaemons/com.hasna.recordings.updater.plist"
583
583
  /usr/bin/plutil -lint "$ROOT/Library/LaunchDaemons/com.hasna.recordings.updater.plist" >/dev/null
584
584
 
585
- STAGED_APP="$ROOT/Applications/HasnaRecordings.app"
585
+ STAGED_APP="$ROOT/Applications/Hasna Recordings.app"
586
586
  STAGED_BROKER="$ROOT/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
587
587
  STAGED_CLIENT="$STAGED_APP/Contents/Helpers/recordings-update-client"
588
588
  STAGED_VERIFIER="$ROOT/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier"
@@ -173,7 +173,7 @@ validate_target_ancestry() {
173
173
 
174
174
  validate_target_ancestry
175
175
 
176
- CLIENT="/Applications/HasnaRecordings.app/Contents/Helpers/recordings-update-client"
176
+ CLIENT="/Applications/Hasna Recordings.app/Contents/Helpers/recordings-update-client"
177
177
  STATE="/var/db/com.hasna.recordings.updater/release-state.json"
178
178
  AUTHORIZATION_ROOT="/private/var/db/com.hasna.recordings.bootstrap-authorization"
179
179
  AUTHORIZATION_JOURNAL="${AUTHORIZATION_ROOT}/journal"
@@ -182,7 +182,7 @@ COHORT_PATHS=(
182
182
  "/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
183
183
  "/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier"
184
184
  "/Library/LaunchDaemons/com.hasna.recordings.updater.plist"
185
- "/Applications/HasnaRecordings.app"
185
+ "/Applications/Hasna Recordings.app"
186
186
  "$CLIENT"
187
187
  "/Library/Application Support/Hasna/Recordings/Trust"
188
188
  "/Library/Application Support/Hasna/Recordings/Bootstrap"
@@ -304,7 +304,7 @@ PAYLOAD="$EXPANDED/Payload"
304
304
  PREFLIGHT="$EXPANDED/Scripts/recordings-bootstrap-preflight"
305
305
  EXPANDED_PREINSTALL="$EXPANDED/Scripts/preinstall"
306
306
  EXPANDED_POSTINSTALL="$EXPANDED/Scripts/postinstall"
307
- PAYLOAD_CLIENT="$PAYLOAD/Applications/HasnaRecordings.app/Contents/Helpers/recordings-update-client"
307
+ PAYLOAD_CLIENT="$PAYLOAD/Applications/Hasna Recordings.app/Contents/Helpers/recordings-update-client"
308
308
  [ -d "$PAYLOAD" ] && [ ! -L "$PAYLOAD" ] && \
309
309
  [ -x "$PREFLIGHT" ] && [ ! -L "$PREFLIGHT" ] && \
310
310
  [ -x "$EXPANDED_PREINSTALL" ] && [ ! -L "$EXPANDED_PREINSTALL" ] && \
@@ -512,7 +512,7 @@ cohort_expected_mode() {
512
512
  "/Library/PrivilegedHelperTools/com.hasna.recordings.updater"|\
513
513
  "/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier") printf '555\n' ;;
514
514
  "/Library/LaunchDaemons/com.hasna.recordings.updater.plist") printf '444\n' ;;
515
- "/Applications/HasnaRecordings.app"|"$CLIENT") printf '755\n' ;;
515
+ "/Applications/Hasna Recordings.app"|"$CLIENT") printf '755\n' ;;
516
516
  "/Library/Application Support/Hasna/Recordings/Trust") printf '700-or-755\n' ;;
517
517
  "/Library/Application Support/Hasna/Recordings/Bootstrap"|\
518
518
  "/Library/Application Support/Hasna/Recordings/Updates"|\
@@ -11,9 +11,9 @@ PACKAGE_BOOTSTRAP_ID="__RECORDINGS_PACKAGE_BOOTSTRAP_ID__"
11
11
  AUTHORIZATION_ROOT="/private/var/db/com.hasna.recordings.bootstrap-authorization"
12
12
  AUTHORIZATION_JOURNAL="${AUTHORIZATION_ROOT}/journal"
13
13
  BROKER="/Library/PrivilegedHelperTools/com.hasna.recordings.updater"
14
- CLIENT="/Applications/HasnaRecordings.app/Contents/Helpers/recordings-update-client"
14
+ CLIENT="/Applications/Hasna Recordings.app/Contents/Helpers/recordings-update-client"
15
15
  VERIFIER="/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier"
16
- APP="/Applications/HasnaRecordings.app"
16
+ APP="/Applications/Hasna Recordings.app"
17
17
  STATE_ROOT="/Library/Application Support/Hasna/Recordings/Updates"
18
18
  TRUST_ROOT="/Library/Application Support/Hasna/Recordings/Trust"
19
19
  BOOTSTRAP_ROOT="/Library/Application Support/Hasna/Recordings/Bootstrap"
@@ -248,8 +248,8 @@ COHORT_PATHS=(
248
248
  "/Library/PrivilegedHelperTools/com.hasna.recordings.updater:555"
249
249
  "/Library/PrivilegedHelperTools/com.hasna.recordings.artifact-verifier:555"
250
250
  "/Library/LaunchDaemons/com.hasna.recordings.updater.plist:444"
251
- "/Applications/HasnaRecordings.app:755"
252
- "/Applications/HasnaRecordings.app/Contents/Helpers/recordings-update-client:755"
251
+ "/Applications/Hasna Recordings.app:755"
252
+ "/Applications/Hasna Recordings.app/Contents/Helpers/recordings-update-client:755"
253
253
  "/Applications/Recordings.app:755"
254
254
  "/Applications/Recordings.app/Contents/Helpers/recordings-update-client:755"
255
255
  "/Library/Application Support/Hasna/Recordings/Trust:700-or-755"
@@ -151,7 +151,13 @@ COMPILED_ARM64="$COMPILE_DIR/recordings.arm64"
151
151
  COMPILED_X86_64="$COMPILE_DIR/recordings.x86_64"
152
152
  "$MKDIR_EXECUTABLE" -p "$BUILD_HOME" "$BUN_CACHE" "$STAGED_ROOT" "$COMPILE_DIR"
153
153
  "$CP_EXECUTABLE" "$ROOT/package.json" "$ROOT/bun.lock" "$ROOT/bunfig.toml" "$ROOT/tsconfig.json" "$STAGED_ROOT/"
154
- "$CP_EXECUTABLE" -R "$ROOT/src" "$STAGED_ROOT/src"
154
+ "$MKDIR_EXECUTABLE" -p "$STAGED_ROOT/src"
155
+ # The CLI has no Swift inputs. Walking src/native also walks SwiftPM's live
156
+ # .build cache, whose temporary files can disappear during a native build.
157
+ for source_entry in "$ROOT/src/"*; do
158
+ [ "$source_entry" != "$ROOT/src/native" ] || continue
159
+ "$CP_EXECUTABLE" -R "$source_entry" "$STAGED_ROOT/src/"
160
+ done
155
161
  if [ -d "$ROOT/migrations" ]; then
156
162
  "$CP_EXECUTABLE" -R "$ROOT/migrations" "$STAGED_ROOT/migrations"
157
163
  fi
@@ -126,18 +126,18 @@ require_absolute_canonical_owned_home() {
126
126
  local canonical
127
127
  case "$candidate" in
128
128
  /*) ;;
129
- *) echo "HasnaRecordings.app installation requires HOME to be an absolute canonical path." >&2; exit 1 ;;
129
+ *) echo "Hasna Recordings.app installation requires HOME to be an absolute canonical path." >&2; exit 1 ;;
130
130
  esac
131
131
  [ -d "$candidate" ] && [ ! -L "$candidate" ] || {
132
- echo "HasnaRecordings.app installation requires HOME to be an absolute canonical path to a non-symlink directory." >&2
132
+ echo "Hasna Recordings.app installation requires HOME to be an absolute canonical path to a non-symlink directory." >&2
133
133
  exit 1
134
134
  }
135
135
  canonical="$(cd "$candidate" 2>/dev/null && builtin pwd -P)" || {
136
- echo "HasnaRecordings.app installation could not resolve HOME canonically." >&2
136
+ echo "Hasna Recordings.app installation could not resolve HOME canonically." >&2
137
137
  exit 1
138
138
  }
139
139
  [ "$candidate" = "$canonical" ] || {
140
- echo "HasnaRecordings.app installation requires HOME to be an absolute canonical path." >&2
140
+ echo "Hasna Recordings.app installation requires HOME to be an absolute canonical path." >&2
141
141
  exit 1
142
142
  }
143
143
  [ "$("$STAT_EXECUTABLE" -f '%u' "$candidate")" = "$("$ID_EXECUTABLE" -u)" ] || {
@@ -352,7 +352,7 @@ require_absolute_executable "BUN_EXECUTABLE" "$BUN_EXECUTABLE"
352
352
  require_absolute_canonical_owned_home
353
353
 
354
354
  if [ "$("$UNAME_EXECUTABLE" -s)" != "Darwin" ]; then
355
- echo "HasnaRecordings.app installation is only supported on macOS." >&2
355
+ echo "Hasna Recordings.app installation is only supported on macOS." >&2
356
356
  exit 1
357
357
  fi
358
358
 
@@ -546,7 +546,7 @@ fi
546
546
  "$BUN_EXECUTABLE" "$ARTIFACT_TOOL" native-fs-guard-check
547
547
  DATA_DIR="${HOME}/.hasna/recordings"
548
548
  DATA_PARENT="$("$DIRNAME_EXECUTABLE" "$DATA_DIR")"
549
- MANIFEST_BUNDLE_NAME="HasnaRecordings.app"
549
+ MANIFEST_BUNDLE_NAME="Hasna Recordings.app"
550
550
  APP_DEST="${HOME}/Applications/${MANIFEST_BUNDLE_NAME}"
551
551
  APP_PARENT="$("$DIRNAME_EXECUTABLE" "$APP_DEST")"
552
552
  ROLLBACK_DIR="${DATA_DIR}/rollbacks"
@@ -794,7 +794,7 @@ acquire_install_lock() {
794
794
  if kill -0 "$owner_pid" 2>/dev/null; then
795
795
  actual_start="$("$PS_EXECUTABLE" -o lstart= -p "$owner_pid" 2>/dev/null | "$TR_EXECUTABLE" -s ' ' | "$SED_EXECUTABLE" 's/^ //;s/ $//' || true)"
796
796
  if [ -z "$owner_start" ] || [ -z "$actual_start" ] || [ "$owner_start" = "$actual_start" ]; then
797
- echo "Another HasnaRecordings.app installer owns the active install lock." >&2
797
+ echo "Another Hasna Recordings.app installer owns the active install lock." >&2
798
798
  exit 1
799
799
  fi
800
800
  fi
@@ -807,17 +807,17 @@ acquire_install_lock() {
807
807
  now="$("$DATE_EXECUTABLE" +%s)"
808
808
  lock_age=$((now - $("$STAT_EXECUTABLE" -f '%m' "$LOCK_DIR")))
809
809
  if [ "$lock_age" -lt "$stale_seconds" ]; then
810
- echo "HasnaRecordings.app install lock is incomplete and too recent to reclaim safely." >&2
810
+ echo "Hasna Recordings.app install lock is incomplete and too recent to reclaim safely." >&2
811
811
  exit 1
812
812
  fi
813
813
  fi
814
814
  stale_claim="${LOCK_DIR}.stale.$$"
815
815
  if ! "$MV_EXECUTABLE" "$LOCK_DIR" "$stale_claim" 2>/dev/null; then
816
- echo "HasnaRecordings.app install lock changed during stale-owner recovery." >&2
816
+ echo "Hasna Recordings.app install lock changed during stale-owner recovery." >&2
817
817
  exit 1
818
818
  fi
819
819
  "$RM_EXECUTABLE" -rf "$stale_claim"
820
- "$MKDIR_EXECUTABLE" -m 700 "$LOCK_DIR" || { echo "Could not acquire HasnaRecordings.app install lock." >&2; exit 1; }
820
+ "$MKDIR_EXECUTABLE" -m 700 "$LOCK_DIR" || { echo "Could not acquire Hasna Recordings.app install lock." >&2; exit 1; }
821
821
  fi
822
822
  LOCK_OWNED=1
823
823
  local start
@@ -1263,13 +1263,13 @@ stop_uncommitted_candidate() {
1263
1263
  done <<< "$remaining"
1264
1264
  "$SLEEP_EXECUTABLE" 0.1
1265
1265
  [ -z "$(pids_for_exact_executable "$expected")" ] || {
1266
- echo "Uncommitted HasnaRecordings.app process could not be stopped before recovery." >&2
1266
+ echo "Uncommitted Hasna Recordings.app process could not be stopped before recovery." >&2
1267
1267
  return 1
1268
1268
  }
1269
1269
  }
1270
1270
 
1271
1271
  if [ -f "$JOURNAL_PATH" ]; then
1272
- echo "Recovering incomplete HasnaRecordings.app installation transaction." >&2
1272
+ echo "Recovering incomplete Hasna Recordings.app installation transaction." >&2
1273
1273
  if ! RECOVER_WAS_RUNNING="$("$BUN_EXECUTABLE" "$ARTIFACT_TOOL" journal-get --journal "$JOURNAL_PATH" --field was_running)" || \
1274
1274
  ! RECOVER_PHASE="$("$BUN_EXECUTABLE" "$ARTIFACT_TOOL" journal-get --journal "$JOURNAL_PATH" --field phase)" || \
1275
1275
  ! RECOVER_RUNNING_APP_PATHS_JSON="$("$BUN_EXECUTABLE" "$ARTIFACT_TOOL" journal-get --journal "$JOURNAL_PATH" --field prior_running_app_paths)"; then
@@ -1376,7 +1376,7 @@ if ! "$BUN_EXECUTABLE" -e '
1376
1376
  if ((actual[i] ?? 0) < (minimum[i] ?? 0)) process.exit(1);
1377
1377
  }
1378
1378
  ' "$CURRENT_MACOS" "$MINIMUM_MACOS"; then
1379
- echo "HasnaRecordings.app requires macOS ${MINIMUM_MACOS} or later; target is ${CURRENT_MACOS}." >&2
1379
+ echo "Hasna Recordings.app requires macOS ${MINIMUM_MACOS} or later; target is ${CURRENT_MACOS}." >&2
1380
1380
  exit 1
1381
1381
  fi
1382
1382
  TARGET_ARCH="$("$UNAME_EXECUTABLE" -m)"
@@ -1386,7 +1386,7 @@ MANIFEST_ARCHITECTURES="$("$BUN_EXECUTABLE" "$ARTIFACT_TOOL" manifest-get \
1386
1386
  --field architectures)"
1387
1387
  case " ${MANIFEST_ARCHITECTURES} " in
1388
1388
  *" ${TARGET_ARCH} "*) ;;
1389
- *) echo "HasnaRecordings.app artifact does not support target architecture ${TARGET_ARCH}." >&2; exit 1 ;;
1389
+ *) echo "Hasna Recordings.app artifact does not support target architecture ${TARGET_ARCH}." >&2; exit 1 ;;
1390
1390
  esac
1391
1391
 
1392
1392
  verify_secure_parent "$APP_PARENT"
@@ -1412,7 +1412,7 @@ add_unique_app() {
1412
1412
  local existing
1413
1413
  if [ -e "$candidate" ] || [ -L "$candidate" ]; then
1414
1414
  [ -d "$candidate" ] && [ ! -L "$candidate" ] || {
1415
- echo "HasnaRecordings.app path is not a secure directory: ${candidate}" >&2
1415
+ echo "Hasna Recordings.app path is not a secure directory: ${candidate}" >&2
1416
1416
  exit 1
1417
1417
  }
1418
1418
  fi
@@ -1524,7 +1524,7 @@ stop_old_processes() {
1524
1524
  "$SLEEP_EXECUTABLE" 0.1
1525
1525
  done
1526
1526
  if [ "$remaining" -ne 0 ]; then
1527
- echo "Existing HasnaRecordings.app process did not stop before replacement." >&2
1527
+ echo "Existing Hasna Recordings.app process did not stop before replacement." >&2
1528
1528
  exit 1
1529
1529
  fi
1530
1530
  }
@@ -1545,7 +1545,7 @@ quiesce_old_processes() {
1545
1545
  fi
1546
1546
  "$SLEEP_EXECUTABLE" 0.1
1547
1547
  done
1548
- echo "Existing HasnaRecordings.app processes did not remain quiescent before replacement." >&2
1548
+ echo "Existing Hasna Recordings.app processes did not remain quiescent before replacement." >&2
1549
1549
  exit 1
1550
1550
  }
1551
1551
 
@@ -1706,11 +1706,14 @@ fi
1706
1706
  DISCOVERED_APPS=()
1707
1707
  add_unique_app "$APP_DEST"
1708
1708
  add_unique_app "${DATA_DIR}/Recordings.app"
1709
+ add_unique_app "${DATA_DIR}/Hasna Recordings.app"
1709
1710
  add_unique_app "${DATA_DIR}/HasnaRecordings.app"
1710
- for candidate in "${HOME}"/Applications/Recordings.app.* "${HOME}"/Applications/HasnaRecordings.app.*; do
1711
+ add_unique_app "${HOME}/Applications/HasnaRecordings.app"
1712
+ for candidate in "${HOME}"/Applications/Recordings.app.* "${HOME}/Applications/Hasna Recordings.app."* "${HOME}/Applications/HasnaRecordings.app."*; do
1711
1713
  add_unique_app "$candidate"
1712
1714
  done
1713
1715
  add_unique_app "/Applications/Recordings.app"
1716
+ add_unique_app "/Applications/Hasna Recordings.app"
1714
1717
  add_unique_app "/Applications/HasnaRecordings.app"
1715
1718
  if [ -x "$MDFIND_EXECUTABLE" ]; then
1716
1719
  while IFS= read -r candidate; do
@@ -1722,12 +1725,12 @@ fi
1722
1725
  MANAGEABLE_APPS=()
1723
1726
  for existing_app in ${DISCOVERED_APPS[@]+"${DISCOVERED_APPS[@]}"}; do
1724
1727
  case "$existing_app" in
1725
- "$APP_DEST"|"${DATA_DIR}/Recordings.app"|"${DATA_DIR}/HasnaRecordings.app"|"${HOME}/Applications/Recordings.app."*|"${HOME}/Applications/HasnaRecordings.app."*)
1728
+ "$APP_DEST"|"${DATA_DIR}/Recordings.app"|"${DATA_DIR}/Hasna Recordings.app"|"${DATA_DIR}/HasnaRecordings.app"|"${HOME}/Applications/HasnaRecordings.app"|"${HOME}/Applications/Recordings.app."*|"${HOME}/Applications/Hasna Recordings.app."*|"${HOME}/Applications/HasnaRecordings.app."*)
1726
1729
  echo "Duplicate disposition: archive transactionally, remove after activation: ${existing_app}"
1727
1730
  MANAGEABLE_APPS+=("$existing_app")
1728
1731
  ;;
1729
1732
  *)
1730
- echo "Duplicate HasnaRecordings.app at ${existing_app} is outside the transactional user install paths; archive or remove it before installing." >&2
1733
+ echo "Duplicate Hasna Recordings.app at ${existing_app} is outside the transactional user install paths; archive or remove it before installing." >&2
1731
1734
  exit 1
1732
1735
  ;;
1733
1736
  esac
@@ -1954,7 +1957,7 @@ for ((refresh_attempt = 1; refresh_attempt <= 5; refresh_attempt++)); do
1954
1957
  fi
1955
1958
  done
1956
1959
  [ "$STOPPED_REFRESH_STABLE" -eq 1 ] || {
1957
- echo "Existing HasnaRecordings.app writers did not remain quiescent around the stopped-state refresh." >&2
1960
+ echo "Existing Hasna Recordings.app writers did not remain quiescent around the stopped-state refresh." >&2
1958
1961
  exit 1
1959
1962
  }
1960
1963
 
@@ -2004,7 +2007,7 @@ for ((move_index = 0; move_index < MOVED_ORIGINAL_COUNT; move_index++)); do
2004
2007
  existing_app="${MOVED_ORIGINALS[$move_index]}"
2005
2008
  moved_path="${MOVED_PATHS[$move_index]}"
2006
2009
  [ "$("$BUN_EXECUTABLE" "$ARTIFACT_TOOL" tree-digest --path "$existing_app")" = "${MOVED_DIGESTS[$move_index]}" ] || {
2007
- echo "Installed HasnaRecordings.app changed after transactional backup planning." >&2
2010
+ echo "Installed Hasna Recordings.app changed after transactional backup planning." >&2
2008
2011
  exit 1
2009
2012
  }
2010
2013
  RECORDINGS_TEST_INSTALLER_PID="$$" \
@@ -2117,7 +2120,7 @@ if [ "$LAUNCH_APP" -eq 1 ] || [ "$was_running" -eq 1 ]; then
2117
2120
  fi
2118
2121
 
2119
2122
  if [ "$ARTIFACT_POLICY" = "local_only" ]; then
2120
- echo "Installed local-only HasnaRecordings.app for ${APPROVED_TARGET}; this artifact is ad-hoc signed and non-notarized."
2123
+ echo "Installed local-only Hasna Recordings.app for ${APPROVED_TARGET}; this artifact is ad-hoc signed and non-notarized."
2121
2124
  if [ "$identity_migration" -eq 1 ]; then
2122
2125
  # Not a maybe: the designated requirement did change, under an explicit approval.
2123
2126
  echo "Code identity changed under --allow-adhoc-identity-migration; the Microphone and Accessibility grants held by the replaced app no longer apply and must be reauthorized."
@@ -2127,5 +2130,5 @@ if [ "$ARTIFACT_POLICY" = "local_only" ]; then
2127
2130
  elif [ "$identity_migration" -eq 1 ]; then
2128
2131
  echo "Installed a new signing identity; macOS will require one-time permission approval for this migration."
2129
2132
  else
2130
- echo "Installed verified HasnaRecordings.app release artifact: ${APP_DEST}"
2133
+ echo "Installed verified Hasna Recordings.app release artifact: ${APP_DEST}"
2131
2134
  fi
@@ -183,7 +183,7 @@ export type BuildProvenance = {
183
183
 
184
184
  export type MacOSArtifactManifest = BuildProvenance & {
185
185
  artifact_type: "recordings-macos-app";
186
- /// The top-level bundle directory name inside the artifact (HasnaRecordings.app for
186
+ /// The top-level bundle directory name inside the artifact (Hasna Recordings.app for
187
187
  /// both the full app and the bar variant per the fleet naming rule).
188
188
  bundle_name: string;
189
189
  app_sha256: string;
@@ -843,6 +843,7 @@ function manifestVariant(manifest: MacOSArtifactManifest): ArtifactVariant {
843
843
  }
844
844
 
845
845
  function manifestBundleName(manifest: MacOSArtifactManifest): string {
846
+ // Manifests predating explicit bundle names describe the original unspaced bundle.
846
847
  return manifest.bundle_name ?? "HasnaRecordings.app";
847
848
  }
848
849
 
@@ -1094,23 +1095,23 @@ function assertCanonicalZipEntries(entries: Array<{ name: string; isDirectory: b
1094
1095
  const components = logicalPath.split("/");
1095
1096
  if (
1096
1097
  !logicalPath ||
1097
- components[0] !== "HasnaRecordings.app" ||
1098
+ components[0] !== "Hasna Recordings.app" ||
1098
1099
  components.some((component) => !component || component === "." || component === "..")
1099
1100
  ) {
1100
- throw new Error("release ZIP contains an entry outside the canonical HasnaRecordings.app tree");
1101
+ throw new Error("release ZIP contains an entry outside the canonical Hasna Recordings.app tree");
1101
1102
  }
1102
1103
  const collisionKey = canonicalZipCollisionKey(logicalPath);
1103
1104
  if (logicalPaths.has(collisionKey)) {
1104
1105
  throw new Error("release ZIP contains duplicate, file/directory, case-fold, or Unicode-colliding entries");
1105
1106
  }
1106
1107
  logicalPaths.set(collisionKey, { name: logicalPath, isDirectory: entry.isDirectory });
1107
- if (logicalPath === "HasnaRecordings.app") {
1108
- if (!entry.isDirectory) throw new Error("release ZIP HasnaRecordings.app root is not a directory entry");
1108
+ if (logicalPath === "Hasna Recordings.app") {
1109
+ if (!entry.isDirectory) throw new Error("release ZIP Hasna Recordings.app root is not a directory entry");
1109
1110
  rootDirectoryCount += 1;
1110
1111
  }
1111
1112
  }
1112
1113
  if (rootDirectoryCount !== 1) {
1113
- throw new Error("release ZIP must contain exactly one canonical HasnaRecordings.app root entry");
1114
+ throw new Error("release ZIP must contain exactly one canonical Hasna Recordings.app root entry");
1114
1115
  }
1115
1116
  for (const { name } of logicalPaths.values()) {
1116
1117
  const components = name.split("/");
@@ -1426,7 +1427,7 @@ export function withPrivatelyExtractedArchiveApp<T>(
1426
1427
  operation: (appPath: string) => T,
1427
1428
  platformArchiveTool = "/usr/bin/ditto",
1428
1429
  expectedArchiveSha256?: string,
1429
- expectedBundleName = "HasnaRecordings.app",
1430
+ expectedBundleName = "Hasna Recordings.app",
1430
1431
  ): T {
1431
1432
  const privateRoot = mkdtempSync(join(tmpdir(), "recordings-artifact-extract-"));
1432
1433
  chmodSync(privateRoot, 0o700);
@@ -1751,8 +1752,8 @@ export function assertManifestShape(manifest: MacOSArtifactManifest): void {
1751
1752
  manifest.container?.type !== "zip" ||
1752
1753
  JSON.stringify(manifest.container.install_locations) !== JSON.stringify(
1753
1754
  artifactPolicy === "release"
1754
- ? ["/Applications/HasnaRecordings.app"]
1755
- : ["~/Applications/HasnaRecordings.app"],
1755
+ ? ["/Applications/Hasna Recordings.app"]
1756
+ : ["~/Applications/Hasna Recordings.app"],
1756
1757
  )
1757
1758
  ) {
1758
1759
  throw new Error("manifest has an unexpected container install policy");
@@ -2516,7 +2517,7 @@ export function assertVersionTransition(
2516
2517
  assertManifestShape(manifest);
2517
2518
  if (compareVersions(manifest.bundle_version, installedVersion) < 0) {
2518
2519
  throw new Error(
2519
- `refusing to downgrade HasnaRecordings.app from ${installedVersion} to ${manifest.bundle_version}`,
2520
+ `refusing to downgrade Hasna Recordings.app from ${installedVersion} to ${manifest.bundle_version}`,
2520
2521
  );
2521
2522
  }
2522
2523
  if (compareVersions(manifest.bundle_version, installedVersion) === 0) {
@@ -2981,7 +2982,7 @@ function readJournal(path: string): InstallJournal {
2981
2982
  if (resolve(path) !== resolve(join(expectedParent, ".Recordings-install-transaction.json"))) {
2982
2983
  throw new Error("install transaction journal is outside the expected app parent");
2983
2984
  }
2984
- if (resolve(journal.app_destination) !== resolve(join(expectedParent, "HasnaRecordings.app"))) {
2985
+ if (!["Hasna Recordings.app", "HasnaRecordings.app"].some((name) => resolve(journal.app_destination) === resolve(join(expectedParent, name)))) {
2985
2986
  throw new Error("install transaction journal has an unexpected app destination");
2986
2987
  }
2987
2988
  const expectedDataDir = resolve(join(dirname(expectedParent), ".hasna", "recordings"));
@@ -2999,9 +3000,12 @@ function readJournal(path: string): InstallJournal {
2999
3000
  return (
3000
3001
  resolved === resolve(journal.app_destination) ||
3001
3002
  resolved === resolve(join(journal.data_dir, "Recordings.app")) ||
3003
+ resolved === resolve(join(journal.data_dir, "Hasna Recordings.app")) ||
3002
3004
  resolved === resolve(join(journal.data_dir, "HasnaRecordings.app")) ||
3005
+ resolved === resolve(join(journal.app_parent, "HasnaRecordings.app")) ||
3003
3006
  resolved.startsWith(`${resolve(journal.app_parent)}/Recordings.app.`) ||
3004
- resolved.startsWith(`${resolve(journal.app_parent)}/HasnaRecordings.app.`)
3007
+ resolved.startsWith(`${resolve(journal.app_parent)}/HasnaRecordings.app.`) ||
3008
+ resolved.startsWith(`${resolve(journal.app_parent)}/Hasna Recordings.app.`)
3005
3009
  );
3006
3010
  };
3007
3011
  if (!journal.originals.every((entry) => allowedOriginal(entry.path))) {
@@ -3939,7 +3943,7 @@ function openRecoveryCapabilities(
3939
3943
  const homePath = resolve(dirname(appParent));
3940
3944
  if (
3941
3945
  basename(appParent) !== "Applications" ||
3942
- resolve(journal.app_destination) !== resolve(join(appParent, "HasnaRecordings.app")) ||
3946
+ !["Hasna Recordings.app", "HasnaRecordings.app"].some((name) => resolve(journal.app_destination) === resolve(join(appParent, name))) ||
3943
3947
  resolve(journal.data_dir) !== resolve(join(homePath, ".hasna", "recordings")) ||
3944
3948
  dirname(resolve(journal.transaction_dir)) !== appParent
3945
3949
  ) {
@@ -4573,16 +4577,16 @@ function originalDestinationCapability(
4573
4577
  }
4574
4578
  if (
4575
4579
  dirname(resolved) === resolve(journal.data_dir) &&
4576
- (basename(resolved) === "Recordings.app" || basename(resolved) === "HasnaRecordings.app")
4580
+ ["Recordings.app", "Hasna Recordings.app", "HasnaRecordings.app"].includes(basename(resolved))
4577
4581
  ) {
4578
4582
  // Install site inside the state data directory: the legacy pre-rename
4579
- // Recordings.app and the renamed HasnaRecordings.app are both recognized and
4583
+ // Recordings.app and the renamed Hasna Recordings.app are both recognized and
4580
4584
  // preserved, never treated as the canonical Applications destination.
4581
4585
  return { parent: capabilities.data, leaf: basename(resolved) };
4582
4586
  }
4583
4587
  if (
4584
4588
  dirname(resolved) === resolve(journal.app_parent) &&
4585
- /^(?:Hasna)?Recordings\.app\.[A-Za-z0-9._-]+$/.test(basename(resolved))
4589
+ (basename(resolved) === "HasnaRecordings.app" || /^(?:Hasna ?)?Recordings\.app\.[A-Za-z0-9._-]+$/.test(basename(resolved)))
4586
4590
  ) {
4587
4591
  return { parent: capabilities.applications, leaf: basename(resolved) };
4588
4592
  }
@@ -29,32 +29,16 @@ async function runPublishedEntrypoint(): Promise<boolean> {
29
29
  async function main() {
30
30
  // Published packages ship the compiled server but intentionally omit src/.
31
31
  if (await runPublishedEntrypoint()) return;
32
- const {
33
- closeCloud,
34
- getCloudPg,
35
- migrateCloudSchema,
36
- pingCloudConnectivity,
37
- resolveDatabaseUrl,
38
- } = await import("../src/server/cloud.js");
39
- const { assertCloudSchemaContract } = await import("../src/server/cloud-readiness.js");
40
- const { runCloudMigration } = await import("../src/server/migrate-command.js");
41
- const url = resolveDatabaseUrl();
42
- if (!url) {
32
+ const { closeCloud, resolveMigrationDatabaseUrl, runRecordedMigration } = await import("../src/server/cloud.js");
33
+ if (!resolveMigrationDatabaseUrl()) {
43
34
  console.error(
44
- "migrate: no database URL (HASNA_RECORDINGS_DATABASE_URL / RECORDINGS_DATABASE_URL / DATABASE_URL)",
35
+ "migrate: no database URL (HASNA_RECORDINGS_MIGRATE_DATABASE_URL / RECORDINGS_MIGRATE_DATABASE_URL / HASNA_RECORDINGS_DATABASE_URL / RECORDINGS_DATABASE_URL / DATABASE_URL)",
45
36
  );
46
37
  process.exitCode = 2;
47
38
  return;
48
39
  }
49
40
  console.log("migrate: connecting…");
50
- await runCloudMigration({
51
- pingConnectivity: pingCloudConnectivity,
52
- applyMigrations: async () => {
53
- console.log("migrate: applying schema (recordings tables + api_keys)…");
54
- await migrateCloudSchema();
55
- },
56
- validateContract: () => assertCloudSchemaContract(getCloudPg()),
57
- });
41
+ await runRecordedMigration();
58
42
  console.log("migrate: done");
59
43
  await closeCloud();
60
44
  }