@mnemonik/cli 7.111.10 → 7.112.3

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 (55) hide show
  1. package/dist/auth/credentials.d.ts +7 -2
  2. package/dist/auth/credentials.d.ts.map +1 -1
  3. package/dist/auth/credentials.js +311 -98
  4. package/dist/auth/index.d.ts +15 -0
  5. package/dist/auth/index.d.ts.map +1 -1
  6. package/dist/auth/index.js +72 -15
  7. package/dist/auth/index.js.map +1 -1
  8. package/dist/auth/installSession.js +3 -2
  9. package/dist/auth/status.js +3 -2
  10. package/dist/diagnostics.js +315 -102
  11. package/dist/digests.json +53 -53
  12. package/dist/identity/migrate.js +40 -2
  13. package/dist/install/hosts.js +3 -2
  14. package/dist/install/journal.js +40 -2
  15. package/dist/install/journey.js +40 -2
  16. package/dist/install/ownership.js +40 -2
  17. package/dist/install/transaction.d.ts +1 -3
  18. package/dist/install/transaction.d.ts.map +1 -1
  19. package/dist/install/transaction.js +67 -16
  20. package/dist/install/transaction.js.map +1 -1
  21. package/dist/install/ui.d.ts.map +1 -1
  22. package/dist/install/ui.js +42 -2
  23. package/dist/install/ui.js.map +1 -1
  24. package/dist/installSession.js +3 -2
  25. package/dist/installation.js +40 -2
  26. package/dist/launcher.js +40 -2
  27. package/dist/preflight.js +4 -3
  28. package/dist/project/eligibility.js +40 -2
  29. package/dist/project/records.js +40 -2
  30. package/dist/project.d.ts +11 -2
  31. package/dist/project.d.ts.map +1 -1
  32. package/dist/project.js +46 -4
  33. package/dist/project.js.map +1 -1
  34. package/dist/router.js +41 -3
  35. package/dist/runtime/releaseSource.js +40 -2
  36. package/dist/runtime/selfUpdate.js +40 -2
  37. package/dist/runtime/signers.js +242 -50
  38. package/dist/runtime/store.js +34 -0
  39. package/dist/runtime/updateCheck.js +40 -2
  40. package/dist/sbom.json +21 -21
  41. package/dist/scanner/control.js +40 -2
  42. package/dist/scanner/data.js +3 -2
  43. package/dist/scanner/discover.js +4 -3
  44. package/dist/scanner/enable.js +40 -2
  45. package/dist/scanner/picker.js +3 -2
  46. package/dist/scanner/service.js +40 -2
  47. package/dist/scanner/update.js +40 -2
  48. package/dist/scanner-release.json +29 -29
  49. package/dist/status.js +44 -6
  50. package/dist/transport/server.d.ts +21 -2
  51. package/dist/transport/server.d.ts.map +1 -1
  52. package/dist/transport/server.js +15 -1
  53. package/dist/transport/server.js.map +1 -1
  54. package/dist/vendor/local-setup.js +40 -2
  55. package/package.json +31 -31
@@ -501,6 +501,13 @@ var require_ignore = __commonJS({
501
501
  }
502
502
  });
503
503
 
504
+ // packages/shared/dist/hookTimeouts.js
505
+ var init_hookTimeouts = __esm({
506
+ "packages/shared/dist/hookTimeouts.js"() {
507
+ "use strict";
508
+ }
509
+ });
510
+
504
511
  // packages/shared/dist/runtimeSigners.js
505
512
  import { basename, dirname as dirname2, join as join2, resolve, sep, win32 } from "node:path";
506
513
  import { createHash, createPublicKey, randomUUID, timingSafeEqual, verify as verifySignature } from "node:crypto";
@@ -648,11 +655,37 @@ var init_runtimeReader = __esm({
648
655
  });
649
656
 
650
657
  // packages/shared/dist/projectSetupHandoff.js
658
+ var PROJECT_ENSURE_TIMEOUT_MS, SUPERVISOR, RUN_STALE_MS;
651
659
  var init_projectSetupHandoff = __esm({
652
660
  "packages/shared/dist/projectSetupHandoff.js"() {
653
661
  "use strict";
654
662
  init_runtimeSigners();
663
+ init_hookTimeouts();
655
664
  init_runtimeReader();
665
+ PROJECT_ENSURE_TIMEOUT_MS = 3e4;
666
+ SUPERVISOR = `
667
+ const { execFile } = require('node:child_process');
668
+ const { writeFileSync, renameSync } = require('node:fs');
669
+ const [out, bin, ...args] = process.argv.slice(1);
670
+ let input = '';
671
+ process.stdin.setEncoding('utf8');
672
+ process.stdin.on('data', (chunk) => (input += chunk));
673
+ process.stdin.on('end', () => {
674
+ const child = execFile(
675
+ process.execPath,
676
+ [bin, ...args],
677
+ { shell: false, timeout: ${PROJECT_ENSURE_TIMEOUT_MS}, killSignal: 'SIGKILL', maxBuffer: 64 * 1024, env: process.env },
678
+ (error, stdout) => {
679
+ const result = { code: error ? (typeof error.code === 'number' ? error.code : null) : 0, killed: !!(error && error.killed), stdout: String(stdout) };
680
+ writeFileSync(out + '.tmp', JSON.stringify(result), { mode: 0o600 });
681
+ renameSync(out + '.tmp', out);
682
+ }
683
+ );
684
+ child.stdin.on('error', () => {});
685
+ child.stdin.end(input);
686
+ });
687
+ `;
688
+ RUN_STALE_MS = PROJECT_ENSURE_TIMEOUT_MS + 1e4;
656
689
  }
657
690
  });
