@hasna/recordings 0.2.14 → 0.3.2
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.
- package/Dockerfile.package +4 -5
- package/README.md +113 -8
- package/bun.lock +2 -2
- package/dist/__tests__/helpers/installer-guard-execution.d.ts +22 -0
- package/dist/__tests__/helpers/installer-guard-execution.d.ts.map +1 -0
- package/dist/__tests__/helpers/installer-preflight.d.ts +22 -0
- package/dist/__tests__/helpers/installer-preflight.d.ts.map +1 -0
- package/dist/__tests__/helpers/native-fs-guard.d.ts.map +1 -1
- package/dist/__tests__/helpers/source-assertions.d.ts +169 -0
- package/dist/__tests__/helpers/source-assertions.d.ts.map +1 -0
- package/dist/__tests__/preload.d.ts +1 -4
- package/dist/__tests__/preload.d.ts.map +1 -1
- package/dist/cli/desktop-snapshot.d.ts +20 -0
- package/dist/cli/desktop-snapshot.d.ts.map +1 -0
- package/dist/cli/index.js +2094 -280
- package/dist/cli/macos-permissions.d.ts +72 -0
- package/dist/cli/macos-permissions.d.ts.map +1 -1
- package/dist/cli/macos-shortcut.d.ts +139 -0
- package/dist/cli/macos-shortcut.d.ts.map +1 -0
- package/dist/cli/trigger-probe.d.ts +172 -0
- package/dist/cli/trigger-probe.d.ts.map +1 -0
- package/dist/db/database.d.ts +9 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/http/client.d.ts +19 -7
- package/dist/http/client.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +635 -50
- package/dist/lib/capture-probe.d.ts +216 -0
- package/dist/lib/capture-probe.d.ts.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/macos-bundle.d.ts +50 -0
- package/dist/lib/macos-bundle.d.ts.map +1 -0
- package/dist/lib/persistence-probe.d.ts +208 -0
- package/dist/lib/persistence-probe.d.ts.map +1 -0
- package/dist/lib/recorder.d.ts.map +1 -1
- package/dist/lib/retired-deployment-modes.d.ts +24 -0
- package/dist/lib/retired-deployment-modes.d.ts.map +1 -0
- package/dist/lib/transcriber.d.ts +60 -0
- package/dist/lib/transcriber.d.ts.map +1 -1
- package/dist/mcp/index.js +141 -57
- package/dist/server/cloud-config.d.ts +25 -3
- package/dist/server/cloud-config.d.ts.map +1 -1
- package/dist/server/cloud-readiness.d.ts.map +1 -1
- package/dist/server/cloud.d.ts +8 -7
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.js +188 -80
- package/dist/server/migrate-command.d.ts.map +1 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +109 -50
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +25 -6
- package/scripts/ci-linux-suite.ts +403 -0
- package/scripts/ci-native-build.ts +402 -0
- package/scripts/enforce_identity_migration.sh +110 -0
- package/scripts/generate-sdk.ts +1 -1
- package/scripts/install_macos_app.sh +192 -31
- package/scripts/macos_artifact.ts +323 -43
- package/scripts/native/realtime-settle-probe/README.md +39 -0
- package/scripts/native/realtime-settle-probe/main.swift +135 -0
- package/scripts/policy/local-only-approved-targets.txt +21 -0
- package/scripts/read_local_only_targets.sh +203 -0
- package/scripts/scan-artifact.ts +40 -0
- package/scripts/set-version.ts +145 -0
- package/scripts/smoke_macos_app.sh +62 -16
- package/scripts/vacuity-manifest-gen.ts +96 -0
- package/scripts/vacuity-manifests/enhancement-screen-mirror.tsv +44 -0
- package/scripts/vacuity-manifests/install-chain.tsv +13 -0
- package/scripts/vacuity-manifests/must-survive-controls.tsv +10 -0
- package/scripts/vacuity-manifests/reorder.tsv +4 -0
- package/scripts/vacuity-manifests/source-side.tsv +15 -0
- package/scripts/vacuity-manifests/variable-operands.tsv +16 -0
- package/scripts/vacuity-manifests/version-sites.tsv +61 -0
- package/scripts/vacuity-mutation-battery.ts +266 -0
- package/src/native/Recordings/App/MenuBarStatusView.swift +23 -11
- package/src/native/Recordings/App/RecordingsApp.swift +37 -1
- package/src/native/Recordings/App/RuntimeSmoke.swift +5 -1
- package/src/native/Recordings/App/SidebarView.swift +1 -1
- package/src/native/Recordings/Package.swift +24 -5
- package/src/native/Recordings/RecordingsLib/EnhancementScreen.swift +91 -0
- package/src/native/Recordings/RecordingsLib/FnKeyMonitor.swift +27 -4
- package/src/native/Recordings/RecordingsLib/Info.plist +2 -2
- package/src/native/Recordings/RecordingsLib/MenuBarPresentation.swift +56 -3
- package/src/native/Recordings/RecordingsLib/NativePCMRecorder.swift +13 -0
- package/src/native/Recordings/RecordingsLib/PasteDeliveryVerification.swift +460 -0
- package/src/native/Recordings/RecordingsLib/PermissionRequestLaunchPlan.swift +21 -1
- package/src/native/Recordings/RecordingsLib/RealtimeTranscriptionClient.swift +41 -7
- package/src/native/Recordings/RecordingsLib/RecordingAttemptAlert.swift +36 -0
- package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +1071 -75
- package/src/native/Recordings/RecordingsLib/SettingsView.swift +47 -3
- package/src/native/Recordings/RecordingsLib/VoiceShortcuts.swift +11 -6
- package/src/native/Recordings/RecordingsTests/BarOnlyLaunchPlanTests.swift +99 -0
- package/src/native/Recordings/RecordingsTests/CLIRunnerTests.swift +3 -3
- package/src/native/Recordings/RecordingsTests/EnhancementScreenTests.swift +191 -0
- package/src/native/Recordings/RecordingsTests/MenuBarPresentationTests.swift +144 -4
- package/src/native/Recordings/RecordingsTests/PasteDeliveryVerificationTests.swift +463 -0
- package/src/native/Recordings/RecordingsTests/PasteTargetTests.swift +33 -20
- package/src/native/Recordings/RecordingsTests/ProjectStoreTests.swift +1 -1
- package/src/native/Recordings/RecordingsTests/RealtimeSettleBenchmark.swift +200 -0
- package/src/native/Recordings/RecordingsTests/RealtimeSettleBudgetTests.swift +80 -0
- package/src/native/Recordings/RecordingsTests/RealtimeTranscriptionTests.swift +22 -4
- package/src/native/Recordings/RecordingsTests/RecordingEngineDeliveryTests.swift +12 -6
- package/src/native/Recordings/RecordingsTests/RecordingEngineHomeIsolationTests.swift +67 -0
- package/src/native/Recordings/RecordingsTests/RecordingStartGateTests.swift +12 -3
- package/src/native/Recordings/RecordingsTests/RecordingStartTimingTests.swift +207 -11
- package/src/native/Recordings/RecordingsTests/SpeechIntentTests.swift +17 -6
- package/src/native/Recordings/RecordingsTests/TestHomeDirectory.swift +23 -0
- package/src/native/Recordings/Updater/Broker/ApplicationProcessQuiescence.swift +7 -1
- package/src/native/Recordings/Updater/Broker/AtomicActivation.swift +10 -10
- package/src/native/Recordings/Updater/Broker/BrokerMain.swift +5 -1
- package/src/native/Recordings/Updater/Broker/HostOSProductVersion.swift +1 -0
- package/src/native/Recordings/Updater/Broker/PeerIdentity.swift +59 -3
- package/src/native/Recordings/Updater/Protocol/UpdateProtocol.swift +21 -2
- package/src/native/Recordings/Updater/ProtocolTests/ExpectationIntegrityTests.swift +60 -0
- package/src/native/Recordings/Updater/ProtocolTests/UpdateXPCInterfaceTests.swift +113 -0
- package/src/native/Recordings/Updater/VerifierLauncher/RecordingsVerifierLauncher.c +106 -5
- package/src/native/Recordings/build.sh +226 -20
- package/scripts/native/prebuilds/darwin-universal/recordings_fs_guard.node +0 -0
package/dist/storage.js
CHANGED
|
@@ -462,7 +462,8 @@ function findProjectRecordingsPath(entry) {
|
|
|
462
462
|
function findRepositoryRoot(start) {
|
|
463
463
|
let dir = start;
|
|
464
464
|
while (true) {
|
|
465
|
-
|
|
465
|
+
const gitPath = join2(dir, ".git");
|
|
466
|
+
if (isRepositoryMarker(gitPath))
|
|
466
467
|
return dir;
|
|
467
468
|
const parent = dirname2(dir);
|
|
468
469
|
if (parent === dir)
|
|
@@ -470,6 +471,15 @@ function findRepositoryRoot(start) {
|
|
|
470
471
|
dir = parent;
|
|
471
472
|
}
|
|
472
473
|
}
|
|
474
|
+
function isRepositoryMarker(gitPath) {
|
|
475
|
+
try {
|
|
476
|
+
if (statSync(gitPath).isFile())
|
|
477
|
+
return true;
|
|
478
|
+
return existsSync(join2(gitPath, "HEAD"));
|
|
479
|
+
} catch {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
473
483
|
function canonicalExistingPath(path) {
|
|
474
484
|
try {
|
|
475
485
|
return realpathSync2(path);
|
|
@@ -498,14 +508,17 @@ function loadSecretKey(keyName) {
|
|
|
498
508
|
try {
|
|
499
509
|
const content = readFileSync(candidate, "utf-8");
|
|
500
510
|
const match = content.match(new RegExp(`export\\s+${keyName}\\s*=\\s*"([^"]+)"`));
|
|
501
|
-
|
|
502
|
-
|
|
511
|
+
const doubleQuotedValue = match?.[1];
|
|
512
|
+
if (doubleQuotedValue !== undefined)
|
|
513
|
+
return doubleQuotedValue;
|
|
503
514
|
const match2 = content.match(new RegExp(`export\\s+${keyName}\\s*=\\s*'([^']+)'`));
|
|
504
|
-
|
|
505
|
-
|
|
515
|
+
const singleQuotedValue = match2?.[1];
|
|
516
|
+
if (singleQuotedValue !== undefined)
|
|
517
|
+
return singleQuotedValue;
|
|
506
518
|
const match3 = content.match(new RegExp(`${keyName}\\s*=\\s*(.+)`));
|
|
507
|
-
|
|
508
|
-
|
|
519
|
+
const unquotedValue = match3?.[1];
|
|
520
|
+
if (unquotedValue !== undefined)
|
|
521
|
+
return unquotedValue.trim().replace(/^["']|["']$/g, "");
|
|
509
522
|
} catch {}
|
|
510
523
|
}
|
|
511
524
|
return "";
|
|
@@ -630,6 +643,7 @@ var MIGRATIONS = [
|
|
|
630
643
|
ALTER TABLE agents ADD COLUMN active_project_id TEXT REFERENCES projects(id) ON DELETE SET NULL;
|
|
631
644
|
`
|
|
632
645
|
];
|
|
646
|
+
var CURRENT_MIGRATION_LEVEL = MIGRATIONS.length - 1;
|
|
633
647
|
function getDatabase(dbPath) {
|
|
634
648
|
if (_db)
|
|
635
649
|
return _db;
|
|
@@ -653,7 +667,11 @@ function runMigrations(db) {
|
|
|
653
667
|
const currentLevel = result?.max_id ?? -1;
|
|
654
668
|
for (let i = currentLevel + 1;i < MIGRATIONS.length; i++) {
|
|
655
669
|
try {
|
|
656
|
-
|
|
670
|
+
const migration = MIGRATIONS[i];
|
|
671
|
+
if (migration === undefined) {
|
|
672
|
+
throw new Error(`Missing SQLite migration at version ${i}`);
|
|
673
|
+
}
|
|
674
|
+
db.run(migration);
|
|
657
675
|
db.query("INSERT INTO _migrations (id) VALUES (?)").run(i);
|
|
658
676
|
} catch (e) {
|
|
659
677
|
if (isBenignMigrationError(e)) {
|
|
@@ -1003,7 +1021,7 @@ function setAgentFocus(idOrName, projectId, db) {
|
|
|
1003
1021
|
}
|
|
1004
1022
|
|
|
1005
1023
|
// src/version.ts
|
|
1006
|
-
var VERSION = "0.2
|
|
1024
|
+
var VERSION = "0.3.2";
|
|
1007
1025
|
|
|
1008
1026
|
// src/db/feedback.ts
|
|
1009
1027
|
function saveFeedback(input) {
|
|
@@ -1011,29 +1029,54 @@ function saveFeedback(input) {
|
|
|
1011
1029
|
db.query("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)").run(input.message, input.email ?? null, input.category ?? "general", input.version ?? VERSION);
|
|
1012
1030
|
}
|
|
1013
1031
|
|
|
1032
|
+
// src/lib/retired-deployment-modes.ts
|
|
1033
|
+
var RETIRED_DEPLOYMENT_MODES = [
|
|
1034
|
+
"local",
|
|
1035
|
+
"self_hosted",
|
|
1036
|
+
"cloud",
|
|
1037
|
+
"remote",
|
|
1038
|
+
"hybrid"
|
|
1039
|
+
];
|
|
1040
|
+
function normalizeModeToken(value) {
|
|
1041
|
+
return value.trim().toLowerCase().replace(/-/g, "_");
|
|
1042
|
+
}
|
|
1043
|
+
function asRetiredDeploymentMode(value) {
|
|
1044
|
+
const token = normalizeModeToken(value);
|
|
1045
|
+
return RETIRED_DEPLOYMENT_MODES.includes(token) ? token : null;
|
|
1046
|
+
}
|
|
1047
|
+
function retiredDeploymentModeError(rawValue, sourceEnvKey, replacement) {
|
|
1048
|
+
const mode = asRetiredDeploymentMode(rawValue);
|
|
1049
|
+
const value = mode === "local" ? replacement.onBox : replacement.offBox;
|
|
1050
|
+
return new Error(`${sourceEnvKey}=${rawValue} names a deployment mode, and deployment modes are removed: ` + `${RETIRED_DEPLOYMENT_MODES.join(" | ")} no longer select anything. ` + `Set ${replacement.envKey}=${value} instead ` + `(${replacement.envKey} takes ${replacement.onBox} or ${replacement.offBox}).`);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1014
1053
|
// src/http/client.ts
|
|
1015
|
-
var
|
|
1054
|
+
var SERVER_BACKEND_VALUES = ["sqlite", "postgresql", "postgres"];
|
|
1016
1055
|
function envToken(name) {
|
|
1017
1056
|
return name.toUpperCase().replace(/-/g, "_");
|
|
1018
1057
|
}
|
|
1019
|
-
function
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1058
|
+
function clientStoreReplacement(envKey) {
|
|
1059
|
+
return { envKey, onBox: "sqlite", offBox: "http" };
|
|
1060
|
+
}
|
|
1061
|
+
function normalizeClientStore(value, sourceEnvKey, replacementEnvKey) {
|
|
1062
|
+
const normalized = normalizeModeToken(value);
|
|
1063
|
+
if (normalized === "sqlite")
|
|
1064
|
+
return "sqlite";
|
|
1065
|
+
if (normalized === "http" || normalized === "https")
|
|
1066
|
+
return "http";
|
|
1067
|
+
if (asRetiredDeploymentMode(value)) {
|
|
1068
|
+
throw retiredDeploymentModeError(value, sourceEnvKey, clientStoreReplacement(replacementEnvKey));
|
|
1027
1069
|
}
|
|
1028
|
-
throw new Error(`Unknown
|
|
1070
|
+
throw new Error(`Unknown client store: ${value}. Use sqlite or http.`);
|
|
1029
1071
|
}
|
|
1030
|
-
function
|
|
1031
|
-
return `
|
|
1072
|
+
function defaultApiBaseUrl(name) {
|
|
1073
|
+
return `http://localhost:8874`;
|
|
1032
1074
|
}
|
|
1033
1075
|
function envKeys(name) {
|
|
1034
1076
|
const token = envToken(name);
|
|
1035
1077
|
return {
|
|
1036
|
-
|
|
1078
|
+
storeKeys: [`HASNA_${token}_CLIENT_STORE`, `${token}_CLIENT_STORE`],
|
|
1079
|
+
retiredModeKeys: [`HASNA_${token}_STORAGE_MODE`, `HASNA_${token}_MODE`, `${token}_STORAGE_MODE`, `${token}_MODE`],
|
|
1037
1080
|
apiUrlKeys: [`HASNA_${token}_API_URL`, `${token}_API_URL`],
|
|
1038
1081
|
apiKeyKeys: [`HASNA_${token}_API_KEY`, `${token}_API_KEY`]
|
|
1039
1082
|
};
|
|
@@ -1046,6 +1089,20 @@ function firstEnv(env, keys) {
|
|
|
1046
1089
|
}
|
|
1047
1090
|
return null;
|
|
1048
1091
|
}
|
|
1092
|
+
function assertNoRetiredMode(env, keys) {
|
|
1093
|
+
for (const key of keys.retiredModeKeys) {
|
|
1094
|
+
const value = env[key]?.trim();
|
|
1095
|
+
if (!value)
|
|
1096
|
+
continue;
|
|
1097
|
+
const normalized = normalizeModeToken(value);
|
|
1098
|
+
if (SERVER_BACKEND_VALUES.includes(normalized))
|
|
1099
|
+
continue;
|
|
1100
|
+
if (asRetiredDeploymentMode(value)) {
|
|
1101
|
+
throw retiredDeploymentModeError(value, key, clientStoreReplacement(keys.storeKeys[0]));
|
|
1102
|
+
}
|
|
1103
|
+
throw new Error(`${key}=${value} is not a client store. ${key} no longer selects one; ` + `set ${keys.storeKeys[0]}=sqlite or ${keys.storeKeys[0]}=http instead.`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1049
1106
|
function toV1BaseUrl(apiUrl) {
|
|
1050
1107
|
const url = new URL(apiUrl);
|
|
1051
1108
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
@@ -1061,45 +1118,42 @@ function toV1BaseUrl(apiUrl) {
|
|
|
1061
1118
|
}
|
|
1062
1119
|
function resolveTransport(name, env = process.env) {
|
|
1063
1120
|
const keys = envKeys(name);
|
|
1064
|
-
|
|
1121
|
+
assertNoRetiredMode(env, keys);
|
|
1122
|
+
const storeHit = firstEnv(env, keys.storeKeys);
|
|
1065
1123
|
const urlHit = firstEnv(env, keys.apiUrlKeys);
|
|
1066
1124
|
const keyHit = firstEnv(env, keys.apiKeyKeys);
|
|
1067
|
-
let
|
|
1068
|
-
let deprecatedAlias = null;
|
|
1125
|
+
let requested = "sqlite";
|
|
1069
1126
|
let modeSource = "default";
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
deprecatedAlias = normalized.deprecatedAlias;
|
|
1074
|
-
modeSource = modeHit.key;
|
|
1127
|
+
if (storeHit) {
|
|
1128
|
+
requested = normalizeClientStore(storeHit.value, storeHit.key, keys.storeKeys[0]);
|
|
1129
|
+
modeSource = storeHit.key;
|
|
1075
1130
|
} else if (urlHit && keyHit) {
|
|
1076
|
-
|
|
1131
|
+
requested = "http";
|
|
1077
1132
|
modeSource = "auto:api-url+api-key";
|
|
1078
1133
|
}
|
|
1079
|
-
if (
|
|
1080
|
-
return { transport: "
|
|
1134
|
+
if (requested === "sqlite") {
|
|
1135
|
+
return { transport: "sqlite", requested, modeSource, baseUrl: null, apiKeyPresent: Boolean(keyHit), misconfigured: false, warning: null };
|
|
1081
1136
|
}
|
|
1082
1137
|
if (!keyHit) {
|
|
1083
1138
|
return {
|
|
1084
|
-
transport: "
|
|
1085
|
-
|
|
1086
|
-
deprecatedAlias,
|
|
1139
|
+
transport: "sqlite",
|
|
1140
|
+
requested,
|
|
1087
1141
|
modeSource,
|
|
1088
1142
|
baseUrl: null,
|
|
1089
1143
|
apiKeyPresent: false,
|
|
1090
1144
|
misconfigured: true,
|
|
1091
|
-
warning: `${modeSource}=
|
|
1145
|
+
warning: `${modeSource}=http but no API key is set (${keys.apiKeyKeys[0]}). Refusing to route to the API.`
|
|
1092
1146
|
};
|
|
1093
1147
|
}
|
|
1094
|
-
const rawUrl = urlHit?.value ??
|
|
1148
|
+
const rawUrl = urlHit?.value ?? defaultApiBaseUrl(name);
|
|
1095
1149
|
let baseUrl;
|
|
1096
1150
|
try {
|
|
1097
1151
|
baseUrl = toV1BaseUrl(rawUrl);
|
|
1098
1152
|
} catch (error) {
|
|
1099
1153
|
const message = error instanceof Error ? error.message : String(error);
|
|
1100
|
-
return { transport: "
|
|
1154
|
+
return { transport: "sqlite", requested, modeSource, baseUrl: null, apiKeyPresent: true, misconfigured: true, warning: `Invalid API URL: ${message}.` };
|
|
1101
1155
|
}
|
|
1102
|
-
return { transport: "
|
|
1156
|
+
return { transport: "http", requested, modeSource, baseUrl, apiKeyPresent: true, misconfigured: false, warning: null };
|
|
1103
1157
|
}
|
|
1104
1158
|
|
|
1105
1159
|
class HasnaHttpError extends Error {
|
|
@@ -1211,6 +1265,8 @@ function createHttpTransport(options) {
|
|
|
1211
1265
|
const jitter = Math.floor(Math.random() * (backoff / 2 + 1));
|
|
1212
1266
|
await sleep(backoff + jitter);
|
|
1213
1267
|
}
|
|
1268
|
+
if (last === null)
|
|
1269
|
+
throw new Error(`Request to ${rel} completed without a result`);
|
|
1214
1270
|
throw last.error;
|
|
1215
1271
|
}
|
|
1216
1272
|
return {
|
|
@@ -1282,17 +1338,17 @@ function createStorageClient(name, transport) {
|
|
|
1282
1338
|
function resolveStorageClient(name, env = process.env, fetchImpl) {
|
|
1283
1339
|
const resolution = resolveTransport(name, env);
|
|
1284
1340
|
if (resolution.misconfigured) {
|
|
1285
|
-
throw new Error(resolution.warning ?? `Client for '${name}' is misconfigured for
|
|
1341
|
+
throw new Error(resolution.warning ?? `Client for '${name}' is misconfigured for the /v1 API.`);
|
|
1286
1342
|
}
|
|
1287
|
-
if (resolution.transport === "
|
|
1288
|
-
return { transport: "
|
|
1343
|
+
if (resolution.transport === "sqlite" || !resolution.baseUrl) {
|
|
1344
|
+
return { transport: "sqlite", client: null, resolution };
|
|
1289
1345
|
}
|
|
1290
1346
|
const keys = envKeys(name);
|
|
1291
1347
|
const apiKey = firstEnv(env, keys.apiKeyKeys)?.value;
|
|
1292
1348
|
if (!apiKey)
|
|
1293
|
-
throw new Error(`Client for '${name}' resolved to
|
|
1349
|
+
throw new Error(`Client for '${name}' resolved to the /v1 API without an API key.`);
|
|
1294
1350
|
const transport = createHttpTransport({ name, baseUrl: resolution.baseUrl, apiKey, ...fetchImpl ? { fetchImpl } : {} });
|
|
1295
|
-
return { transport: "
|
|
1351
|
+
return { transport: "http", client: createStorageClient(name, transport), resolution };
|
|
1296
1352
|
}
|
|
1297
1353
|
|
|
1298
1354
|
// src/store.ts
|
|
@@ -1316,12 +1372,15 @@ function listQuery(filter) {
|
|
|
1316
1372
|
}
|
|
1317
1373
|
function unwrap(res, key) {
|
|
1318
1374
|
if (res && typeof res === "object" && key in res) {
|
|
1319
|
-
|
|
1375
|
+
const value = res[key];
|
|
1376
|
+
if (value === undefined)
|
|
1377
|
+
throw new Error(`Response field ${key} is undefined`);
|
|
1378
|
+
return value;
|
|
1320
1379
|
}
|
|
1321
1380
|
return res;
|
|
1322
1381
|
}
|
|
1323
1382
|
var localStore = {
|
|
1324
|
-
mode: "
|
|
1383
|
+
mode: "sqlite",
|
|
1325
1384
|
baseUrl: null,
|
|
1326
1385
|
async createRecording(input, idempotencyKey) {
|
|
1327
1386
|
return withLocalStoreReaderLease(() => createRecording(input, undefined, idempotencyKey));
|
|
@@ -1374,7 +1433,7 @@ var localStore = {
|
|
|
1374
1433
|
};
|
|
1375
1434
|
function apiStore(client) {
|
|
1376
1435
|
return {
|
|
1377
|
-
mode: "
|
|
1436
|
+
mode: "http",
|
|
1378
1437
|
baseUrl: client.baseUrl,
|
|
1379
1438
|
async createRecording(input, idempotencyKey) {
|
|
1380
1439
|
const keyCandidate = idempotencyKey === undefined && (input.id === undefined || input.id === null) ? randomUUID2() : idempotencyKey;
|
|
@@ -1517,7 +1576,7 @@ function getStore(env = process.env) {
|
|
|
1517
1576
|
if (env === process.env && cached)
|
|
1518
1577
|
return cached;
|
|
1519
1578
|
const resolved = resolveStorageClient(APP, env);
|
|
1520
|
-
const store = resolved.transport === "
|
|
1579
|
+
const store = resolved.transport === "http" ? apiStore(resolved.client) : localStore;
|
|
1521
1580
|
if (env === process.env)
|
|
1522
1581
|
cached = store;
|
|
1523
1582
|
return store;
|
|
@@ -1558,7 +1617,7 @@ export {
|
|
|
1558
1617
|
resolveTransport,
|
|
1559
1618
|
resolveStorageClient,
|
|
1560
1619
|
getStore,
|
|
1561
|
-
|
|
1620
|
+
defaultApiBaseUrl,
|
|
1562
1621
|
createStorageClient,
|
|
1563
1622
|
createHttpTransport,
|
|
1564
1623
|
__resetStore,
|
package/dist/store.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface RecordingStats {
|
|
|
10
10
|
by_model: Record<string, number>;
|
|
11
11
|
}
|
|
12
12
|
export interface Store {
|
|
13
|
-
readonly mode: "
|
|
13
|
+
readonly mode: "sqlite" | "http";
|
|
14
14
|
readonly baseUrl: string | null;
|
|
15
15
|
createRecording(input: CreateRecordingInput, idempotencyKey?: string): Promise<Recording>;
|
|
16
16
|
getRecording(id: string): Promise<Recording | null>;
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAkBA,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;AAMzF,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;AAwPD,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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.2
|
|
1
|
+
export declare const VERSION = "0.3.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/recordings",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
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": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/hasna/
|
|
8
|
+
"url": "git+https://github.com/hasna/apps"
|
|
9
9
|
},
|
|
10
10
|
"main": "dist/index.js",
|
|
11
11
|
"types": "dist/index.d.ts",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"types": "./dist/sdk/index.d.ts"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"bun": ">=1.0.0"
|
|
33
|
+
},
|
|
31
34
|
"scripts": {
|
|
32
35
|
"clean": "rm -rf dist",
|
|
33
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",
|
|
@@ -39,13 +42,29 @@
|
|
|
39
42
|
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
40
43
|
"migrate": "bun run scripts/migrate.ts",
|
|
41
44
|
"typecheck": "tsc --noEmit",
|
|
45
|
+
"typecheck:tcc-contract": "tsc --noEmit -p tsconfig.tcc-contract.json",
|
|
42
46
|
"test": "bun test",
|
|
47
|
+
"verify:ci-suite": "bun scripts/ci-linux-suite.ts --check",
|
|
48
|
+
"verify:ci-suite:run": "bun scripts/ci-linux-suite.ts --verify-run",
|
|
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)",
|
|
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
|
+
"test:vacuity-battery:source": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/source-side.tsv",
|
|
53
|
+
"test:vacuity-battery:chain": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/install-chain.tsv",
|
|
54
|
+
"test:vacuity-battery:vars": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/variable-operands.tsv",
|
|
55
|
+
"test:vacuity-battery:reorder": "bun scripts/vacuity-mutation-battery.ts scripts/vacuity-manifests/reorder.tsv",
|
|
43
56
|
"test:coverage": "bun test --coverage",
|
|
44
57
|
"dev:cli": "bun run src/cli/index.ts",
|
|
58
|
+
"desktop:snapshot": "bun run src/cli/index.ts app snapshot",
|
|
45
59
|
"dev:mcp": "bun run src/mcp/index.ts",
|
|
46
60
|
"verify:release": "bun run scripts/release-guard.ts",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
61
|
+
"scan:artifact": "bun run scripts/scan-artifact.ts",
|
|
62
|
+
"version:set": "bun run scripts/set-version.ts",
|
|
63
|
+
"version:check": "bun run scripts/set-version.ts --check",
|
|
64
|
+
"prepack": "bun run prepack:platform-gate && bun run version:check && bun run build && bun run verify:release && bun run scan:artifact",
|
|
65
|
+
"prepack:platform-gate": "bash -c 'if [ \"$(uname -s)\" = Darwin ]; then bun run build:native-fs-guard; else echo \"WARN: native fs-guard build skipped on $(uname -s) — dry-run/CI pack; publish recordings from macOS\"; fi'",
|
|
66
|
+
"prepublishOnly": "bun run typecheck && bun run test",
|
|
67
|
+
"typecheck:shortcut-contract": "tsc --noEmit -p tsconfig.test.json"
|
|
49
68
|
},
|
|
50
69
|
"files": [
|
|
51
70
|
"dist/",
|
|
@@ -64,8 +83,8 @@
|
|
|
64
83
|
"LICENSE"
|
|
65
84
|
],
|
|
66
85
|
"dependencies": {
|
|
67
|
-
"@hasna/contracts": "
|
|
68
|
-
"@hasna/events": "
|
|
86
|
+
"@hasna/contracts": "0.8.4",
|
|
87
|
+
"@hasna/events": "0.1.11",
|
|
69
88
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
70
89
|
"chalk": "^5.4.1",
|
|
71
90
|
"commander": "^13.1.0",
|