658
691
 
@@ -661,6 +694,7 @@ var init_hookRuntime = __esm({
661
694
  "packages/shared/dist/hookRuntime.js"() {
662
695
  "use strict";
663
696
  init_runtimeSigners();
697
+ init_hookTimeouts();
664
698
  init_repositoryRoot();
665
699
  init_runtimeReader();
666
700
  init_runtimeSigners();
@@ -2262,7 +2296,7 @@ Project work items live in tasks. A pending list requires action:"list" and stat
2262
2296
 
2263
2297
  Which tool for what:
2264
2298
  - memory_get: hydrates exact originals by id.
2265
- - memory_add: saves a discrete decision or root cause.
2299
+ - memory_add: saves a decision, a user's preference, or a root cause.
2266
2300
  - memory_state: corrects wrong, outdated, or conflicting memory.
2267
2301
  - memory_info: explains confidence or origin when memory looks suspect.
2268
2302
  - memory_links: connects related decisions so they surface together.
@@ -2271,7 +2305,8 @@ Which tool for what:
2271
2305
  - policy: stores durable enforced rules or preferences, not memories.
2272
2306
  - tasks: creates follow-up work and closes completed work.
2273
2307
  - code_search: finds conceptual code when source wording differs.
2274
- - memory_search: finds rationale, intent, decisions, and prior work.`;
2308
+ - memory_search: finds rationale, intent, decisions, and prior work.
2309
+ - memory_ingest: brings the project's docs and code comments into memory when asked.`;
2275
2310
  function getMcpInstructions() {
2276
2311
  const process2 = globalThis.process;
2277
2312
  if (!process2?.env) {
@@ -6433,6 +6468,9 @@ var DEFAULT_OPTIONS = {
6433
6468
  };
6434
6469
  var BUILT_IN_IGNORE_DIR_SET = new Set(BUILT_IN_IGNORE_DIRS);
6435
6470
 
6471
+ // packages/shared/dist/index.js
6472
+ init_hookTimeouts();
6473
+
6436
6474
  // packages/shared/dist/jitDeliveryAck.js
6437
6475
  init_runtimeSigners();
6438
6476
 
@@ -501,6 +501,13 @@ var require_ignore = __commonJS({
501
501
  }
502
502
  });
503
503
 
504
+ // packages/shared/dist/hookTimeouts.js
505
+ var init_hookTimeouts = __esm({
506
+ "packages/shared/dist/hookTimeouts.js"() {
507
+ "use strict";
508
+ }
509
+ });
510
+
504
511
  // packages/shared/dist/runtimeSigners.js
505
512
  import { basename, dirname as dirname2, join as join2, resolve, sep, win32 } from "node:path";
506
513
  import { execFile, execFileSync } from "node:child_process";
@@ -618,11 +625,37 @@ var init_runtimeReader = __esm({
618
625
  });
619
626
 
620
627
  // packages/shared/dist/projectSetupHandoff.js
628
+ var PROJECT_ENSURE_TIMEOUT_MS, SUPERVISOR, RUN_STALE_MS;
621
629
  var init_projectSetupHandoff = __esm({
622
630
  "packages/shared/dist/projectSetupHandoff.js"() {
623
631
  "use strict";
624
632
  init_runtimeSigners();
633
+ init_hookTimeouts();
625
634
  init_runtimeReader();
635
+ PROJECT_ENSURE_TIMEOUT_MS = 3e4;
636
+ SUPERVISOR = `
637
+ const { execFile } = require('node:child_process');
638
+ const { writeFileSync, renameSync } = require('node:fs');
639
+ const [out, bin, ...args] = process.argv.slice(1);
640
+ let input = '';
641
+ process.stdin.setEncoding('utf8');
642
+ process.stdin.on('data', (chunk) => (input += chunk));
643
+ process.stdin.on('end', () => {
644
+ const child = execFile(
645
+ process.execPath,
646
+ [bin, ...args],
647
+ { shell: false, timeout: ${PROJECT_ENSURE_TIMEOUT_MS}, killSignal: 'SIGKILL', maxBuffer: 64 * 1024, env: process.env },
648
+ (error, stdout) => {
649
+ const result = { code: error ? (typeof error.code === 'number' ? error.code : null) : 0, killed: !!(error && error.killed), stdout: String(stdout) };
650
+ writeFileSync(out + '.tmp', JSON.stringify(result), { mode: 0o600 });
651
+ renameSync(out + '.tmp', out);
652
+ }
653
+ );
654
+ child.stdin.on('error', () => {});
655
+ child.stdin.end(input);
656
+ });
657
+ `;
658
+ RUN_STALE_MS = PROJECT_ENSURE_TIMEOUT_MS + 1e4;
626
659
  }
627
660
  });
628
661
 
@@ -631,6 +664,7 @@ var init_hookRuntime = __esm({
631
664
  "packages/shared/dist/hookRuntime.js"() {
632
665
  "use strict";
633
666
  init_runtimeSigners();
667
+ init_hookTimeouts();
634
668
  init_repositoryRoot();
635
669
  init_runtimeReader();
636
670
  init_runtimeSigners();
@@ -2231,7 +2265,7 @@ Project work items live in tasks. A pending list requires action:"list" and stat
2231
2265
 
2232
2266
  Which tool for what:
2233
2267
  - memory_get: hydrates exact originals by id.
2234
- - memory_add: saves a discrete decision or root cause.
2268
+ - memory_add: saves a decision, a user's preference, or a root cause.
2235
2269
  - memory_state: corrects wrong, outdated, or conflicting memory.
2236
2270
  - memory_info: explains confidence or origin when memory looks suspect.
2237
2271
  - memory_links: connects related decisions so they surface together.
@@ -2240,7 +2274,8 @@ Which tool for what:
2240
2274
  - policy: stores durable enforced rules or preferences, not memories.
2241
2275
  - tasks: creates follow-up work and closes completed work.
2242
2276
  - code_search: finds conceptual code when source wording differs.
2243
- - memory_search: finds rationale, intent, decisions, and prior work.`;
2277
+ - memory_search: finds rationale, intent, decisions, and prior work.
2278
+ - memory_ingest: brings the project's docs and code comments into memory when asked.`;
2244
2279
  function getMcpInstructions() {
2245
2280
  const process2 = globalThis.process;
2246
2281
  if (!process2?.env) {
@@ -6402,6 +6437,9 @@ var DEFAULT_OPTIONS = {
6402
6437
  };
6403
6438
  var BUILT_IN_IGNORE_DIR_SET = new Set(BUILT_IN_IGNORE_DIRS);
6404
6439
 
6440
+ // packages/shared/dist/index.js
6441
+ init_hookTimeouts();
6442
+
6405
6443
  // packages/shared/dist/jitDeliveryAck.js
6406
6444
  init_runtimeSigners();
6407
6445
 
@@ -519,6 +519,26 @@ var init_runtimeSigners = __esm({
519
519
  }
520
520
  });
521
521
 
522
+ // packages/shared/dist/hookTimeouts.js
523
+ function hookDeadlineMs(host) {
524
+ return HOST_HOOK_TIMEOUT_MS[host] - HOOK_TIMEOUT_MARGIN_MS - HOOK_STDIN_TIMEOUT_MS;
525
+ }
526
+ var HOST_HOOK_TIMEOUT_MS, HOOK_TIMEOUT_MARGIN_MS, HOOK_STDIN_TIMEOUT_MS;
527
+ var init_hookTimeouts = __esm({
528
+ "packages/shared/dist/hookTimeouts.js"() {
529
+ "use strict";
530
+ HOST_HOOK_TIMEOUT_MS = {
531
+ claude_code: 5e3,
532
+ copilot: 5e3,
533
+ codex: 5e3,
534
+ grok: 5e3,
535
+ cursor: 3e4
536
+ };
537
+ HOOK_TIMEOUT_MARGIN_MS = 500;
538
+ HOOK_STDIN_TIMEOUT_MS = 500;
539
+ }
540
+ });
541
+
522
542
  // packages/shared/dist/projectIdentityFile.js
523
543
  import { lstat, readFile as readFile2 } from "node:fs/promises";
524
544
  import { join as join2 } from "node:path";
@@ -585,7 +605,7 @@ async function readIdentityFile(dir, options = {}) {
585
605
  if (options.selectedRoot) {
586
606
  try {
587
607
  const value = JSON.parse(text);
588
- if (value && typeof value === "object" && !Array.isArray(value) && !("projectId" in value))
608
+ if (value && typeof value === "object" && !Array.isArray(value) && !("projectId" in value) && (!("schemaVersion" in value) || value.schemaVersion === 1))
589
609
  return { kind: "absent" };
590
610
  } catch {
591
611
  }
@@ -1191,11 +1211,12 @@ var init_runtimeReader = __esm({
1191
1211
  });
1192
1212
 
1193
1213
  // packages/shared/dist/projectSetupHandoff.js
1194
- import { execFile as execFile3 } from "node:child_process";
1214
+ import { spawn } from "node:child_process";
1195
1215
  import { constants as constants2 } from "node:fs";
1196
1216
  import { lstat as lstat4, mkdir, open as open2, readdir as readdir2, realpath, rename, rm } from "node:fs/promises";
1197
1217
  import { tmpdir } from "node:os";
1198
- import { dirname as dirname4, join as join5, relative } from "node:path";
1218
+ import { basename as basename2, dirname as dirname4, join as join5, relative } from "node:path";
1219
+ import { performance as performance2 } from "node:perf_hooks";
1199
1220
  import { randomUUID as randomUUID2 } from "node:crypto";
1200
1221
  function projectSetupActions(value) {
1201
1222
  return Array.isArray(value) ? value.slice(0, 20).map(words).join(", ") : "retry, cancel";
@@ -1260,6 +1281,115 @@ async function writeDiagnostic(path, value) {
1260
1281
  await rm(temp, { force: true });
1261
1282
  }
1262
1283
  }
1284
+ async function readResult(path) {
1285
+ let raw;
1286
+ try {
1287
+ raw = await readPrivate(path);
1288
+ } catch (error) {
1289
+ if (error.code === "ENOENT")
1290
+ return void 0;
1291
+ throw error;
1292
+ }
1293
+ const result = JSON.parse(raw);
1294
+ if (result.killed || result.code !== 0 && result.code !== 3)
1295
+ throw new Error("helper_failed");
1296
+ try {
1297
+ return JSON.parse(String(result.stdout));
1298
+ } catch {
1299
+ throw new Error("helper_invalid_json");
1300
+ }
1301
+ }
1302
+ async function waitForResult(path, waitMs) {
1303
+ const deadline = Date.now() + waitMs;
1304
+ for (; ; ) {
1305
+ const result = await readResult(path);
1306
+ if (result !== void 0)
1307
+ return result;
1308
+ if (Date.now() >= deadline)
1309
+ return RUNNING;
1310
+ await new Promise((resolve4) => setTimeout(resolve4, Math.min(50, deadline - Date.now())));
1311
+ }
1312
+ }
1313
+ async function runEnsure(options) {
1314
+ await privateDirectory(dirname4(options.directory), options.directory);
1315
+ await privateDirectory(options.directory, options.directory);
1316
+ const runFile = join5(options.directory, "project-setup-run.json");
1317
+ let previous;
1318
+ try {
1319
+ previous = JSON.parse(await readPrivate(runFile));
1320
+ } catch {
1321
+ previous = void 0;
1322
+ }
1323
+ if (previous && previous.root === options.root && typeof previous.result === "string") {
1324
+ const result2 = join5(options.directory, basename2(previous.result));
1325
+ const finished = await readResult(result2).catch(() => ({ status: "failed" }));
1326
+ if (finished === void 0 && Date.now() - previous.startedAt < RUN_STALE_MS) {
1327
+ const outcome2 = await waitForResult(result2, options.waitMs);
1328
+ if (outcome2 !== RUNNING)
1329
+ await rm(runFile, { force: true });
1330
+ return outcome2;
1331
+ }
1332
+ await rm(runFile, { force: true });
1333
+ await rm(result2, { force: true });
1334
+ if (record(finished) && finished.status === "done")
1335
+ return finished;
1336
+ }
1337
+ const result = join5(options.directory, `project-setup-${randomUUID2()}.result.json`);
1338
+ const run = {
1339
+ requestId: options.requestId,
1340
+ root: options.root,
1341
+ result: basename2(result),
1342
+ startedAt: Date.now()
1343
+ };
1344
+ await writeFileAtomic(runFile, JSON.stringify(run));
1345
+ const child = spawn(process.execPath, ["-e", SUPERVISOR, result, options.bin, "project", "ensure", "--agent", "--json"], {
1346
+ cwd: options.root,
1347
+ shell: false,
1348
+ detached: true,
1349
+ windowsHide: true,
1350
+ stdio: ["pipe", "ignore", "ignore"],
1351
+ // Runtime injection variables and repository/PATH executables are not inherited.
1352
+ env: Object.fromEntries([
1353
+ "HOME",
1354
+ "USERPROFILE",
1355
+ "LOCALAPPDATA",
1356
+ "XDG_STATE_HOME",
1357
+ "MNEMONIK_STATE_DIR",
1358
+ "MNEMONIK_SERVER",
1359
+ "MNEMONIK_API_RESOURCE",
1360
+ "MNEMONIK_OAUTH_ISSUER",
1361
+ "SYSTEMROOT",
1362
+ "TEMP",
1363
+ "TMP",
1364
+ "TMPDIR"
1365
+ ].flatMap((key) => process.env[key] === void 0 ? [] : [[key, process.env[key]]]))
1366
+ });
1367
+ const spawnFailed = new Promise((_, reject2) => child.once("error", () => reject2(new Error("helper_failed"))));
1368
+ child.stdin?.on("error", () => {
1369
+ });
1370
+ child.stdin?.end(JSON.stringify({ requestId: options.requestId }));
1371
+ child.unref();
1372
+ const outcome = await Promise.race([waitForResult(result, options.waitMs), spawnFailed]);
1373
+ if (outcome !== RUNNING) {
1374
+ await rm(runFile, { force: true });
1375
+ await rm(result, { force: true });
1376
+ }
1377
+ return outcome;
1378
+ }
1379
+ async function writeFileAtomic(path, data) {
1380
+ const temp = `${path}.${randomUUID2()}`;
1381
+ try {
1382
+ const file = await open2(temp, "wx", 384);
1383
+ try {
1384
+ await file.writeFile(data);
1385
+ } finally {
1386
+ await file.close();
1387
+ }
1388
+ await rename(temp, path);
1389
+ } finally {
1390
+ await rm(temp, { force: true });
1391
+ }
1392
+ }
1263
1393
  async function handoffProjectSetup(input) {
1264
1394
  const response = setupResponse(input.response);
1265
1395
  if (!response)
@@ -1289,41 +1419,17 @@ async function handoffProjectSetup(input) {
1289
1419
  const bin = join5(dirname4(runtime.entry), "bin.js");
1290
1420
  if (!runtime.manifest.files[relative(runtime.directory, bin).replaceAll("\\", "/")])
1291
1421
  throw new Error("verified_cli_bin_missing");
1292
- const result = await new Promise((resolve4, reject2) => {
1293
- const child = execFile3(process.execPath, [bin, "project", "ensure", "--agent", "--json"], {
1294
- cwd: root,
1295
- shell: false,
1296
- timeout: 3e4,
1297
- killSignal: "SIGKILL",
1298
- maxBuffer: 64 * 1024,
1299
- // Runtime injection variables and repository/PATH executables are not inherited.
1300
- env: Object.fromEntries([
1301
- "HOME",
1302
- "USERPROFILE",
1303
- "LOCALAPPDATA",
1304
- "XDG_STATE_HOME",
1305
- "MNEMONIK_STATE_DIR",
1306
- "MNEMONIK_SERVER",
1307
- "MNEMONIK_API_RESOURCE",
1308
- "MNEMONIK_OAUTH_ISSUER",
1309
- "SYSTEMROOT",
1310
- "TEMP",
1311
- "TMP",
1312
- "TMPDIR"
1313
- ].flatMap((key) => process.env[key] === void 0 ? [] : [[key, process.env[key]]]))
1314
- }, (error, stdout2) => {
1315
- if (error && (error.killed || error.code !== 3))
1316
- return reject2(new Error("helper_failed"));
1317
- try {
1318
- resolve4(JSON.parse(stdout2));
1319
- } catch {
1320
- reject2(new Error("helper_invalid_json"));
1321
- }
1322
- });
1323
- child.stdin?.on("error", () => {
1324
- });
1325
- child.stdin?.end(JSON.stringify({ requestId }));
1422
+ const result = await runEnsure({
1423
+ bin,
1424
+ root,
1425
+ requestId,
1426
+ directory: dirname4(input.stateFile),
1427
+ waitMs: input.waitMs ?? Math.max(0, hookDeadlineMs(input.host) - performance2.now())
1326
1428
  });
1429
+ if (result === RUNNING) {
1430
+ return PROJECT_SETUP_RUNNING;
1431
+ }
1432
+ (await Promise.resolve().then(() => (init_hookRuntime(), hookRuntime_exports))).clearProjectIdentityCache();
1327
1433
  if (!record(result))
1328
1434
  throw new Error("helper_invalid_json");
1329
1435
  if (result.status === "done") {
@@ -1384,15 +1490,42 @@ async function pendingProjectSetup(root) {
1384
1490
  results.sort((a, b) => Date.parse(b.time) - Date.parse(a.time));
1385
1491
  return results[0]?.outcome === "done" ? [] : results.slice(0, 1);
1386
1492
  }
1387
- var PROJECT_SETUP_MANUAL, words, record;
1493
+ var PROJECT_SETUP_MANUAL, words, record, PROJECT_SETUP_RUNNING, PROJECT_ENSURE_TIMEOUT_MS, RUNNING, SUPERVISOR, RUN_STALE_MS;
1388
1494
  var init_projectSetupHandoff = __esm({
1389
1495
  "packages/shared/dist/projectSetupHandoff.js"() {
1390
1496
  "use strict";
1391
1497
  init_runtimeSigners();
1498
+ init_hookTimeouts();
1392
1499
  init_runtimeReader();
1393
1500
  PROJECT_SETUP_MANUAL = "Mnemonik project setup needs attention; ask the person to run `mnemonik project init` in this folder.";
1394
1501
  words = (value) => typeof value === "string" && /^[a-z][a-z0-9_]{0,79}$/.test(value) ? value.replaceAll("_", " ") : "needs attention";
1395
1502
  record = (value) => !!value && typeof value === "object" && !Array.isArray(value);
1503
+ PROJECT_SETUP_RUNNING = "Mnemonik project setup is still running; call session_bootstrap again in a few seconds.";
1504
+ PROJECT_ENSURE_TIMEOUT_MS = 3e4;
1505
+ RUNNING = /* @__PURE__ */ Symbol("running");
1506
+ SUPERVISOR = `
1507
+ const { execFile } = require('node:child_process');
1508
+ const { writeFileSync, renameSync } = require('node:fs');
1509
+ const [out, bin, ...args] = process.argv.slice(1);
1510
+ let input = '';
1511
+ process.stdin.setEncoding('utf8');
1512
+ process.stdin.on('data', (chunk) => (input += chunk));
1513
+ process.stdin.on('end', () => {
1514
+ const child = execFile(
1515
+ process.execPath,
1516
+ [bin, ...args],
1517
+ { shell: false, timeout: ${PROJECT_ENSURE_TIMEOUT_MS}, killSignal: 'SIGKILL', maxBuffer: 64 * 1024, env: process.env },
1518
+ (error, stdout) => {
1519
+ const result = { code: error ? (typeof error.code === 'number' ? error.code : null) : 0, killed: !!(error && error.killed), stdout: String(stdout) };
1520
+ writeFileSync(out + '.tmp', JSON.stringify(result), { mode: 0o600 });
1521
+ renameSync(out + '.tmp', out);
1522
+ }
1523
+ );
1524
+ child.stdin.on('error', () => {});
1525
+ child.stdin.end(input);
1526
+ });
1527
+ `;
1528
+ RUN_STALE_MS = PROJECT_ENSURE_TIMEOUT_MS + 1e4;
1396
1529
  }
1397
1530
  });
1398
1531
 
@@ -1557,13 +1690,17 @@ var init_repositoryFingerprint = __esm({
1557
1690
  // packages/shared/dist/hookRuntime.js
1558
1691
  var hookRuntime_exports = {};
1559
1692
  __export(hookRuntime_exports, {
1693
+ HOOK_STDIN_MAX_BYTES: () => HOOK_STDIN_MAX_BYTES,
1694
+ PROJECT_ENSURE_TIMEOUT_MS: () => PROJECT_ENSURE_TIMEOUT_MS,
1560
1695
  PROJECT_SETUP_MANUAL: () => PROJECT_SETUP_MANUAL,
1696
+ PROJECT_SETUP_RUNNING: () => PROJECT_SETUP_RUNNING,
1561
1697
  RELEASE_MINISIGN_PUBLIC_KEY: () => RELEASE_MINISIGN_PUBLIC_KEY,
1562
1698
  RuntimeError: () => RuntimeError,
1563
1699
  RuntimeReader: () => RuntimeReader,
1564
1700
  aclRecords: () => aclRecords,
1565
1701
  auditWindowsPermissions: () => auditWindowsPermissions,
1566
1702
  bindHookContext: () => bindHookContext,
1703
+ clearProjectIdentityCache: () => clearProjectIdentityCache,
1567
1704
  ensureWindowsPrivateDirectorySync: () => ensureWindowsPrivateDirectorySync,
1568
1705
  execute: () => execute,
1569
1706
  findProjectIdentity: () => findProjectIdentity,
@@ -1577,6 +1714,7 @@ __export(hookRuntime_exports, {
1577
1714
  prepareWindowsAclDirectory: () => prepareWindowsAclDirectory,
1578
1715
  projectSetupActions: () => projectSetupActions,
1579
1716
  protectWindowsDirectory: () => protectWindowsDirectory,
1717
+ readHookStdin: () => readHookStdin,
1580
1718
  safePath: () => safePath,
1581
1719
  setupResponse: () => setupResponse,
1582
1720
  validHookSessionId: () => validHookSessionId,
@@ -1588,22 +1726,68 @@ __export(hookRuntime_exports, {
1588
1726
  versionName: () => versionName,
1589
1727
  windowsCurrentAccountSync: () => windowsCurrentAccountSync
1590
1728
  });
1591
- import { stderr } from "node:process";
1729
+ import { stderr, stdin } from "node:process";
1730
+ function clearProjectIdentityCache() {
1731
+ identityCache.clear();
1732
+ }
1592
1733
  async function findProjectIdentity(startCwd, options = {}) {
1593
1734
  if (!startCwd)
1594
1735
  return null;
1595
- const result = await findProjectIdentityDetailed(startCwd, options);
1596
- if (result.kind !== "ok")
1597
- return null;
1598
- return {
1599
- projectId: result.identity.projectId,
1600
- projectName: result.identity.projectName,
1601
- projectRoot: result.root
1602
- };
1736
+ const key = JSON.stringify([
1737
+ startCwd,
1738
+ options.allowNestedInherit ?? null,
1739
+ options.maxDepth ?? null
1740
+ ]);
1741
+ let pending = identityCache.get(key);
1742
+ if (!pending) {
1743
+ pending = findProjectIdentityDetailed(startCwd, options).then((result) => result.kind === "ok" ? {
1744
+ projectId: result.identity.projectId,
1745
+ projectName: result.identity.projectName,
1746
+ projectRoot: result.root
1747
+ } : null);
1748
+ identityCache.set(key, pending);
1749
+ pending.catch(() => identityCache.delete(key));
1750
+ }
1751
+ return pending;
1603
1752
  }
1604
1753
  async function findProjectIdentityDetailed(startCwd, options = {}) {
1605
1754
  return resolveProjectIdentity(startCwd, options);
1606
1755
  }
1756
+ function readHookStdin(options = {}) {
1757
+ const stream = options.stream ?? stdin;
1758
+ const maxBytes = options.maxBytes ?? HOOK_STDIN_MAX_BYTES;
1759
+ return new Promise((resolve4) => {
1760
+ const chunks = [];
1761
+ let bytes = 0;
1762
+ let settled = false;
1763
+ const text = () => Buffer.concat(chunks).toString("utf8").replace(/^\uFEFF/, "");
1764
+ const finish = (value, release) => {
1765
+ if (settled)
1766
+ return;
1767
+ settled = true;
1768
+ clearTimeout(timer);
1769
+ stream.removeListener("data", onData);
1770
+ stream.removeListener("end", onEnd);
1771
+ if (release) {
1772
+ stream.pause();
1773
+ stream.destroy?.();
1774
+ }
1775
+ resolve4(value);
1776
+ };
1777
+ const onData = (chunk) => {
1778
+ const buffer = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
1779
+ bytes += buffer.length;
1780
+ if (bytes > maxBytes)
1781
+ return finish(null, true);
1782
+ chunks.push(buffer);
1783
+ };
1784
+ const onEnd = () => finish(text(), false);
1785
+ const timer = setTimeout(() => finish(text(), true), options.timeoutMs ?? HOOK_STDIN_TIMEOUT_MS);
1786
+ stream.on("data", onData);
1787
+ stream.on("end", onEnd);
1788
+ stream.on("error", () => finish(null, false));
1789
+ });
1790
+ }
1607
1791
  async function parseHookResponse(response) {
1608
1792
  const body = await response.json();
1609
1793
  const result = body;
@@ -1626,7 +1810,7 @@ async function postHookBoundJson(server, path, token, body) {
1626
1810
  return { status: response.status, body: await response.json() };
1627
1811
  }
1628
1812
  async function bindHookContext(input, familyId, hmac, post, options = {}) {
1629
- const { execFile: execFile4 } = await import("node:child_process");
1813
+ const { execFile: execFile3 } = await import("node:child_process");
1630
1814
  const { constants: constants3 } = await import("node:fs");
1631
1815
  const { lstat: lstat5, mkdir: mkdir2, open: open3, realpath: realpath2 } = await import("node:fs/promises");
1632
1816
  const { dirname: dirname5 } = await import("node:path");
@@ -1641,7 +1825,7 @@ async function bindHookContext(input, familyId, hmac, post, options = {}) {
1641
1825
  if (process.env[key2] !== void 0)
1642
1826
  gitEnv[key2] = process.env[key2];
1643
1827
  const git = (args) => new Promise((resolve4) => {
1644
- execFile4("git", args, { cwd: root, env: gitEnv, timeout: 2e3, encoding: "utf8" }, (error, stdout2) => resolve4(error ? [] : stdout2.trim().split(/\r?\n/).filter(Boolean)));
1828
+ execFile3("git", args, { cwd: root, env: gitEnv, timeout: 2e3, encoding: "utf8" }, (error, stdout2) => resolve4(error ? [] : stdout2.trim().split(/\r?\n/).filter(Boolean)));
1645
1829
  });
1646
1830
  const remotes = identity.repository.kind === "git" ? await git(["remote"]) : [];
1647
1831
  const selection = selectRemote2(await Promise.all(remotes.map(async (name) => ({
@@ -1706,15 +1890,18 @@ async function bindHookContext(input, familyId, hmac, post, options = {}) {
1706
1890
  await file.close();
1707
1891
  }
1708
1892
  }
1709
- var mismatchEmitted;
1893
+ var identityCache, HOOK_STDIN_MAX_BYTES, mismatchEmitted;
1710
1894
  var init_hookRuntime = __esm({
1711
1895
  "packages/shared/dist/hookRuntime.js"() {
1712
1896
  "use strict";
1713
1897
  init_runtimeSigners();
1898
+ init_hookTimeouts();
1714
1899
  init_repositoryRoot();
1715
1900
  init_runtimeReader();
1716
1901
  init_runtimeSigners();
1717
1902
  init_projectSetupHandoff();
1903
+ identityCache = /* @__PURE__ */ new Map();
1904
+ HOOK_STDIN_MAX_BYTES = 1048576;
1718
1905
  mismatchEmitted = false;
1719
1906
  }
1720
1907
  });
@@ -1722,13 +1909,17 @@ var init_hookRuntime = __esm({
1722
1909
  // packages/cli/src/runtime/signers.ts
1723
1910
  init_hookRuntime();
1724
1911
  export {
1912
+ HOOK_STDIN_MAX_BYTES,
1913
+ PROJECT_ENSURE_TIMEOUT_MS,
1725
1914
  PROJECT_SETUP_MANUAL,
1915
+ PROJECT_SETUP_RUNNING,
1726
1916
  RELEASE_MINISIGN_PUBLIC_KEY,
1727
1917
  RuntimeError,
1728
1918
  RuntimeReader,
1729
1919
  aclRecords,
1730
1920
  auditWindowsPermissions,
1731
1921
  bindHookContext,
1922
+ clearProjectIdentityCache,
1732
1923
  ensureWindowsPrivateDirectorySync,
1733
1924
  execute,
1734
1925
  findProjectIdentity,
@@ -1742,6 +1933,7 @@ export {
1742
1933
  prepareWindowsAclDirectory,
1743
1934
  projectSetupActions,
1744
1935
  protectWindowsDirectory,
1936
+ readHookStdin,
1745
1937
  safePath,
1746
1938
  setupResponse,
1747
1939
  validHookSessionId,
@@ -405,6 +405,13 @@ var init_runtimeSigners = __esm({
405
405
  }
406
406
  });
407
407
 
408
+ // packages/shared/dist/hookTimeouts.js
409
+ var init_hookTimeouts = __esm({
410
+ "packages/shared/dist/hookTimeouts.js"() {
411
+ "use strict";
412
+ }
413
+ });
414
+
408
415
  // packages/shared/dist/projectIdentityFile.js
409
416
  var init_projectIdentityFile = __esm({
410
417
  "packages/shared/dist/projectIdentityFile.js"() {
@@ -783,11 +790,37 @@ var init_runtimeReader = __esm({
783
790
  });
784
791
 
785
792
  // packages/shared/dist/projectSetupHandoff.js
793
+ var PROJECT_ENSURE_TIMEOUT_MS, SUPERVISOR, RUN_STALE_MS;
786
794
  var init_projectSetupHandoff = __esm({
787
795
  "packages/shared/dist/projectSetupHandoff.js"() {
788
796
  "use strict";
789
797
  init_runtimeSigners();
798
+ init_hookTimeouts();
790
799
  init_runtimeReader();
800
+ PROJECT_ENSURE_TIMEOUT_MS = 3e4;
801
+ SUPERVISOR = `
802
+ const { execFile } = require('node:child_process');
803
+ const { writeFileSync, renameSync } = require('node:fs');
804
+ const [out, bin, ...args] = process.argv.slice(1);
805
+ let input = '';
806
+ process.stdin.setEncoding('utf8');
807
+ process.stdin.on('data', (chunk) => (input += chunk));
808
+ process.stdin.on('end', () => {
809
+ const child = execFile(
810
+ process.execPath,
811
+ [bin, ...args],
812
+ { shell: false, timeout: ${PROJECT_ENSURE_TIMEOUT_MS}, killSignal: 'SIGKILL', maxBuffer: 64 * 1024, env: process.env },
813
+ (error, stdout) => {
814
+ const result = { code: error ? (typeof error.code === 'number' ? error.code : null) : 0, killed: !!(error && error.killed), stdout: String(stdout) };
815
+ writeFileSync(out + '.tmp', JSON.stringify(result), { mode: 0o600 });
816
+ renameSync(out + '.tmp', out);
817
+ }
818
+ );
819
+ child.stdin.on('error', () => {});
820
+ child.stdin.end(input);
821
+ });
822
+ `;
823
+ RUN_STALE_MS = PROJECT_ENSURE_TIMEOUT_MS + 1e4;
791
824
  }
792
825
  });
793
826
 
@@ -796,6 +829,7 @@ var init_hookRuntime = __esm({
796
829
  "packages/shared/dist/hookRuntime.js"() {
797
830
  "use strict";
798
831
  init_runtimeSigners();
832
+ init_hookTimeouts();
799
833
  init_repositoryRoot();
800
834
  init_runtimeReader();
801
835
  init_runtimeSigners();