snipara-companion 3.6.21 → 3.6.22

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/dist/index.js CHANGED
@@ -405,9 +405,9 @@ function warnIfCompanionUpdateAvailable(currentVersion) {
405
405
 
406
406
  // src/commands/init.ts
407
407
  var readline = __toESM(require("readline"));
408
- var fs10 = __toESM(require("fs"));
409
- var path10 = __toESM(require("path"));
410
- var import_node_crypto = require("crypto");
408
+ var fs11 = __toESM(require("fs"));
409
+ var path11 = __toESM(require("path"));
410
+ var import_node_crypto2 = require("crypto");
411
411
 
412
412
  // src/config/store.ts
413
413
  var fs2 = __toESM(require("fs"));
@@ -608,9 +608,9 @@ function getConfigPath(options = {}) {
608
608
  }
609
609
 
610
610
  // src/api/client.ts
611
- var fs4 = __toESM(require("fs"));
611
+ var fs5 = __toESM(require("fs"));
612
612
  var os3 = __toESM(require("os"));
613
- var path4 = __toESM(require("path"));
613
+ var path5 = __toESM(require("path"));
614
614
 
615
615
  // src/project/resolver.ts
616
616
  var fs3 = __toESM(require("fs"));
@@ -690,6 +690,70 @@ function readGitRemote(cwd) {
690
690
  return `${match[1]}/${match[2]}`;
691
691
  }
692
692
 
693
+ // src/session/checkpoint.ts
694
+ var fs4 = __toESM(require("fs"));
695
+ var path4 = __toESM(require("path"));
696
+ var import_node_crypto = require("crypto");
697
+ function checkpointText(value, limit = 12e3) {
698
+ return value.replace(
699
+ /-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/g,
700
+ "[REDACTED PRIVATE KEY]"
701
+ ).replace(/\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, "Bearer [REDACTED]").replace(/\b(?:sk|snp|rlm)[_-][A-Za-z0-9_-]{16,}\b/g, "[REDACTED KEY]").replace(
702
+ /\b([\w-]*(?:api[_-]?key|token|password|passwd|secret)[\w-]*)\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,
703
+ "$1=[REDACTED]"
704
+ ).trim().slice(0, limit);
705
+ }
706
+ function normalizeSessionCheckpoint(input) {
707
+ if (!/^[A-Za-z0-9_.:-]{1,200}$/.test(input.sessionId)) {
708
+ throw new Error(
709
+ "Session id must contain 1-200 letters, digits, dots, colons, underscores or hyphens"
710
+ );
711
+ }
712
+ return {
713
+ sessionId: input.sessionId,
714
+ summary: checkpointText(input.summary ?? ""),
715
+ files: [
716
+ ...new Set((input.files ?? []).map((file) => checkpointText(file, 500)).filter(Boolean))
717
+ ].sort().slice(0, 100)
718
+ };
719
+ }
720
+ function sessionCloseoutPath(cwd, projectId, checkpoint) {
721
+ const digest = (0, import_node_crypto.createHash)("sha256").update(JSON.stringify({ projectId, checkpoint })).digest("hex");
722
+ return path4.join(cwd, ".snipara", "companion", "session-closeouts", `${digest}.json`);
723
+ }
724
+ function lockSessionCloseout(file) {
725
+ const lockPath = `${file}.lock`;
726
+ if (fs4.existsSync(lockPath)) {
727
+ const owner = Number(fs4.readFileSync(lockPath, "utf8"));
728
+ if (Number.isSafeInteger(owner) && owner > 0) {
729
+ try {
730
+ process.kill(owner, 0);
731
+ } catch (error) {
732
+ if (error instanceof Error && "code" in error && error.code === "ESRCH") {
733
+ fs4.unlinkSync(lockPath);
734
+ }
735
+ }
736
+ }
737
+ }
738
+ const lock = fs4.openSync(lockPath, "wx", 384);
739
+ fs4.writeSync(lock, String(process.pid));
740
+ return lock;
741
+ }
742
+ function readSessionCloseout(file) {
743
+ if (!fs4.existsSync(file)) return void 0;
744
+ const value = JSON.parse(fs4.readFileSync(file, "utf8"));
745
+ if (value.version !== "snipara.session_closeout.v1" || typeof value.workspace !== "string" || typeof value.projectId !== "string" || typeof value.checkpoint?.sessionId !== "string" || typeof value.checkpoint.summary !== "string" || !Array.isArray(value.checkpoint.files) || !value.checkpoint.files.every((file2) => typeof file2 === "string") || value.status === "saved" && (typeof value.entryId !== "string" || !value.entryId.trim()) || !["pending", "saved", "skipped", "error"].includes(value.status)) {
746
+ throw new Error("Invalid session closeout receipt");
747
+ }
748
+ return value;
749
+ }
750
+ function writeSessionCloseout(file, value) {
751
+ fs4.mkdirSync(path4.dirname(file), { recursive: true, mode: 448 });
752
+ const temporary = `${file}.${(0, import_node_crypto.randomUUID)()}.tmp`;
753
+ fs4.writeFileSync(temporary, JSON.stringify(value, null, 2) + "\n", { mode: 384 });
754
+ fs4.renameSync(temporary, file);
755
+ }
756
+
693
757
  // src/api/client.ts
694
758
  var CORRELATED_RETRIEVAL_TOOL_NAMES = /* @__PURE__ */ new Set([
695
759
  "snipara_context_query",
@@ -708,15 +772,15 @@ function withCompanionRetrievalClient(toolName, args) {
708
772
  };
709
773
  }
710
774
  function getSniparaTokenStorePath() {
711
- return path4.join(os3.homedir(), ".snipara", "tokens.json");
775
+ return path5.join(os3.homedir(), ".snipara", "tokens.json");
712
776
  }
713
777
  function loadProjectApiKeyFromTokenStore(projectIdentifier, currentApiKey) {
714
778
  const tokensPath = getSniparaTokenStorePath();
715
- if (!fs4.existsSync(tokensPath)) {
779
+ if (!fs5.existsSync(tokensPath)) {
716
780
  return null;
717
781
  }
718
782
  try {
719
- const raw = fs4.readFileSync(tokensPath, "utf8");
783
+ const raw = fs5.readFileSync(tokensPath, "utf8");
720
784
  const parsed = JSON.parse(raw);
721
785
  const direct = parsed[projectIdentifier];
722
786
  if (direct?.api_key && direct.api_key !== currentApiKey) {
@@ -1100,13 +1164,41 @@ var RLMClient = class {
1100
1164
  };
1101
1165
  }
1102
1166
  /**
1103
- * Persist session context using snipara_remember
1167
+ * Persist an explicit bounded checkpoint to the hosted journal. An event
1168
+ * acknowledgement is not a persistence receipt.
1104
1169
  */
1105
- async persistSession() {
1170
+ async persistSession(input = {}) {
1171
+ const checkpoint = normalizeSessionCheckpoint({
1172
+ ...input,
1173
+ sessionId: input.sessionId ?? this.config.sessionId ?? "unknown"
1174
+ });
1175
+ if (!checkpoint.summary && checkpoint.files.length === 0) {
1176
+ return {
1177
+ success: false,
1178
+ status: "skipped",
1179
+ session_id: checkpoint.sessionId,
1180
+ files_tracked: 0
1181
+ };
1182
+ }
1183
+ const receipt = await this.journalAppend(
1184
+ [
1185
+ "Checkpoint: session-end",
1186
+ `Session: ${checkpoint.sessionId}`,
1187
+ checkpoint.summary ? `Summary: ${checkpoint.summary}` : "Summary: Session file checkpoint",
1188
+ checkpoint.files.length ? `Files: ${checkpoint.files.join(", ")}` : ""
1189
+ ].filter(Boolean).join("\n"),
1190
+ ["companion", "checkpoint", "session-end"]
1191
+ );
1192
+ if (receipt.success === false || typeof receipt.entry_id !== "string" || !receipt.entry_id.trim()) {
1193
+ throw new Error("Hosted journal did not confirm a persisted entry");
1194
+ }
1106
1195
  return {
1107
1196
  success: true,
1108
- session_id: this.config.sessionId || "unknown",
1109
- files_tracked: 0
1197
+ status: "saved",
1198
+ session_id: checkpoint.sessionId,
1199
+ files_tracked: checkpoint.files.length,
1200
+ entry_id: receipt.entry_id,
1201
+ date: receipt.date
1110
1202
  };
1111
1203
  }
1112
1204
  /**
@@ -1748,9 +1840,9 @@ var RLMClient = class {
1748
1840
  ...maxTokens ? { max_tokens: maxTokens } : {}
1749
1841
  });
1750
1842
  }
1751
- async uploadDocument(path44, content, options = {}) {
1843
+ async uploadDocument(path46, content, options = {}) {
1752
1844
  return this.mcpCall("snipara_upload_document", {
1753
- path: path44,
1845
+ path: path46,
1754
1846
  content,
1755
1847
  ...options.kind ? { kind: options.kind } : {},
1756
1848
  ...options.format ? { format: options.format } : {},
@@ -1877,9 +1969,9 @@ var RLMClient = class {
1877
1969
  ...maxTokens ? { max_tokens: maxTokens } : {}
1878
1970
  });
1879
1971
  }
1880
- async loadDocument(path44) {
1972
+ async loadDocument(path46) {
1881
1973
  return this.mcpCall("snipara_load_document", {
1882
- path: path44
1974
+ path: path46
1883
1975
  });
1884
1976
  }
1885
1977
  async getSessionMemories(maxCriticalTokens, maxDailyTokens, includeYesterday) {
@@ -1945,8 +2037,8 @@ function createClient(timeout, options = {}) {
1945
2037
 
1946
2038
  // src/commands/automations.ts
1947
2039
  var crypto = __toESM(require("crypto"));
1948
- var fs5 = __toESM(require("fs"));
1949
- var path5 = __toESM(require("path"));
2040
+ var fs6 = __toESM(require("fs"));
2041
+ var path6 = __toESM(require("path"));
1950
2042
  var AUTOMATION_MANIFEST_RELATIVE_PATH = ".snipara/automations/manifest.json";
1951
2043
  var MANIFEST_VERSION = 1;
1952
2044
  var SUPPORTED_CLIENTS = /* @__PURE__ */ new Set([
@@ -2061,20 +2153,20 @@ function canInstallNativeHookBundle(client) {
2061
2153
  return NATIVE_HOOK_CAPABLE_CLIENTS.has(client);
2062
2154
  }
2063
2155
  function normalizeProjectDir(dir) {
2064
- return path5.resolve(dir || process.cwd());
2156
+ return path6.resolve(dir || process.cwd());
2065
2157
  }
2066
2158
  function normalizeRelativePath(filePath) {
2067
- const normalized = path5.posix.normalize(filePath.replace(/\\/g, "/"));
2068
- if (normalized === "." || normalized.startsWith("../") || normalized.includes("/../") || path5.isAbsolute(filePath)) {
2159
+ const normalized = path6.posix.normalize(filePath.replace(/\\/g, "/"));
2160
+ if (normalized === "." || normalized.startsWith("../") || normalized.includes("/../") || path6.isAbsolute(filePath)) {
2069
2161
  throw new Error(`Unsafe automation file path: ${filePath}`);
2070
2162
  }
2071
2163
  return normalized;
2072
2164
  }
2073
2165
  function resolveTargetPath(projectDir, filePath) {
2074
2166
  const normalized = normalizeRelativePath(filePath);
2075
- const target = path5.resolve(projectDir, normalized);
2076
- const root = path5.resolve(projectDir);
2077
- if (target !== root && !target.startsWith(`${root}${path5.sep}`)) {
2167
+ const target = path6.resolve(projectDir, normalized);
2168
+ const root = path6.resolve(projectDir);
2169
+ if (target !== root && !target.startsWith(`${root}${path6.sep}`)) {
2078
2170
  throw new Error(`Automation file escapes project directory: ${filePath}`);
2079
2171
  }
2080
2172
  return target;
@@ -2234,21 +2326,21 @@ function prepareBundleForLocalInstall(client, bundle) {
2234
2326
  };
2235
2327
  }
2236
2328
  function readFileIfExists(filePath) {
2237
- if (!fs5.existsSync(filePath)) {
2329
+ if (!fs6.existsSync(filePath)) {
2238
2330
  return null;
2239
2331
  }
2240
- return fs5.readFileSync(filePath, "utf8");
2332
+ return fs6.readFileSync(filePath, "utf8");
2241
2333
  }
2242
2334
  function getAutomationManifestPath(projectDir = process.cwd()) {
2243
- return path5.join(normalizeProjectDir(projectDir), AUTOMATION_MANIFEST_RELATIVE_PATH);
2335
+ return path6.join(normalizeProjectDir(projectDir), AUTOMATION_MANIFEST_RELATIVE_PATH);
2244
2336
  }
2245
2337
  function loadAutomationManifest(projectDir = process.cwd()) {
2246
2338
  const manifestPath2 = getAutomationManifestPath(projectDir);
2247
- if (!fs5.existsSync(manifestPath2)) {
2339
+ if (!fs6.existsSync(manifestPath2)) {
2248
2340
  return null;
2249
2341
  }
2250
2342
  try {
2251
- const parsed = JSON.parse(fs5.readFileSync(manifestPath2, "utf8"));
2343
+ const parsed = JSON.parse(fs6.readFileSync(manifestPath2, "utf8"));
2252
2344
  if (!Array.isArray(parsed.files)) {
2253
2345
  return null;
2254
2346
  }
@@ -2259,8 +2351,8 @@ function loadAutomationManifest(projectDir = process.cwd()) {
2259
2351
  }
2260
2352
  function writeAutomationManifest(projectDir, manifest) {
2261
2353
  const manifestPath2 = getAutomationManifestPath(projectDir);
2262
- fs5.mkdirSync(path5.dirname(manifestPath2), { recursive: true });
2263
- fs5.writeFileSync(manifestPath2, `${JSON.stringify(manifest, null, 2)}
2354
+ fs6.mkdirSync(path6.dirname(manifestPath2), { recursive: true });
2355
+ fs6.writeFileSync(manifestPath2, `${JSON.stringify(manifest, null, 2)}
2264
2356
  `, "utf8");
2265
2357
  }
2266
2358
  function findManifestFile(manifest, filePath) {
@@ -2373,10 +2465,10 @@ function manifestFromBundle(args) {
2373
2465
  function writeBundleFile(projectDir, file, content = file.content) {
2374
2466
  const relativePath2 = normalizeRelativePath(file.path);
2375
2467
  const targetPath = resolveTargetPath(projectDir, relativePath2);
2376
- fs5.mkdirSync(path5.dirname(targetPath), { recursive: true });
2377
- fs5.writeFileSync(targetPath, content, "utf8");
2468
+ fs6.mkdirSync(path6.dirname(targetPath), { recursive: true });
2469
+ fs6.writeFileSync(targetPath, content, "utf8");
2378
2470
  if (shouldMakeExecutable(relativePath2)) {
2379
- fs5.chmodSync(targetPath, 493);
2471
+ fs6.chmodSync(targetPath, 493);
2380
2472
  }
2381
2473
  }
2382
2474
  async function fetchAutomationBundle(args) {
@@ -2578,13 +2670,13 @@ var import_typescript = __toESM(require("typescript"));
2578
2670
 
2579
2671
  // src/commands/context-pack.ts
2580
2672
  var crypto2 = __toESM(require("crypto"));
2581
- var fs6 = __toESM(require("fs"));
2582
- var path6 = __toESM(require("path"));
2673
+ var fs7 = __toESM(require("fs"));
2674
+ var path7 = __toESM(require("path"));
2583
2675
  var DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
2584
- var BASE_RELATIVE_PATH = path6.join(".snipara", "context-pack");
2585
- var BLOBS_RELATIVE_PATH = path6.join(BASE_RELATIVE_PATH, "blobs");
2586
- var MANIFESTS_RELATIVE_PATH = path6.join(BASE_RELATIVE_PATH, "items");
2587
- var LATEST_RELATIVE_PATH = path6.join(BASE_RELATIVE_PATH, "latest.json");
2676
+ var BASE_RELATIVE_PATH = path7.join(".snipara", "context-pack");
2677
+ var BLOBS_RELATIVE_PATH = path7.join(BASE_RELATIVE_PATH, "blobs");
2678
+ var MANIFESTS_RELATIVE_PATH = path7.join(BASE_RELATIVE_PATH, "items");
2679
+ var LATEST_RELATIVE_PATH = path7.join(BASE_RELATIVE_PATH, "latest.json");
2588
2680
  var STORAGE_GITIGNORE_CONTENT = "*\n!.gitignore\n";
2589
2681
  var SECRET_REDACTION_PATTERNS = [
2590
2682
  [
@@ -2600,14 +2692,14 @@ var SECRET_REDACTION_PATTERNS = [
2600
2692
  ]
2601
2693
  ];
2602
2694
  function resolveRepoRoot(cwd) {
2603
- return findWorkspaceRoot(path6.resolve(cwd), true) ?? path6.resolve(cwd);
2695
+ return findWorkspaceRoot(path7.resolve(cwd), true) ?? path7.resolve(cwd);
2604
2696
  }
2605
2697
  function normalizeRelativePath2(value) {
2606
- return value.split(path6.sep).join("/");
2698
+ return value.split(path7.sep).join("/");
2607
2699
  }
2608
2700
  function toRepoRelative(repoRoot, absolutePath) {
2609
- const relative15 = path6.relative(repoRoot, absolutePath);
2610
- return normalizeRelativePath2(relative15 || path6.basename(absolutePath));
2701
+ const relative15 = path7.relative(repoRoot, absolutePath);
2702
+ return normalizeRelativePath2(relative15 || path7.basename(absolutePath));
2611
2703
  }
2612
2704
  function sha2562(content) {
2613
2705
  return crypto2.createHash("sha256").update(content, "utf8").digest("hex");
@@ -2641,18 +2733,18 @@ function optionalPositiveInteger(value) {
2641
2733
  return Number.isFinite(value) && value !== void 0 && value > 0 ? Math.floor(value) : void 0;
2642
2734
  }
2643
2735
  function ensureDir(dir, mode = 448) {
2644
- fs6.mkdirSync(dir, { recursive: true, mode });
2736
+ fs7.mkdirSync(dir, { recursive: true, mode });
2645
2737
  }
2646
2738
  function maybeReadJsonFile(filePath) {
2647
2739
  try {
2648
- return JSON.parse(fs6.readFileSync(filePath, "utf8"));
2740
+ return JSON.parse(fs7.readFileSync(filePath, "utf8"));
2649
2741
  } catch {
2650
2742
  return null;
2651
2743
  }
2652
2744
  }
2653
2745
  function writeJsonFile(filePath, value) {
2654
- ensureDir(path6.dirname(filePath));
2655
- fs6.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
2746
+ ensureDir(path7.dirname(filePath));
2747
+ fs7.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
2656
2748
  `, {
2657
2749
  encoding: "utf8",
2658
2750
  mode: 384
@@ -2660,9 +2752,9 @@ function writeJsonFile(filePath, value) {
2660
2752
  }
2661
2753
  function ensureStorageGitignore(paths) {
2662
2754
  ensureDir(paths.baseDir);
2663
- const gitignorePath = path6.join(paths.baseDir, ".gitignore");
2664
- if (!fs6.existsSync(gitignorePath)) {
2665
- fs6.writeFileSync(gitignorePath, STORAGE_GITIGNORE_CONTENT, {
2755
+ const gitignorePath = path7.join(paths.baseDir, ".gitignore");
2756
+ if (!fs7.existsSync(gitignorePath)) {
2757
+ fs7.writeFileSync(gitignorePath, STORAGE_GITIGNORE_CONTENT, {
2666
2758
  encoding: "utf8",
2667
2759
  mode: 384
2668
2760
  });
@@ -2725,19 +2817,19 @@ function readManifest(paths, manifestPath2) {
2725
2817
  };
2726
2818
  }
2727
2819
  function listManifestPaths(paths) {
2728
- if (!fs6.existsSync(paths.manifestsDir)) {
2820
+ if (!fs7.existsSync(paths.manifestsDir)) {
2729
2821
  return [];
2730
2822
  }
2731
- return fs6.readdirSync(paths.manifestsDir).filter((name) => name.endsWith(".json")).sort().map((name) => path6.join(paths.manifestsDir, name));
2823
+ return fs7.readdirSync(paths.manifestsDir).filter((name) => name.endsWith(".json")).sort().map((name) => path7.join(paths.manifestsDir, name));
2732
2824
  }
2733
2825
  function loadRecords(paths) {
2734
2826
  return listManifestPaths(paths).map((manifestPath2) => readManifest(paths, manifestPath2)).filter((record2) => record2 !== null);
2735
2827
  }
2736
2828
  function recordManifestPath(paths, id) {
2737
- return path6.join(paths.manifestsDir, `${id}.json`);
2829
+ return path7.join(paths.manifestsDir, `${id}.json`);
2738
2830
  }
2739
2831
  function recordBlobPath(paths, sha) {
2740
- return path6.join(paths.blobsDir, `${sha}.txt`);
2832
+ return path7.join(paths.blobsDir, `${sha}.txt`);
2741
2833
  }
2742
2834
  function writeLatestPointer(paths, record2) {
2743
2835
  writeJsonFile(paths.latestPath, {
@@ -2750,8 +2842,8 @@ function writeLatestPointer(paths, record2) {
2750
2842
  function refreshLatestPointer(paths) {
2751
2843
  const records = loadRecords(paths).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
2752
2844
  if (records.length === 0) {
2753
- if (fs6.existsSync(paths.latestPath)) {
2754
- fs6.rmSync(paths.latestPath);
2845
+ if (fs7.existsSync(paths.latestPath)) {
2846
+ fs7.rmSync(paths.latestPath);
2755
2847
  }
2756
2848
  return;
2757
2849
  }
@@ -2759,13 +2851,13 @@ function refreshLatestPointer(paths) {
2759
2851
  }
2760
2852
  function getContextPackStoragePaths(cwd = process.cwd()) {
2761
2853
  const repoRoot = resolveRepoRoot(cwd);
2762
- const baseDir = path6.join(repoRoot, BASE_RELATIVE_PATH);
2854
+ const baseDir = path7.join(repoRoot, BASE_RELATIVE_PATH);
2763
2855
  return {
2764
2856
  repoRoot,
2765
2857
  baseDir,
2766
- blobsDir: path6.join(repoRoot, BLOBS_RELATIVE_PATH),
2767
- manifestsDir: path6.join(repoRoot, MANIFESTS_RELATIVE_PATH),
2768
- latestPath: path6.join(repoRoot, LATEST_RELATIVE_PATH)
2858
+ blobsDir: path7.join(repoRoot, BLOBS_RELATIVE_PATH),
2859
+ manifestsDir: path7.join(repoRoot, MANIFESTS_RELATIVE_PATH),
2860
+ latestPath: path7.join(repoRoot, LATEST_RELATIVE_PATH)
2769
2861
  };
2770
2862
  }
2771
2863
  function packContext(options) {
@@ -2823,15 +2915,15 @@ function packContext(options) {
2823
2915
  warnings,
2824
2916
  storage: {
2825
2917
  baseRelativePath: normalizeRelativePath2(BASE_RELATIVE_PATH),
2826
- manifestRelativePath: normalizeRelativePath2(path6.relative(paths.repoRoot, manifestPath2)),
2827
- blobRelativePath: normalizeRelativePath2(path6.relative(paths.repoRoot, blobPath))
2918
+ manifestRelativePath: normalizeRelativePath2(path7.relative(paths.repoRoot, manifestPath2)),
2919
+ blobRelativePath: normalizeRelativePath2(path7.relative(paths.repoRoot, blobPath))
2828
2920
  }
2829
2921
  };
2830
2922
  ensureStorageGitignore(paths);
2831
2923
  ensureDir(paths.blobsDir);
2832
2924
  ensureDir(paths.manifestsDir);
2833
- if (!fs6.existsSync(blobPath)) {
2834
- fs6.writeFileSync(blobPath, content, { encoding: "utf8", mode: 384 });
2925
+ if (!fs7.existsSync(blobPath)) {
2926
+ fs7.writeFileSync(blobPath, content, { encoding: "utf8", mode: 384 });
2835
2927
  }
2836
2928
  writeJsonFile(manifestPath2, record2);
2837
2929
  writeLatestPointer(paths, record2);
@@ -2854,7 +2946,7 @@ function resolveContextPackRecord(idOrRef, cwd = process.cwd()) {
2854
2946
  if (!pointer) {
2855
2947
  throw new Error("No latest context pack is available.");
2856
2948
  }
2857
- const manifestPath2 = path6.join(paths.repoRoot, pointer.manifestRelativePath);
2949
+ const manifestPath2 = path7.join(paths.repoRoot, pointer.manifestRelativePath);
2858
2950
  const record3 = readManifest(paths, manifestPath2);
2859
2951
  if (!record3) {
2860
2952
  throw new Error(`Latest context pack manifest is missing or invalid: ${pointer.id}`);
@@ -2881,13 +2973,13 @@ function resolveContextPackRecord(idOrRef, cwd = process.cwd()) {
2881
2973
  }
2882
2974
  function retrieveContextPack(idOrRef, cwd = process.cwd()) {
2883
2975
  const { paths, record: record2, manifestPath: manifestPath2 } = resolveContextPackRecord(idOrRef, cwd);
2884
- const blobPath = path6.join(paths.repoRoot, record2.storage.blobRelativePath);
2885
- if (!fs6.existsSync(blobPath)) {
2976
+ const blobPath = path7.join(paths.repoRoot, record2.storage.blobRelativePath);
2977
+ if (!fs7.existsSync(blobPath)) {
2886
2978
  throw new Error(`Context pack blob is missing for ${record2.id}`);
2887
2979
  }
2888
2980
  return {
2889
2981
  record: record2,
2890
- content: fs6.readFileSync(blobPath, "utf8"),
2982
+ content: fs7.readFileSync(blobPath, "utf8"),
2891
2983
  baseDir: paths.baseDir,
2892
2984
  manifestPath: manifestPath2,
2893
2985
  blobPath
@@ -2935,8 +3027,8 @@ function cleanContextPacks(options = {}) {
2935
3027
  });
2936
3028
  if (!options.dryRun) {
2937
3029
  for (const record2 of selected) {
2938
- fs6.rmSync(recordManifestPath(paths, record2.id), { force: true });
2939
- fs6.rmSync(path6.join(paths.repoRoot, record2.storage.blobRelativePath), { force: true });
3030
+ fs7.rmSync(recordManifestPath(paths, record2.id), { force: true });
3031
+ fs7.rmSync(path7.join(paths.repoRoot, record2.storage.blobRelativePath), { force: true });
2940
3032
  }
2941
3033
  refreshLatestPointer(paths);
2942
3034
  }
@@ -2951,8 +3043,8 @@ function cleanContextPacks(options = {}) {
2951
3043
  }
2952
3044
  function readPackContent(options) {
2953
3045
  if (options.file) {
2954
- const filePath = path6.resolve(options.cwd ?? process.cwd(), options.file);
2955
- const content = fs6.readFileSync(filePath, "utf8");
3046
+ const filePath = path7.resolve(options.cwd ?? process.cwd(), options.file);
3047
+ const content = fs7.readFileSync(filePath, "utf8");
2956
3048
  const paths = getContextPackStoragePaths(options.cwd ?? process.cwd());
2957
3049
  return {
2958
3050
  content,
@@ -3016,9 +3108,9 @@ async function contextPackPackCommand(options) {
3016
3108
  async function contextPackRetrieveCommand(idOrRef, options = {}) {
3017
3109
  const result = retrieveContextPack(idOrRef, options.cwd);
3018
3110
  if (options.output) {
3019
- const outputPath = path6.resolve(options.cwd ?? process.cwd(), options.output);
3020
- ensureDir(path6.dirname(outputPath));
3021
- fs6.writeFileSync(outputPath, result.content, { encoding: "utf8", mode: 384 });
3111
+ const outputPath = path7.resolve(options.cwd ?? process.cwd(), options.output);
3112
+ ensureDir(path7.dirname(outputPath));
3113
+ fs7.writeFileSync(outputPath, result.content, { encoding: "utf8", mode: 384 });
3022
3114
  if (options.json) {
3023
3115
  const payload = options.metadataOnly ? {
3024
3116
  record: result.record,
@@ -7252,7 +7344,7 @@ async function startLocalCodeHttpServer(options) {
7252
7344
  const server = import_http.default.createServer((req, res) => {
7253
7345
  void handleLocalCodeHttpRequest(req, res, options);
7254
7346
  });
7255
- await new Promise((resolve25, reject) => {
7347
+ await new Promise((resolve26, reject) => {
7256
7348
  server.once("error", reject);
7257
7349
  server.listen(port, host, () => {
7258
7350
  server.off("error", reject);
@@ -7270,12 +7362,12 @@ async function startLocalCodeHttpServer(options) {
7270
7362
  } else {
7271
7363
  console.log(`Snipara local code overlay HTTP server listening on ${ready.baseUrl}`);
7272
7364
  }
7273
- resolve25();
7365
+ resolve26();
7274
7366
  });
7275
7367
  });
7276
- await new Promise((resolve25) => {
7368
+ await new Promise((resolve26) => {
7277
7369
  const shutdown = () => {
7278
- server.close(() => resolve25());
7370
+ server.close(() => resolve26());
7279
7371
  };
7280
7372
  process.once("SIGINT", shutdown);
7281
7373
  process.once("SIGTERM", shutdown);
@@ -7375,8 +7467,8 @@ async function startLocalCodeMcpStdioServer(options) {
7375
7467
  }
7376
7468
  }
7377
7469
  });
7378
- await new Promise((resolve25) => {
7379
- process.stdin.once("end", resolve25);
7470
+ await new Promise((resolve26) => {
7471
+ process.stdin.once("end", resolve26);
7380
7472
  process.once("SIGINT", () => process.exit(0));
7381
7473
  process.once("SIGTERM", () => process.exit(0));
7382
7474
  });
@@ -7394,8 +7486,8 @@ async function codeMcpCommand(options) {
7394
7486
  }
7395
7487
 
7396
7488
  // src/commands/project-auth.ts
7397
- var fs9 = __toESM(require("fs"));
7398
- var path9 = __toESM(require("path"));
7489
+ var fs10 = __toESM(require("fs"));
7490
+ var path10 = __toESM(require("path"));
7399
7491
  var os4 = __toESM(require("os"));
7400
7492
  var import_child_process3 = require("child_process");
7401
7493
  var PROJECT_DEVICE_CLIENT_ID = "snipara-companion";
@@ -7403,7 +7495,7 @@ var DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
7403
7495
  var DEVICE_POLL_TIMEOUT_MS = 15 * 60 * 1e3;
7404
7496
  var DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;
7405
7497
  function sleep(ms) {
7406
- return new Promise((resolve25) => setTimeout(resolve25, ms));
7498
+ return new Promise((resolve26) => setTimeout(resolve26, ms));
7407
7499
  }
7408
7500
  function openBrowser(url) {
7409
7501
  try {
@@ -7418,14 +7510,14 @@ function openBrowser(url) {
7418
7510
  }
7419
7511
  }
7420
7512
  function getSniparaTokenStorePath2() {
7421
- return path9.join(os4.homedir(), ".snipara", "tokens.json");
7513
+ return path10.join(os4.homedir(), ".snipara", "tokens.json");
7422
7514
  }
7423
7515
  function rememberProjectApiKey(projectId, projectSlug, apiKey) {
7424
7516
  const tokensPath = getSniparaTokenStorePath2();
7425
7517
  let tokens = {};
7426
- if (fs9.existsSync(tokensPath)) {
7518
+ if (fs10.existsSync(tokensPath)) {
7427
7519
  try {
7428
- const parsed = JSON.parse(fs9.readFileSync(tokensPath, "utf8"));
7520
+ const parsed = JSON.parse(fs10.readFileSync(tokensPath, "utf8"));
7429
7521
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
7430
7522
  tokens = parsed;
7431
7523
  }
@@ -7439,15 +7531,15 @@ function rememberProjectApiKey(projectId, projectSlug, apiKey) {
7439
7531
  project_slug: projectSlug,
7440
7532
  api_key: apiKey
7441
7533
  };
7442
- fs9.mkdirSync(path9.dirname(tokensPath), { recursive: true });
7443
- fs9.writeFileSync(tokensPath, `${JSON.stringify(tokens, null, 2)}
7534
+ fs10.mkdirSync(path10.dirname(tokensPath), { recursive: true });
7535
+ fs10.writeFileSync(tokensPath, `${JSON.stringify(tokens, null, 2)}
7444
7536
  `, "utf8");
7445
7537
  }
7446
7538
  function writeProjectBinding(projectDir, projectSlug) {
7447
- const bindingDir = path9.join(projectDir, ".snipara");
7448
- const bindingPath = path9.join(bindingDir, "project");
7449
- fs9.mkdirSync(bindingDir, { recursive: true });
7450
- fs9.writeFileSync(bindingPath, `${projectSlug}
7539
+ const bindingDir = path10.join(projectDir, ".snipara");
7540
+ const bindingPath = path10.join(bindingDir, "project");
7541
+ fs10.mkdirSync(bindingDir, { recursive: true });
7542
+ fs10.writeFileSync(bindingPath, `${projectSlug}
7451
7543
  `, "utf8");
7452
7544
  }
7453
7545
  function normalizeLocalProjectValue(value) {
@@ -7481,23 +7573,23 @@ function addLocalIdentifier(identifiers, seen, source2, value) {
7481
7573
  }
7482
7574
  function readWorkspaceCompanionProject(projectDir) {
7483
7575
  const configPath = getConfigPath({ cwd: projectDir, scope: "workspace" });
7484
- if (!fs9.existsSync(configPath)) {
7576
+ if (!fs10.existsSync(configPath)) {
7485
7577
  return null;
7486
7578
  }
7487
7579
  try {
7488
- const parsed = JSON.parse(fs9.readFileSync(configPath, "utf8"));
7580
+ const parsed = JSON.parse(fs10.readFileSync(configPath, "utf8"));
7489
7581
  return normalizeLocalProjectValue(parsed.projectId ?? parsed.project_id ?? parsed.project);
7490
7582
  } catch {
7491
7583
  return null;
7492
7584
  }
7493
7585
  }
7494
7586
  function readProjectBinding(projectDir) {
7495
- const bindingPath = path9.join(projectDir, ".snipara", "project");
7496
- if (!fs9.existsSync(bindingPath)) {
7587
+ const bindingPath = path10.join(projectDir, ".snipara", "project");
7588
+ if (!fs10.existsSync(bindingPath)) {
7497
7589
  return null;
7498
7590
  }
7499
7591
  try {
7500
- const content = fs9.readFileSync(bindingPath, "utf8").trim();
7592
+ const content = fs10.readFileSync(bindingPath, "utf8").trim();
7501
7593
  if (!content) {
7502
7594
  return null;
7503
7595
  }
@@ -7535,12 +7627,12 @@ function extractProjectSlugFromMcpUrl(value) {
7535
7627
  return match?.[1] ? normalizeLocalProjectValue(decodeURIComponent(match[1])) : null;
7536
7628
  }
7537
7629
  function readProjectFromMcpJson(projectDir) {
7538
- const configPath = path9.join(projectDir, ".mcp.json");
7539
- if (!fs9.existsSync(configPath)) {
7630
+ const configPath = path10.join(projectDir, ".mcp.json");
7631
+ if (!fs10.existsSync(configPath)) {
7540
7632
  return null;
7541
7633
  }
7542
7634
  try {
7543
- const parsed = JSON.parse(fs9.readFileSync(configPath, "utf8"));
7635
+ const parsed = JSON.parse(fs10.readFileSync(configPath, "utf8"));
7544
7636
  for (const [serverName, serverConfig] of Object.entries(parsed.mcpServers ?? {})) {
7545
7637
  const endpointSlug = extractProjectSlugFromMcpUrl(serverConfig?.url);
7546
7638
  if (endpointSlug) {
@@ -7778,15 +7870,15 @@ function getNativeHookBlockReason(client) {
7778
7870
  return reasons[client] ?? "This client is MCP-first; no native hook files are installed.";
7779
7871
  }
7780
7872
  function ensureCompanionConfigIsGitIgnored(projectDir) {
7781
- const gitignorePath = path10.join(projectDir, ".gitignore");
7873
+ const gitignorePath = path11.join(projectDir, ".gitignore");
7782
7874
  const ignoreEntry = "/.snipara/companion/";
7783
- const current = fs10.existsSync(gitignorePath) ? fs10.readFileSync(gitignorePath, "utf8") : "";
7875
+ const current = fs11.existsSync(gitignorePath) ? fs11.readFileSync(gitignorePath, "utf8") : "";
7784
7876
  const entries = current.split(/\r?\n/).map((entry) => entry.trim());
7785
7877
  if (entries.includes(ignoreEntry)) {
7786
7878
  return;
7787
7879
  }
7788
7880
  const separator = current.length === 0 || current.endsWith("\n") ? "" : "\n";
7789
- fs10.writeFileSync(gitignorePath, `${current}${separator}${ignoreEntry}
7881
+ fs11.writeFileSync(gitignorePath, `${current}${separator}${ignoreEntry}
7790
7882
  `, "utf8");
7791
7883
  }
7792
7884
  function formatClientName(client) {
@@ -7945,14 +8037,14 @@ alwaysApply: true
7945
8037
  ${body}`;
7946
8038
  }
7947
8039
  function ensureWorkflowInstructionFile(projectDir, relativePath2, generatedContent) {
7948
- const filePath = path10.join(projectDir, relativePath2);
7949
- const currentContent = fs10.existsSync(filePath) ? fs10.readFileSync(filePath, "utf8") : void 0;
8040
+ const filePath = path11.join(projectDir, relativePath2);
8041
+ const currentContent = fs11.existsSync(filePath) ? fs11.readFileSync(filePath, "utf8") : void 0;
7950
8042
  const nextContent = relativePath2 === ".cursor/rules/snipara.mdc" ? mergeCursorRuleInstructionContent(relativePath2, generatedContent, currentContent) : mergeWorkflowInstructionContent(relativePath2, generatedContent, currentContent);
7951
8043
  if (currentContent === nextContent) {
7952
8044
  return { relativePath: relativePath2, action: "unchanged" };
7953
8045
  }
7954
- fs10.mkdirSync(path10.dirname(filePath), { recursive: true });
7955
- fs10.writeFileSync(filePath, nextContent);
8046
+ fs11.mkdirSync(path11.dirname(filePath), { recursive: true });
8047
+ fs11.writeFileSync(filePath, nextContent);
7956
8048
  return { relativePath: relativePath2, action: currentContent === void 0 ? "created" : "updated" };
7957
8049
  }
7958
8050
  function ensureWorkflowInstructions(projectDir, projectSlug, client) {
@@ -7975,10 +8067,10 @@ function prompt(question) {
7975
8067
  input: process.stdin,
7976
8068
  output: process.stdout
7977
8069
  });
7978
- return new Promise((resolve25) => {
8070
+ return new Promise((resolve26) => {
7979
8071
  rl.question(question, (answer) => {
7980
8072
  rl.close();
7981
- resolve25(answer.trim());
8073
+ resolve26(answer.trim());
7982
8074
  });
7983
8075
  });
7984
8076
  }
@@ -8528,38 +8620,38 @@ fi
8528
8620
  function installHooks(projectDir, projectId, _apiKey, client) {
8529
8621
  try {
8530
8622
  if (client === "cursor") {
8531
- const cursorDir = path10.join(projectDir, ".cursor");
8532
- const hooksDir2 = path10.join(cursorDir, "hooks");
8533
- const hooksPath = path10.join(cursorDir, "hooks.json");
8534
- if (!fs10.existsSync(cursorDir)) {
8535
- fs10.mkdirSync(cursorDir, { recursive: true });
8536
- }
8537
- if (!fs10.existsSync(hooksDir2)) {
8538
- fs10.mkdirSync(hooksDir2, { recursive: true });
8539
- }
8540
- const preCompactPath = path10.join(hooksDir2, "preCompact.sh");
8541
- fs10.writeFileSync(preCompactPath, generateCursorPreCompactScript(projectId));
8542
- fs10.chmodSync(preCompactPath, "755");
8543
- const sessionStartPath = path10.join(hooksDir2, "sessionStart.sh");
8544
- fs10.writeFileSync(sessionStartPath, generateCursorSessionStartScript(projectId));
8545
- fs10.chmodSync(sessionStartPath, "755");
8546
- const beforeReadPath = path10.join(hooksDir2, "beforeReadFile.sh");
8547
- fs10.writeFileSync(beforeReadPath, generateCursorBeforeReadScript());
8548
- fs10.chmodSync(beforeReadPath, "755");
8549
- const afterEditPath = path10.join(hooksDir2, "afterFileEdit.sh");
8550
- fs10.writeFileSync(afterEditPath, generateCursorAfterFileEditScript());
8551
- fs10.chmodSync(afterEditPath, "755");
8552
- fs10.writeFileSync(hooksPath, JSON.stringify(generateCursorHookConfig(), null, 2));
8623
+ const cursorDir = path11.join(projectDir, ".cursor");
8624
+ const hooksDir2 = path11.join(cursorDir, "hooks");
8625
+ const hooksPath = path11.join(cursorDir, "hooks.json");
8626
+ if (!fs11.existsSync(cursorDir)) {
8627
+ fs11.mkdirSync(cursorDir, { recursive: true });
8628
+ }
8629
+ if (!fs11.existsSync(hooksDir2)) {
8630
+ fs11.mkdirSync(hooksDir2, { recursive: true });
8631
+ }
8632
+ const preCompactPath = path11.join(hooksDir2, "preCompact.sh");
8633
+ fs11.writeFileSync(preCompactPath, generateCursorPreCompactScript(projectId));
8634
+ fs11.chmodSync(preCompactPath, "755");
8635
+ const sessionStartPath = path11.join(hooksDir2, "sessionStart.sh");
8636
+ fs11.writeFileSync(sessionStartPath, generateCursorSessionStartScript(projectId));
8637
+ fs11.chmodSync(sessionStartPath, "755");
8638
+ const beforeReadPath = path11.join(hooksDir2, "beforeReadFile.sh");
8639
+ fs11.writeFileSync(beforeReadPath, generateCursorBeforeReadScript());
8640
+ fs11.chmodSync(beforeReadPath, "755");
8641
+ const afterEditPath = path11.join(hooksDir2, "afterFileEdit.sh");
8642
+ fs11.writeFileSync(afterEditPath, generateCursorAfterFileEditScript());
8643
+ fs11.chmodSync(afterEditPath, "755");
8644
+ fs11.writeFileSync(hooksPath, JSON.stringify(generateCursorHookConfig(), null, 2));
8553
8645
  return { success: true };
8554
8646
  }
8555
- const claudeDir = path10.join(projectDir, ".claude");
8556
- const hooksDir = path10.join(claudeDir, "hooks");
8557
- const settingsPath = path10.join(claudeDir, "settings.json");
8558
- if (!fs10.existsSync(claudeDir)) {
8559
- fs10.mkdirSync(claudeDir, { recursive: true });
8647
+ const claudeDir = path11.join(projectDir, ".claude");
8648
+ const hooksDir = path11.join(claudeDir, "hooks");
8649
+ const settingsPath = path11.join(claudeDir, "settings.json");
8650
+ if (!fs11.existsSync(claudeDir)) {
8651
+ fs11.mkdirSync(claudeDir, { recursive: true });
8560
8652
  }
8561
- if (!fs10.existsSync(hooksDir)) {
8562
- fs10.mkdirSync(hooksDir, { recursive: true });
8653
+ if (!fs11.existsSync(hooksDir)) {
8654
+ fs11.mkdirSync(hooksDir, { recursive: true });
8563
8655
  }
8564
8656
  const hookScripts = [
8565
8657
  ["snipara-stuck-guard.sh", generateClaudeStuckGuardScript()],
@@ -8568,14 +8660,14 @@ function installHooks(projectDir, projectId, _apiKey, client) {
8568
8660
  ["snipara-compact.sh", generateClaudeCompactScript()]
8569
8661
  ];
8570
8662
  for (const [fileName, content] of hookScripts) {
8571
- const hookPath = path10.join(hooksDir, fileName);
8572
- fs10.writeFileSync(hookPath, content);
8573
- fs10.chmodSync(hookPath, "755");
8663
+ const hookPath = path11.join(hooksDir, fileName);
8664
+ fs11.writeFileSync(hookPath, content);
8665
+ fs11.chmodSync(hookPath, "755");
8574
8666
  }
8575
8667
  let settings = {};
8576
- if (fs10.existsSync(settingsPath)) {
8668
+ if (fs11.existsSync(settingsPath)) {
8577
8669
  try {
8578
- settings = JSON.parse(fs10.readFileSync(settingsPath, "utf-8"));
8670
+ settings = JSON.parse(fs11.readFileSync(settingsPath, "utf-8"));
8579
8671
  } catch {
8580
8672
  }
8581
8673
  }
@@ -8584,7 +8676,7 @@ function installHooks(projectDir, projectId, _apiKey, client) {
8584
8676
  restoreOnSessionStart: true
8585
8677
  });
8586
8678
  settings = { ...settings, ...hookConfig };
8587
- fs10.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
8679
+ fs11.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
8588
8680
  return { success: true };
8589
8681
  } catch (error) {
8590
8682
  return {
@@ -8720,7 +8812,7 @@ async function initCommand(options) {
8720
8812
  existingProjectId: existingConfig.projectId,
8721
8813
  selectedProject
8722
8814
  });
8723
- const sessionId = `sess_${Date.now()}_${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
8815
+ const sessionId = `sess_${Date.now()}_${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
8724
8816
  saveConfig(
8725
8817
  {
8726
8818
  apiKey,
@@ -8933,7 +9025,7 @@ function showConfig() {
8933
9025
 
8934
9026
  // src/commands/login.ts
8935
9027
  var import_child_process4 = require("child_process");
8936
- var import_node_crypto2 = require("crypto");
9028
+ var import_node_crypto3 = require("crypto");
8937
9029
  var USER_KEY_CLIENT_ID = "snipara-cli";
8938
9030
  var CLIENT_VERSION = "1.1.20";
8939
9031
  var GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
@@ -8994,7 +9086,7 @@ async function pollForToken(apiUrl, deviceCode, intervalSeconds) {
8994
9086
  throw new Error("Login timed out (15 min). Run `snipara-companion login --user-key` again.");
8995
9087
  }
8996
9088
  function createSessionId() {
8997
- return `sess_${Date.now()}_${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
9089
+ return `sess_${Date.now()}_${(0, import_node_crypto3.randomBytes)(6).toString("hex")}`;
8998
9090
  }
8999
9091
  async function loginCommand(options = {}) {
9000
9092
  const projectDir = options.dir || process.cwd();
@@ -9075,9 +9167,9 @@ async function userKeyLoginCommand(apiUrl) {
9075
9167
 
9076
9168
  // src/cache/query-cache.ts
9077
9169
  var crypto5 = __toESM(require("crypto"));
9078
- var fs11 = __toESM(require("fs"));
9170
+ var fs12 = __toESM(require("fs"));
9079
9171
  var os5 = __toESM(require("os"));
9080
- var path11 = __toESM(require("path"));
9172
+ var path12 = __toESM(require("path"));
9081
9173
  var CACHE_VERSION = 2;
9082
9174
  var WARM_SNAPSHOT_VERSION = 1;
9083
9175
  var SEARCH_MODE = "hybrid";
@@ -9169,7 +9261,7 @@ var LocalQueryCache = class {
9169
9261
  }
9170
9262
  const key = buildCacheKey(this.scope.workspaceKey, normalizedQuery, options.maxTokens);
9171
9263
  const fileName = `${key}.json`;
9172
- const filePath = path11.join(getCacheDir(), fileName);
9264
+ const filePath = path12.join(getCacheDir(), fileName);
9173
9265
  const now = Date.now();
9174
9266
  const payload = {
9175
9267
  version: CACHE_VERSION,
@@ -9179,7 +9271,7 @@ var LocalQueryCache = class {
9179
9271
  const content = JSON.stringify(payload);
9180
9272
  ensureCacheDir();
9181
9273
  try {
9182
- fs11.writeFileSync(filePath, content, "utf8");
9274
+ fs12.writeFileSync(filePath, content, "utf8");
9183
9275
  } catch {
9184
9276
  return;
9185
9277
  }
@@ -9209,7 +9301,7 @@ var LocalQueryCache = class {
9209
9301
  const entries = extractWarmSnapshotEntries(result);
9210
9302
  const index = this.loadIndex();
9211
9303
  const fileName = `warm-${this.scope.workspaceKey}.json`;
9212
- const filePath = path11.join(getCacheDir(), fileName);
9304
+ const filePath = path12.join(getCacheDir(), fileName);
9213
9305
  index.warmSnapshots = index.warmSnapshots.filter(
9214
9306
  (snapshot2) => snapshot2.workspaceKey !== this.scope.workspaceKey
9215
9307
  );
@@ -9232,7 +9324,7 @@ var LocalQueryCache = class {
9232
9324
  const content = JSON.stringify(snapshot);
9233
9325
  ensureCacheDir();
9234
9326
  try {
9235
- fs11.writeFileSync(filePath, content, "utf8");
9327
+ fs12.writeFileSync(filePath, content, "utf8");
9236
9328
  } catch {
9237
9329
  return { storedEntries: 0 };
9238
9330
  }
@@ -9252,21 +9344,21 @@ var LocalQueryCache = class {
9252
9344
  }
9253
9345
  clear() {
9254
9346
  const cacheDir = getCacheDir();
9255
- if (!fs11.existsSync(cacheDir)) {
9347
+ if (!fs12.existsSync(cacheDir)) {
9256
9348
  return 0;
9257
9349
  }
9258
- const files = fs11.readdirSync(cacheDir).filter((file) => file.endsWith(".json"));
9259
- fs11.rmSync(cacheDir, { recursive: true, force: true });
9350
+ const files = fs12.readdirSync(cacheDir).filter((file) => file.endsWith(".json"));
9351
+ fs12.rmSync(cacheDir, { recursive: true, force: true });
9260
9352
  return files.length;
9261
9353
  }
9262
9354
  loadIndex() {
9263
9355
  ensureCacheDir();
9264
9356
  const indexFile = getIndexFile();
9265
- if (!fs11.existsSync(indexFile)) {
9357
+ if (!fs12.existsSync(indexFile)) {
9266
9358
  return emptyIndex();
9267
9359
  }
9268
9360
  try {
9269
- const content = fs11.readFileSync(indexFile, "utf8");
9361
+ const content = fs12.readFileSync(indexFile, "utf8");
9270
9362
  const parsed = JSON.parse(content);
9271
9363
  const index = {
9272
9364
  version: parsed.version === CACHE_VERSION ? CACHE_VERSION : CACHE_VERSION,
@@ -9282,7 +9374,7 @@ var LocalQueryCache = class {
9282
9374
  const pruned = this.pruneIndex(index);
9283
9375
  ensureCacheDir();
9284
9376
  try {
9285
- fs11.writeFileSync(getIndexFile(), JSON.stringify(pruned, null, 2), "utf8");
9377
+ fs12.writeFileSync(getIndexFile(), JSON.stringify(pruned, null, 2), "utf8");
9286
9378
  } catch {
9287
9379
  }
9288
9380
  }
@@ -9291,20 +9383,20 @@ var LocalQueryCache = class {
9291
9383
  const cacheDir = getCacheDir();
9292
9384
  index.entries = index.entries.filter((entry) => {
9293
9385
  if (entry.expiresAt <= now) {
9294
- tryDeleteFile(path11.join(cacheDir, entry.fileName));
9386
+ tryDeleteFile(path12.join(cacheDir, entry.fileName));
9295
9387
  return false;
9296
9388
  }
9297
- if (!fs11.existsSync(path11.join(cacheDir, entry.fileName))) {
9389
+ if (!fs12.existsSync(path12.join(cacheDir, entry.fileName))) {
9298
9390
  return false;
9299
9391
  }
9300
9392
  return true;
9301
9393
  });
9302
9394
  index.warmSnapshots = index.warmSnapshots.filter((snapshot) => {
9303
9395
  if (snapshot.expiresAt <= now) {
9304
- tryDeleteFile(path11.join(cacheDir, snapshot.fileName));
9396
+ tryDeleteFile(path12.join(cacheDir, snapshot.fileName));
9305
9397
  return false;
9306
9398
  }
9307
- if (!fs11.existsSync(path11.join(cacheDir, snapshot.fileName))) {
9399
+ if (!fs12.existsSync(path12.join(cacheDir, snapshot.fileName))) {
9308
9400
  return false;
9309
9401
  }
9310
9402
  return true;
@@ -9317,19 +9409,19 @@ var LocalQueryCache = class {
9317
9409
  break;
9318
9410
  }
9319
9411
  totalBytes -= removed.sizeBytes;
9320
- tryDeleteFile(path11.join(cacheDir, removed.fileName));
9412
+ tryDeleteFile(path12.join(cacheDir, removed.fileName));
9321
9413
  }
9322
9414
  return index;
9323
9415
  }
9324
9416
  readEntry(entry, index) {
9325
- const filePath = path11.join(getCacheDir(), entry.fileName);
9326
- if (!fs11.existsSync(filePath)) {
9417
+ const filePath = path12.join(getCacheDir(), entry.fileName);
9418
+ if (!fs12.existsSync(filePath)) {
9327
9419
  index.entries = index.entries.filter((candidate) => candidate.key !== entry.key);
9328
9420
  this.persistIndex(index);
9329
9421
  return null;
9330
9422
  }
9331
9423
  try {
9332
- const content = fs11.readFileSync(filePath, "utf8");
9424
+ const content = fs12.readFileSync(filePath, "utf8");
9333
9425
  const parsed = JSON.parse(content);
9334
9426
  if (parsed.version !== CACHE_VERSION || !isContextQueryResult(parsed.result)) {
9335
9427
  throw new Error("invalid cache payload");
@@ -9373,8 +9465,8 @@ var LocalQueryCache = class {
9373
9465
  if (!snapshotMeta) {
9374
9466
  return null;
9375
9467
  }
9376
- const filePath = path11.join(getCacheDir(), snapshotMeta.fileName);
9377
- if (!fs11.existsSync(filePath)) {
9468
+ const filePath = path12.join(getCacheDir(), snapshotMeta.fileName);
9469
+ if (!fs12.existsSync(filePath)) {
9378
9470
  index.warmSnapshots = index.warmSnapshots.filter(
9379
9471
  (snapshot) => snapshot.workspaceKey !== this.scope.workspaceKey
9380
9472
  );
@@ -9382,7 +9474,7 @@ var LocalQueryCache = class {
9382
9474
  return null;
9383
9475
  }
9384
9476
  try {
9385
- const content = fs11.readFileSync(filePath, "utf8");
9477
+ const content = fs12.readFileSync(filePath, "utf8");
9386
9478
  const snapshot = JSON.parse(content);
9387
9479
  if (snapshot.version !== WARM_SNAPSHOT_VERSION || snapshot.workspaceKey !== this.scope.workspaceKey || !Array.isArray(snapshot.entries)) {
9388
9480
  throw new Error("invalid warm snapshot");
@@ -9431,7 +9523,7 @@ function createLocalQueryCache(scope = {}) {
9431
9523
  return new LocalQueryCache(scope);
9432
9524
  }
9433
9525
  function resolveScope(scope) {
9434
- const cwd = path11.resolve(scope.cwd ?? process.cwd());
9526
+ const cwd = path12.resolve(scope.cwd ?? process.cwd());
9435
9527
  const workspaceRoot2 = normalizeFilePath(findWorkspaceRoot(cwd, true) ?? cwd);
9436
9528
  const workspaceKey = hashString(
9437
9529
  JSON.stringify({ projectId: scope.projectId ?? "", workspaceRoot: workspaceRoot2 })
@@ -9575,13 +9667,13 @@ function emptyIndex() {
9575
9667
  }
9576
9668
  function ensureCacheDir() {
9577
9669
  const cacheDir = getCacheDir();
9578
- if (!fs11.existsSync(cacheDir)) {
9579
- fs11.mkdirSync(cacheDir, { recursive: true });
9670
+ if (!fs12.existsSync(cacheDir)) {
9671
+ fs12.mkdirSync(cacheDir, { recursive: true });
9580
9672
  }
9581
9673
  }
9582
9674
  function tryDeleteFile(filePath) {
9583
9675
  try {
9584
- fs11.unlinkSync(filePath);
9676
+ fs12.unlinkSync(filePath);
9585
9677
  } catch {
9586
9678
  }
9587
9679
  }
@@ -9611,14 +9703,14 @@ function readPositiveFloat(name, fallback) {
9611
9703
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
9612
9704
  }
9613
9705
  function getCacheDir() {
9614
- return path11.join(os5.homedir(), ".snipara", "cache", "context-v2");
9706
+ return path12.join(os5.homedir(), ".snipara", "cache", "context-v2");
9615
9707
  }
9616
9708
  function getIndexFile() {
9617
- return path11.join(getCacheDir(), "index.json");
9709
+ return path12.join(getCacheDir(), "index.json");
9618
9710
  }
9619
9711
 
9620
9712
  // src/commands/stuck-guard.ts
9621
- var fs12 = __toESM(require("fs"));
9713
+ var fs13 = __toESM(require("fs"));
9622
9714
  var SEARCH_TOOL_PATTERN = /\b(read|grep|glob|find|rg|ripgrep|search|ls)\b/i;
9623
9715
  var SECRET_PATTERNS2 = [
9624
9716
  [/\b(Bearer\s+)[A-Za-z0-9._~+/=-]{20,}\b/g, "$1[REDACTED]"],
@@ -9826,7 +9918,7 @@ async function stuckGuardCheckCommand(toolInput, options) {
9826
9918
  }
9827
9919
  async function stuckGuardSimulateCommand(options) {
9828
9920
  ensureConfiguredForCommand();
9829
- const fixture = JSON.parse(fs12.readFileSync(options.fixture, "utf8"));
9921
+ const fixture = JSON.parse(fs13.readFileSync(options.fixture, "utf8"));
9830
9922
  const payload = normalizeFixture(fixture);
9831
9923
  const client = createClient(1e4);
9832
9924
  const result = await client.evaluateStuckGuard(payload);
@@ -10187,8 +10279,8 @@ function clearCache() {
10187
10279
  var import_node_child_process5 = require("child_process");
10188
10280
 
10189
10281
  // src/commands/memory-guard.ts
10190
- var fs13 = __toESM(require("fs"));
10191
- var path12 = __toESM(require("path"));
10282
+ var fs14 = __toESM(require("fs"));
10283
+ var path13 = __toESM(require("path"));
10192
10284
  var import_node_child_process3 = require("child_process");
10193
10285
  var import_chalk2 = __toESM(require("chalk"));
10194
10286
  var MEMORY_GUARD_EXIT_CODES = {
@@ -10305,12 +10397,12 @@ function buildValidationResult(errors) {
10305
10397
  };
10306
10398
  }
10307
10399
  function safeRelative(root, filePath) {
10308
- const absolute = path12.isAbsolute(filePath) ? filePath : path12.join(root, filePath);
10309
- return path12.relative(root, absolute).replaceAll(path12.sep, "/");
10400
+ const absolute = path13.isAbsolute(filePath) ? filePath : path13.join(root, filePath);
10401
+ return path13.relative(root, absolute).replaceAll(path13.sep, "/");
10310
10402
  }
10311
10403
  function readJsonFile(filePath) {
10312
10404
  try {
10313
- const parsed = JSON.parse(fs13.readFileSync(filePath, "utf8"));
10405
+ const parsed = JSON.parse(fs14.readFileSync(filePath, "utf8"));
10314
10406
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null;
10315
10407
  } catch {
10316
10408
  return null;
@@ -10327,17 +10419,17 @@ function parsePyprojectProject(content) {
10327
10419
  return { name, version };
10328
10420
  }
10329
10421
  function findManifestForFile(root, filePath, manifest) {
10330
- let current = path12.dirname(path12.join(root, filePath));
10331
- const resolvedRoot = path12.resolve(root);
10422
+ let current = path13.dirname(path13.join(root, filePath));
10423
+ const resolvedRoot = path13.resolve(root);
10332
10424
  while (current.startsWith(resolvedRoot)) {
10333
- const candidate = path12.join(current, manifest);
10334
- if (fs13.existsSync(candidate)) {
10425
+ const candidate = path13.join(current, manifest);
10426
+ if (fs14.existsSync(candidate)) {
10335
10427
  return candidate;
10336
10428
  }
10337
10429
  if (current === resolvedRoot) {
10338
10430
  break;
10339
10431
  }
10340
- current = path12.dirname(current);
10432
+ current = path13.dirname(current);
10341
10433
  }
10342
10434
  return null;
10343
10435
  }
@@ -10346,7 +10438,7 @@ function detectReleaseSurfacesFromFiles(root, files) {
10346
10438
  const seen = /* @__PURE__ */ new Set();
10347
10439
  for (const rawFile of files) {
10348
10440
  const file = safeRelative(root, rawFile);
10349
- const packageManifest = file.endsWith("package.json") && fs13.existsSync(path12.join(root, file)) ? path12.join(root, file) : findManifestForFile(root, file, "package.json");
10441
+ const packageManifest = file.endsWith("package.json") && fs14.existsSync(path13.join(root, file)) ? path13.join(root, file) : findManifestForFile(root, file, "package.json");
10350
10442
  if (packageManifest && !seen.has(packageManifest)) {
10351
10443
  seen.add(packageManifest);
10352
10444
  const packageJson = readJsonFile(packageManifest);
@@ -10361,10 +10453,10 @@ function detectReleaseSurfacesFromFiles(root, files) {
10361
10453
  });
10362
10454
  }
10363
10455
  }
10364
- const pyprojectManifest = file.endsWith("pyproject.toml") && fs13.existsSync(path12.join(root, file)) ? path12.join(root, file) : findManifestForFile(root, file, "pyproject.toml");
10456
+ const pyprojectManifest = file.endsWith("pyproject.toml") && fs14.existsSync(path13.join(root, file)) ? path13.join(root, file) : findManifestForFile(root, file, "pyproject.toml");
10365
10457
  if (pyprojectManifest && !seen.has(pyprojectManifest)) {
10366
10458
  seen.add(pyprojectManifest);
10367
- const project = parsePyprojectProject(fs13.readFileSync(pyprojectManifest, "utf8"));
10459
+ const project = parsePyprojectProject(fs14.readFileSync(pyprojectManifest, "utf8"));
10368
10460
  if (project.name) {
10369
10461
  surfaces.push({
10370
10462
  ecosystem: "pypi",
@@ -10851,9 +10943,9 @@ async function rememberGuardMemoryCommand(options) {
10851
10943
  }
10852
10944
 
10853
10945
  // src/commands/activity.ts
10854
- var fs14 = __toESM(require("fs"));
10855
- var path13 = __toESM(require("path"));
10856
- var import_node_crypto7 = require("crypto");
10946
+ var fs15 = __toESM(require("fs"));
10947
+ var path14 = __toESM(require("path"));
10948
+ var import_node_crypto8 = require("crypto");
10857
10949
 
10858
10950
  // ../project-intelligence-contracts/src/engineering-lead.ts
10859
10951
  var PROJECT_HEALTH_COCKPIT_STATUSES = ["healthy", "watch", "risk", "unknown"];
@@ -11481,7 +11573,7 @@ function buildProjectIntentLedger(input, changedFilesOverride) {
11481
11573
  }
11482
11574
 
11483
11575
  // ../project-intelligence-contracts/src/worker-profile.ts
11484
- var import_node_crypto3 = require("crypto");
11576
+ var import_node_crypto4 = require("crypto");
11485
11577
  var WORKER_PROFILE_SCHEMA_VERSION = "snipara.worker_profile.v0";
11486
11578
  var WORKER_PROFILE_RISK_CEILINGS = ["low", "medium", "high", "critical"];
11487
11579
  var WORKER_PROFILE_PRIVACY_CLASSES = ["local", "cloud"];
@@ -11575,7 +11667,7 @@ function stableWorkerProfileJsonStringify(value) {
11575
11667
  return JSON.stringify(sortJsonValue(value), null, 2);
11576
11668
  }
11577
11669
  function hashWorkerProfileContent(content) {
11578
- return (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex");
11670
+ return (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex");
11579
11671
  }
11580
11672
  function normalizeWorkerProfileTransport(value) {
11581
11673
  if (!isRecord2(value)) {
@@ -12329,10 +12421,10 @@ function renderProjectRealityCheckMarkdown(result) {
12329
12421
  }
12330
12422
 
12331
12423
  // ../project-intelligence-contracts/src/producer-loop.ts
12332
- var import_node_crypto4 = require("crypto");
12424
+ var import_node_crypto5 = require("crypto");
12333
12425
 
12334
12426
  // ../project-intelligence-contracts/src/decision-request.ts
12335
- var import_node_crypto5 = require("crypto");
12427
+ var import_node_crypto6 = require("crypto");
12336
12428
  var DECISION_REQUEST_VERSION = "snipara.decision_request.v0";
12337
12429
  var DECISION_RESPONSE_VERSION = "snipara.decision_response.v0";
12338
12430
  var DECISION_REQUEST_RELATIVE_DIR = ".snipara/decisions";
@@ -12340,7 +12432,7 @@ function stableDecisionJsonStringify(value) {
12340
12432
  return JSON.stringify(sortJsonValue2(value), null, 2);
12341
12433
  }
12342
12434
  function hashDecisionContent(content) {
12343
- return (0, import_node_crypto5.createHash)("sha256").update(content).digest("hex");
12435
+ return (0, import_node_crypto6.createHash)("sha256").update(content).digest("hex");
12344
12436
  }
12345
12437
  function hashDecisionJsonValue(value) {
12346
12438
  return `sha256:${hashDecisionContent(stableDecisionJsonStringify(value))}`;
@@ -14177,7 +14269,7 @@ var WHY_CAPTURE_CONFIDENCE_VERSION = why_capture_confidence_v1_default.version;
14177
14269
  var WHY_CAPTURE_CONFIDENCE_TEST_VECTORS = why_capture_confidence_v1_default.vectors;
14178
14270
 
14179
14271
  // ../project-intelligence-contracts/src/judgment-integrity.ts
14180
- var import_node_crypto6 = require("crypto");
14272
+ var import_node_crypto7 = require("crypto");
14181
14273
 
14182
14274
  // ../project-intelligence-contracts/src/agent-context.ts
14183
14275
  var AGENT_CONTEXT_MANIFEST_VERSION = "snipara.agent_context_manifest.v0";
@@ -15414,9 +15506,9 @@ function isAgentContextEvidenceReceipt(value) {
15414
15506
  // src/commands/activity.ts
15415
15507
  var ACTIVITY_TIMELINE_VERSION = "snipara.activity_timeline.v0";
15416
15508
  var SESSION_SNAPSHOT_VERSION = "snipara.session_snapshot.v0";
15417
- var ACTIVITY_RELATIVE_DIR = path13.join(".snipara", "activity");
15418
- var ACTIVITY_TIMELINE_RELATIVE_PATH = path13.join(ACTIVITY_RELATIVE_DIR, "timeline.jsonl");
15419
- var SESSION_SNAPSHOT_RELATIVE_PATH = path13.join(ACTIVITY_RELATIVE_DIR, "session.json");
15509
+ var ACTIVITY_RELATIVE_DIR = path14.join(".snipara", "activity");
15510
+ var ACTIVITY_TIMELINE_RELATIVE_PATH = path14.join(ACTIVITY_RELATIVE_DIR, "timeline.jsonl");
15511
+ var SESSION_SNAPSHOT_RELATIVE_PATH = path14.join(ACTIVITY_RELATIVE_DIR, "session.json");
15420
15512
  function uniqueStrings15(values) {
15421
15513
  return Array.from(new Set(values.map((value) => value?.trim()).filter(Boolean)));
15422
15514
  }
@@ -15435,11 +15527,11 @@ function sortJsonValue3(value) {
15435
15527
  return value;
15436
15528
  }
15437
15529
  function hashEvent(input) {
15438
- return (0, import_node_crypto7.createHash)("sha256").update(stableJson(input)).digest("hex").slice(0, 16);
15530
+ return (0, import_node_crypto8.createHash)("sha256").update(stableJson(input)).digest("hex").slice(0, 16);
15439
15531
  }
15440
15532
  function safeReadJson(filePath) {
15441
15533
  try {
15442
- const parsed = JSON.parse(fs14.readFileSync(filePath, "utf8"));
15534
+ const parsed = JSON.parse(fs15.readFileSync(filePath, "utf8"));
15443
15535
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
15444
15536
  } catch {
15445
15537
  return null;
@@ -15447,7 +15539,7 @@ function safeReadJson(filePath) {
15447
15539
  }
15448
15540
  function readJsonDir(dir) {
15449
15541
  try {
15450
- return fs14.readdirSync(dir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => safeReadJson(path13.join(dir, fileName))).filter((record2) => Boolean(record2));
15542
+ return fs15.readdirSync(dir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => safeReadJson(path14.join(dir, fileName))).filter((record2) => Boolean(record2));
15451
15543
  } catch {
15452
15544
  return [];
15453
15545
  }
@@ -15461,10 +15553,10 @@ function countBy(items, key) {
15461
15553
  return counts;
15462
15554
  }
15463
15555
  function getActivityTimelinePath(cwd = process.cwd()) {
15464
- return path13.join(cwd, ACTIVITY_TIMELINE_RELATIVE_PATH);
15556
+ return path14.join(cwd, ACTIVITY_TIMELINE_RELATIVE_PATH);
15465
15557
  }
15466
15558
  function getSessionSnapshotPath(cwd = process.cwd()) {
15467
- return path13.join(cwd, SESSION_SNAPSHOT_RELATIVE_PATH);
15559
+ return path14.join(cwd, SESSION_SNAPSHOT_RELATIVE_PATH);
15468
15560
  }
15469
15561
  function appendActivityEvent(input) {
15470
15562
  const cwd = input.cwd ?? process.cwd();
@@ -15495,8 +15587,8 @@ function appendActivityEvent(input) {
15495
15587
  metadata: input.metadata ?? {}
15496
15588
  };
15497
15589
  const timelinePath = getActivityTimelinePath(cwd);
15498
- fs14.mkdirSync(path13.dirname(timelinePath), { recursive: true });
15499
- fs14.appendFileSync(timelinePath, `${JSON.stringify(event)}
15590
+ fs15.mkdirSync(path14.dirname(timelinePath), { recursive: true });
15591
+ fs15.appendFileSync(timelinePath, `${JSON.stringify(event)}
15500
15592
  `, "utf8");
15501
15593
  return event;
15502
15594
  }
@@ -15505,7 +15597,7 @@ function readActivityTimeline(options = {}) {
15505
15597
  const limit = options.limit && options.limit > 0 ? options.limit : void 0;
15506
15598
  let lines;
15507
15599
  try {
15508
- lines = fs14.readFileSync(timelinePath, "utf8").split(/\r?\n/).filter(Boolean);
15600
+ lines = fs15.readFileSync(timelinePath, "utf8").split(/\r?\n/).filter(Boolean);
15509
15601
  } catch {
15510
15602
  return [];
15511
15603
  }
@@ -15519,7 +15611,7 @@ function readActivityTimeline(options = {}) {
15519
15611
  return limit ? events.slice(0, limit) : events;
15520
15612
  }
15521
15613
  function workflowSnapshot(cwd) {
15522
- const state = safeReadJson(path13.join(cwd, ".snipara", "workflow", "current.json"));
15614
+ const state = safeReadJson(path14.join(cwd, ".snipara", "workflow", "current.json"));
15523
15615
  if (!state) {
15524
15616
  return null;
15525
15617
  }
@@ -15541,7 +15633,7 @@ function countDecisionFingerprintRepeats(records) {
15541
15633
  return Object.values(counts).filter((count2) => count2 > 1).length;
15542
15634
  }
15543
15635
  function producerLoopSummary(cwd) {
15544
- const records = readJsonDir(path13.join(cwd, ".snipara", "producer-loop"));
15636
+ const records = readJsonDir(path14.join(cwd, ".snipara", "producer-loop"));
15545
15637
  let reviewedCount = 0;
15546
15638
  let rejectedCount = 0;
15547
15639
  let unreviewedCount = 0;
@@ -15562,7 +15654,7 @@ function producerLoopSummary(cwd) {
15562
15654
  };
15563
15655
  }
15564
15656
  function teamSyncSnapshot(cwd) {
15565
- const state = safeReadJson(path13.join(cwd, ".snipara", "team-sync", "session.json"));
15657
+ const state = safeReadJson(path14.join(cwd, ".snipara", "team-sync", "session.json"));
15566
15658
  const work = Array.isArray(state?.work) ? state?.work : [];
15567
15659
  const handoffs = Array.isArray(state?.handoffs) ? state?.handoffs : [];
15568
15660
  const latestHandoffAt = handoffs.map((handoff) => typeof handoff.createdAt === "string" ? handoff.createdAt : void 0).filter(Boolean).sort().at(-1);
@@ -15608,8 +15700,8 @@ function buildSessionSnapshot(options = {}) {
15608
15700
  const cwd = options.cwd ?? process.cwd();
15609
15701
  const events = readActivityTimeline({ cwd });
15610
15702
  const latestEvents = events.slice(0, options.limit && options.limit > 0 ? options.limit : 20);
15611
- const pendingDecisions = readJsonDir(path13.join(cwd, ".snipara", "decisions", "pending"));
15612
- const resolvedDecisions = readJsonDir(path13.join(cwd, ".snipara", "decisions", "resolved"));
15703
+ const pendingDecisions = readJsonDir(path14.join(cwd, ".snipara", "decisions", "pending"));
15704
+ const resolvedDecisions = readJsonDir(path14.join(cwd, ".snipara", "decisions", "resolved"));
15613
15705
  const workflow2 = workflowSnapshot(cwd);
15614
15706
  const producerLoop = producerLoopSummary(cwd);
15615
15707
  const teamSync2 = teamSyncSnapshot(cwd);
@@ -15672,8 +15764,8 @@ function writeSessionSnapshot(options = {}) {
15672
15764
  const cwd = options.cwd ?? process.cwd();
15673
15765
  const snapshot = buildSessionSnapshot({ cwd, limit: options.limit });
15674
15766
  const snapshotPath = getSessionSnapshotPath(cwd);
15675
- fs14.mkdirSync(path13.dirname(snapshotPath), { recursive: true });
15676
- fs14.writeFileSync(snapshotPath, `${JSON.stringify(snapshot, null, 2)}
15767
+ fs15.mkdirSync(path14.dirname(snapshotPath), { recursive: true });
15768
+ fs15.writeFileSync(snapshotPath, `${JSON.stringify(snapshot, null, 2)}
15677
15769
  `, "utf8");
15678
15770
  return snapshot;
15679
15771
  }
@@ -15687,8 +15779,8 @@ function readSessionSnapshot(cwd = process.cwd()) {
15687
15779
 
15688
15780
  // src/commands/why-capture.ts
15689
15781
  var import_node_child_process4 = require("child_process");
15690
- var fs15 = __toESM(require("fs"));
15691
- var path14 = __toESM(require("path"));
15782
+ var fs16 = __toESM(require("fs"));
15783
+ var path15 = __toESM(require("path"));
15692
15784
  var MAX_SOURCE_TEXT_CHARS = 12e3;
15693
15785
  var MAX_TASK_CHARS = 700;
15694
15786
  var MAX_RECEIPT_TEXT_CHARS = 900;
@@ -15794,12 +15886,12 @@ function readCommitSha(cwd) {
15794
15886
  return readGitValue(cwd, ["rev-parse", "--verify", "HEAD^{commit}"]);
15795
15887
  }
15796
15888
  function hasActiveManagedWorkflow(cwd) {
15797
- const statePath = path14.join(cwd, ".snipara", "workflow", "current.json");
15798
- if (!fs15.existsSync(statePath)) {
15889
+ const statePath = path15.join(cwd, ".snipara", "workflow", "current.json");
15890
+ if (!fs16.existsSync(statePath)) {
15799
15891
  return false;
15800
15892
  }
15801
15893
  try {
15802
- const parsed = JSON.parse(fs15.readFileSync(statePath, "utf8"));
15894
+ const parsed = JSON.parse(fs16.readFileSync(statePath, "utf8"));
15803
15895
  return parsed.status !== "completed";
15804
15896
  } catch {
15805
15897
  return true;
@@ -15830,7 +15922,7 @@ function readStandaloneCommitEvidence(cwd, commitSha, additionalFiles = []) {
15830
15922
  function readLatestWorkflowCommands(cwd) {
15831
15923
  try {
15832
15924
  const state = JSON.parse(
15833
- fs15.readFileSync(path14.join(cwd, ".snipara", "workflow", "current.json"), "utf8")
15925
+ fs16.readFileSync(path15.join(cwd, ".snipara", "workflow", "current.json"), "utf8")
15834
15926
  );
15835
15927
  const bindings = state.runtime?.sandbox?.bindings ?? [];
15836
15928
  for (let index = bindings.length - 1; index >= 0; index -= 1) {
@@ -16295,38 +16387,100 @@ async function postToolCommand(options) {
16295
16387
  }
16296
16388
 
16297
16389
  // src/commands/session.ts
16298
- async function sessionEndCommand() {
16390
+ var fs17 = __toESM(require("fs"));
16391
+ var path16 = __toESM(require("path"));
16392
+ var import_node_crypto9 = require("crypto");
16393
+ function printCloseout(report, file, json) {
16394
+ if (json) {
16395
+ console.log(JSON.stringify({ ...report, reportPath: file }, null, 2));
16396
+ return;
16397
+ }
16398
+ const message = report.status === "saved" ? `Session saved to journal (${report.checkpoint.files.length} files; entry ${report.entryId})` : report.status === "skipped" ? "Session checkpoint skipped: no summary or files supplied" : "Session NOT saved; local checkpoint retained for retry";
16399
+ console.log(`${message}
16400
+ Receipt: ${file}`);
16401
+ if (report.status === "error" || report.status === "pending") {
16402
+ console.error(`Retry: snipara-companion session-end --retry ${JSON.stringify(file)}`);
16403
+ }
16404
+ if (report.status === "saved" && report.eventDelivered === false) {
16405
+ console.error("Journal saved; automation event delivery was not confirmed.");
16406
+ }
16407
+ }
16408
+ async function sessionEndCommand(options = {}) {
16299
16409
  if (!isConfigured()) {
16300
- console.log("Not configured. Run 'npx -y snipara-companion@latest init' first.");
16301
- process.exit(0);
16410
+ console.log(
16411
+ options.json ? JSON.stringify({ status: "skipped", reason: "not_configured", reportPath: null }) : "Not configured. Run 'npx -y snipara-companion@latest init' first."
16412
+ );
16413
+ return;
16302
16414
  }
16415
+ const cwd = path16.resolve(process.env.SNIPARA_WORKSPACE_DIR || process.cwd());
16416
+ const config = loadConfig();
16417
+ const previous = options.retry ? readSessionCloseout(path16.resolve(options.retry)) : void 0;
16418
+ if (options.retry && (!previous || previous.workspace !== cwd || previous.projectId !== config.projectId)) {
16419
+ throw new Error("Retry receipt does not belong to this workspace and project");
16420
+ }
16421
+ const checkpoint = normalizeSessionCheckpoint(
16422
+ previous?.checkpoint ?? {
16423
+ sessionId: options.sessionId ?? config.sessionId ?? `sess_${(0, import_node_crypto9.randomUUID)()}`,
16424
+ summary: options.summary,
16425
+ files: options.files
16426
+ }
16427
+ );
16428
+ const file = sessionCloseoutPath(cwd, config.projectId, checkpoint);
16429
+ const existing = readSessionCloseout(file);
16430
+ if (existing?.status === "saved" && existing.entryId) {
16431
+ printCloseout(existing, file, options.json);
16432
+ return;
16433
+ }
16434
+ const report = {
16435
+ version: "snipara.session_closeout.v1",
16436
+ workspace: cwd,
16437
+ projectId: config.projectId,
16438
+ checkpoint,
16439
+ status: "pending",
16440
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
16441
+ };
16442
+ fs17.mkdirSync(path16.dirname(file), { recursive: true, mode: 448 });
16443
+ const lock = lockSessionCloseout(file);
16303
16444
  try {
16304
- const client = createClient(3e4);
16305
- const result = await client.persistSession();
16306
- await emitCanonicalEvent({
16307
- eventType: "session_end",
16308
- payload: {
16309
- persisted: true,
16310
- files_tracked: result.files_tracked
16311
- }
16312
- });
16313
- console.log(`\u2713 Session saved (${result.files_tracked} files tracked)`);
16314
- const newSessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
16315
- saveConfig({ sessionId: newSessionId });
16316
- } catch (error) {
16317
- await emitCanonicalEvent({
16318
- eventType: "session_end",
16319
- payload: {
16320
- persisted: false,
16321
- offline: true
16322
- }
16323
- });
16324
- if (process.env.RLM_DEBUG) {
16325
- console.error(
16326
- `[Snipara] Session error: ${error instanceof Error ? error.message : "Unknown error"}`
16327
- );
16445
+ const confirmed = readSessionCloseout(file);
16446
+ if (confirmed?.status === "saved" && confirmed.entryId) {
16447
+ printCloseout(confirmed, file, options.json);
16448
+ return;
16328
16449
  }
16329
- console.log("Session ended (offline)");
16450
+ writeSessionCloseout(file, report);
16451
+ try {
16452
+ const result = await createClient(15e3).persistSession(checkpoint);
16453
+ report.status = result.status;
16454
+ report.entryId = result.entry_id;
16455
+ report.journalDate = result.date;
16456
+ } catch {
16457
+ report.status = "error";
16458
+ report.error = "Hosted journal persistence was not confirmed. The checkpoint is retained locally.";
16459
+ process.exitCode = 1;
16460
+ }
16461
+ writeSessionCloseout(file, report);
16462
+ report.eventDelivered = await emitCanonicalEvent(
16463
+ {
16464
+ eventType: "session_end",
16465
+ sessionId: checkpoint.sessionId,
16466
+ payload: {
16467
+ persisted: report.status === "saved",
16468
+ persistence_status: report.status,
16469
+ files_tracked: checkpoint.files.length,
16470
+ ...report.entryId ? { journal_entry_id: report.entryId } : {}
16471
+ }
16472
+ },
16473
+ { timeoutMs: 2e3 }
16474
+ );
16475
+ writeSessionCloseout(file, report);
16476
+ writeSessionCloseout(path16.join(cwd, ".snipara", "companion", "session-closeout.json"), report);
16477
+ if (report.status === "saved" && !options.sessionId && loadConfig().sessionId === checkpoint.sessionId) {
16478
+ saveConfig({ sessionId: `sess_${(0, import_node_crypto9.randomUUID)()}` });
16479
+ }
16480
+ printCloseout(report, file, options.json);
16481
+ } finally {
16482
+ fs17.closeSync(lock);
16483
+ fs17.unlinkSync(`${file}.lock`);
16330
16484
  }
16331
16485
  }
16332
16486
  async function sessionStatusCommand() {
@@ -16337,6 +16491,17 @@ async function sessionStatusCommand() {
16337
16491
  const config = loadConfig();
16338
16492
  console.log("\n\u{1F4CA} Session Status\n");
16339
16493
  console.log(`Session ID: ${config.sessionId || "none"}`);
16494
+ const reportFile = path16.join(
16495
+ process.env.SNIPARA_WORKSPACE_DIR || process.cwd(),
16496
+ ".snipara",
16497
+ "companion",
16498
+ "session-closeout.json"
16499
+ );
16500
+ const report = readSessionCloseout(reportFile);
16501
+ if (report) {
16502
+ console.log(`Last checkpoint: ${report.status}${report.entryId ? ` (${report.entryId})` : ""}`);
16503
+ console.log(`Receipt: ${reportFile}`);
16504
+ }
16340
16505
  try {
16341
16506
  const client = createClient(5e3);
16342
16507
  const status = await client.getSession();
@@ -16358,17 +16523,17 @@ function sessionResetCommand() {
16358
16523
  var import_chalk3 = __toESM(require("chalk"));
16359
16524
 
16360
16525
  // src/commands/decision-requests.ts
16361
- var fs16 = __toESM(require("fs"));
16362
- var path15 = __toESM(require("path"));
16526
+ var fs18 = __toESM(require("fs"));
16527
+ var path17 = __toESM(require("path"));
16363
16528
  function decisionPendingDir(cwd = process.cwd()) {
16364
- return path15.join(cwd, DECISION_REQUEST_RELATIVE_DIR, "pending");
16529
+ return path17.join(cwd, DECISION_REQUEST_RELATIVE_DIR, "pending");
16365
16530
  }
16366
16531
  function decisionResolvedDir(cwd = process.cwd()) {
16367
- return path15.join(cwd, DECISION_REQUEST_RELATIVE_DIR, "resolved");
16532
+ return path17.join(cwd, DECISION_REQUEST_RELATIVE_DIR, "resolved");
16368
16533
  }
16369
16534
  function ensureDecisionDirs(cwd = process.cwd()) {
16370
- fs16.mkdirSync(decisionPendingDir(cwd), { recursive: true });
16371
- fs16.mkdirSync(decisionResolvedDir(cwd), { recursive: true });
16535
+ fs18.mkdirSync(decisionPendingDir(cwd), { recursive: true });
16536
+ fs18.mkdirSync(decisionResolvedDir(cwd), { recursive: true });
16372
16537
  }
16373
16538
  function writeDecisionRequest(request, cwd = process.cwd()) {
16374
16539
  ensureDecisionDirs(cwd);
@@ -16393,8 +16558,8 @@ function writeDecisionRequest(request, cwd = process.cwd()) {
16393
16558
  relativePath: existing.relativePath
16394
16559
  };
16395
16560
  }
16396
- const filePath = path15.join(decisionPendingDir(cwd), `${request.requestId}.json`);
16397
- fs16.writeFileSync(filePath, `${stableDecisionJsonStringify(request)}
16561
+ const filePath = path17.join(decisionPendingDir(cwd), `${request.requestId}.json`);
16562
+ fs18.writeFileSync(filePath, `${stableDecisionJsonStringify(request)}
16398
16563
  `, "utf8");
16399
16564
  return {
16400
16565
  status: "written",
@@ -16409,8 +16574,8 @@ function listPendingDecisionRequests(cwd = process.cwd()) {
16409
16574
  const resolved = new Set(
16410
16575
  listResolvedDecisionRecords(cwd).map((record2) => record2.request.fingerprint)
16411
16576
  );
16412
- return fs16.readdirSync(decisionPendingDir(cwd)).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path15.join(decisionPendingDir(cwd), fileName)).sort().map((filePath) => {
16413
- const parsed = JSON.parse(fs16.readFileSync(filePath, "utf8"));
16577
+ return fs18.readdirSync(decisionPendingDir(cwd)).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path17.join(decisionPendingDir(cwd), fileName)).sort().map((filePath) => {
16578
+ const parsed = JSON.parse(fs18.readFileSync(filePath, "utf8"));
16414
16579
  if (!isDecisionRequest(parsed)) {
16415
16580
  throw new Error(
16416
16581
  `Invalid decision request artifact: ${toProjectRelativePath(filePath, cwd)}`
@@ -16426,8 +16591,8 @@ function listPendingDecisionRequests(cwd = process.cwd()) {
16426
16591
  });
16427
16592
  }
16428
16593
  function listResolvedDecisionRecords(cwd = process.cwd()) {
16429
- fs16.mkdirSync(decisionResolvedDir(cwd), { recursive: true });
16430
- return fs16.readdirSync(decisionResolvedDir(cwd)).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path15.join(decisionResolvedDir(cwd), fileName)).sort().map((filePath) => JSON.parse(fs16.readFileSync(filePath, "utf8"))).filter((record2) => record2?.schemaVersion === "snipara.decision_resolution.v0");
16594
+ fs18.mkdirSync(decisionResolvedDir(cwd), { recursive: true });
16595
+ return fs18.readdirSync(decisionResolvedDir(cwd)).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path17.join(decisionResolvedDir(cwd), fileName)).sort().map((filePath) => JSON.parse(fs18.readFileSync(filePath, "utf8"))).filter((record2) => record2?.schemaVersion === "snipara.decision_resolution.v0");
16431
16596
  }
16432
16597
  function resolveDecisionRequest(options) {
16433
16598
  const cwd = options.cwd ?? process.cwd();
@@ -16455,18 +16620,18 @@ function resolveDecisionRequest(options) {
16455
16620
  request: entry.request,
16456
16621
  response
16457
16622
  };
16458
- const resolvedPath = path15.join(decisionResolvedDir(cwd), `${entry.request.requestId}.json`);
16459
- fs16.writeFileSync(resolvedPath, `${stableDecisionJsonStringify(record2)}
16623
+ const resolvedPath = path17.join(decisionResolvedDir(cwd), `${entry.request.requestId}.json`);
16624
+ fs18.writeFileSync(resolvedPath, `${stableDecisionJsonStringify(record2)}
16460
16625
  `, "utf8");
16461
- fs16.unlinkSync(entry.path);
16626
+ fs18.unlinkSync(entry.path);
16462
16627
  return { request: entry.request, response, resolvedPath };
16463
16628
  }
16464
16629
  function decisionPendingCount(cwd = process.cwd()) {
16465
16630
  return listPendingDecisionRequests(cwd).filter((entry) => entry.status === "pending").length;
16466
16631
  }
16467
16632
  function toProjectRelativePath(absolutePath, cwd) {
16468
- const relative15 = path15.relative(cwd, absolutePath).replace(/\\/g, "/");
16469
- return relative15.startsWith(".") ? relative15 : `.${path15.sep}${relative15}`.replace(/\\/g, "/");
16633
+ const relative15 = path17.relative(cwd, absolutePath).replace(/\\/g, "/");
16634
+ return relative15.startsWith(".") ? relative15 : `.${path17.sep}${relative15}`.replace(/\\/g, "/");
16470
16635
  }
16471
16636
 
16472
16637
  // src/commands/memory.ts
@@ -17249,8 +17414,8 @@ async function memoryAuditCommand(options) {
17249
17414
  }
17250
17415
 
17251
17416
  // src/commands/local-stack.ts
17252
- var fs17 = __toESM(require("fs"));
17253
- var path16 = __toESM(require("path"));
17417
+ var fs19 = __toESM(require("fs"));
17418
+ var path18 = __toESM(require("path"));
17254
17419
  var import_node_child_process6 = require("child_process");
17255
17420
  function uniqueStrings17(values) {
17256
17421
  return Array.from(new Set((values ?? []).map((value) => value.trim()).filter(Boolean)));
@@ -17266,13 +17431,13 @@ function keywordHints(value) {
17266
17431
  }
17267
17432
  function readJsonFile2(filePath) {
17268
17433
  try {
17269
- return JSON.parse(fs17.readFileSync(filePath, "utf8"));
17434
+ return JSON.parse(fs19.readFileSync(filePath, "utf8"));
17270
17435
  } catch {
17271
17436
  return void 0;
17272
17437
  }
17273
17438
  }
17274
17439
  function maybeLocalArtifact(rootDir, relativePath2) {
17275
- const absolutePath = path16.join(rootDir, relativePath2);
17440
+ const absolutePath = path18.join(rootDir, relativePath2);
17276
17441
  const value = readJsonFile2(absolutePath);
17277
17442
  if (!value) {
17278
17443
  return null;
@@ -17305,7 +17470,7 @@ function expectedItems(section, values, files) {
17305
17470
  });
17306
17471
  }
17307
17472
  function buildEvalCaseArtifact(options = {}) {
17308
- const rootDir = path16.resolve(options.dir ?? process.cwd());
17473
+ const rootDir = path18.resolve(options.dir ?? process.cwd());
17309
17474
  const files = uniqueStrings17(options.files);
17310
17475
  const commandsRun = uniqueStrings17(options.commandRun);
17311
17476
  const summary = options.summary?.trim() || "Snipara companion local workflow evaluation";
@@ -17324,8 +17489,8 @@ function buildEvalCaseArtifact(options = {}) {
17324
17489
  }
17325
17490
  }
17326
17491
  const artifacts = [
17327
- maybeLocalArtifact(rootDir, path16.join(".snipara", "workflow", "current.json")),
17328
- maybeLocalArtifact(rootDir, path16.join(".snipara", "team-sync", "session.json"))
17492
+ maybeLocalArtifact(rootDir, path18.join(".snipara", "workflow", "current.json")),
17493
+ maybeLocalArtifact(rootDir, path18.join(".snipara", "team-sync", "session.json"))
17329
17494
  ].filter((artifact) => artifact !== null);
17330
17495
  return {
17331
17496
  id,
@@ -17345,8 +17510,8 @@ function buildEvalCaseArtifact(options = {}) {
17345
17510
  };
17346
17511
  }
17347
17512
  function writeOutput(filePath, content) {
17348
- fs17.mkdirSync(path16.dirname(filePath), { recursive: true });
17349
- fs17.writeFileSync(filePath, content, "utf8");
17513
+ fs19.mkdirSync(path18.dirname(filePath), { recursive: true });
17514
+ fs19.writeFileSync(filePath, content, "utf8");
17350
17515
  }
17351
17516
  function runCommand(command, args, missingHint) {
17352
17517
  const result = (0, import_node_child_process6.spawnSync)(command, args, {
@@ -17377,10 +17542,10 @@ async function memoryLocalCommand(options) {
17377
17542
  process.exitCode = code2;
17378
17543
  }
17379
17544
  async function evalExportCommand(options) {
17380
- const rootDir = path16.resolve(options.dir ?? process.cwd());
17381
- const output = path16.resolve(
17545
+ const rootDir = path18.resolve(options.dir ?? process.cwd());
17546
+ const output = path18.resolve(
17382
17547
  rootDir,
17383
- options.output ?? path16.join(".snipara", "evals", "case.json")
17548
+ options.output ?? path18.join(".snipara", "evals", "case.json")
17384
17549
  );
17385
17550
  const artifact = buildEvalCaseArtifact(options);
17386
17551
  const content = `${JSON.stringify(artifact, null, 2)}
@@ -17399,7 +17564,7 @@ async function evalRunCommand(options) {
17399
17564
  }
17400
17565
  const runner = options.runner || process.env.SNIPARA_EVALS_RUNNER || "npx";
17401
17566
  const packageSpec = options.packageSpec || "snipara-evals@latest";
17402
- const args = path16.basename(runner) === "snipara-evals" ? ["run", ...options.cases] : ["--yes", packageSpec, "run", ...options.cases];
17567
+ const args = path18.basename(runner) === "snipara-evals" ? ["run", ...options.cases] : ["--yes", packageSpec, "run", ...options.cases];
17403
17568
  if (options.json) {
17404
17569
  args.push("--json");
17405
17570
  }
@@ -17415,15 +17580,15 @@ async function evalRunCommand(options) {
17415
17580
  }
17416
17581
 
17417
17582
  // src/commands/doctor.ts
17418
- var fs19 = __toESM(require("fs"));
17419
- var path18 = __toESM(require("path"));
17583
+ var fs21 = __toESM(require("fs"));
17584
+ var path20 = __toESM(require("path"));
17420
17585
  var import_node_child_process7 = require("child_process");
17421
17586
  var import_chalk4 = __toESM(require("chalk"));
17422
17587
 
17423
17588
  // src/runtime/detection.ts
17424
- var fs18 = __toESM(require("fs"));
17589
+ var fs20 = __toESM(require("fs"));
17425
17590
  var os6 = __toESM(require("os"));
17426
- var path17 = __toESM(require("path"));
17591
+ var path19 = __toESM(require("path"));
17427
17592
  var import_child_process5 = require("child_process");
17428
17593
  var RUNTIME_INTENT_PATTERN = /\b(test|tests|validate|validation|verify|evaluate|eval|execute|execution|run|sandbox|sandboxed|isolated|isolation|simulate|script|python|csv|dataframe|notebook|generate report|lint|type-?check|build|benchmark|parse|transform|repeatable|reproducible)\b/i;
17429
17594
  var ORCHESTRATOR_PRODUCTION_PATTERN = /\b(prod|production|deploy|deployment|release|rollout|cutover|drift|live validation|live check|live checks)\b/i;
@@ -17599,14 +17764,14 @@ function getCommandVersion(command) {
17599
17764
  }
17600
17765
  function executableExists(filePath) {
17601
17766
  try {
17602
- const stat = fs18.statSync(filePath);
17767
+ const stat = fs20.statSync(filePath);
17603
17768
  if (!stat.isFile()) {
17604
17769
  return false;
17605
17770
  }
17606
17771
  if (process.platform === "win32") {
17607
17772
  return true;
17608
17773
  }
17609
- fs18.accessSync(filePath, fs18.constants.X_OK);
17774
+ fs20.accessSync(filePath, fs20.constants.X_OK);
17610
17775
  return true;
17611
17776
  } catch {
17612
17777
  return false;
@@ -17652,11 +17817,11 @@ function detectOrchestratorCli(cwd, workspaceRoot2) {
17652
17817
  }
17653
17818
  function findWorkspaceOrchestratorVersion(cwd, workspaceRoot2) {
17654
17819
  const roots = Array.from(
17655
- new Set([workspaceRoot2, path17.resolve(cwd)].filter((value) => Boolean(value)))
17820
+ new Set([workspaceRoot2, path19.resolve(cwd)].filter((value) => Boolean(value)))
17656
17821
  );
17657
17822
  for (const root of roots) {
17658
17823
  const version = readPyprojectVersion(
17659
- path17.join(root, "packages", "agentic-orchestrator", "pyproject.toml"),
17824
+ path19.join(root, "packages", "agentic-orchestrator", "pyproject.toml"),
17660
17825
  "snipara-orchestrator"
17661
17826
  );
17662
17827
  if (version) {
@@ -17666,10 +17831,10 @@ function findWorkspaceOrchestratorVersion(cwd, workspaceRoot2) {
17666
17831
  return void 0;
17667
17832
  }
17668
17833
  function readPyprojectVersion(filePath, packageName) {
17669
- if (!fs18.existsSync(filePath)) {
17834
+ if (!fs20.existsSync(filePath)) {
17670
17835
  return void 0;
17671
17836
  }
17672
- const content = fs18.readFileSync(filePath, "utf-8");
17837
+ const content = fs20.readFileSync(filePath, "utf-8");
17673
17838
  const nameMatch = content.match(/^\s*name\s*=\s*["']([^"']+)["']/m);
17674
17839
  if (nameMatch && nameMatch[1] !== packageName) {
17675
17840
  return void 0;
@@ -17687,13 +17852,13 @@ function parseOrchestratorVersion(version) {
17687
17852
  function findWorkspaceExecutableCandidates(command, cwd, workspaceRoot2) {
17688
17853
  const executableName = process.platform === "win32" ? `${command}.exe` : command;
17689
17854
  const roots = Array.from(
17690
- new Set([workspaceRoot2, path17.resolve(cwd)].filter((value) => Boolean(value)))
17855
+ new Set([workspaceRoot2, path19.resolve(cwd)].filter((value) => Boolean(value)))
17691
17856
  );
17692
17857
  return roots.flatMap((root) => [
17693
- path17.join(root, ".venv", "bin", executableName),
17694
- path17.join(root, "venv", "bin", executableName),
17695
- path17.join(root, "packages", "agentic-orchestrator", ".venv", "bin", executableName),
17696
- path17.join(root, "apps", "mcp-server", ".venv", "bin", executableName)
17858
+ path19.join(root, ".venv", "bin", executableName),
17859
+ path19.join(root, "venv", "bin", executableName),
17860
+ path19.join(root, "packages", "agentic-orchestrator", ".venv", "bin", executableName),
17861
+ path19.join(root, "apps", "mcp-server", ".venv", "bin", executableName)
17697
17862
  ]);
17698
17863
  }
17699
17864
  function parseRuntimeVersion(version) {
@@ -17748,7 +17913,7 @@ function loadEnvFiles(cwd, workspaceRoot2) {
17748
17913
  const values = {};
17749
17914
  const files = [];
17750
17915
  for (const envFile of findEnvFilePaths(cwd, workspaceRoot2)) {
17751
- if (!fs18.existsSync(envFile)) {
17916
+ if (!fs20.existsSync(envFile)) {
17752
17917
  continue;
17753
17918
  }
17754
17919
  const parsed = parseEnvFile(envFile);
@@ -17759,17 +17924,17 @@ function loadEnvFiles(cwd, workspaceRoot2) {
17759
17924
  }
17760
17925
  function findEnvFilePaths(cwd, workspaceRoot2) {
17761
17926
  const names = [".env", ".env.local", ".env.development", ".env.development.local"];
17762
- const roots = [workspaceRoot2, path17.resolve(cwd)].filter(
17927
+ const roots = [workspaceRoot2, path19.resolve(cwd)].filter(
17763
17928
  (value) => Boolean(value)
17764
17929
  );
17765
- const candidates = roots.flatMap((root) => names.map((name) => path17.join(root, name)));
17930
+ const candidates = roots.flatMap((root) => names.map((name) => path19.join(root, name)));
17766
17931
  return Array.from(new Set(candidates));
17767
17932
  }
17768
17933
  function parseEnvFile(filePath) {
17769
17934
  const values = {};
17770
17935
  let content;
17771
17936
  try {
17772
- content = fs18.readFileSync(filePath, "utf-8");
17937
+ content = fs20.readFileSync(filePath, "utf-8");
17773
17938
  } catch {
17774
17939
  return values;
17775
17940
  }
@@ -17813,24 +17978,24 @@ function parseEnvValue(rawValue) {
17813
17978
  }
17814
17979
  function findRuntimeMcpConfigPaths(cwd, workspaceRoot2) {
17815
17980
  const candidatePaths = [
17816
- workspaceRoot2 ? path17.join(workspaceRoot2, ".mcp.json") : null,
17817
- path17.join(cwd, ".mcp.json"),
17818
- path17.join(os6.homedir(), ".mcp.json"),
17819
- path17.join(os6.homedir(), ".claude", "claude_desktop_config.json"),
17820
- path17.join(os6.homedir(), ".codex", "config.toml")
17981
+ workspaceRoot2 ? path19.join(workspaceRoot2, ".mcp.json") : null,
17982
+ path19.join(cwd, ".mcp.json"),
17983
+ path19.join(os6.homedir(), ".mcp.json"),
17984
+ path19.join(os6.homedir(), ".claude", "claude_desktop_config.json"),
17985
+ path19.join(os6.homedir(), ".codex", "config.toml")
17821
17986
  ].filter((value) => Boolean(value));
17822
17987
  const uniquePaths = Array.from(new Set(candidatePaths));
17823
17988
  return uniquePaths.filter((configPath) => configHasRuntimeServer(configPath));
17824
17989
  }
17825
17990
  function configHasRuntimeServer(configPath) {
17826
- if (!fs18.existsSync(configPath)) {
17991
+ if (!fs20.existsSync(configPath)) {
17827
17992
  return false;
17828
17993
  }
17829
17994
  if (configPath.endsWith(".toml")) {
17830
17995
  return tomlConfigHasRuntimeServer(configPath);
17831
17996
  }
17832
17997
  try {
17833
- const parsed = JSON.parse(fs18.readFileSync(configPath, "utf-8"));
17998
+ const parsed = JSON.parse(fs20.readFileSync(configPath, "utf-8"));
17834
17999
  if (!isRecord9(parsed)) {
17835
18000
  return false;
17836
18001
  }
@@ -17857,7 +18022,7 @@ function configHasRuntimeServer(configPath) {
17857
18022
  function tomlConfigHasRuntimeServer(configPath) {
17858
18023
  let content;
17859
18024
  try {
17860
- content = fs18.readFileSync(configPath, "utf-8");
18025
+ content = fs20.readFileSync(configPath, "utf-8");
17861
18026
  } catch {
17862
18027
  return false;
17863
18028
  }
@@ -17910,7 +18075,7 @@ async function doctorCommand(options = {}) {
17910
18075
  printDoctorReport(report, companionVersion, auth, toolCatalog);
17911
18076
  }
17912
18077
  function probeCompanionVersion(report) {
17913
- const currentVersion = readPackageVersion(path18.resolve(__dirname, "../package.json"));
18078
+ const currentVersion = readPackageVersion(path20.resolve(__dirname, "../package.json"));
17914
18079
  const workspacePackageVersion = findWorkspaceCompanionVersion(report);
17915
18080
  const latestNpm = probeLatestNpmVersion();
17916
18081
  const warnings = [];
@@ -17950,7 +18115,7 @@ function probeCompanionVersion(report) {
17950
18115
  }
17951
18116
  function readPackageVersion(packageJsonPath) {
17952
18117
  try {
17953
- const raw = fs19.readFileSync(packageJsonPath, "utf8");
18118
+ const raw = fs21.readFileSync(packageJsonPath, "utf8");
17954
18119
  const parsed = JSON.parse(raw);
17955
18120
  return typeof parsed.version === "string" && parsed.version.length > 0 ? parsed.version : void 0;
17956
18121
  } catch {
@@ -17959,9 +18124,9 @@ function readPackageVersion(packageJsonPath) {
17959
18124
  }
17960
18125
  function findWorkspaceCompanionVersion(report) {
17961
18126
  const candidates = [
17962
- path18.join(report.cwd, "packages", "cli", "package.json"),
17963
- report.workspaceRoot ? path18.join(report.workspaceRoot, "packages", "cli", "package.json") : void 0,
17964
- path18.basename(report.cwd) === "cli" ? path18.join(report.cwd, "package.json") : void 0
18127
+ path20.join(report.cwd, "packages", "cli", "package.json"),
18128
+ report.workspaceRoot ? path20.join(report.workspaceRoot, "packages", "cli", "package.json") : void 0,
18129
+ path20.basename(report.cwd) === "cli" ? path20.join(report.cwd, "package.json") : void 0
17965
18130
  ].filter((value) => Boolean(value));
17966
18131
  for (const candidate of candidates) {
17967
18132
  const version = readPackageVersion(candidate);
@@ -18304,23 +18469,23 @@ var import_path5 = __toESM(require("path"));
18304
18469
  var import_chalk10 = __toESM(require("chalk"));
18305
18470
 
18306
18471
  // src/commands/workflows.ts
18307
- var fs30 = __toESM(require("fs"));
18308
- var path29 = __toESM(require("path"));
18472
+ var fs32 = __toESM(require("fs"));
18473
+ var path31 = __toESM(require("path"));
18309
18474
  var import_node_child_process15 = require("child_process");
18310
- var import_node_crypto13 = require("crypto");
18475
+ var import_node_crypto15 = require("crypto");
18311
18476
  var import_chalk9 = __toESM(require("chalk"));
18312
18477
 
18313
18478
  // src/runtime/orchestrator-handoff.ts
18314
- var fs20 = __toESM(require("fs"));
18315
- var path19 = __toESM(require("path"));
18479
+ var fs22 = __toESM(require("fs"));
18480
+ var path21 = __toESM(require("path"));
18316
18481
  var import_child_process6 = require("child_process");
18317
- var ORCHESTRATOR_HANDOFF_RELATIVE_PATH = path19.join(
18482
+ var ORCHESTRATOR_HANDOFF_RELATIVE_PATH = path21.join(
18318
18483
  ".snipara",
18319
18484
  "orchestrator",
18320
18485
  "handoff.json"
18321
18486
  );
18322
18487
  function buildOrchestratorHandoff(options) {
18323
- const rootDir = path19.resolve(options.rootDir ?? process.cwd());
18488
+ const rootDir = path21.resolve(options.rootDir ?? process.cwd());
18324
18489
  const workflowState = readWorkflowState(rootDir);
18325
18490
  const changedFiles = normalizeStringList2(
18326
18491
  options.changedFiles ?? (Array.isArray(workflowState?.currentPhase?.files) ? workflowState.currentPhase.files : [])
@@ -18672,11 +18837,11 @@ function compactObject2(value) {
18672
18837
  );
18673
18838
  }
18674
18839
  function writeOrchestratorHandoff(options) {
18675
- const rootDir = path19.resolve(options.rootDir ?? process.cwd());
18840
+ const rootDir = path21.resolve(options.rootDir ?? process.cwd());
18676
18841
  const handoff = buildOrchestratorHandoff({ ...options, rootDir });
18677
- const absolutePath = path19.join(rootDir, ORCHESTRATOR_HANDOFF_RELATIVE_PATH);
18678
- fs20.mkdirSync(path19.dirname(absolutePath), { recursive: true });
18679
- fs20.writeFileSync(absolutePath, `${JSON.stringify(handoff, null, 2)}
18842
+ const absolutePath = path21.join(rootDir, ORCHESTRATOR_HANDOFF_RELATIVE_PATH);
18843
+ fs22.mkdirSync(path21.dirname(absolutePath), { recursive: true });
18844
+ fs22.writeFileSync(absolutePath, `${JSON.stringify(handoff, null, 2)}
18680
18845
  `, "utf8");
18681
18846
  return {
18682
18847
  handoff,
@@ -18686,11 +18851,11 @@ function writeOrchestratorHandoff(options) {
18686
18851
  };
18687
18852
  }
18688
18853
  function readWorkflowState(rootDir) {
18689
- const workflowPath = path19.join(rootDir, ".snipara", "workflow", "current.json");
18690
- if (!fs20.existsSync(workflowPath)) {
18854
+ const workflowPath = path21.join(rootDir, ".snipara", "workflow", "current.json");
18855
+ if (!fs22.existsSync(workflowPath)) {
18691
18856
  return null;
18692
18857
  }
18693
- const parsed = JSON.parse(fs20.readFileSync(workflowPath, "utf8"));
18858
+ const parsed = JSON.parse(fs22.readFileSync(workflowPath, "utf8"));
18694
18859
  const phases = Array.isArray(parsed.phases) ? parsed.phases.filter(isRecord10).map((phase, index) => normalizeWorkflowPhase(phase, index)) : [];
18695
18860
  const currentPhase = phases.find((phase) => phase.id === parsed.currentPhaseId);
18696
18861
  const runtimeBindings = Array.isArray(parsed.runtime?.sandbox?.bindings) ? parsed.runtime?.sandbox?.bindings.filter(isRecord10) : [];
@@ -18837,9 +19002,9 @@ async function appendJournalCheckpoint(payload) {
18837
19002
  }
18838
19003
 
18839
19004
  // src/commands/coding-ledger.ts
18840
- var fs21 = __toESM(require("fs"));
18841
- var path20 = __toESM(require("path"));
18842
- var import_node_crypto8 = require("crypto");
19005
+ var fs23 = __toESM(require("fs"));
19006
+ var path22 = __toESM(require("path"));
19007
+ var import_node_crypto10 = require("crypto");
18843
19008
  var import_node_child_process8 = require("child_process");
18844
19009
  var CODING_INTELLIGENCE_LEDGER_VERSION = "snipara.coding_intelligence_ledger.v0";
18845
19010
  var MAX_SECTION_ITEMS = 24;
@@ -18883,7 +19048,7 @@ function isRecord11(value) {
18883
19048
  function createRedactor2(rootDir) {
18884
19049
  const patterns = /* @__PURE__ */ new Set();
18885
19050
  let redactedValueCount = 0;
18886
- const repoPath = path20.resolve(rootDir);
19051
+ const repoPath = path22.resolve(rootDir);
18887
19052
  function redact(value) {
18888
19053
  let result = truncateText(String(value ?? ""));
18889
19054
  const matchedPatterns = [];
@@ -18929,7 +19094,7 @@ function createRedactor2(rootDir) {
18929
19094
  };
18930
19095
  }
18931
19096
  function buildCodingIntelligenceLedger(options = {}) {
18932
- const rootDir = path20.resolve(options.dir ?? process.cwd());
19097
+ const rootDir = path22.resolve(options.dir ?? process.cwd());
18933
19098
  const input = mergeInputs(readInputFile(options.fromFile, rootDir), options.input);
18934
19099
  const redactor = createRedactor2(rootDir);
18935
19100
  const prompt2 = buildPrompt(input, options, redactor);
@@ -18990,9 +19155,9 @@ async function codingLedgerExportCommand(options) {
18990
19155
  const ledger = buildCodingIntelligenceLedger(options);
18991
19156
  const content = JSON.stringify(ledger, null, 2);
18992
19157
  if (options.output) {
18993
- const absolute = path20.resolve(options.dir ?? process.cwd(), options.output);
18994
- fs21.mkdirSync(path20.dirname(absolute), { recursive: true });
18995
- fs21.writeFileSync(absolute, `${content}
19158
+ const absolute = path22.resolve(options.dir ?? process.cwd(), options.output);
19159
+ fs23.mkdirSync(path22.dirname(absolute), { recursive: true });
19160
+ fs23.writeFileSync(absolute, `${content}
18996
19161
  `, "utf8");
18997
19162
  if (!options.json) {
18998
19163
  console.log(`Wrote coding intelligence ledger: ${absolute}`);
@@ -19189,8 +19354,8 @@ function readInputFile(filePath, rootDir) {
19189
19354
  if (!filePath) {
19190
19355
  return {};
19191
19356
  }
19192
- const absolute = path20.resolve(rootDir, filePath);
19193
- const parsed = JSON.parse(fs21.readFileSync(absolute, "utf8"));
19357
+ const absolute = path22.resolve(rootDir, filePath);
19358
+ const parsed = JSON.parse(fs23.readFileSync(absolute, "utf8"));
19194
19359
  if (!isRecord11(parsed)) {
19195
19360
  throw new Error("coding ledger --from-file must contain a JSON object.");
19196
19361
  }
@@ -19295,7 +19460,7 @@ function itemId(section, index, value) {
19295
19460
  return `${section}:${stableHash([section, String(index), value]).slice(0, 16)}`;
19296
19461
  }
19297
19462
  function stableHash(parts) {
19298
- return (0, import_node_crypto8.createHash)("sha256").update(parts.join("\0")).digest("hex");
19463
+ return (0, import_node_crypto10.createHash)("sha256").update(parts.join("\0")).digest("hex");
19299
19464
  }
19300
19465
  function stringValue5(value) {
19301
19466
  if (typeof value === "string") {
@@ -19389,11 +19554,11 @@ function removeUndefined(value) {
19389
19554
  }
19390
19555
 
19391
19556
  // src/commands/decision-apply.ts
19392
- var fs22 = __toESM(require("fs"));
19393
- var path21 = __toESM(require("path"));
19557
+ var fs24 = __toESM(require("fs"));
19558
+ var path23 = __toESM(require("path"));
19394
19559
  var DECISION_APPLY_LEDGER_VERSION = "snipara.decision_apply_ledger.v0";
19395
- var DECISION_APPLY_RELATIVE_DIR = path21.join(".snipara", "policy-ledger", "applied");
19396
- var POLICY_DRAFT_RELATIVE_DIR = path21.join(".snipara", "policies", "drafts");
19560
+ var DECISION_APPLY_RELATIVE_DIR = path23.join(".snipara", "policy-ledger", "applied");
19561
+ var POLICY_DRAFT_RELATIVE_DIR = path23.join(".snipara", "policies", "drafts");
19397
19562
  function buildDecisionApplyReport(options = {}) {
19398
19563
  const cwd = options.cwd ?? process.cwd();
19399
19564
  const dryRun = options.dryRun ?? true;
@@ -19542,12 +19707,12 @@ function summarizeDecisionApplyItems(items, written) {
19542
19707
  };
19543
19708
  }
19544
19709
  function writeAppliedDecisionRecord(item, cwd) {
19545
- fs22.mkdirSync(appliedDecisionDir(cwd), { recursive: true });
19710
+ fs24.mkdirSync(appliedDecisionDir(cwd), { recursive: true });
19546
19711
  let policyDraftPath;
19547
19712
  if (item.policyDraftPath) {
19548
19713
  const absoluteDraftPath = policyDraftPathFor(cwd, item.requestId);
19549
- fs22.mkdirSync(path21.dirname(absoluteDraftPath), { recursive: true });
19550
- fs22.writeFileSync(
19714
+ fs24.mkdirSync(path23.dirname(absoluteDraftPath), { recursive: true });
19715
+ fs24.writeFileSync(
19551
19716
  absoluteDraftPath,
19552
19717
  `${stableDecisionJsonStringify({
19553
19718
  schemaVersion: "snipara.project_policy_draft.v0",
@@ -19592,7 +19757,7 @@ function writeAppliedDecisionRecord(item, cwd) {
19592
19757
  policyDraftPath,
19593
19758
  caveats: item.caveats
19594
19759
  };
19595
- fs22.writeFileSync(
19760
+ fs24.writeFileSync(
19596
19761
  appliedDecisionPath(cwd, item.requestId),
19597
19762
  `${stableDecisionJsonStringify(record2)}
19598
19763
  `,
@@ -19601,36 +19766,36 @@ function writeAppliedDecisionRecord(item, cwd) {
19601
19766
  }
19602
19767
  function readAppliedDecisionRecord(cwd, requestId) {
19603
19768
  const filePath = appliedDecisionPath(cwd, requestId);
19604
- if (!fs22.existsSync(filePath)) {
19769
+ if (!fs24.existsSync(filePath)) {
19605
19770
  return void 0;
19606
19771
  }
19607
- const parsed = JSON.parse(fs22.readFileSync(filePath, "utf8"));
19772
+ const parsed = JSON.parse(fs24.readFileSync(filePath, "utf8"));
19608
19773
  return parsed.schemaVersion === DECISION_APPLY_LEDGER_VERSION ? parsed : void 0;
19609
19774
  }
19610
19775
  function appliedDecisionDir(cwd) {
19611
- return path21.join(cwd, DECISION_APPLY_RELATIVE_DIR);
19776
+ return path23.join(cwd, DECISION_APPLY_RELATIVE_DIR);
19612
19777
  }
19613
19778
  function appliedDecisionPath(cwd, requestId) {
19614
- return path21.join(appliedDecisionDir(cwd), `${sanitizeFileStem(requestId)}.json`);
19779
+ return path23.join(appliedDecisionDir(cwd), `${sanitizeFileStem(requestId)}.json`);
19615
19780
  }
19616
19781
  function policyDraftPathFor(cwd, requestId) {
19617
- return path21.join(cwd, POLICY_DRAFT_RELATIVE_DIR, `${sanitizeFileStem(requestId)}.json`);
19782
+ return path23.join(cwd, POLICY_DRAFT_RELATIVE_DIR, `${sanitizeFileStem(requestId)}.json`);
19618
19783
  }
19619
19784
  function sanitizeFileStem(value) {
19620
19785
  return value.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 160) || "decision";
19621
19786
  }
19622
19787
  function toProjectRelativePath2(absolutePath, cwd) {
19623
- const relative15 = path21.relative(cwd, absolutePath).replace(/\\/g, "/");
19624
- return relative15.startsWith(".") ? relative15 : `.${path21.sep}${relative15}`.replace(/\\/g, "/");
19788
+ const relative15 = path23.relative(cwd, absolutePath).replace(/\\/g, "/");
19789
+ return relative15.startsWith(".") ? relative15 : `.${path23.sep}${relative15}`.replace(/\\/g, "/");
19625
19790
  }
19626
19791
 
19627
19792
  // src/commands/collaboration.ts
19628
19793
  var import_node_child_process9 = require("child_process");
19629
- var import_node_crypto9 = require("crypto");
19630
- var fs23 = __toESM(require("fs"));
19794
+ var import_node_crypto11 = require("crypto");
19795
+ var fs25 = __toESM(require("fs"));
19631
19796
  var os7 = __toESM(require("os"));
19632
- var path22 = __toESM(require("path"));
19633
- var COLLABORATION_STATE_RELATIVE_PATH = path22.join(
19797
+ var path24 = __toESM(require("path"));
19798
+ var COLLABORATION_STATE_RELATIVE_PATH = path24.join(
19634
19799
  ".snipara",
19635
19800
  "collaboration",
19636
19801
  "session.json"
@@ -19725,16 +19890,16 @@ function createEmptyCollaborationState(now = /* @__PURE__ */ new Date()) {
19725
19890
  };
19726
19891
  }
19727
19892
  function getCollaborationStatePath(rootDir = process.cwd()) {
19728
- return path22.join(rootDir, COLLABORATION_STATE_RELATIVE_PATH);
19893
+ return path24.join(rootDir, COLLABORATION_STATE_RELATIVE_PATH);
19729
19894
  }
19730
19895
  function loadCollaborationState(rootDir = process.cwd()) {
19731
19896
  const statePath = getCollaborationStatePath(rootDir);
19732
- if (!fs23.existsSync(statePath)) {
19897
+ if (!fs25.existsSync(statePath)) {
19733
19898
  return createEmptyCollaborationState();
19734
19899
  }
19735
19900
  let parsed;
19736
19901
  try {
19737
- parsed = JSON.parse(fs23.readFileSync(statePath, "utf8"));
19902
+ parsed = JSON.parse(fs25.readFileSync(statePath, "utf8"));
19738
19903
  } catch {
19739
19904
  return createEmptyCollaborationState();
19740
19905
  }
@@ -19767,15 +19932,15 @@ function saveCollaborationState(state, rootDir = process.cwd()) {
19767
19932
  expireLocalLeases(state);
19768
19933
  expireReviewOnlyAcknowledgements(state);
19769
19934
  const statePath = getCollaborationStatePath(rootDir);
19770
- fs23.mkdirSync(path22.dirname(statePath), { recursive: true });
19935
+ fs25.mkdirSync(path24.dirname(statePath), { recursive: true });
19771
19936
  const tempPath = `${statePath}.${process.pid}.${Date.now()}.tmp`;
19772
19937
  try {
19773
- fs23.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
19938
+ fs25.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
19774
19939
  `, "utf8");
19775
- fs23.renameSync(tempPath, statePath);
19940
+ fs25.renameSync(tempPath, statePath);
19776
19941
  } finally {
19777
- if (fs23.existsSync(tempPath)) {
19778
- fs23.unlinkSync(tempPath);
19942
+ if (fs25.existsSync(tempPath)) {
19943
+ fs25.unlinkSync(tempPath);
19779
19944
  }
19780
19945
  }
19781
19946
  }
@@ -19969,7 +20134,7 @@ async function collaborationClaimCommand(options) {
19969
20134
  );
19970
20135
  }
19971
20136
  async function workflowCollaborationStart(options) {
19972
- const rootDir = path22.resolve(options.rootDir ?? process.cwd());
20137
+ const rootDir = path24.resolve(options.rootDir ?? process.cwd());
19973
20138
  const workSessionId = workflowWorkSessionId(options.workflowId);
19974
20139
  const context = resolveCollaborationContext({
19975
20140
  dir: rootDir,
@@ -20041,7 +20206,7 @@ async function workflowCollaborationStart(options) {
20041
20206
  };
20042
20207
  }
20043
20208
  async function workflowCollaborationRelease(options) {
20044
- const rootDir = path22.resolve(options.rootDir ?? process.cwd());
20209
+ const rootDir = path24.resolve(options.rootDir ?? process.cwd());
20045
20210
  const context = resolveCollaborationContext({
20046
20211
  dir: rootDir,
20047
20212
  client: "snipara-companion:workflow"
@@ -20660,9 +20825,9 @@ function readGitChangedFiles(rootDir, args) {
20660
20825
  return output ? normalizeFiles(output.split(/\r?\n/)) : [];
20661
20826
  }
20662
20827
  function resolveRepoRoot3(cwd) {
20663
- const resolved = path22.resolve(cwd);
20828
+ const resolved = path24.resolve(cwd);
20664
20829
  const gitRoot = readGitValue4(resolved, ["rev-parse", "--show-toplevel"]);
20665
- return gitRoot ? path22.resolve(gitRoot) : resolved;
20830
+ return gitRoot ? path24.resolve(gitRoot) : resolved;
20666
20831
  }
20667
20832
  function deriveGuardProfileResources(profile, files) {
20668
20833
  const resources = [];
@@ -20939,26 +21104,26 @@ ${nextBlock}`);
20939
21104
  }
20940
21105
  function resolveGitHooksDir2(repoRoot) {
20941
21106
  const gitHooksPath = readGitValue4(repoRoot, ["rev-parse", "--git-path", "hooks"]);
20942
- const hooksDir = path22.resolve(repoRoot, gitHooksPath ?? path22.join(".git", "hooks"));
20943
- const huskyUserHooksDir = path22.dirname(hooksDir);
20944
- if (path22.basename(hooksDir) === "_" && path22.basename(huskyUserHooksDir) === ".husky" && fs23.existsSync(path22.join(hooksDir, "h"))) {
21107
+ const hooksDir = path24.resolve(repoRoot, gitHooksPath ?? path24.join(".git", "hooks"));
21108
+ const huskyUserHooksDir = path24.dirname(hooksDir);
21109
+ if (path24.basename(hooksDir) === "_" && path24.basename(huskyUserHooksDir) === ".husky" && fs25.existsSync(path24.join(hooksDir, "h"))) {
20945
21110
  return huskyUserHooksDir;
20946
21111
  }
20947
21112
  return hooksDir;
20948
21113
  }
20949
21114
  function installManagedCollaborationGitHook(repoRoot, hookName, options) {
20950
21115
  const hooksDir = resolveGitHooksDir2(repoRoot);
20951
- const hookPath = path22.join(hooksDir, hookName);
20952
- const currentContent = fs23.existsSync(hookPath) ? fs23.readFileSync(hookPath, "utf8") : null;
21116
+ const hookPath = path24.join(hooksDir, hookName);
21117
+ const currentContent = fs25.existsSync(hookPath) ? fs25.readFileSync(hookPath, "utf8") : null;
20953
21118
  const block = buildCollaborationGitHookBlock(hookName);
20954
21119
  const nextContent = mergeManagedCollaborationHookBlock(hookName, currentContent, block);
20955
21120
  const action = currentContent === null ? "created" : currentContent === nextContent ? "unchanged" : "updated";
20956
21121
  if (!options.dryRun && action !== "unchanged") {
20957
- fs23.mkdirSync(hooksDir, { recursive: true });
20958
- fs23.writeFileSync(hookPath, nextContent, "utf8");
20959
- fs23.chmodSync(hookPath, 493);
20960
- } else if (!options.dryRun && fs23.existsSync(hookPath)) {
20961
- fs23.chmodSync(hookPath, fs23.statSync(hookPath).mode | 493);
21122
+ fs25.mkdirSync(hooksDir, { recursive: true });
21123
+ fs25.writeFileSync(hookPath, nextContent, "utf8");
21124
+ fs25.chmodSync(hookPath, 493);
21125
+ } else if (!options.dryRun && fs25.existsSync(hookPath)) {
21126
+ fs25.chmodSync(hookPath, fs25.statSync(hookPath).mode | 493);
20962
21127
  }
20963
21128
  return { hook: hookName, path: hookPath, action, content: nextContent };
20964
21129
  }
@@ -21370,7 +21535,7 @@ function printGuardActionCards(cards) {
21370
21535
  }
21371
21536
  }
21372
21537
  function buildLocalSessionId(context, task, files) {
21373
- const hash = (0, import_node_crypto9.createHash)("sha1").update([context.actor.actorId, context.branch ?? "", task ?? "", files.join(",")].join("\n")).digest("hex").slice(0, 12);
21538
+ const hash = (0, import_node_crypto11.createHash)("sha1").update([context.actor.actorId, context.branch ?? "", task ?? "", files.join(",")].join("\n")).digest("hex").slice(0, 12);
21374
21539
  return `local_${hash}`;
21375
21540
  }
21376
21541
  function normalizeFiles(files) {
@@ -21475,7 +21640,7 @@ function fingerprintReviewOnlyGuardEvaluation(evaluation) {
21475
21640
  workSessionId: conflict.workSessionId ?? null,
21476
21641
  reason: conflict.reason
21477
21642
  })).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
21478
- return (0, import_node_crypto9.createHash)("sha256").update(JSON.stringify(findings)).digest("hex");
21643
+ return (0, import_node_crypto11.createHash)("sha256").update(JSON.stringify(findings)).digest("hex");
21479
21644
  }
21480
21645
  function persistReviewOnlyAcknowledgement(state, profile, action, findingFingerprint, now = /* @__PURE__ */ new Date()) {
21481
21646
  invalidateReviewOnlyAcknowledgements(state, profile, action);
@@ -21554,7 +21719,7 @@ function normalizeResourceId(kind, id) {
21554
21719
  return normalized;
21555
21720
  }
21556
21721
  function normalizeRepoPath3(value) {
21557
- return value.trim().split(path22.sep).join("/").replace(/^\.?\//, "");
21722
+ return value.trim().split(path24.sep).join("/").replace(/^\.?\//, "");
21558
21723
  }
21559
21724
  function normalizeOptionalString3(value) {
21560
21725
  const normalized = typeof value === "string" ? value.trim() : "";
@@ -21601,15 +21766,15 @@ function ensureTrailingNewline3(value) {
21601
21766
  `;
21602
21767
  }
21603
21768
  function sleep2(ms) {
21604
- return new Promise((resolve25) => setTimeout(resolve25, ms));
21769
+ return new Promise((resolve26) => setTimeout(resolve26, ms));
21605
21770
  }
21606
21771
 
21607
21772
  // src/commands/team-sync.ts
21608
- var fs24 = __toESM(require("fs"));
21609
- var path23 = __toESM(require("path"));
21773
+ var fs26 = __toESM(require("fs"));
21774
+ var path25 = __toESM(require("path"));
21610
21775
  var import_node_child_process10 = require("child_process");
21611
- var import_node_crypto10 = require("crypto");
21612
- var TEAM_SYNC_STATE_RELATIVE_PATH = path23.join(".snipara", "team-sync", "session.json");
21776
+ var import_node_crypto12 = require("crypto");
21777
+ var TEAM_SYNC_STATE_RELATIVE_PATH = path25.join(".snipara", "team-sync", "session.json");
21613
21778
  var TEAM_SYNC_STALE_WORK_MS = 48 * 60 * 60 * 1e3;
21614
21779
  var TEAM_SYNC_AUTO_ARCHIVE_WORK_MS = 14 * 24 * 60 * 60 * 1e3;
21615
21780
  function buildTeamSyncStartWorkRecord(input) {
@@ -21813,10 +21978,10 @@ function autoArchiveTeamSyncState(rootDir = process.cwd(), now = /* @__PURE__ */
21813
21978
  }
21814
21979
  function loadTeamSyncState(rootDir = process.cwd()) {
21815
21980
  const statePath = getTeamSyncStatePath(rootDir);
21816
- if (!fs24.existsSync(statePath)) {
21981
+ if (!fs26.existsSync(statePath)) {
21817
21982
  return createEmptyTeamSyncState();
21818
21983
  }
21819
- const parsed = JSON.parse(fs24.readFileSync(statePath, "utf8"));
21984
+ const parsed = JSON.parse(fs26.readFileSync(statePath, "utf8"));
21820
21985
  return {
21821
21986
  schemaVersion: "snipara.team-sync.v1",
21822
21987
  updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString(),
@@ -21826,12 +21991,12 @@ function loadTeamSyncState(rootDir = process.cwd()) {
21826
21991
  }
21827
21992
  function saveTeamSyncState(state, rootDir = process.cwd()) {
21828
21993
  const statePath = getTeamSyncStatePath(rootDir);
21829
- fs24.mkdirSync(path23.dirname(statePath), { recursive: true });
21830
- fs24.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}
21994
+ fs26.mkdirSync(path25.dirname(statePath), { recursive: true });
21995
+ fs26.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}
21831
21996
  `, "utf8");
21832
21997
  }
21833
21998
  function getTeamSyncStatePath(rootDir = process.cwd()) {
21834
- return path23.join(rootDir, TEAM_SYNC_STATE_RELATIVE_PATH);
21999
+ return path25.join(rootDir, TEAM_SYNC_STATE_RELATIVE_PATH);
21835
22000
  }
21836
22001
  async function createTeamSyncStartWorkPayload(rootDir, options) {
21837
22002
  const state = loadTeamSyncState(rootDir);
@@ -22026,12 +22191,12 @@ async function createTeamSyncHandoffPayload(rootDir, options) {
22026
22191
  };
22027
22192
  }
22028
22193
  function readWorkflowSnapshot(rootDir) {
22029
- const statePath = path23.join(rootDir, ".snipara", "workflow", "current.json");
22030
- if (!fs24.existsSync(statePath)) {
22194
+ const statePath = path25.join(rootDir, ".snipara", "workflow", "current.json");
22195
+ if (!fs26.existsSync(statePath)) {
22031
22196
  return void 0;
22032
22197
  }
22033
22198
  try {
22034
- const parsed = JSON.parse(fs24.readFileSync(statePath, "utf8"));
22199
+ const parsed = JSON.parse(fs26.readFileSync(statePath, "utf8"));
22035
22200
  const currentPhaseId = typeof parsed.currentPhaseId === "string" ? parsed.currentPhaseId : void 0;
22036
22201
  const currentPhase = Array.isArray(parsed.phases) ? parsed.phases.find((phase) => phase.id === currentPhaseId) : void 0;
22037
22202
  return {
@@ -22304,7 +22469,7 @@ function redactHandoffText(value, rootDir) {
22304
22469
  let result = value;
22305
22470
  const aliases = /* @__PURE__ */ new Set([rootDir]);
22306
22471
  try {
22307
- aliases.add(fs24.realpathSync(rootDir));
22472
+ aliases.add(fs26.realpathSync(rootDir));
22308
22473
  } catch {
22309
22474
  }
22310
22475
  for (const alias of aliases) {
@@ -22333,21 +22498,21 @@ function sanitizeHandoffArtifact(artifact, rootDir) {
22333
22498
  return sanitizeHandoffValue(artifact, rootDir);
22334
22499
  }
22335
22500
  function canonicalizePathForBoundary(value) {
22336
- let current = path23.resolve(value);
22501
+ let current = path25.resolve(value);
22337
22502
  const suffix = [];
22338
- while (!fs24.existsSync(current)) {
22339
- const parent = path23.dirname(current);
22503
+ while (!fs26.existsSync(current)) {
22504
+ const parent = path25.dirname(current);
22340
22505
  if (parent === current) {
22341
22506
  break;
22342
22507
  }
22343
- suffix.unshift(path23.basename(current));
22508
+ suffix.unshift(path25.basename(current));
22344
22509
  current = parent;
22345
22510
  }
22346
22511
  try {
22347
- current = fs24.realpathSync(current);
22512
+ current = fs26.realpathSync(current);
22348
22513
  } catch {
22349
22514
  }
22350
- return path23.join(current, ...suffix);
22515
+ return path25.join(current, ...suffix);
22351
22516
  }
22352
22517
  function markdownList(values) {
22353
22518
  return values.map((value) => `- ${value}`).join("\n");
@@ -22420,18 +22585,18 @@ function writeAgenticHandoffArtifact(rootDir, output, artifact) {
22420
22585
  if (!output) {
22421
22586
  return void 0;
22422
22587
  }
22423
- const outputPath = path23.resolve(rootDir, output);
22424
- const relative15 = path23.relative(
22588
+ const outputPath = path25.resolve(rootDir, output);
22589
+ const relative15 = path25.relative(
22425
22590
  canonicalizePathForBoundary(rootDir),
22426
22591
  canonicalizePathForBoundary(outputPath)
22427
22592
  );
22428
- if (!relative15 || relative15.startsWith("..") || path23.isAbsolute(relative15) || relative15 === ".git" || relative15.startsWith(`.git${path23.sep}`)) {
22593
+ if (!relative15 || relative15.startsWith("..") || path25.isAbsolute(relative15) || relative15 === ".git" || relative15.startsWith(`.git${path25.sep}`)) {
22429
22594
  throw new Error("Handoff output must stay inside the project directory and outside .git.");
22430
22595
  }
22431
- fs24.mkdirSync(path23.dirname(outputPath), { recursive: true });
22596
+ fs26.mkdirSync(path25.dirname(outputPath), { recursive: true });
22432
22597
  const content = outputPath.toLowerCase().endsWith(".json") ? `${JSON.stringify(artifact, null, 2)}
22433
22598
  ` : buildAgenticHandoffMarkdown(artifact);
22434
- fs24.writeFileSync(outputPath, content, "utf8");
22599
+ fs26.writeFileSync(outputPath, content, "utf8");
22435
22600
  return outputPath;
22436
22601
  }
22437
22602
  async function agenticHandoffCommand(options) {
@@ -23174,7 +23339,7 @@ function readHostedContext(rootDir) {
23174
23339
  };
23175
23340
  }
23176
23341
  function resolveRootDir(dir) {
23177
- return path23.resolve(dir ?? process.cwd());
23342
+ return path25.resolve(dir ?? process.cwd());
23178
23343
  }
23179
23344
  function matchesCompletionEvidence(item, evidence) {
23180
23345
  if (matchesDirectCompletionEvidence(item, evidence)) {
@@ -23393,7 +23558,7 @@ function formatError2(error) {
23393
23558
  return error instanceof Error ? error.message : String(error);
23394
23559
  }
23395
23560
  function buildRecordId(prefix, createdAt, summary, files) {
23396
- const hash = (0, import_node_crypto10.createHash)("sha1").update([createdAt, summary, files.join(",")].join("\n")).digest("hex").slice(0, 10);
23561
+ const hash = (0, import_node_crypto12.createHash)("sha1").update([createdAt, summary, files.join(",")].join("\n")).digest("hex").slice(0, 10);
23397
23562
  return `${prefix}_${hash}`;
23398
23563
  }
23399
23564
 
@@ -24298,12 +24463,12 @@ function printKeyValue(label, value) {
24298
24463
  }
24299
24464
 
24300
24465
  // src/commands/final-commit-report.ts
24301
- var import_node_crypto11 = require("crypto");
24466
+ var import_node_crypto13 = require("crypto");
24302
24467
  var import_node_child_process12 = require("child_process");
24303
- var fs26 = __toESM(require("fs"));
24304
- var path25 = __toESM(require("path"));
24468
+ var fs28 = __toESM(require("fs"));
24469
+ var path27 = __toESM(require("path"));
24305
24470
  var FINAL_COMMIT_REPORT_VERSION = "snipara.final_commit_report.v1";
24306
- var FINAL_COMMIT_REPORT_RELATIVE_PATH = path25.join(
24471
+ var FINAL_COMMIT_REPORT_RELATIVE_PATH = path27.join(
24307
24472
  ".snipara",
24308
24473
  "workflow",
24309
24474
  "final-report.json"
@@ -24445,7 +24610,7 @@ function whyCaptureRationale(receipt) {
24445
24610
  return receipt.previewCandidates.map((candidate) => candidate.rationale).find(Boolean);
24446
24611
  }
24447
24612
  function buildFinalCommitReport(input) {
24448
- const cwd = path25.resolve(input.cwd ?? process.cwd());
24613
+ const cwd = path27.resolve(input.cwd ?? process.cwd());
24449
24614
  const phases = (input.state?.phases ?? []).map((phase) => ({
24450
24615
  id: phase.id,
24451
24616
  title: phase.title,
@@ -24568,18 +24733,18 @@ function buildFinalCommitReport(input) {
24568
24733
  };
24569
24734
  }
24570
24735
  function writeFinalCommitReport(report, cwd = process.cwd()) {
24571
- const outputPath = path25.join(cwd, FINAL_COMMIT_REPORT_RELATIVE_PATH);
24736
+ const outputPath = path27.join(cwd, FINAL_COMMIT_REPORT_RELATIVE_PATH);
24572
24737
  try {
24573
- fs26.mkdirSync(path25.dirname(outputPath), { recursive: true });
24738
+ fs28.mkdirSync(path27.dirname(outputPath), { recursive: true });
24574
24739
  const content = `${JSON.stringify(report, null, 2)}
24575
24740
  `;
24576
- fs26.writeFileSync(outputPath, content, "utf8");
24741
+ fs28.writeFileSync(outputPath, content, "utf8");
24577
24742
  return {
24578
24743
  status: "written",
24579
24744
  version: FINAL_COMMIT_REPORT_VERSION,
24580
24745
  path: outputPath,
24581
24746
  relativePath: FINAL_COMMIT_REPORT_RELATIVE_PATH,
24582
- hash: `sha256:${(0, import_node_crypto11.createHash)("sha256").update(content).digest("hex")}`
24747
+ hash: `sha256:${(0, import_node_crypto13.createHash)("sha256").update(content).digest("hex")}`
24583
24748
  };
24584
24749
  } catch (error) {
24585
24750
  return {
@@ -24651,9 +24816,9 @@ function formatFinalCommitReport(report) {
24651
24816
 
24652
24817
  // src/commands/run.ts
24653
24818
  var import_node_child_process14 = require("child_process");
24654
- var import_node_crypto12 = require("crypto");
24655
- var fs28 = __toESM(require("fs"));
24656
- var path27 = __toESM(require("path"));
24819
+ var import_node_crypto14 = require("crypto");
24820
+ var fs30 = __toESM(require("fs"));
24821
+ var path29 = __toESM(require("path"));
24657
24822
  var import_chalk8 = __toESM(require("chalk"));
24658
24823
 
24659
24824
  // src/commands/intelligence.ts
@@ -26751,7 +26916,7 @@ function buildProjectIntelligenceRunEnvelope(startedAt = /* @__PURE__ */ new Dat
26751
26916
  const codexSessionId = stringValue10(process.env.CODEX_SESSION_ID)?.slice(0, 200);
26752
26917
  return {
26753
26918
  version: "project-intelligence.judgment-run-envelope.v1",
26754
- runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto12.randomUUID)()}`,
26919
+ runId: sniparaSessionId ?? codexSessionId ?? `judgment-run:${(0, import_node_crypto14.randomUUID)()}`,
26755
26920
  identitySource: sniparaSessionId ? "snipara_session" : codexSessionId ? "codex_session" : "generated",
26756
26921
  startedAt: startedAt.toISOString()
26757
26922
  };
@@ -26792,8 +26957,8 @@ function packageReviewCommand3() {
26792
26957
  function readOutcomeReceipts(files) {
26793
26958
  const receipts = [];
26794
26959
  for (const file of normalizeStringList5(files)) {
26795
- const resolved = path27.resolve(process.cwd(), file);
26796
- const parsed = JSON.parse(fs28.readFileSync(resolved, "utf8"));
26960
+ const resolved = path29.resolve(process.cwd(), file);
26961
+ const parsed = JSON.parse(fs30.readFileSync(resolved, "utf8"));
26797
26962
  receipts.push(...outcomeReceiptsFromUnknown(parsed));
26798
26963
  }
26799
26964
  return receipts;
@@ -27693,12 +27858,12 @@ async function projectIntelligenceRunCommand(options) {
27693
27858
  }
27694
27859
 
27695
27860
  // src/commands/agent-context.ts
27696
- var fs29 = __toESM(require("fs"));
27697
- var path28 = __toESM(require("path"));
27861
+ var fs31 = __toESM(require("fs"));
27862
+ var path30 = __toESM(require("path"));
27698
27863
  var AGENT_CONTEXT_MANIFEST_DEFAULT_PATH = "snipara.agent-context.json";
27699
27864
  function readManifest2(manifestPath2) {
27700
27865
  try {
27701
- return JSON.parse(fs29.readFileSync(manifestPath2, "utf8"));
27866
+ return JSON.parse(fs31.readFileSync(manifestPath2, "utf8"));
27702
27867
  } catch (error) {
27703
27868
  const message = error instanceof Error ? error.message : String(error);
27704
27869
  throw new Error(`Unable to read Agent Context manifest ${manifestPath2}: ${message}`);
@@ -27714,15 +27879,15 @@ function localSourceFinding(sourceId, sourcePath, summary) {
27714
27879
  };
27715
27880
  }
27716
27881
  function buildLocalAgentContextValidationReport(options) {
27717
- const cwd = path28.resolve(options.cwd ?? process.cwd());
27882
+ const cwd = path30.resolve(options.cwd ?? process.cwd());
27718
27883
  const report = validateAgentContextManifest({
27719
27884
  manifest: options.manifest,
27720
27885
  generatedAt: options.generatedAt
27721
27886
  });
27722
27887
  if (!report.manifest) return report;
27723
27888
  const localFindings = report.manifest.sources.flatMap((source2) => {
27724
- const absolutePath = path28.resolve(cwd, source2.path);
27725
- if (!fs29.existsSync(absolutePath)) {
27889
+ const absolutePath = path30.resolve(cwd, source2.path);
27890
+ if (!fs31.existsSync(absolutePath)) {
27726
27891
  return [
27727
27892
  localSourceFinding(
27728
27893
  source2.id,
@@ -27731,7 +27896,7 @@ function buildLocalAgentContextValidationReport(options) {
27731
27896
  )
27732
27897
  ];
27733
27898
  }
27734
- if (!fs29.statSync(absolutePath).isFile()) {
27899
+ if (!fs31.statSync(absolutePath).isFile()) {
27735
27900
  return [
27736
27901
  localSourceFinding(
27737
27902
  source2.id,
@@ -27750,10 +27915,10 @@ function buildLocalAgentContextValidationReport(options) {
27750
27915
  };
27751
27916
  }
27752
27917
  function manifestPath(cwd, candidate) {
27753
- return path28.resolve(cwd, candidate ?? AGENT_CONTEXT_MANIFEST_DEFAULT_PATH);
27918
+ return path30.resolve(cwd, candidate ?? AGENT_CONTEXT_MANIFEST_DEFAULT_PATH);
27754
27919
  }
27755
27920
  function resolveLocalAgentContext(options) {
27756
- const cwd = path28.resolve(options.cwd ?? process.cwd());
27921
+ const cwd = path30.resolve(options.cwd ?? process.cwd());
27757
27922
  const resolvedManifestPath = manifestPath(cwd, options.manifest);
27758
27923
  const manifest = readManifest2(resolvedManifestPath);
27759
27924
  const validation = buildLocalAgentContextValidationReport({ cwd, manifest });
@@ -27762,7 +27927,7 @@ function resolveLocalAgentContext(options) {
27762
27927
  throw new Error(`Invalid Agent Context manifest. ${errors}`.trim());
27763
27928
  }
27764
27929
  return {
27765
- manifestPath: path28.relative(cwd, resolvedManifestPath) || path28.basename(resolvedManifestPath),
27930
+ manifestPath: path30.relative(cwd, resolvedManifestPath) || path30.basename(resolvedManifestPath),
27766
27931
  resolution: resolveAgentContext({
27767
27932
  manifest,
27768
27933
  agent: options.agent,
@@ -27838,14 +28003,14 @@ function formatAgentContextResolution(resolution) {
27838
28003
  return lines.join("\n");
27839
28004
  }
27840
28005
  async function agentContextValidateCommand(options = {}) {
27841
- const cwd = path28.resolve(options.cwd ?? process.cwd());
28006
+ const cwd = path30.resolve(options.cwd ?? process.cwd());
27842
28007
  const resolvedManifestPath = manifestPath(cwd, options.manifest);
27843
28008
  const report = buildLocalAgentContextValidationReport({
27844
28009
  cwd,
27845
28010
  manifest: readManifest2(resolvedManifestPath)
27846
28011
  });
27847
28012
  console.log(
27848
- options.json ? stableDecisionJsonStringify(report) : formatValidationReport(report, path28.relative(cwd, resolvedManifestPath))
28013
+ options.json ? stableDecisionJsonStringify(report) : formatValidationReport(report, path30.relative(cwd, resolvedManifestPath))
27849
28014
  );
27850
28015
  if (report.status === "invalid") {
27851
28016
  process.exitCode = 1;
@@ -27882,7 +28047,7 @@ var FINAL_COMMIT_SUMMARY_MAX_CHARS = 1200;
27882
28047
  var FINAL_COMMIT_RETRY_SUMMARY_MAX_CHARS = 600;
27883
28048
  var DEFAULT_ADAPTIVE_ROUTING_CATALOG_LIMIT = 20;
27884
28049
  var DEFAULT_LOCAL_ORCHESTRATOR_TIMEOUT_MS = 8e3;
27885
- var ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2 = path29.join(".snipara", "adaptive-routing.json");
28050
+ var ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2 = path31.join(".snipara", "adaptive-routing.json");
27886
28051
  var MEMORY_DECISION_PRODUCER_ACTIONS = /* @__PURE__ */ new Set([
27887
28052
  "accept",
27888
28053
  "reject",
@@ -27953,11 +28118,11 @@ var REUPLOAD_REASONS = /* @__PURE__ */ new Set([
27953
28118
  "source_modified_after_upload",
27954
28119
  "source_hash_changed"
27955
28120
  ]);
27956
- var WORKFLOW_STATE_RELATIVE_PATH = path29.join(".snipara", "workflow", "current.json");
27957
- var WORKFLOW_PLANS_RELATIVE_DIR = path29.join(".snipara", "workflow", "plans");
28121
+ var WORKFLOW_STATE_RELATIVE_PATH = path31.join(".snipara", "workflow", "current.json");
28122
+ var WORKFLOW_PLANS_RELATIVE_DIR = path31.join(".snipara", "workflow", "plans");
27958
28123
  var PRODUCER_LOOP_ARTIFACT_VERSION = "snipara.producer_loop_artifact.v0";
27959
28124
  var PRODUCER_LOOP_REPORT_VERSION = "snipara.producer_loop_report.v0";
27960
- var PRODUCER_LOOP_RELATIVE_DIR = path29.join(".snipara", "producer-loop");
28125
+ var PRODUCER_LOOP_RELATIVE_DIR = path31.join(".snipara", "producer-loop");
27961
28126
  var PRODUCER_LOOP_MIN_REVIEW_SAMPLE_SIZE = 5;
27962
28127
  var WORKFLOW_PLAN_PRESET_IDS = [
27963
28128
  "memory-backend-unification",
@@ -28049,7 +28214,7 @@ function parseJsonRecord(value, label) {
28049
28214
  return parsed;
28050
28215
  }
28051
28216
  function readJsonRecord3(file, label) {
28052
- return parseJsonRecord(fs30.readFileSync(file, "utf-8"), label);
28217
+ return parseJsonRecord(fs32.readFileSync(file, "utf-8"), label);
28053
28218
  }
28054
28219
  function parseCsv(value) {
28055
28220
  if (!value) {
@@ -28093,7 +28258,7 @@ function optionalReindexMode(value) {
28093
28258
  return value === "incremental" || value === "full" ? value : void 0;
28094
28259
  }
28095
28260
  function inferDocumentFormat(filePath) {
28096
- return DOCUMENT_SYNC_FORMATS[path29.extname(filePath).toLowerCase()];
28261
+ return DOCUMENT_SYNC_FORMATS[path31.extname(filePath).toLowerCase()];
28097
28262
  }
28098
28263
  function normalizeDocumentKind(value) {
28099
28264
  const normalized = normalizeEnum(value);
@@ -28126,7 +28291,7 @@ function contentBufferForHash(content) {
28126
28291
  return Buffer.from(content, "utf8");
28127
28292
  }
28128
28293
  function hashContent(content) {
28129
- return (0, import_node_crypto13.createHash)("sha256").update(contentBufferForHash(content)).digest("hex");
28294
+ return (0, import_node_crypto15.createHash)("sha256").update(contentBufferForHash(content)).digest("hex");
28130
28295
  }
28131
28296
  function toPreview(value, maxLength = 160) {
28132
28297
  if (typeof value === "string") {
@@ -28373,7 +28538,7 @@ function buildPlanRelevanceWarnings(plan, options) {
28373
28538
  if (/^(?:https?:)?\/\//i.test(fileHint)) {
28374
28539
  return false;
28375
28540
  }
28376
- return !fs30.existsSync(path29.resolve(options.cwd, fileHint));
28541
+ return !fs32.existsSync(path31.resolve(options.cwd, fileHint));
28377
28542
  });
28378
28543
  if (missingHints.length > 0) {
28379
28544
  warnings.push(
@@ -28934,12 +29099,12 @@ function buildGeneratedWorkflowPlanDocument(plan, fallbackGoal) {
28934
29099
  }
28935
29100
  function defaultGeneratedPlanFilePath(query) {
28936
29101
  const filename = `${sanitizeWorkflowId(query, "snipara-plan")}-plan.json`;
28937
- return path29.join(process.cwd(), WORKFLOW_PLANS_RELATIVE_DIR, filename);
29102
+ return path31.join(process.cwd(), WORKFLOW_PLANS_RELATIVE_DIR, filename);
28938
29103
  }
28939
29104
  function writeGeneratedWorkflowPlanFile(plan, fallbackGoal, outputFile) {
28940
- const outputPath = path29.resolve(outputFile ?? defaultGeneratedPlanFilePath(fallbackGoal));
28941
- fs30.mkdirSync(path29.dirname(outputPath), { recursive: true });
28942
- fs30.writeFileSync(
29105
+ const outputPath = path31.resolve(outputFile ?? defaultGeneratedPlanFilePath(fallbackGoal));
29106
+ fs32.mkdirSync(path31.dirname(outputPath), { recursive: true });
29107
+ fs32.writeFileSync(
28943
29108
  outputPath,
28944
29109
  `${JSON.stringify(buildGeneratedWorkflowPlanDocument(plan, fallbackGoal), null, 2)}
28945
29110
  `,
@@ -28947,7 +29112,7 @@ function writeGeneratedWorkflowPlanFile(plan, fallbackGoal, outputFile) {
28947
29112
  );
28948
29113
  return {
28949
29114
  path: outputPath,
28950
- relativePath: path29.relative(process.cwd(), outputPath) || path29.basename(outputPath)
29115
+ relativePath: path31.relative(process.cwd(), outputPath) || path31.basename(outputPath)
28951
29116
  };
28952
29117
  }
28953
29118
  function booleanValue4(value) {
@@ -29364,15 +29529,15 @@ function buildWorkflowPlanPresetDocument(preset, goal) {
29364
29529
  }
29365
29530
  }
29366
29531
  function defaultWorkflowPlanOutputPath(preset, cwd = process.cwd()) {
29367
- return path29.resolve(cwd, WORKFLOW_PLANS_RELATIVE_DIR, `${preset}-plan.json`);
29532
+ return path31.resolve(cwd, WORKFLOW_PLANS_RELATIVE_DIR, `${preset}-plan.json`);
29368
29533
  }
29369
29534
  function toProjectRelativePath3(absolutePath, cwd = process.cwd()) {
29370
- const relative15 = path29.relative(cwd, absolutePath);
29535
+ const relative15 = path31.relative(cwd, absolutePath);
29371
29536
  return relative15 && !relative15.startsWith("..") ? relative15 : absolutePath;
29372
29537
  }
29373
29538
  function buildWorkflowPlanScaffold(preset, options = {}) {
29374
- const cwd = path29.resolve(options.cwd ?? process.cwd());
29375
- const outputPath = path29.resolve(options.outputPath ?? defaultWorkflowPlanOutputPath(preset, cwd));
29539
+ const cwd = path31.resolve(options.cwd ?? process.cwd());
29540
+ const outputPath = path31.resolve(options.outputPath ?? defaultWorkflowPlanOutputPath(preset, cwd));
29376
29541
  const plan = buildWorkflowPlanPresetDocument(preset, options.goal);
29377
29542
  return {
29378
29543
  preset,
@@ -29383,18 +29548,18 @@ function buildWorkflowPlanScaffold(preset, options = {}) {
29383
29548
  };
29384
29549
  }
29385
29550
  function readWorkflowPlanFile(planFile, fallbackGoal) {
29386
- const content = fs30.readFileSync(planFile, "utf-8");
29551
+ const content = fs32.readFileSync(planFile, "utf-8");
29387
29552
  if (planFile.toLowerCase().endsWith(".json")) {
29388
29553
  return normalizeWorkflowPlanInput(JSON.parse(content), fallbackGoal);
29389
29554
  }
29390
29555
  return normalizeWorkflowPlanInput(content, fallbackGoal);
29391
29556
  }
29392
29557
  function readWorkflowPlanMode(planFile) {
29393
- if (!planFile || !planFile.toLowerCase().endsWith(".json") || !fs30.existsSync(planFile)) {
29558
+ if (!planFile || !planFile.toLowerCase().endsWith(".json") || !fs32.existsSync(planFile)) {
29394
29559
  return void 0;
29395
29560
  }
29396
29561
  try {
29397
- const parsed = JSON.parse(fs30.readFileSync(planFile, "utf-8"));
29562
+ const parsed = JSON.parse(fs32.readFileSync(planFile, "utf-8"));
29398
29563
  return normalizeWorkflowCoordinationMode(parsed.mode);
29399
29564
  } catch {
29400
29565
  return void 0;
@@ -29411,7 +29576,7 @@ function inferWorkflowCoordinationMode(options) {
29411
29576
  return readWorkflowPlanMode(options.planFile) ?? (options.planFile ? "full" : "standard");
29412
29577
  }
29413
29578
  function getWorkflowStatePath(cwd = process.cwd()) {
29414
- return path29.join(cwd, WORKFLOW_STATE_RELATIVE_PATH);
29579
+ return path31.join(cwd, WORKFLOW_STATE_RELATIVE_PATH);
29415
29580
  }
29416
29581
  function normalizeManagedWorkflowTaskState(task, phase, index, fallbackStatus) {
29417
29582
  const status = normalizeTaskStatus(task.status ?? fallbackStatus);
@@ -29542,10 +29707,10 @@ function normalizeManagedWorkflowRuntimeState(runtime) {
29542
29707
  }
29543
29708
  function readWorkflowState2(cwd = process.cwd()) {
29544
29709
  const statePath = getWorkflowStatePath(cwd);
29545
- if (!fs30.existsSync(statePath)) {
29710
+ if (!fs32.existsSync(statePath)) {
29546
29711
  return void 0;
29547
29712
  }
29548
- const parsed = JSON.parse(fs30.readFileSync(statePath, "utf-8"));
29713
+ const parsed = JSON.parse(fs32.readFileSync(statePath, "utf-8"));
29549
29714
  if (!Array.isArray(parsed.phases)) {
29550
29715
  throw new Error(`${WORKFLOW_STATE_RELATIVE_PATH} is not a valid Snipara workflow state file`);
29551
29716
  }
@@ -29562,14 +29727,14 @@ function readRequiredWorkflowState() {
29562
29727
  }
29563
29728
  function writeWorkflowState(state) {
29564
29729
  const statePath = getWorkflowStatePath();
29565
- fs30.mkdirSync(path29.dirname(statePath), { recursive: true });
29730
+ fs32.mkdirSync(path31.dirname(statePath), { recursive: true });
29566
29731
  const normalizedState = normalizeManagedWorkflowState(state);
29567
29732
  const normalized = {
29568
29733
  ...normalizedState,
29569
29734
  schemaVersion: "snipara.workflow.v2",
29570
29735
  runtime: normalizeManagedWorkflowRuntimeState(normalizedState.runtime)
29571
29736
  };
29572
- fs30.writeFileSync(statePath, `${JSON.stringify(normalized, null, 2)}
29737
+ fs32.writeFileSync(statePath, `${JSON.stringify(normalized, null, 2)}
29573
29738
  `, "utf-8");
29574
29739
  }
29575
29740
  function sortJsonValue4(value) {
@@ -29592,7 +29757,7 @@ function hashJsonValue(value) {
29592
29757
  return `sha256:${hashContent(stableJsonStringify(value))}`;
29593
29758
  }
29594
29759
  function getProducerLoopDir(cwd = process.cwd()) {
29595
- return path29.join(cwd, PRODUCER_LOOP_RELATIVE_DIR);
29760
+ return path31.join(cwd, PRODUCER_LOOP_RELATIVE_DIR);
29596
29761
  }
29597
29762
  function buildProducerLoopArtifactId(options) {
29598
29763
  const source2 = [
@@ -29705,9 +29870,9 @@ function writeProducerLoopArtifact(options) {
29705
29870
  const artifact = buildProducerLoopArtifact(options);
29706
29871
  const artifactHash = hashJsonValue(artifact);
29707
29872
  const fileName = `${artifact.generatedAt.replace(/[:.]/g, "-")}-${artifact.artifactId}.json`;
29708
- const outputPath = path29.join(getProducerLoopDir(), fileName);
29709
- fs30.mkdirSync(path29.dirname(outputPath), { recursive: true });
29710
- fs30.writeFileSync(outputPath, stableJsonStringify(artifact), "utf-8");
29873
+ const outputPath = path31.join(getProducerLoopDir(), fileName);
29874
+ fs32.mkdirSync(path31.dirname(outputPath), { recursive: true });
29875
+ fs32.writeFileSync(outputPath, stableJsonStringify(artifact), "utf-8");
29711
29876
  return {
29712
29877
  status: "written",
29713
29878
  schemaVersion: PRODUCER_LOOP_ARTIFACT_VERSION,
@@ -29760,7 +29925,7 @@ function stringArrayValue(value) {
29760
29925
  function summarizeProducerLoopArtifactFile(filePath, cwd) {
29761
29926
  const relativePath2 = toProjectRelativePath3(filePath, cwd);
29762
29927
  try {
29763
- const content = fs30.readFileSync(filePath, "utf-8");
29928
+ const content = fs32.readFileSync(filePath, "utf-8");
29764
29929
  const parsed = JSON.parse(content);
29765
29930
  if (!isRecord19(parsed)) {
29766
29931
  throw new Error("artifact must be a JSON object");
@@ -29826,10 +29991,10 @@ function summarizeProducerLoopArtifactFile(filePath, cwd) {
29826
29991
  }
29827
29992
  function listProducerLoopArtifactFiles(cwd) {
29828
29993
  const dir = getProducerLoopDir(cwd);
29829
- if (!fs30.existsSync(dir)) {
29994
+ if (!fs32.existsSync(dir)) {
29830
29995
  return [];
29831
29996
  }
29832
- return fs30.readdirSync(dir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path29.join(dir, fileName)).sort();
29997
+ return fs32.readdirSync(dir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => path31.join(dir, fileName)).sort();
29833
29998
  }
29834
29999
  function producerLoopCalibrationStatus(sampleSize, reviewedSampleSize, minReviewSampleSize) {
29835
30000
  if (sampleSize === 0) {
@@ -29840,8 +30005,8 @@ function producerLoopCalibrationStatus(sampleSize, reviewedSampleSize, minReview
29840
30005
  }
29841
30006
  return "reviewable_sample_set";
29842
30007
  }
29843
- var WORKER_RECEIPT_RELATIVE_DIR = path29.join(".snipara", "orchestrator", "executions");
29844
- var WORKER_REVIEW_RELATIVE_DIR = path29.join(".snipara", "orchestrator", "reviews");
30008
+ var WORKER_RECEIPT_RELATIVE_DIR = path31.join(".snipara", "orchestrator", "executions");
30009
+ var WORKER_REVIEW_RELATIVE_DIR = path31.join(".snipara", "orchestrator", "reviews");
29845
30010
  var REQUIRED_WORKER_RECEIPT_FAMILIES = [
29846
30011
  "handoffReceiptId",
29847
30012
  "claimId",
@@ -29850,18 +30015,18 @@ var REQUIRED_WORKER_RECEIPT_FAMILIES = [
29850
30015
  "brainUpdateReceiptId"
29851
30016
  ];
29852
30017
  function listJsonFiles(relativeDir, cwd) {
29853
- const directory = path29.join(cwd, relativeDir);
29854
- if (!fs30.existsSync(directory)) {
30018
+ const directory = path31.join(cwd, relativeDir);
30019
+ if (!fs32.existsSync(directory)) {
29855
30020
  return [];
29856
30021
  }
29857
- return fs30.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => path29.join(directory, entry.name)).sort();
30022
+ return fs32.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => path31.join(directory, entry.name)).sort();
29858
30023
  }
29859
30024
  function readWorkerReviewFiles(cwd) {
29860
30025
  const reviews = /* @__PURE__ */ new Map();
29861
30026
  const invalid = [];
29862
30027
  for (const filePath of listJsonFiles(WORKER_REVIEW_RELATIVE_DIR, cwd)) {
29863
30028
  try {
29864
- const parsed = JSON.parse(fs30.readFileSync(filePath, "utf-8"));
30029
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
29865
30030
  if (!isRecord19(parsed)) {
29866
30031
  throw new Error("review must be a JSON object");
29867
30032
  }
@@ -29893,7 +30058,7 @@ function summarizeWorkerExecutionReceipts(cwd) {
29893
30058
  const samples = [];
29894
30059
  for (const filePath of listJsonFiles(WORKER_RECEIPT_RELATIVE_DIR, cwd)) {
29895
30060
  try {
29896
- const parsed = JSON.parse(fs30.readFileSync(filePath, "utf-8"));
30061
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
29897
30062
  if (!isRecord19(parsed)) {
29898
30063
  throw new Error("receipt must be a JSON object");
29899
30064
  }
@@ -29989,7 +30154,7 @@ function buildWorkerTrustRows(samples, minReviewSampleSize) {
29989
30154
  );
29990
30155
  }
29991
30156
  function buildProducerLoopReport(options = {}) {
29992
- const cwd = path29.resolve(options.cwd ?? process.cwd());
30157
+ const cwd = path31.resolve(options.cwd ?? process.cwd());
29993
30158
  const minReviewSampleSize = Math.max(
29994
30159
  1,
29995
30160
  Math.floor(options.minReviewSampleSize ?? PRODUCER_LOOP_MIN_REVIEW_SAMPLE_SIZE)
@@ -30110,22 +30275,22 @@ function resolveProducerLoopReviewTarget(cwd, selector, latest) {
30110
30275
  return latestArtifact.path;
30111
30276
  }
30112
30277
  const directCandidates = [
30113
- path29.resolve(cwd, normalizedSelector),
30114
- path29.resolve(cwd, PRODUCER_LOOP_RELATIVE_DIR, normalizedSelector)
30278
+ path31.resolve(cwd, normalizedSelector),
30279
+ path31.resolve(cwd, PRODUCER_LOOP_RELATIVE_DIR, normalizedSelector)
30115
30280
  ];
30116
- const directMatch = directCandidates.find((candidate) => fs30.existsSync(candidate));
30281
+ const directMatch = directCandidates.find((candidate) => fs32.existsSync(candidate));
30117
30282
  if (directMatch) {
30118
30283
  return directMatch;
30119
30284
  }
30120
30285
  const normalizedPathSelector = normalizedSelector.replace(/\\/g, "/").replace(/^\.\//, "");
30121
30286
  const matches = files.filter((filePath) => {
30122
30287
  const relativePath2 = toProjectRelativePath3(filePath, cwd).replace(/\\/g, "/");
30123
- const basename12 = path29.basename(filePath);
30288
+ const basename12 = path31.basename(filePath);
30124
30289
  if (basename12 === normalizedSelector || relativePath2 === normalizedPathSelector || relativePath2.replace(/^\.\//, "") === normalizedPathSelector) {
30125
30290
  return true;
30126
30291
  }
30127
30292
  try {
30128
- const parsed = JSON.parse(fs30.readFileSync(filePath, "utf-8"));
30293
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
30129
30294
  return isRecord19(parsed) && stringValue11(parsed.artifactId) === normalizedSelector;
30130
30295
  } catch {
30131
30296
  return false;
@@ -30142,7 +30307,7 @@ function resolveProducerLoopReviewTarget(cwd, selector, latest) {
30142
30307
  return matches[0];
30143
30308
  }
30144
30309
  function readProducerLoopArtifactForReview(filePath) {
30145
- const parsed = JSON.parse(fs30.readFileSync(filePath, "utf-8"));
30310
+ const parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
30146
30311
  if (!isRecord19(parsed)) {
30147
30312
  throw new Error("artifact must be a JSON object");
30148
30313
  }
@@ -30197,7 +30362,7 @@ function applyProducerLoopArtifactReview(artifact, options) {
30197
30362
  };
30198
30363
  }
30199
30364
  function reviewProducerLoopArtifact(options) {
30200
- const cwd = path29.resolve(options.cwd ?? process.cwd());
30365
+ const cwd = path31.resolve(options.cwd ?? process.cwd());
30201
30366
  const targetPath = resolveProducerLoopReviewTarget(cwd, options.artifact, options.latest);
30202
30367
  const artifact = readProducerLoopArtifactForReview(targetPath);
30203
30368
  const rawOutcome = stringValue11(options.outcome);
@@ -30217,8 +30382,8 @@ function reviewProducerLoopArtifact(options) {
30217
30382
  ...outcome ? { outcome } : {},
30218
30383
  notes: options.notes ?? []
30219
30384
  });
30220
- fs30.writeFileSync(targetPath, stableJsonStringify(reviewed), "utf-8");
30221
- const content = fs30.readFileSync(targetPath, "utf-8");
30385
+ fs32.writeFileSync(targetPath, stableJsonStringify(reviewed), "utf-8");
30386
+ const content = fs32.readFileSync(targetPath, "utf-8");
30222
30387
  return {
30223
30388
  status: "reviewed",
30224
30389
  schemaVersion: PRODUCER_LOOP_ARTIFACT_VERSION,
@@ -30967,8 +31132,8 @@ async function workflowScaffoldCommand(options) {
30967
31132
  goal: options.goal,
30968
31133
  outputPath: options.output
30969
31134
  });
30970
- fs30.mkdirSync(path29.dirname(scaffold.outputPath), { recursive: true });
30971
- fs30.writeFileSync(`${scaffold.outputPath}`, `${JSON.stringify(scaffold.plan, null, 2)}
31135
+ fs32.mkdirSync(path31.dirname(scaffold.outputPath), { recursive: true });
31136
+ fs32.writeFileSync(`${scaffold.outputPath}`, `${JSON.stringify(scaffold.plan, null, 2)}
30972
31137
  `, "utf8");
30973
31138
  if (options.json) {
30974
31139
  printJson2({
@@ -31062,17 +31227,17 @@ function nextEligibleWorkflowTask(state, phase) {
31062
31227
  }
31063
31228
  var DEFAULT_AGENT_CONTEXT_AGENT = "snipara-code";
31064
31229
  function agentContextManifestConfig(cwd = process.cwd()) {
31065
- const manifestPath2 = path29.resolve(cwd, "snipara.agent-context.json");
31066
- if (!fs30.existsSync(manifestPath2)) return void 0;
31230
+ const manifestPath2 = path31.resolve(cwd, "snipara.agent-context.json");
31231
+ if (!fs32.existsSync(manifestPath2)) return void 0;
31067
31232
  try {
31068
- const parsed = JSON.parse(fs30.readFileSync(manifestPath2, "utf8"));
31233
+ const parsed = JSON.parse(fs32.readFileSync(manifestPath2, "utf8"));
31069
31234
  const agentId = process.env.SNIPARA_AGENT_ID?.trim() || DEFAULT_AGENT_CONTEXT_AGENT;
31070
31235
  if (!parsed.agents || !Object.prototype.hasOwnProperty.call(parsed.agents, agentId)) {
31071
31236
  return void 0;
31072
31237
  }
31073
31238
  return {
31074
31239
  agentId,
31075
- manifest: path29.relative(cwd, manifestPath2) || path29.basename(manifestPath2)
31240
+ manifest: path31.relative(cwd, manifestPath2) || path31.basename(manifestPath2)
31076
31241
  };
31077
31242
  } catch {
31078
31243
  return void 0;
@@ -31245,7 +31410,7 @@ function findSandboxRuntimeBinding(state, phaseId) {
31245
31410
  function defaultSandboxSessionId(state, phase) {
31246
31411
  const workflowSlug = sanitizeWorkflowId(state.workflowId, "workflow").slice(0, 24);
31247
31412
  const phaseSlug = sanitizeWorkflowId(phase.id, "phase").slice(0, 24);
31248
- const digest = (0, import_node_crypto13.createHash)("sha1").update(`${state.workflowId}:${phase.id}`).digest("hex").slice(0, 10);
31413
+ const digest = (0, import_node_crypto15.createHash)("sha1").update(`${state.workflowId}:${phase.id}`).digest("hex").slice(0, 10);
31249
31414
  return `sandbox-${workflowSlug}-${phaseSlug}-${digest}`.slice(0, 96);
31250
31415
  }
31251
31416
  function ensureSandboxRuntimeBinding(state, phase, now) {
@@ -31806,10 +31971,10 @@ function readGitNulList(args, cwd) {
31806
31971
  return output.split("\0").map((item) => item.trim()).filter(Boolean);
31807
31972
  }
31808
31973
  function readGitRepoRoot(cwd = process.cwd()) {
31809
- return path29.resolve(runGitText(["rev-parse", "--show-toplevel"], cwd) ?? cwd);
31974
+ return path31.resolve(runGitText(["rev-parse", "--show-toplevel"], cwd) ?? cwd);
31810
31975
  }
31811
31976
  function normalizeRepoFilePath(value) {
31812
- return value.split(path29.sep).join("/").replace(/^\/+/, "");
31977
+ return value.split(path31.sep).join("/").replace(/^\/+/, "");
31813
31978
  }
31814
31979
  function resolveWorkflowImpactBaseRef(repoRoot, base) {
31815
31980
  const explicitBase = base?.trim();
@@ -31868,7 +32033,7 @@ function parseDirtyFileFromStatusLine(line) {
31868
32033
  return renamedPath ? normalizeRepoFilePath(renamedPath.replace(/^"|"$/g, "")) : void 0;
31869
32034
  }
31870
32035
  function isLocalImpactCodeFile(filePath) {
31871
- return [".ts", ".tsx", ".mts", ".cts", ".py", ".pyi", ".go"].includes(path29.extname(filePath));
32036
+ return [".ts", ".tsx", ".mts", ".cts", ".py", ".pyi", ".go"].includes(path31.extname(filePath));
31872
32037
  }
31873
32038
  function completedWorkflowPhasesForImpact(state, changedFiles) {
31874
32039
  const changedFileSet = new Set(changedFiles);
@@ -32787,12 +32952,12 @@ function readLocalAdaptiveRoutingProjectPolicy() {
32787
32952
  if (!workspaceRoot2) {
32788
32953
  return null;
32789
32954
  }
32790
- const policyPath = path29.join(workspaceRoot2, ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2);
32791
- if (!fs30.existsSync(policyPath)) {
32955
+ const policyPath = path31.join(workspaceRoot2, ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2);
32956
+ if (!fs32.existsSync(policyPath)) {
32792
32957
  return null;
32793
32958
  }
32794
32959
  try {
32795
- const parsed = JSON.parse(fs30.readFileSync(policyPath, "utf8"));
32960
+ const parsed = JSON.parse(fs32.readFileSync(policyPath, "utf8"));
32796
32961
  if (!isRecord19(parsed)) {
32797
32962
  return null;
32798
32963
  }
@@ -33261,8 +33426,8 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
33261
33426
  };
33262
33427
  }
33263
33428
  }
33264
- function printUploadResult(path44, result) {
33265
- printKeyValue2("Uploaded:", path44);
33429
+ function printUploadResult(path46, result) {
33430
+ printKeyValue2("Uploaded:", path46);
33266
33431
  printCompactObject(result, ["message", "document_id", "documentId", "version", "status"]);
33267
33432
  console.log("");
33268
33433
  printJson2(result);
@@ -33607,9 +33772,9 @@ function printOrchestrateResult(result) {
33607
33772
  }
33608
33773
  printJson2(result);
33609
33774
  }
33610
- function printLoadDocumentResult(path44, result) {
33775
+ function printLoadDocumentResult(path46, result) {
33611
33776
  printKeyValue2("Tool:", "snipara_load_document");
33612
- printKeyValue2("Path:", path44);
33777
+ printKeyValue2("Path:", path46);
33613
33778
  console.log("");
33614
33779
  if (typeof result === "string") {
33615
33780
  console.log(result.trim());
@@ -33749,7 +33914,7 @@ async function uploadCommand(options) {
33749
33914
  const inferred = inferDocumentFormat(options.path) ?? (options.file ? inferDocumentFormat(options.file) : void 0);
33750
33915
  const kind = normalizeDocumentKind(options.kind) ?? inferred?.kind;
33751
33916
  const format = normalizeDocumentFormat(options.format) ?? inferred?.format;
33752
- const content = options.content ?? (options.file ? kind === "BINARY" ? `base64:${fs30.readFileSync(options.file).toString("base64")}` : fs30.readFileSync(options.file, "utf-8") : void 0);
33917
+ const content = options.content ?? (options.file ? kind === "BINARY" ? `base64:${fs32.readFileSync(options.file).toString("base64")}` : fs32.readFileSync(options.file, "utf-8") : void 0);
33753
33918
  if (!content) {
33754
33919
  throw new Error("Provide either --content or --file");
33755
33920
  }
@@ -33825,7 +33990,7 @@ async function businessCollectionEnsureCommand(options) {
33825
33990
  }
33826
33991
  async function businessCollectionUploadCommand(options) {
33827
33992
  ensureConfigured();
33828
- const content = options.content ?? (options.file ? fs30.readFileSync(options.file, "utf-8") : void 0);
33993
+ const content = options.content ?? (options.file ? fs32.readFileSync(options.file, "utf-8") : void 0);
33829
33994
  if (!content) {
33830
33995
  throw new Error("Provide either --content or --file");
33831
33996
  }
@@ -33937,30 +34102,30 @@ function normalizeSyncDocumentsPayload(payload) {
33937
34102
  };
33938
34103
  }
33939
34104
  function toUploadPath(filePath, rootDir, prefix) {
33940
- const relative15 = path29.relative(rootDir, filePath).split(path29.sep).join("/");
34105
+ const relative15 = path31.relative(rootDir, filePath).split(path31.sep).join("/");
33941
34106
  const trimmedPrefix = prefix?.replace(/^\/+|\/+$/g, "");
33942
34107
  return trimmedPrefix ? `${trimmedPrefix}/${relative15}` : relative15;
33943
34108
  }
33944
34109
  function collectDirectoryDocuments(options) {
33945
- const rootDir = path29.resolve(options.dir);
34110
+ const rootDir = path31.resolve(options.dir);
33946
34111
  const documents = [];
33947
34112
  function visit(directory) {
33948
- for (const entry of fs30.readdirSync(directory, { withFileTypes: true })) {
33949
- const entryPath = path29.join(directory, entry.name);
34113
+ for (const entry of fs32.readdirSync(directory, { withFileTypes: true })) {
34114
+ const entryPath = path31.join(directory, entry.name);
33950
34115
  if (entry.isDirectory()) {
33951
34116
  if (options.recursive) {
33952
34117
  visit(entryPath);
33953
34118
  }
33954
34119
  continue;
33955
34120
  }
33956
- if (!entry.isFile() || !DEFAULT_SYNC_EXTENSIONS.has(path29.extname(entry.name).toLowerCase())) {
34121
+ if (!entry.isFile() || !DEFAULT_SYNC_EXTENSIONS.has(path31.extname(entry.name).toLowerCase())) {
33957
34122
  continue;
33958
34123
  }
33959
34124
  const documentFormat = inferDocumentFormat(entry.name);
33960
34125
  if (!documentFormat) {
33961
34126
  continue;
33962
34127
  }
33963
- const rawContent = fs30.readFileSync(entryPath);
34128
+ const rawContent = fs32.readFileSync(entryPath);
33964
34129
  const content = documentFormat.kind === "BINARY" ? `base64:${rawContent.toString("base64")}` : rawContent.toString("utf-8");
33965
34130
  documents.push({
33966
34131
  path: toUploadPath(entryPath, rootDir, options.prefix),
@@ -33985,7 +34150,7 @@ function collectSyncDocumentsInput(options) {
33985
34150
  throw new Error("Provide either --file or --dir");
33986
34151
  }
33987
34152
  if (options.file) {
33988
- const payload = JSON.parse(fs30.readFileSync(options.file, "utf-8"));
34153
+ const payload = JSON.parse(fs32.readFileSync(options.file, "utf-8"));
33989
34154
  return normalizeSyncDocumentsPayload(payload);
33990
34155
  }
33991
34156
  return {
@@ -34128,7 +34293,7 @@ function normalizeOnboardFolderMode(value) {
34128
34293
  throw new Error("Onboard mode must be one of: auto, business_context, code_project, mixed");
34129
34294
  }
34130
34295
  function toPosixPath(filePath) {
34131
- return filePath.split(path29.sep).join("/");
34296
+ return filePath.split(path31.sep).join("/");
34132
34297
  }
34133
34298
  function firstPathSegment(filePath) {
34134
34299
  return filePath.split("/")[0]?.toLowerCase() ?? "";
@@ -34138,31 +34303,31 @@ function hasBusinessKeyword(filePath) {
34138
34303
  return BUSINESS_PATH_KEYWORDS.some((keyword) => lower.includes(keyword));
34139
34304
  }
34140
34305
  function isBusinessLookingFile(file) {
34141
- return BUSINESS_MARKER_EXTENSIONS.has(path29.extname(file.path).toLowerCase()) || hasBusinessKeyword(file.path);
34306
+ return BUSINESS_MARKER_EXTENSIONS.has(path31.extname(file.path).toLowerCase()) || hasBusinessKeyword(file.path);
34142
34307
  }
34143
34308
  function scanOnboardFolder(options) {
34144
- const rootDir = path29.resolve(options.dir);
34145
- if (!fs30.existsSync(rootDir)) {
34309
+ const rootDir = path31.resolve(options.dir);
34310
+ if (!fs32.existsSync(rootDir)) {
34146
34311
  throw new Error(`Directory does not exist: ${options.dir}`);
34147
34312
  }
34148
- if (!fs30.statSync(rootDir).isDirectory()) {
34313
+ if (!fs32.statSync(rootDir).isDirectory()) {
34149
34314
  throw new Error(`Expected a directory: ${options.dir}`);
34150
34315
  }
34151
34316
  const files = [];
34152
34317
  function visit(directory) {
34153
- for (const entry of fs30.readdirSync(directory, { withFileTypes: true })) {
34318
+ for (const entry of fs32.readdirSync(directory, { withFileTypes: true })) {
34154
34319
  if (entry.isDirectory()) {
34155
34320
  if (options.recursive && !ONBOARD_IGNORED_DIRS.has(entry.name)) {
34156
- visit(path29.join(directory, entry.name));
34321
+ visit(path31.join(directory, entry.name));
34157
34322
  }
34158
34323
  continue;
34159
34324
  }
34160
34325
  if (!entry.isFile()) {
34161
34326
  continue;
34162
34327
  }
34163
- const absolutePath = path29.join(directory, entry.name);
34164
- const stat = fs30.statSync(absolutePath);
34165
- const relativePath2 = toPosixPath(path29.relative(rootDir, absolutePath));
34328
+ const absolutePath = path31.join(directory, entry.name);
34329
+ const stat = fs32.statSync(absolutePath);
34330
+ const relativePath2 = toPosixPath(path31.relative(rootDir, absolutePath));
34166
34331
  const format = inferDocumentFormat(entry.name);
34167
34332
  files.push({
34168
34333
  absolutePath,
@@ -34190,13 +34355,13 @@ function classifyOnboardFolder(rootDir, files, overrideMode = "auto") {
34190
34355
  let businessScore = 0;
34191
34356
  let codeSourceFiles = 0;
34192
34357
  let supportedPlainDocuments = 0;
34193
- if (fs30.existsSync(path29.join(rootDir, ".git"))) {
34358
+ if (fs32.existsSync(path31.join(rootDir, ".git"))) {
34194
34359
  codeScore += 4;
34195
34360
  addSignal2(codeSignals, ".git directory");
34196
34361
  }
34197
34362
  for (const file of files) {
34198
- const base = path29.basename(file.path);
34199
- const ext = path29.extname(file.path).toLowerCase();
34363
+ const base = path31.basename(file.path);
34364
+ const ext = path31.extname(file.path).toLowerCase();
34200
34365
  const firstSegment = firstPathSegment(file.path);
34201
34366
  if (CODE_MARKER_FILES.has(base)) {
34202
34367
  codeScore += 3;
@@ -34273,10 +34438,10 @@ function inferOnboardContextLane(file, mode) {
34273
34438
  if (hasBusinessKeyword(file.path)) {
34274
34439
  return "business_context";
34275
34440
  }
34276
- if (REPO_DOC_FILES.has(path29.basename(file.path))) {
34441
+ if (REPO_DOC_FILES.has(path31.basename(file.path))) {
34277
34442
  return "repo_docs";
34278
34443
  }
34279
- const ext = path29.extname(file.path).toLowerCase();
34444
+ const ext = path31.extname(file.path).toLowerCase();
34280
34445
  if ([".docx", ".pdf", ".pptx", ".vsdx"].includes(ext)) {
34281
34446
  return "business_context";
34282
34447
  }
@@ -34304,7 +34469,7 @@ function buildOnboardSyncManifestPayload(result) {
34304
34469
  };
34305
34470
  }
34306
34471
  function buildOnboardFolderManifest(options) {
34307
- const rootDir = path29.resolve(options.dir);
34472
+ const rootDir = path31.resolve(options.dir);
34308
34473
  const recursive = options.recursive ?? true;
34309
34474
  const files = scanOnboardFolder({ dir: rootDir, recursive });
34310
34475
  const modeOverride = normalizeOnboardFolderMode(options.mode);
@@ -34335,7 +34500,7 @@ function buildOnboardFolderManifest(options) {
34335
34500
  options.clientId ? { clientId: options.clientId } : void 0
34336
34501
  );
34337
34502
  const documents = supportedFiles.map((file) => {
34338
- const rawContent = fs30.readFileSync(file.absolutePath);
34503
+ const rawContent = fs32.readFileSync(file.absolutePath);
34339
34504
  const content = file.kind === "BINARY" ? `base64:${rawContent.toString("base64")}` : rawContent.toString("utf-8");
34340
34505
  const lane = inferOnboardContextLane(file, classification.mode);
34341
34506
  const metadata = mergeRecords(metadataDefaults, {
@@ -34633,7 +34798,7 @@ async function syncDocumentsCommand(options) {
34633
34798
  async function onboardFolderCommand(options) {
34634
34799
  const manifest = buildOnboardFolderManifest(options);
34635
34800
  if (options.writeManifest) {
34636
- fs30.writeFileSync(
34801
+ fs32.writeFileSync(
34637
34802
  options.writeManifest,
34638
34803
  `${JSON.stringify(buildOnboardSyncManifestPayload(manifest), null, 2)}
34639
34804
  `,
@@ -35228,7 +35393,7 @@ function startManagedWorkflowState(options) {
35228
35393
  `Active workflow '${existing.workflowId}' already exists. Use --force to replace ${WORKFLOW_STATE_RELATIVE_PATH}.`
35229
35394
  );
35230
35395
  }
35231
- const goal = options.goal ?? (options.planFile ? `Workflow from ${path29.basename(options.planFile)}` : void 0);
35396
+ const goal = options.goal ?? (options.planFile ? `Workflow from ${path31.basename(options.planFile)}` : void 0);
35232
35397
  if (!goal) {
35233
35398
  throw new Error("Provide --goal or --plan-file");
35234
35399
  }
@@ -35246,7 +35411,7 @@ function startManagedWorkflowState(options) {
35246
35411
  status: "active",
35247
35412
  currentPhaseId: phases[0]?.id,
35248
35413
  planSource: options.planFile ? "file" : "inline",
35249
- ...options.planFile ? { planFile: path29.resolve(options.planFile) } : {},
35414
+ ...options.planFile ? { planFile: path31.resolve(options.planFile) } : {},
35250
35415
  createdAt: now,
35251
35416
  updatedAt: now,
35252
35417
  phases,
@@ -36380,7 +36545,7 @@ function localWorkspacePathAliases() {
36380
36545
  const cwd = process.cwd();
36381
36546
  const aliases = /* @__PURE__ */ new Set([cwd]);
36382
36547
  try {
36383
- aliases.add(fs30.realpathSync(cwd));
36548
+ aliases.add(fs32.realpathSync(cwd));
36384
36549
  } catch {
36385
36550
  }
36386
36551
  for (const alias of [...aliases]) {
@@ -36398,9 +36563,9 @@ function redactTimelineText(value, maxLength = 180) {
36398
36563
  }
36399
36564
  function redactTimelineFile(file) {
36400
36565
  const workspaceAlias = localWorkspacePathAliases().find(
36401
- (alias) => path29.isAbsolute(file) && file.startsWith(alias)
36566
+ (alias) => path31.isAbsolute(file) && file.startsWith(alias)
36402
36567
  );
36403
- const relative15 = workspaceAlias ? path29.relative(workspaceAlias, file) : file;
36568
+ const relative15 = workspaceAlias ? path31.relative(workspaceAlias, file) : file;
36404
36569
  if (relative15.startsWith(".snipara/") || relative15 === ".snipara") {
36405
36570
  return "[local-state]";
36406
36571
  }
@@ -37806,12 +37971,12 @@ function emptySessionMemoriesResult() {
37806
37971
  };
37807
37972
  }
37808
37973
  function readLocalJsonFile(relativePath2) {
37809
- const absolutePath = path29.join(process.cwd(), relativePath2);
37810
- if (!fs30.existsSync(absolutePath)) {
37974
+ const absolutePath = path31.join(process.cwd(), relativePath2);
37975
+ if (!fs32.existsSync(absolutePath)) {
37811
37976
  return null;
37812
37977
  }
37813
37978
  try {
37814
- const parsed = JSON.parse(fs30.readFileSync(absolutePath, "utf-8"));
37979
+ const parsed = JSON.parse(fs32.readFileSync(absolutePath, "utf-8"));
37815
37980
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
37816
37981
  } catch {
37817
37982
  return null;
@@ -37821,14 +37986,14 @@ function summarizeSourceSnapshot(snapshot) {
37821
37986
  if (!snapshot) {
37822
37987
  return {
37823
37988
  status: "missing",
37824
- snapshotPath: path29.join(".snipara", "source", "latest.json"),
37989
+ snapshotPath: path31.join(".snipara", "source", "latest.json"),
37825
37990
  nextAction: "Run snipara-companion source sync --json after meaningful local code or docs movement."
37826
37991
  };
37827
37992
  }
37828
37993
  const summary = snapshot.summary && typeof snapshot.summary === "object" && !Array.isArray(snapshot.summary) ? snapshot.summary : {};
37829
37994
  return {
37830
37995
  status: "present",
37831
- snapshotPath: path29.join(".snipara", "source", "latest.json"),
37996
+ snapshotPath: path31.join(".snipara", "source", "latest.json"),
37832
37997
  generatedAt: snapshot.generatedAt,
37833
37998
  revision: snapshot.revision,
37834
37999
  totalFiles: summary.totalFiles,
@@ -37862,7 +38027,7 @@ function summarizeTeamSyncForContinuity() {
37862
38027
  const summary = buildTeamSyncSummary(state);
37863
38028
  const latestHandoff = state.handoffs.at(-1);
37864
38029
  return {
37865
- statePath: path29.relative(process.cwd(), getTeamSyncStatePath()),
38030
+ statePath: path31.relative(process.cwd(), getTeamSyncStatePath()),
37866
38031
  activeWorkCount: summary.activeWorkCount,
37867
38032
  staleWorkCount: summary.staleWorkCount,
37868
38033
  completedWorkCount: summary.completedWorkCount,
@@ -37880,7 +38045,7 @@ function buildCompanionContinuityPayload(args) {
37880
38045
  const config = args.configured ? loadConfig() : null;
37881
38046
  const workflow2 = readWorkflowState2();
37882
38047
  const sessionSnapshot = readSessionSnapshot();
37883
- const sourceSnapshot = readLocalJsonFile(path29.join(".snipara", "source", "latest.json"));
38048
+ const sourceSnapshot = readLocalJsonFile(path31.join(".snipara", "source", "latest.json"));
37884
38049
  return {
37885
38050
  version: COMPANION_CONTINUITY_CONTRACT_VERSION,
37886
38051
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -37892,9 +38057,9 @@ function buildCompanionContinuityPayload(args) {
37892
38057
  } : null,
37893
38058
  artifacts: {
37894
38059
  workflowStatePath: WORKFLOW_STATE_RELATIVE_PATH,
37895
- teamSyncStatePath: path29.relative(process.cwd(), getTeamSyncStatePath()),
37896
- sessionSnapshotPath: path29.join(".snipara", "activity", "session.json"),
37897
- sourceSnapshotPath: path29.join(".snipara", "source", "latest.json")
38060
+ teamSyncStatePath: path31.relative(process.cwd(), getTeamSyncStatePath()),
38061
+ sessionSnapshotPath: path31.join(".snipara", "activity", "session.json"),
38062
+ sourceSnapshotPath: path31.join(".snipara", "source", "latest.json")
37898
38063
  },
37899
38064
  bootstrap: args.bootstrap,
37900
38065
  bootstrapQuality: args.bootstrapQuality,
@@ -38632,12 +38797,12 @@ async function sourceWatchCommand(options = {}) {
38632
38797
  if (stopping) {
38633
38798
  break;
38634
38799
  }
38635
- await new Promise((resolve25) => {
38636
- resolveWait = resolve25;
38800
+ await new Promise((resolve26) => {
38801
+ resolveWait = resolve26;
38637
38802
  activeTimer = setTimeout(() => {
38638
38803
  activeTimer = null;
38639
38804
  resolveWait = null;
38640
- resolve25();
38805
+ resolve26();
38641
38806
  }, intervalMs);
38642
38807
  });
38643
38808
  }
@@ -38903,7 +39068,7 @@ async function docsBootstrapCommand(options = {}) {
38903
39068
  var import_fs7 = __toESM(require("fs"));
38904
39069
  var import_path7 = __toESM(require("path"));
38905
39070
  var import_node_child_process16 = require("child_process");
38906
- var import_node_crypto14 = require("crypto");
39071
+ var import_node_crypto16 = require("crypto");
38907
39072
  var import_chalk12 = __toESM(require("chalk"));
38908
39073
  var CONTROLLED_WORKER_EXECUTIONS_DIR = import_path7.default.join(".snipara", "worker-executions");
38909
39074
  var UNIFIED_RECEIPTS_DIR = import_path7.default.join(".snipara", "unified-receipts");
@@ -39171,7 +39336,7 @@ function pathFingerprint(workspaceRoot2, relativePath2) {
39171
39336
  const stat = import_fs7.default.lstatSync(candidate);
39172
39337
  if (stat.isSymbolicLink()) return `symlink:${import_fs7.default.readlinkSync(candidate)}`;
39173
39338
  if (!stat.isFile()) return `mode:${stat.mode}:size:${stat.size}`;
39174
- return `file:${stat.mode}:${(0, import_node_crypto14.createHash)("sha256").update(import_fs7.default.readFileSync(candidate)).digest("hex")}`;
39339
+ return `file:${stat.mode}:${(0, import_node_crypto16.createHash)("sha256").update(import_fs7.default.readFileSync(candidate)).digest("hex")}`;
39175
39340
  } catch {
39176
39341
  return "missing";
39177
39342
  }
@@ -39546,8 +39711,8 @@ function printJson5(value) {
39546
39711
  }
39547
39712
 
39548
39713
  // src/commands/agent-readiness.ts
39549
- var fs35 = __toESM(require("fs"));
39550
- var path34 = __toESM(require("path"));
39714
+ var fs37 = __toESM(require("fs"));
39715
+ var path36 = __toESM(require("path"));
39551
39716
  var TARGETS = {
39552
39717
  codex: {
39553
39718
  label: "Codex",
@@ -39602,18 +39767,18 @@ function recordList2(value) {
39602
39767
  }
39603
39768
  function safeReadJson2(filePath) {
39604
39769
  try {
39605
- const parsed = JSON.parse(fs35.readFileSync(filePath, "utf8"));
39770
+ const parsed = JSON.parse(fs37.readFileSync(filePath, "utf8"));
39606
39771
  return isRecord21(parsed) ? parsed : void 0;
39607
39772
  } catch {
39608
39773
  return void 0;
39609
39774
  }
39610
39775
  }
39611
39776
  function relativePath(rootDir, filePath) {
39612
- const relative15 = path34.relative(rootDir, filePath);
39777
+ const relative15 = path36.relative(rootDir, filePath);
39613
39778
  return relative15 && !relative15.startsWith("..") ? relative15 : filePath;
39614
39779
  }
39615
39780
  function collectAgentReadinessLocalSignals(rootDir = process.cwd()) {
39616
- const workflowPath = path34.join(rootDir, ".snipara", "workflow", "current.json");
39781
+ const workflowPath = path36.join(rootDir, ".snipara", "workflow", "current.json");
39617
39782
  const workflowJson = safeReadJson2(workflowPath);
39618
39783
  const phases = recordList2(workflowJson?.phases);
39619
39784
  const workflow2 = {
@@ -39625,7 +39790,7 @@ function collectAgentReadinessLocalSignals(rootDir = process.cwd()) {
39625
39790
  completedPhases: phases.filter((phase) => phase.status === "completed").length,
39626
39791
  pendingPhases: phases.filter((phase) => phase.status === "pending").length
39627
39792
  };
39628
- const teamSyncPath = path34.join(rootDir, ".snipara", "team-sync", "session.json");
39793
+ const teamSyncPath = path36.join(rootDir, ".snipara", "team-sync", "session.json");
39629
39794
  const teamSyncJson = safeReadJson2(teamSyncPath);
39630
39795
  const work = recordList2(teamSyncJson?.work);
39631
39796
  const handoffs = recordList2(teamSyncJson?.handoffs);
@@ -39640,9 +39805,9 @@ function collectAgentReadinessLocalSignals(rootDir = process.cwd()) {
39640
39805
  latestActiveSummary: stringValue14(latestActive?.summary),
39641
39806
  latestHandoffSummary: stringValue14(latestHandoff?.summary)
39642
39807
  };
39643
- const agentsPath = path34.join(rootDir, "AGENTS.md");
39808
+ const agentsPath = path36.join(rootDir, "AGENTS.md");
39644
39809
  const projectInstructions = {
39645
- present: fs35.existsSync(agentsPath),
39810
+ present: fs37.existsSync(agentsPath),
39646
39811
  path: relativePath(rootDir, agentsPath)
39647
39812
  };
39648
39813
  return { workflow: workflow2, teamSync: teamSync2, projectInstructions };
@@ -39963,15 +40128,15 @@ function formatAgentReadinessAuditReport(report) {
39963
40128
  return lines.join("\n");
39964
40129
  }
39965
40130
  function writeReport(outputPath, report) {
39966
- const absolute = path34.resolve(outputPath);
39967
- fs35.mkdirSync(path34.dirname(absolute), { recursive: true });
40131
+ const absolute = path36.resolve(outputPath);
40132
+ fs37.mkdirSync(path36.dirname(absolute), { recursive: true });
39968
40133
  const content = outputPath.endsWith(".json") ? `${JSON.stringify(report, null, 2)}
39969
40134
  ` : `${formatAgentReadinessAuditReport(report)}
39970
40135
  `;
39971
- fs35.writeFileSync(absolute, content, "utf8");
40136
+ fs37.writeFileSync(absolute, content, "utf8");
39972
40137
  }
39973
40138
  async function agentReadinessAuditCommand(options) {
39974
- const cwd = path34.resolve(options.dir ?? process.cwd());
40139
+ const cwd = path36.resolve(options.dir ?? process.cwd());
39975
40140
  const report = buildAgentReadinessAuditReport({
39976
40141
  ...options,
39977
40142
  cwd,
@@ -39988,8 +40153,8 @@ async function agentReadinessAuditCommand(options) {
39988
40153
  }
39989
40154
 
39990
40155
  // src/commands/lead-plan.ts
39991
- var fs36 = __toESM(require("fs"));
39992
- var path35 = __toESM(require("path"));
40156
+ var fs38 = __toESM(require("fs"));
40157
+ var path37 = __toESM(require("path"));
39993
40158
 
39994
40159
  // src/commands/execution-receipts.ts
39995
40160
  var ENGINEERING_LEAD_PROOF_VERIFICATION_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
@@ -41233,7 +41398,7 @@ function applyReconciliationToPlan(plan, reconciliation) {
41233
41398
  };
41234
41399
  }
41235
41400
  function readJsonFile3(filePath) {
41236
- const parsed = JSON.parse(fs36.readFileSync(path35.resolve(filePath), "utf8"));
41401
+ const parsed = JSON.parse(fs38.readFileSync(path37.resolve(filePath), "utf8"));
41237
41402
  if (!isRecord22(parsed)) {
41238
41403
  throw new Error(`${filePath} must contain a JSON object`);
41239
41404
  }
@@ -41419,16 +41584,16 @@ function formatCompanionEngineeringLeadPlanReport(report) {
41419
41584
  return lines.join("\n");
41420
41585
  }
41421
41586
  function writeReport2(outputPath, report) {
41422
- const absolute = path35.resolve(outputPath);
41423
- fs36.mkdirSync(path35.dirname(absolute), { recursive: true });
41587
+ const absolute = path37.resolve(outputPath);
41588
+ fs38.mkdirSync(path37.dirname(absolute), { recursive: true });
41424
41589
  const content = outputPath.endsWith(".json") ? `${JSON.stringify(report, null, 2)}
41425
41590
  ` : `${formatCompanionEngineeringLeadPlanReport(report)}
41426
41591
  `;
41427
- fs36.writeFileSync(absolute, content, "utf8");
41592
+ fs38.writeFileSync(absolute, content, "utf8");
41428
41593
  }
41429
41594
  function defaultJsonOutputPath(cwd, report) {
41430
41595
  const timestamp = report.generatedAt.replace(/[:.]/g, "-");
41431
- return path35.join(
41596
+ return path37.join(
41432
41597
  cwd,
41433
41598
  ".snipara",
41434
41599
  "lead-plans",
@@ -41436,7 +41601,7 @@ function defaultJsonOutputPath(cwd, report) {
41436
41601
  );
41437
41602
  }
41438
41603
  async function leadPlanCommand(options) {
41439
- const cwd = path35.resolve(options.dir ?? process.cwd());
41604
+ const cwd = path37.resolve(options.dir ?? process.cwd());
41440
41605
  const report = buildCompanionEngineeringLeadPlanReport({
41441
41606
  ...options,
41442
41607
  cwd,
@@ -41451,11 +41616,11 @@ async function leadPlanCommand(options) {
41451
41616
  JSON.stringify(
41452
41617
  {
41453
41618
  ...report,
41454
- outputPath: writtenOutput ? path35.resolve(writtenOutput) : void 0,
41455
- relativeOutputPath: writtenOutput ? path35.relative(cwd, path35.resolve(writtenOutput)) : void 0,
41456
- nextCommand: writtenOutput ? `snipara-orchestrator team-sync gate --plan ${path35.relative(
41619
+ outputPath: writtenOutput ? path37.resolve(writtenOutput) : void 0,
41620
+ relativeOutputPath: writtenOutput ? path37.relative(cwd, path37.resolve(writtenOutput)) : void 0,
41621
+ nextCommand: writtenOutput ? `snipara-orchestrator team-sync gate --plan ${path37.relative(
41457
41622
  cwd,
41458
- path35.resolve(writtenOutput)
41623
+ path37.resolve(writtenOutput)
41459
41624
  )} --json` : void 0
41460
41625
  },
41461
41626
  null,
@@ -41468,11 +41633,11 @@ async function leadPlanCommand(options) {
41468
41633
  }
41469
41634
 
41470
41635
  // src/commands/feature.ts
41471
- var fs37 = __toESM(require("fs"));
41472
- var path36 = __toESM(require("path"));
41636
+ var fs39 = __toESM(require("fs"));
41637
+ var path38 = __toESM(require("path"));
41473
41638
  var import_chalk14 = __toESM(require("chalk"));
41474
41639
  var FEATURE_WORK_ITEM_VERSION = "snipara.feature_work_item.v1";
41475
- var FEATURE_DEFAULT_OUTPUT_DIR = path36.join("docs", "specs");
41640
+ var FEATURE_DEFAULT_OUTPUT_DIR = path38.join("docs", "specs");
41476
41641
  function compact(value) {
41477
41642
  return (value ?? "").trim().replace(/\s+/g, " ");
41478
41643
  }
@@ -41491,34 +41656,34 @@ function normalizeFeatureSlug(value) {
41491
41656
  }
41492
41657
  function resolveFeatureArtifactPaths(slug2, options = {}) {
41493
41658
  const normalizedSlug = normalizeFeatureSlug(slug2);
41494
- const cwd = path36.resolve(options.cwd ?? process.cwd());
41659
+ const cwd = path38.resolve(options.cwd ?? process.cwd());
41495
41660
  const workspaceRoot2 = findWorkspaceRoot(cwd, true) ?? cwd;
41496
41661
  const outputDir = options.outputDir ?? FEATURE_DEFAULT_OUTPUT_DIR;
41497
- const root = path36.resolve(workspaceRoot2, outputDir, normalizedSlug);
41662
+ const root = path38.resolve(workspaceRoot2, outputDir, normalizedSlug);
41498
41663
  return {
41499
41664
  root,
41500
- manifest: path36.join(root, "feature.json"),
41501
- spec: path36.join(root, "spec.md"),
41502
- plan: path36.join(root, "plan.md"),
41503
- tasks: path36.join(root, "tasks.md"),
41504
- workflowPlan: path36.join(root, "workflow-plan.json")
41665
+ manifest: path38.join(root, "feature.json"),
41666
+ spec: path38.join(root, "spec.md"),
41667
+ plan: path38.join(root, "plan.md"),
41668
+ tasks: path38.join(root, "tasks.md"),
41669
+ workflowPlan: path38.join(root, "workflow-plan.json")
41505
41670
  };
41506
41671
  }
41507
41672
  function readJsonFile4(filePath) {
41508
- return JSON.parse(fs37.readFileSync(filePath, "utf8"));
41673
+ return JSON.parse(fs39.readFileSync(filePath, "utf8"));
41509
41674
  }
41510
41675
  function writeJsonFile4(filePath, value) {
41511
- fs37.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
41676
+ fs39.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
41512
41677
  `, "utf8");
41513
41678
  }
41514
41679
  function ensureParent(filePath) {
41515
- fs37.mkdirSync(path36.dirname(filePath), { recursive: true });
41680
+ fs39.mkdirSync(path38.dirname(filePath), { recursive: true });
41516
41681
  }
41517
41682
  function assertWritable(filePath, force, allowGeneratedPlaceholder = false) {
41518
- if (!fs37.existsSync(filePath) || force) {
41683
+ if (!fs39.existsSync(filePath) || force) {
41519
41684
  return;
41520
41685
  }
41521
- if (allowGeneratedPlaceholder && isGeneratedPlaceholder(fs37.readFileSync(filePath, "utf8"))) {
41686
+ if (allowGeneratedPlaceholder && isGeneratedPlaceholder(fs39.readFileSync(filePath, "utf8"))) {
41522
41687
  return;
41523
41688
  }
41524
41689
  throw new Error(
@@ -41528,7 +41693,7 @@ function assertWritable(filePath, force, allowGeneratedPlaceholder = false) {
41528
41693
  function writeArtifact(filePath, content, force, allowGeneratedPlaceholder = false) {
41529
41694
  assertWritable(filePath, force, allowGeneratedPlaceholder);
41530
41695
  ensureParent(filePath);
41531
- fs37.writeFileSync(filePath, content.endsWith("\n") ? content : `${content}
41696
+ fs39.writeFileSync(filePath, content.endsWith("\n") ? content : `${content}
41532
41697
  `, "utf8");
41533
41698
  }
41534
41699
  function isGeneratedPlaceholder(content) {
@@ -41556,14 +41721,14 @@ function createManifest(options, paths) {
41556
41721
  },
41557
41722
  status: {
41558
41723
  spec: compact(options.goal).length > 0 ? "ready" : "draft",
41559
- plan: fs37.existsSync(paths.plan) && !isGeneratedPlaceholder(fs37.readFileSync(paths.plan, "utf8")) ? "ready" : "missing",
41560
- tasks: fs37.existsSync(paths.tasks) && !isGeneratedPlaceholder(fs37.readFileSync(paths.tasks, "utf8")) ? "ready" : "missing"
41724
+ plan: fs39.existsSync(paths.plan) && !isGeneratedPlaceholder(fs39.readFileSync(paths.plan, "utf8")) ? "ready" : "missing",
41725
+ tasks: fs39.existsSync(paths.tasks) && !isGeneratedPlaceholder(fs39.readFileSync(paths.tasks, "utf8")) ? "ready" : "missing"
41561
41726
  }
41562
41727
  };
41563
41728
  }
41564
41729
  function readManifest3(paths) {
41565
- if (!fs37.existsSync(paths.manifest)) {
41566
- throw new Error(`Feature '${path36.basename(paths.root)}' is not initialized at ${paths.root}.`);
41730
+ if (!fs39.existsSync(paths.manifest)) {
41731
+ throw new Error(`Feature '${path38.basename(paths.root)}' is not initialized at ${paths.root}.`);
41567
41732
  }
41568
41733
  const manifest = readJsonFile4(paths.manifest);
41569
41734
  if (manifest.schemaVersion !== FEATURE_WORK_ITEM_VERSION) {
@@ -41783,11 +41948,11 @@ function featureInitCommand(options) {
41783
41948
  if (!normalizedGoal) {
41784
41949
  throw new Error("Feature initialization requires --goal.");
41785
41950
  }
41786
- if (fs37.existsSync(paths.manifest) && !options.force) {
41951
+ if (fs39.existsSync(paths.manifest) && !options.force) {
41787
41952
  throw new Error(`Feature already exists at ${paths.root}. Use --force to reinitialize it.`);
41788
41953
  }
41789
41954
  const manifest = createManifest(options, paths);
41790
- fs37.mkdirSync(paths.root, { recursive: true });
41955
+ fs39.mkdirSync(paths.root, { recursive: true });
41791
41956
  writeManifest(paths, manifest);
41792
41957
  writeArtifact(paths.spec, buildFeatureSpecMarkdown(manifest), Boolean(options.force));
41793
41958
  writeArtifact(paths.plan, renderPlanPlaceholder(manifest), Boolean(options.force));
@@ -41803,7 +41968,7 @@ function featureInitCommand(options) {
41803
41968
  }
41804
41969
  function featureSpecifyCommand(options) {
41805
41970
  const paths = resolveFeatureArtifactPaths(options.slug, options);
41806
- const existing = fs37.existsSync(paths.manifest) ? readManifest3(paths) : void 0;
41971
+ const existing = fs39.existsSync(paths.manifest) ? readManifest3(paths) : void 0;
41807
41972
  const manifest = createManifest(
41808
41973
  {
41809
41974
  ...options,
@@ -41819,10 +41984,10 @@ function featureSpecifyCommand(options) {
41819
41984
  if (!manifest.goal) {
41820
41985
  throw new Error("Feature specification requires --goal when no existing manifest is present.");
41821
41986
  }
41822
- if (fs37.existsSync(paths.spec) && !options.force && !isGeneratedPlaceholder(fs37.readFileSync(paths.spec, "utf8"))) {
41987
+ if (fs39.existsSync(paths.spec) && !options.force && !isGeneratedPlaceholder(fs39.readFileSync(paths.spec, "utf8"))) {
41823
41988
  throw new Error(`Refusing to overwrite existing specification: ${paths.spec}. Use --force.`);
41824
41989
  }
41825
- fs37.mkdirSync(paths.root, { recursive: true });
41990
+ fs39.mkdirSync(paths.root, { recursive: true });
41826
41991
  writeArtifact(paths.spec, buildFeatureSpecMarkdown(manifest), Boolean(options.force), true);
41827
41992
  manifest.updatedAt = nowIso2();
41828
41993
  writeManifest(paths, manifest);
@@ -41837,7 +42002,7 @@ function featureSpecifyCommand(options) {
41837
42002
  async function featurePlanCommand(options) {
41838
42003
  const paths = resolveFeatureArtifactPaths(options.slug, options);
41839
42004
  const manifest = readManifest3(paths);
41840
- if (!fs37.existsSync(paths.spec)) {
42005
+ if (!fs39.existsSync(paths.spec)) {
41841
42006
  throw new Error(`Missing specification: ${paths.spec}`);
41842
42007
  }
41843
42008
  if (!isConfigured({ cwd: options.cwd })) {
@@ -41845,7 +42010,7 @@ async function featurePlanCommand(options) {
41845
42010
  "Hosted planning requires Companion configuration. Run 'snipara-companion init' first."
41846
42011
  );
41847
42012
  }
41848
- const spec = fs37.readFileSync(paths.spec, "utf8");
42013
+ const spec = fs39.readFileSync(paths.spec, "utf8");
41849
42014
  const query = buildPlanQuery(manifest, spec);
41850
42015
  const result = await createClient(3e4, { cwd: options.cwd }).plan(query, options.maxTokens);
41851
42016
  const quality = validatePlanResult(result, { query, cwd: options.cwd ?? process.cwd() });
@@ -41879,11 +42044,11 @@ async function featurePlanCommand(options) {
41879
42044
  function featureTasksCommand(options) {
41880
42045
  const paths = resolveFeatureArtifactPaths(options.slug, options);
41881
42046
  const manifest = readManifest3(paths);
41882
- const useLocalPlan = Boolean(options.fromPlan) || !fs37.existsSync(paths.workflowPlan);
41883
- if (useLocalPlan && (!fs37.existsSync(paths.plan) || isGeneratedPlaceholder(fs37.readFileSync(paths.plan, "utf8")))) {
42047
+ const useLocalPlan = Boolean(options.fromPlan) || !fs39.existsSync(paths.workflowPlan);
42048
+ if (useLocalPlan && (!fs39.existsSync(paths.plan) || isGeneratedPlaceholder(fs39.readFileSync(paths.plan, "utf8")))) {
41884
42049
  throw new Error(`Missing workflow plan: ${paths.workflowPlan}. Run feature plan first.`);
41885
42050
  }
41886
- const plan = useLocalPlan ? buildLocalWorkflowPlan(manifest, fs37.readFileSync(paths.plan, "utf8")) : readJsonFile4(paths.workflowPlan);
42051
+ const plan = useLocalPlan ? buildLocalWorkflowPlan(manifest, fs39.readFileSync(paths.plan, "utf8")) : readJsonFile4(paths.workflowPlan);
41887
42052
  if (!Array.isArray(plan.steps) || plan.steps.length === 0) {
41888
42053
  throw new Error(`Workflow plan has no executable phases: ${paths.workflowPlan}`);
41889
42054
  }
@@ -41921,7 +42086,7 @@ async function featureStartCommand(options) {
41921
42086
  outputDir: options.outputDir
41922
42087
  });
41923
42088
  const manifest = readManifest3(paths);
41924
- if (manifest.status.tasks !== "ready" || !fs37.existsSync(paths.tasks)) {
42089
+ if (manifest.status.tasks !== "ready" || !fs39.existsSync(paths.tasks)) {
41925
42090
  throw new Error(
41926
42091
  `Tasks are not ready. Run 'snipara-companion feature tasks ${manifest.slug}' first.`
41927
42092
  );
@@ -41958,9 +42123,9 @@ function featureStatusCommand(options) {
41958
42123
  }
41959
42124
 
41960
42125
  // src/commands/outcome-capture.ts
41961
- var fs38 = __toESM(require("fs"));
41962
- var path37 = __toESM(require("path"));
41963
- var import_node_crypto15 = require("crypto");
42126
+ var fs40 = __toESM(require("fs"));
42127
+ var path39 = __toESM(require("path"));
42128
+ var import_node_crypto17 = require("crypto");
41964
42129
  var WHY_OUTCOME_CAPTURE_VERSION = "snipara.why_outcome_capture.v1";
41965
42130
  var DEFAULT_MAX_CANDIDATES = 20;
41966
42131
  var MAX_EVENTS = 50;
@@ -42040,7 +42205,7 @@ function buildWhyOutcomeCaptureReport(options) {
42040
42205
  };
42041
42206
  }
42042
42207
  async function outcomeCapturePreviewCommand(options) {
42043
- const rootDir = path37.resolve(options.dir ?? process.cwd());
42208
+ const rootDir = path39.resolve(options.dir ?? process.cwd());
42044
42209
  const workflowFile = typeof options.fromWorkflow === "string" ? options.fromWorkflow : options.fromWorkflow ? ".snipara/workflow/current.json" : void 0;
42045
42210
  const workflow2 = workflowFile ? readWorkflowSnapshot2(rootDir, workflowFile) : void 0;
42046
42211
  const workflowEvents = workflow2 ? buildWorkflowOutcomeEvents(workflow2, rootDir) : [];
@@ -42477,8 +42642,8 @@ function normalizeStringList6(value) {
42477
42642
  return values.flatMap((item) => String(item).split("\n")).map((item) => item.trim()).filter(Boolean).slice(0, MAX_LIST_ITEMS4);
42478
42643
  }
42479
42644
  function readEventsFromFile(filePath, cwd = process.cwd()) {
42480
- const resolved = path37.resolve(cwd, filePath);
42481
- const parsed = JSON.parse(fs38.readFileSync(resolved, "utf8"));
42645
+ const resolved = path39.resolve(cwd, filePath);
42646
+ const parsed = JSON.parse(fs40.readFileSync(resolved, "utf8"));
42482
42647
  if (Array.isArray(parsed)) {
42483
42648
  return parsed;
42484
42649
  }
@@ -42495,8 +42660,8 @@ function readEventsFromFile(filePath, cwd = process.cwd()) {
42495
42660
  return [];
42496
42661
  }
42497
42662
  function readWorkflowSnapshot2(rootDir, filePath) {
42498
- const resolved = path37.resolve(rootDir, filePath);
42499
- const parsed = JSON.parse(fs38.readFileSync(resolved, "utf8"));
42663
+ const resolved = path39.resolve(rootDir, filePath);
42664
+ const parsed = JSON.parse(fs40.readFileSync(resolved, "utf8"));
42500
42665
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
42501
42666
  throw new Error("Workflow snapshot must be a JSON object.");
42502
42667
  }
@@ -42539,12 +42704,12 @@ function buildWorkflowOutcomeEvents(workflow2, rootDir) {
42539
42704
  });
42540
42705
  }
42541
42706
  function projectRelativeWorkflowFile(value, rootDir) {
42542
- const absolute = path37.resolve(rootDir, value);
42543
- const relative15 = path37.relative(rootDir, absolute);
42544
- if (!relative15 || relative15.startsWith("..") || path37.isAbsolute(relative15)) {
42707
+ const absolute = path39.resolve(rootDir, value);
42708
+ const relative15 = path39.relative(rootDir, absolute);
42709
+ if (!relative15 || relative15.startsWith("..") || path39.isAbsolute(relative15)) {
42545
42710
  return null;
42546
42711
  }
42547
- return relative15.split(path37.sep).join("/");
42712
+ return relative15.split(path39.sep).join("/");
42548
42713
  }
42549
42714
  function boundedWorkflowValue(value, fallback) {
42550
42715
  if (typeof value !== "string" || !value.trim()) return fallback;
@@ -42554,7 +42719,7 @@ function isRecord23(value) {
42554
42719
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
42555
42720
  }
42556
42721
  function stableHash2(parts) {
42557
- return (0, import_node_crypto15.createHash)("sha256").update(parts.join("\0")).digest("hex");
42722
+ return (0, import_node_crypto17.createHash)("sha256").update(parts.join("\0")).digest("hex");
42558
42723
  }
42559
42724
  function uniqueStrings24(values) {
42560
42725
  return Array.from(new Set(values.filter(Boolean)));
@@ -42998,17 +43163,17 @@ async function realityCheckCommand(options) {
42998
43163
  }
42999
43164
 
43000
43165
  // src/commands/context-control.ts
43001
- var fs40 = __toESM(require("fs"));
43002
- var path39 = __toESM(require("path"));
43166
+ var fs42 = __toESM(require("fs"));
43167
+ var path41 = __toESM(require("path"));
43003
43168
  var import_node_child_process18 = require("child_process");
43004
43169
  var import_chalk16 = __toESM(require("chalk"));
43005
- var CONTEXT_CONTROL_RELATIVE_DIR = path39.join(".snipara", "context-control");
43006
- var CONTEXT_CONTROL_PLANS_RELATIVE_DIR = path39.join(CONTEXT_CONTROL_RELATIVE_DIR, "plans");
43007
- var CONTEXT_CONTROL_APPLIED_RELATIVE_DIR = path39.join(
43170
+ var CONTEXT_CONTROL_RELATIVE_DIR = path41.join(".snipara", "context-control");
43171
+ var CONTEXT_CONTROL_PLANS_RELATIVE_DIR = path41.join(CONTEXT_CONTROL_RELATIVE_DIR, "plans");
43172
+ var CONTEXT_CONTROL_APPLIED_RELATIVE_DIR = path41.join(
43008
43173
  CONTEXT_CONTROL_RELATIVE_DIR,
43009
43174
  "applied"
43010
43175
  );
43011
- var CONTEXT_CONTROL_STATE_RELATIVE_DIR = path39.join(CONTEXT_CONTROL_RELATIVE_DIR, "state");
43176
+ var CONTEXT_CONTROL_STATE_RELATIVE_DIR = path41.join(CONTEXT_CONTROL_RELATIVE_DIR, "state");
43012
43177
  var PROJECT_CONTEXT_MANIFEST_DEFAULT_PATH = "snipara.project-context.json";
43013
43178
  var DEFAULT_PLAN_SUMMARY = "Record local context-control state";
43014
43179
  function runGit4(args, cwd, options = {}) {
@@ -43046,10 +43211,10 @@ function resolveGitDriftScopePaths(cwd) {
43046
43211
  const scopePaths = [
43047
43212
  PROJECT_CONTEXT_MANIFEST_DEFAULT_PATH,
43048
43213
  CONTEXT_CONTROL_RELATIVE_DIR,
43049
- path39.join(".snipara", "decisions")
43214
+ path41.join(".snipara", "decisions")
43050
43215
  ];
43051
43216
  const manifestPath2 = resolveManifestPath(cwd);
43052
- if (!fs40.existsSync(manifestPath2)) {
43217
+ if (!fs42.existsSync(manifestPath2)) {
43053
43218
  return normalizeScopePaths(scopePaths, cwd);
43054
43219
  }
43055
43220
  const manifestRead = readJsonFileSafe(manifestPath2);
@@ -43076,16 +43241,16 @@ function slugify2(value) {
43076
43241
  return slug2 || "context-control-state";
43077
43242
  }
43078
43243
  function toProjectRelativePath4(absolutePath, cwd) {
43079
- const relative15 = path39.relative(cwd, absolutePath);
43244
+ const relative15 = path41.relative(cwd, absolutePath);
43080
43245
  return relative15 && !relative15.startsWith("..") ? relative15 : absolutePath;
43081
43246
  }
43082
43247
  function normalizeProjectRelativePath(filePath, cwd) {
43083
- const absolute = path39.isAbsolute(filePath) ? filePath : path39.resolve(cwd, filePath);
43084
- return toProjectRelativePath4(absolute, cwd).split(path39.sep).join("/");
43248
+ const absolute = path41.isAbsolute(filePath) ? filePath : path41.resolve(cwd, filePath);
43249
+ return toProjectRelativePath4(absolute, cwd).split(path41.sep).join("/");
43085
43250
  }
43086
43251
  function assertContextControlTarget(target, cwd) {
43087
43252
  const relative15 = normalizeProjectRelativePath(target, cwd);
43088
- if (path39.isAbsolute(relative15) || relative15.startsWith("../") || relative15 === ".." || !relative15.startsWith(".snipara/context-control/")) {
43253
+ if (path41.isAbsolute(relative15) || relative15.startsWith("../") || relative15 === ".." || !relative15.startsWith(".snipara/context-control/")) {
43089
43254
  throw new Error(
43090
43255
  `Context-control apply can only write under ${CONTEXT_CONTROL_RELATIVE_DIR}; got ${target}`
43091
43256
  );
@@ -43093,18 +43258,18 @@ function assertContextControlTarget(target, cwd) {
43093
43258
  return relative15;
43094
43259
  }
43095
43260
  function defaultTargetPath(summary) {
43096
- return path39.join(CONTEXT_CONTROL_STATE_RELATIVE_DIR, `${slugify2(summary)}.json`);
43261
+ return path41.join(CONTEXT_CONTROL_STATE_RELATIVE_DIR, `${slugify2(summary)}.json`);
43097
43262
  }
43098
43263
  function receiptPathFor(receipt, cwd) {
43099
- return path39.resolve(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR, `${receipt.receiptId}.json`);
43264
+ return path41.resolve(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR, `${receipt.receiptId}.json`);
43100
43265
  }
43101
43266
  function writeStableJsonFile(filePath, value) {
43102
- fs40.mkdirSync(path39.dirname(filePath), { recursive: true });
43103
- fs40.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
43267
+ fs42.mkdirSync(path41.dirname(filePath), { recursive: true });
43268
+ fs42.writeFileSync(filePath, `${stableDecisionJsonStringify(value)}
43104
43269
  `, "utf8");
43105
43270
  }
43106
43271
  function readJsonFile5(filePath) {
43107
- return JSON.parse(fs40.readFileSync(filePath, "utf8"));
43272
+ return JSON.parse(fs42.readFileSync(filePath, "utf8"));
43108
43273
  }
43109
43274
  function buildStateOperation(options) {
43110
43275
  const target = assertContextControlTarget(
@@ -43128,10 +43293,10 @@ function buildStateOperation(options) {
43128
43293
  };
43129
43294
  }
43130
43295
  function resolveManifestPath(cwd, manifest) {
43131
- return path39.resolve(cwd, manifest ?? PROJECT_CONTEXT_MANIFEST_DEFAULT_PATH);
43296
+ return path41.resolve(cwd, manifest ?? PROJECT_CONTEXT_MANIFEST_DEFAULT_PATH);
43132
43297
  }
43133
43298
  function buildLocalProjectContextValidationReport(options = {}) {
43134
- const cwd = path39.resolve(options.cwd ?? process.cwd());
43299
+ const cwd = path41.resolve(options.cwd ?? process.cwd());
43135
43300
  const manifestPath2 = resolveManifestPath(cwd, options.manifest);
43136
43301
  const manifest = readJsonFile5(manifestPath2);
43137
43302
  return validateProjectContextManifest({
@@ -43142,7 +43307,7 @@ function buildLocalProjectContextValidationReport(options = {}) {
43142
43307
  function buildManifestOperation(options) {
43143
43308
  const relativeManifestPath = toProjectRelativePath4(options.manifestPath, options.cwd);
43144
43309
  const target = assertContextControlTarget(
43145
- options.target ?? path39.join(CONTEXT_CONTROL_STATE_RELATIVE_DIR, "project-context-manifest.json"),
43310
+ options.target ?? path41.join(CONTEXT_CONTROL_STATE_RELATIVE_DIR, "project-context-manifest.json"),
43146
43311
  options.cwd
43147
43312
  );
43148
43313
  return {
@@ -43161,7 +43326,7 @@ function buildManifestOperation(options) {
43161
43326
  };
43162
43327
  }
43163
43328
  function buildLocalContextMutationPlan(options = {}) {
43164
- const cwd = path39.resolve(options.cwd ?? process.cwd());
43329
+ const cwd = path41.resolve(options.cwd ?? process.cwd());
43165
43330
  const now = options.now ?? /* @__PURE__ */ new Date();
43166
43331
  const manifestPath2 = options.manifest ? resolveManifestPath(cwd, options.manifest) : void 0;
43167
43332
  const validation = manifestPath2 ? buildLocalProjectContextValidationReport({ cwd, manifest: manifestPath2, now }) : void 0;
@@ -43208,15 +43373,15 @@ function buildLocalContextMutationPlan(options = {}) {
43208
43373
  approvalRequired: options.approvalRequired ?? true,
43209
43374
  expiresAt: options.expiresAt
43210
43375
  });
43211
- const planPath = options.output ? path39.resolve(cwd, options.output) : void 0;
43376
+ const planPath = options.output ? path41.resolve(cwd, options.output) : void 0;
43212
43377
  if (planPath) {
43213
43378
  writeStableJsonFile(planPath, plan);
43214
43379
  }
43215
43380
  return { plan, ...planPath ? { planPath } : {} };
43216
43381
  }
43217
43382
  function applyLocalContextMutationPlan(options) {
43218
- const cwd = path39.resolve(options.cwd ?? process.cwd());
43219
- const planPath = path39.resolve(cwd, options.plan);
43383
+ const cwd = path41.resolve(options.cwd ?? process.cwd());
43384
+ const planPath = path41.resolve(cwd, options.plan);
43220
43385
  const rawPlan = readJsonFile5(planPath);
43221
43386
  if (!isContextMutationPlan(rawPlan)) {
43222
43387
  throw new Error(`Invalid context mutation plan: ${options.plan}`);
@@ -43296,7 +43461,7 @@ function applyLocalContextMutationPlan(options) {
43296
43461
  baseRevisionAtApply: currentRevision
43297
43462
  });
43298
43463
  const receiptPath = receiptPathFor(pendingReceipt, cwd);
43299
- if (fs40.existsSync(receiptPath)) {
43464
+ if (fs42.existsSync(receiptPath)) {
43300
43465
  const receipt2 = buildContextMutationApplyReceipt({
43301
43466
  plan,
43302
43467
  appliedAt: options.now,
@@ -43333,8 +43498,8 @@ function applyLocalContextMutationPlan(options) {
43333
43498
  });
43334
43499
  continue;
43335
43500
  }
43336
- const absoluteTarget = path39.resolve(cwd, target);
43337
- if (operation.mode === "create" && fs40.existsSync(absoluteTarget)) {
43501
+ const absoluteTarget = path41.resolve(cwd, target);
43502
+ if (operation.mode === "create" && fs42.existsSync(absoluteTarget)) {
43338
43503
  throw new Error(`Refusing to overwrite existing context-control file: ${target}`);
43339
43504
  }
43340
43505
  writeStableJsonFile(absoluteTarget, operation.content ?? {});
@@ -43368,8 +43533,8 @@ function applyLocalContextMutationPlan(options) {
43368
43533
  };
43369
43534
  }
43370
43535
  function listJsonFiles2(dir) {
43371
- if (!fs40.existsSync(dir)) return [];
43372
- return fs40.readdirSync(dir).filter((name) => name.endsWith(".json")).map((name) => path39.join(dir, name)).sort((left, right) => left.localeCompare(right));
43536
+ if (!fs42.existsSync(dir)) return [];
43537
+ return fs42.readdirSync(dir).filter((name) => name.endsWith(".json")).map((name) => path41.join(dir, name)).sort((left, right) => left.localeCompare(right));
43373
43538
  }
43374
43539
  function readJsonFileSafe(filePath) {
43375
43540
  try {
@@ -43447,8 +43612,8 @@ function collectGitDriftSignals(cwd) {
43447
43612
  return [dirtySignal, upstreamSignal];
43448
43613
  }
43449
43614
  function collectWorkflowDriftSignals(cwd) {
43450
- const workflowPath = path39.join(cwd, ".snipara", "workflow", "current.json");
43451
- if (!fs40.existsSync(workflowPath)) {
43615
+ const workflowPath = path41.join(cwd, ".snipara", "workflow", "current.json");
43616
+ if (!fs42.existsSync(workflowPath)) {
43452
43617
  return [
43453
43618
  {
43454
43619
  id: "workflow-state-missing",
@@ -43493,7 +43658,7 @@ function collectWorkflowDriftSignals(cwd) {
43493
43658
  ];
43494
43659
  }
43495
43660
  function collectDecisionDriftSignals(cwd) {
43496
- const pendingDir = path39.join(cwd, ".snipara", "decisions", "pending");
43661
+ const pendingDir = path41.join(cwd, ".snipara", "decisions", "pending");
43497
43662
  const pending = listJsonFiles2(pendingDir).map((file) => toProjectRelativePath4(file, cwd));
43498
43663
  return [
43499
43664
  pending.length > 0 ? {
@@ -43518,8 +43683,8 @@ function collectDecisionDriftSignals(cwd) {
43518
43683
  ];
43519
43684
  }
43520
43685
  function collectContextControlDriftSignals(cwd) {
43521
- const planFiles = listJsonFiles2(path39.join(cwd, CONTEXT_CONTROL_PLANS_RELATIVE_DIR));
43522
- const receiptFiles = listJsonFiles2(path39.join(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR));
43686
+ const planFiles = listJsonFiles2(path41.join(cwd, CONTEXT_CONTROL_PLANS_RELATIVE_DIR));
43687
+ const receiptFiles = listJsonFiles2(path41.join(cwd, CONTEXT_CONTROL_APPLIED_RELATIVE_DIR));
43523
43688
  const receiptPlanHashes = new Set(
43524
43689
  receiptFiles.map((file) => readJsonFileSafe(file).value).filter(isContextMutationApplyReceipt).map((receipt) => receipt.planHash)
43525
43690
  );
@@ -43542,7 +43707,7 @@ function collectContextControlDriftSignals(cwd) {
43542
43707
  const read = readJsonFileSafe(file);
43543
43708
  if (!read.value || !isContextMutationPlan(read.value)) {
43544
43709
  return {
43545
- id: `context-control-plan-invalid-${path39.basename(file, ".json")}`,
43710
+ id: `context-control-plan-invalid-${path41.basename(file, ".json")}`,
43546
43711
  surface: "context_control",
43547
43712
  state: "UNKNOWN",
43548
43713
  summary: "A saved context mutation plan is invalid or unreadable.",
@@ -43591,7 +43756,7 @@ function collectContextControlDriftSignals(cwd) {
43591
43756
  function collectProjectContextManifestDriftSignals(cwd) {
43592
43757
  const manifestPath2 = resolveManifestPath(cwd);
43593
43758
  const relative15 = toProjectRelativePath4(manifestPath2, cwd);
43594
- if (!fs40.existsSync(manifestPath2)) {
43759
+ if (!fs42.existsSync(manifestPath2)) {
43595
43760
  return [
43596
43761
  {
43597
43762
  id: "project-context-manifest-missing",
@@ -43647,7 +43812,7 @@ function collectProjectContextManifestDriftSignals(cwd) {
43647
43812
  ];
43648
43813
  }
43649
43814
  function buildLocalProjectDriftReport(options = {}) {
43650
- const cwd = path39.resolve(options.cwd ?? process.cwd());
43815
+ const cwd = path41.resolve(options.cwd ?? process.cwd());
43651
43816
  return buildProjectDriftReport({
43652
43817
  generatedAt: options.now,
43653
43818
  signals: [
@@ -43794,23 +43959,23 @@ function resolveHostedContextSources(cwd, manifestPath2, report) {
43794
43959
  if (!report.manifest || report.status === "invalid") {
43795
43960
  throw new Error("ProjectContext manifest is invalid; run context-control validate first.");
43796
43961
  }
43797
- const workspaceRoot2 = fs40.realpathSync(cwd);
43962
+ const workspaceRoot2 = fs42.realpathSync(cwd);
43798
43963
  return report.manifest.sources.map((source2) => {
43799
- const candidate = path39.resolve(cwd, source2.path);
43800
- if (!fs40.existsSync(candidate)) {
43964
+ const candidate = path41.resolve(cwd, source2.path);
43965
+ if (!fs42.existsSync(candidate)) {
43801
43966
  throw new Error(`ProjectContext source is missing: ${source2.path}`);
43802
43967
  }
43803
- if (fs40.lstatSync(candidate).isSymbolicLink()) {
43968
+ if (fs42.lstatSync(candidate).isSymbolicLink()) {
43804
43969
  throw new Error(`ProjectContext source symlinks are not allowed: ${source2.path}`);
43805
43970
  }
43806
- const canonical = fs40.realpathSync(candidate);
43807
- if (canonical !== workspaceRoot2 && !canonical.startsWith(`${workspaceRoot2}${path39.sep}`)) {
43971
+ const canonical = fs42.realpathSync(candidate);
43972
+ if (canonical !== workspaceRoot2 && !canonical.startsWith(`${workspaceRoot2}${path41.sep}`)) {
43808
43973
  throw new Error(`ProjectContext source escapes the workspace: ${source2.path}`);
43809
43974
  }
43810
- if (!fs40.statSync(canonical).isFile()) {
43975
+ if (!fs42.statSync(canonical).isFile()) {
43811
43976
  throw new Error(`ProjectContext source must be a file: ${source2.path}`);
43812
43977
  }
43813
- const content = fs40.readFileSync(canonical, "utf8");
43978
+ const content = fs42.readFileSync(canonical, "utf8");
43814
43979
  if (Buffer.byteLength(content, "utf8") > 1e6) {
43815
43980
  throw new Error(`ProjectContext source exceeds 1 MB: ${source2.path}`);
43816
43981
  }
@@ -43831,7 +43996,7 @@ async function contextControlHostedDiffCommand(options) {
43831
43996
  plan: response.plan
43832
43997
  };
43833
43998
  if (options.output) {
43834
- const planPath = path39.resolve(cwd, options.output);
43999
+ const planPath = path41.resolve(cwd, options.output);
43835
44000
  writeStableJsonFile(planPath, response.plan);
43836
44001
  result.planPath = toProjectRelativePath4(planPath, cwd);
43837
44002
  }
@@ -43903,11 +44068,11 @@ async function contextControlHostedDiffCommand(options) {
43903
44068
  }
43904
44069
  async function contextControlHostedApplyCommand(options) {
43905
44070
  const cwd = process.cwd();
43906
- const rawPlan = readJsonFile5(path39.resolve(cwd, options.plan));
44071
+ const rawPlan = readJsonFile5(path41.resolve(cwd, options.plan));
43907
44072
  if (!isHostedContextControlPlan(rawPlan)) {
43908
44073
  throw new Error(`Invalid hosted Context Control plan: ${options.plan}`);
43909
44074
  }
43910
- const approval = options.approval ? readJsonFile5(path39.resolve(cwd, options.approval)) : void 0;
44075
+ const approval = options.approval ? readJsonFile5(path41.resolve(cwd, options.approval)) : void 0;
43911
44076
  const response = await createClient(12e4, { cwd }).applyHostedContextControl({
43912
44077
  plan: rawPlan,
43913
44078
  approval
@@ -43920,7 +44085,7 @@ async function contextControlHostedApplyCommand(options) {
43920
44085
  receipt: response.receipt
43921
44086
  };
43922
44087
  if (options.output) {
43923
- const receiptPath = path39.resolve(cwd, options.output);
44088
+ const receiptPath = path41.resolve(cwd, options.output);
43924
44089
  writeStableJsonFile(receiptPath, response.receipt);
43925
44090
  result.receiptPath = toProjectRelativePath4(receiptPath, cwd);
43926
44091
  }
@@ -43944,16 +44109,16 @@ function uniqueStrings25(values) {
43944
44109
  }
43945
44110
 
43946
44111
  // src/commands/agent-context-evidence.ts
43947
- var fs41 = __toESM(require("fs"));
43948
- var path40 = __toESM(require("path"));
43949
- var AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER = path40.join(
44112
+ var fs43 = __toESM(require("fs"));
44113
+ var path42 = __toESM(require("path"));
44114
+ var AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER = path42.join(
43950
44115
  ".snipara",
43951
44116
  "agent-context",
43952
44117
  "evidence.jsonl"
43953
44118
  );
43954
44119
  function readJson(filePath, label) {
43955
44120
  try {
43956
- return JSON.parse(fs41.readFileSync(filePath, "utf8"));
44121
+ return JSON.parse(fs43.readFileSync(filePath, "utf8"));
43957
44122
  } catch (error) {
43958
44123
  const message = error instanceof Error ? error.message : String(error);
43959
44124
  throw new Error(`Unable to read ${label} ${filePath}: ${message}`);
@@ -43961,7 +44126,7 @@ function readJson(filePath, label) {
43961
44126
  }
43962
44127
  function readManifest4(cwd, candidate) {
43963
44128
  return readJson(
43964
- path40.resolve(cwd, candidate ?? AGENT_CONTEXT_MANIFEST_DEFAULT_PATH),
44129
+ path42.resolve(cwd, candidate ?? AGENT_CONTEXT_MANIFEST_DEFAULT_PATH),
43965
44130
  "Agent Context manifest"
43966
44131
  );
43967
44132
  }
@@ -43979,8 +44144,8 @@ function receiptHash(receipt) {
43979
44144
  return hashDecisionJsonValue(base);
43980
44145
  }
43981
44146
  function readAgentContextEvidenceLedger(ledgerPath) {
43982
- if (!fs41.existsSync(ledgerPath)) return [];
43983
- const content = fs41.readFileSync(ledgerPath, "utf8").trim();
44147
+ if (!fs43.existsSync(ledgerPath)) return [];
44148
+ const content = fs43.readFileSync(ledgerPath, "utf8").trim();
43984
44149
  if (!content) return [];
43985
44150
  return content.split("\n").map((line, index) => {
43986
44151
  let candidate;
@@ -44006,23 +44171,23 @@ function writeJsonOutput(value, outputPath, force = false) {
44006
44171
  console.log(content.trimEnd());
44007
44172
  return void 0;
44008
44173
  }
44009
- if (fs41.existsSync(outputPath) && !force) {
44174
+ if (fs43.existsSync(outputPath) && !force) {
44010
44175
  throw new Error(
44011
44176
  `Refusing to overwrite existing file ${outputPath}; pass --force to replace it.`
44012
44177
  );
44013
44178
  }
44014
- fs41.mkdirSync(path40.dirname(outputPath), { recursive: true });
44015
- fs41.writeFileSync(outputPath, content, "utf8");
44179
+ fs43.mkdirSync(path42.dirname(outputPath), { recursive: true });
44180
+ fs43.writeFileSync(outputPath, content, "utf8");
44016
44181
  return outputPath;
44017
44182
  }
44018
44183
  function safeWorkflowReference(value, cwd) {
44019
44184
  if (typeof value !== "string" || !value.trim()) return void 0;
44020
44185
  const candidate = value.trim();
44021
44186
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(candidate)) return candidate;
44022
- const absolute = path40.isAbsolute(candidate) ? candidate : path40.resolve(cwd, candidate);
44023
- const relative15 = path40.relative(cwd, absolute);
44024
- if (!relative15 || relative15.startsWith("..") || path40.isAbsolute(relative15)) return void 0;
44025
- return relative15.replaceAll(path40.sep, "/");
44187
+ const absolute = path42.isAbsolute(candidate) ? candidate : path42.resolve(cwd, candidate);
44188
+ const relative15 = path42.relative(cwd, absolute);
44189
+ if (!relative15 || relative15.startsWith("..") || path42.isAbsolute(relative15)) return void 0;
44190
+ return relative15.replaceAll(path42.sep, "/");
44026
44191
  }
44027
44192
  function collectWorkflowProofRefs(workflow2, cwd) {
44028
44193
  if (!workflow2 || typeof workflow2 !== "object" || Array.isArray(workflow2)) {
@@ -44115,7 +44280,7 @@ function formatStatus(report, ledgerPath) {
44115
44280
  return lines.join("\n");
44116
44281
  }
44117
44282
  async function agentContextEvidenceTemplateCommand(options) {
44118
- const cwd = path40.resolve(options.cwd ?? process.cwd());
44283
+ const cwd = path42.resolve(options.cwd ?? process.cwd());
44119
44284
  const manifest = validatedManifest(cwd, options.manifest);
44120
44285
  const resolution = resolveAgentContext({
44121
44286
  manifest,
@@ -44123,19 +44288,19 @@ async function agentContextEvidenceTemplateCommand(options) {
44123
44288
  task: options.task
44124
44289
  });
44125
44290
  const template = buildAgentContextEvidenceTemplate(resolution);
44126
- const outputPath = options.output ? path40.resolve(cwd, options.output) : void 0;
44291
+ const outputPath = options.output ? path42.resolve(cwd, options.output) : void 0;
44127
44292
  const written = writeJsonOutput(template, outputPath, Boolean(options.force));
44128
44293
  if (written && !options.json) {
44129
- console.log(`Wrote AC-1 evidence template: ${path40.relative(cwd, written)}`);
44294
+ console.log(`Wrote AC-1 evidence template: ${path42.relative(cwd, written)}`);
44130
44295
  console.log("Complete the task evidence and proofRefs before recording it.");
44131
44296
  }
44132
44297
  }
44133
44298
  async function agentContextEvidenceCollectCommand(options) {
44134
- const cwd = path40.resolve(options.cwd ?? process.cwd());
44299
+ const cwd = path42.resolve(options.cwd ?? process.cwd());
44135
44300
  const manifest = validatedManifest(cwd, options.manifest);
44136
- const workflowPath = path40.resolve(
44301
+ const workflowPath = path42.resolve(
44137
44302
  cwd,
44138
- options.workflow ?? path40.join(".snipara", "workflow", "current.json")
44303
+ options.workflow ?? path42.join(".snipara", "workflow", "current.json")
44139
44304
  );
44140
44305
  const workflow2 = readJson(workflowPath, "workflow state");
44141
44306
  const workflowGoal = workflow2 && typeof workflow2 === "object" && !Array.isArray(workflow2) ? workflow2.goal : void 0;
@@ -44145,19 +44310,19 @@ async function agentContextEvidenceCollectCommand(options) {
44145
44310
  }
44146
44311
  const resolution = resolveAgentContext({ manifest, agent: options.agent, task });
44147
44312
  const draft = workflowDraftEvidence(buildAgentContextEvidenceTemplate(resolution), workflow2, cwd);
44148
- const outputPath = options.output ? path40.resolve(cwd, options.output) : void 0;
44313
+ const outputPath = options.output ? path42.resolve(cwd, options.output) : void 0;
44149
44314
  const written = writeJsonOutput(draft, outputPath, Boolean(options.force));
44150
44315
  if (written && !options.json) {
44151
- console.log(`Wrote AC-1 evidence draft from workflow: ${path40.relative(cwd, written)}`);
44316
+ console.log(`Wrote AC-1 evidence draft from workflow: ${path42.relative(cwd, written)}`);
44152
44317
  console.log(
44153
44318
  "Review usedSourceIds, executedRecallKeys, contextEffect, and capabilityAssessment before recording it."
44154
44319
  );
44155
44320
  }
44156
44321
  }
44157
44322
  async function agentContextEvidenceRecordCommand(options) {
44158
- const cwd = path40.resolve(options.cwd ?? process.cwd());
44323
+ const cwd = path42.resolve(options.cwd ?? process.cwd());
44159
44324
  const manifest = validatedManifest(cwd, options.manifest);
44160
- const evidencePath = path40.resolve(cwd, options.from);
44325
+ const evidencePath = path42.resolve(cwd, options.from);
44161
44326
  const evidence = readJson(evidencePath, "AC-1 evidence input");
44162
44327
  if (!evidence || typeof evidence !== "object" || Array.isArray(evidence)) {
44163
44328
  throw new Error("AC-1 evidence input must be a JSON object.");
@@ -44169,25 +44334,25 @@ async function agentContextEvidenceRecordCommand(options) {
44169
44334
  }
44170
44335
  const resolution = resolveAgentContext({ manifest, agent, task });
44171
44336
  const receipt = buildAgentContextEvidenceReceipt({ resolution, evidence });
44172
- const ledgerPath = path40.resolve(cwd, options.ledger ?? AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER);
44337
+ const ledgerPath = path42.resolve(cwd, options.ledger ?? AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER);
44173
44338
  const existing = readAgentContextEvidenceLedger(ledgerPath);
44174
44339
  if (existing.some((candidate) => candidate.taskId === receipt.taskId)) {
44175
44340
  throw new Error(`Evidence taskId already exists in the ledger: ${receipt.taskId}.`);
44176
44341
  }
44177
- fs41.mkdirSync(path40.dirname(ledgerPath), { recursive: true });
44178
- fs41.appendFileSync(ledgerPath, `${JSON.stringify(receipt)}
44342
+ fs43.mkdirSync(path42.dirname(ledgerPath), { recursive: true });
44343
+ fs43.appendFileSync(ledgerPath, `${JSON.stringify(receipt)}
44179
44344
  `, "utf8");
44180
44345
  if (options.json) {
44181
44346
  console.log(JSON.stringify(receipt, null, 2));
44182
44347
  } else {
44183
44348
  console.log(`Recorded AC-1 evidence: ${receipt.taskId}`);
44184
- console.log(`Ledger: ${path40.relative(cwd, ledgerPath)}`);
44349
+ console.log(`Ledger: ${path42.relative(cwd, ledgerPath)}`);
44185
44350
  console.log(`Receipt: ${receipt.receiptHash}`);
44186
44351
  }
44187
44352
  return receipt;
44188
44353
  }
44189
44354
  async function agentContextEvidenceStatusCommand(options = {}) {
44190
- const cwd = path40.resolve(options.cwd ?? process.cwd());
44355
+ const cwd = path42.resolve(options.cwd ?? process.cwd());
44191
44356
  const validation = buildLocalAgentContextValidationReport({
44192
44357
  cwd,
44193
44358
  manifest: readManifest4(cwd, options.manifest)
@@ -44197,7 +44362,7 @@ async function agentContextEvidenceStatusCommand(options = {}) {
44197
44362
  throw new Error(`Invalid Agent Context manifest. ${errors}`.trim());
44198
44363
  }
44199
44364
  const manifest = validation.manifest;
44200
- const ledgerPath = path40.resolve(cwd, options.ledger ?? AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER);
44365
+ const ledgerPath = path42.resolve(cwd, options.ledger ?? AGENT_CONTEXT_EVIDENCE_DEFAULT_LEDGER);
44201
44366
  const receipts = readAgentContextEvidenceLedger(ledgerPath);
44202
44367
  const report = buildAgentContextEvidenceReport({
44203
44368
  receipts,
@@ -44205,7 +44370,7 @@ async function agentContextEvidenceStatusCommand(options = {}) {
44205
44370
  manifestHash: validation.manifestHash
44206
44371
  });
44207
44372
  console.log(
44208
- options.json ? JSON.stringify(report, null, 2) : formatStatus(report, path40.relative(cwd, ledgerPath))
44373
+ options.json ? JSON.stringify(report, null, 2) : formatStatus(report, path42.relative(cwd, ledgerPath))
44209
44374
  );
44210
44375
  if (options.enforce && report.status !== "ready") process.exitCode = 1;
44211
44376
  return report;
@@ -44213,12 +44378,12 @@ async function agentContextEvidenceStatusCommand(options = {}) {
44213
44378
 
44214
44379
  // src/commands/references.ts
44215
44380
  var crypto7 = __toESM(require("crypto"));
44216
- var fs42 = __toESM(require("fs"));
44217
- var path41 = __toESM(require("path"));
44381
+ var fs44 = __toESM(require("fs"));
44382
+ var path43 = __toESM(require("path"));
44218
44383
  var import_chalk17 = __toESM(require("chalk"));
44219
44384
  var MANIFEST_VERSION2 = "snipara.references.v1";
44220
- var DEFAULT_MANIFEST_PATH = path41.join(".snipara", "references", "manifest.json");
44221
- var DEFAULT_SNAPSHOT_DIR = path41.join(".snipara", "references", "snapshots");
44385
+ var DEFAULT_MANIFEST_PATH = path43.join(".snipara", "references", "manifest.json");
44386
+ var DEFAULT_SNAPSHOT_DIR = path43.join(".snipara", "references", "snapshots");
44222
44387
  var DEFAULT_DESTINATION_PREFIX = "external-references";
44223
44388
  var DEFAULT_SCAN_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx", ".txt", ".rst"]);
44224
44389
  var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
@@ -44294,27 +44459,27 @@ function sanitizeSegment(value, fallback) {
44294
44459
  return sanitized || fallback;
44295
44460
  }
44296
44461
  function toRelative(root, file) {
44297
- return path41.relative(root, file).split(path41.sep).join("/");
44462
+ return path43.relative(root, file).split(path43.sep).join("/");
44298
44463
  }
44299
44464
  function ensureParentDir(file) {
44300
- fs42.mkdirSync(path41.dirname(file), { recursive: true });
44465
+ fs44.mkdirSync(path43.dirname(file), { recursive: true });
44301
44466
  }
44302
44467
  function walkFiles(root, extensions, maxFiles, files = []) {
44303
44468
  if (files.length >= maxFiles) {
44304
44469
  return files;
44305
44470
  }
44306
- for (const entry of fs42.readdirSync(root, { withFileTypes: true })) {
44471
+ for (const entry of fs44.readdirSync(root, { withFileTypes: true })) {
44307
44472
  if (files.length >= maxFiles) {
44308
44473
  break;
44309
44474
  }
44310
- const fullPath = path41.join(root, entry.name);
44475
+ const fullPath = path43.join(root, entry.name);
44311
44476
  if (entry.isDirectory()) {
44312
44477
  if (!DEFAULT_IGNORE_DIRS.has(entry.name)) {
44313
44478
  walkFiles(fullPath, extensions, maxFiles, files);
44314
44479
  }
44315
44480
  continue;
44316
44481
  }
44317
- if (entry.isFile() && extensions.has(path41.extname(entry.name).toLowerCase())) {
44482
+ if (entry.isFile() && extensions.has(path43.extname(entry.name).toLowerCase())) {
44318
44483
  files.push(fullPath);
44319
44484
  }
44320
44485
  }
@@ -44324,7 +44489,7 @@ function collectReferenceItems(root, files, allowDomains, denyDomains) {
44324
44489
  const byUrl = /* @__PURE__ */ new Map();
44325
44490
  const discoveredAt = (/* @__PURE__ */ new Date()).toISOString();
44326
44491
  for (const file of files) {
44327
- const content = fs42.readFileSync(file, "utf-8");
44492
+ const content = fs44.readFileSync(file, "utf-8");
44328
44493
  const lines = content.split(/\r?\n/);
44329
44494
  const markdownLink = /\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g;
44330
44495
  const bareUrl = /https?:\/\/[^\s<>"'`]+/g;
@@ -44369,8 +44534,8 @@ function collectReferenceItems(root, files, allowDomains, denyDomains) {
44369
44534
  return Array.from(byUrl.values()).sort((a, b) => a.normalizedUrl.localeCompare(b.normalizedUrl));
44370
44535
  }
44371
44536
  function scanReferences(options = {}) {
44372
- const root = path41.resolve(options.root ?? process.cwd());
44373
- const outputPath = path41.resolve(root, options.output ?? DEFAULT_MANIFEST_PATH);
44537
+ const root = path43.resolve(options.root ?? process.cwd());
44538
+ const outputPath = path43.resolve(root, options.output ?? DEFAULT_MANIFEST_PATH);
44374
44539
  const allowDomains = normalizeList(options.allowDomain);
44375
44540
  const denyDomains = normalizeList(options.denyDomain);
44376
44541
  const extensions = new Set(
@@ -44390,7 +44555,7 @@ function scanReferences(options = {}) {
44390
44555
  items
44391
44556
  };
44392
44557
  ensureParentDir(outputPath);
44393
- fs42.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
44558
+ fs44.writeFileSync(outputPath, `${JSON.stringify(manifest, null, 2)}
44394
44559
  `, "utf-8");
44395
44560
  return {
44396
44561
  manifest,
@@ -44404,7 +44569,7 @@ function scanReferences(options = {}) {
44404
44569
  };
44405
44570
  }
44406
44571
  function readManifest5(file) {
44407
- const manifest = JSON.parse(fs42.readFileSync(file, "utf-8"));
44572
+ const manifest = JSON.parse(fs44.readFileSync(file, "utf-8"));
44408
44573
  if (manifest.version !== MANIFEST_VERSION2 || !Array.isArray(manifest.items)) {
44409
44574
  throw new Error(`${file} is not a ${MANIFEST_VERSION2} manifest`);
44410
44575
  }
@@ -44472,8 +44637,8 @@ async function fetchReference(item, outputDir, destinationPrefix, timeoutMs, max
44472
44637
  slugSource,
44473
44638
  item.id
44474
44639
  )}-${item.id}.md`;
44475
- const snapshotPath = path41.resolve(outputDir, fileName);
44476
- const destinationPath = path41.posix.join(
44640
+ const snapshotPath = path43.resolve(outputDir, fileName);
44641
+ const destinationPath = path43.posix.join(
44477
44642
  destinationPrefix.replace(/^\/+|\/+$/g, "") || DEFAULT_DESTINATION_PREFIX,
44478
44643
  fileName
44479
44644
  );
@@ -44489,7 +44654,7 @@ async function fetchReference(item, outputDir, destinationPrefix, timeoutMs, max
44489
44654
  bodyHash: hash
44490
44655
  });
44491
44656
  ensureParentDir(snapshotPath);
44492
- fs42.writeFileSync(snapshotPath, markdown, "utf-8");
44657
+ fs44.writeFileSync(snapshotPath, markdown, "utf-8");
44493
44658
  return {
44494
44659
  item,
44495
44660
  fetchedAt,
@@ -44518,14 +44683,14 @@ function selectItems(manifest, options, allowDomains) {
44518
44683
  return typeof options.max === "number" && options.max > 0 ? selected.slice(0, options.max) : selected;
44519
44684
  }
44520
44685
  async function ingestReferences(options = {}) {
44521
- const manifestPath2 = path41.resolve(options.manifest ?? DEFAULT_MANIFEST_PATH);
44686
+ const manifestPath2 = path43.resolve(options.manifest ?? DEFAULT_MANIFEST_PATH);
44522
44687
  const manifest = readManifest5(manifestPath2);
44523
- const root = manifest.root ? path41.resolve(manifest.root) : process.cwd();
44688
+ const root = manifest.root ? path43.resolve(manifest.root) : process.cwd();
44524
44689
  const allowDomains = normalizeList([
44525
44690
  ...manifest.allowDomains ?? [],
44526
44691
  ...options.allowDomain ?? []
44527
44692
  ]);
44528
- const outputDir = path41.resolve(root, options.outputDir ?? DEFAULT_SNAPSHOT_DIR);
44693
+ const outputDir = path43.resolve(root, options.outputDir ?? DEFAULT_SNAPSHOT_DIR);
44529
44694
  const destinationPrefix = options.destinationPrefix ?? DEFAULT_DESTINATION_PREFIX;
44530
44695
  const items = selectItems(manifest, options, allowDomains);
44531
44696
  const summary = {
@@ -44552,7 +44717,7 @@ async function ingestReferences(options = {}) {
44552
44717
  options.maxBytes ?? 512 * 1024
44553
44718
  );
44554
44719
  summary.fetched += 1;
44555
- item.latestSnapshotPath = path41.relative(root, snapshot.snapshotPath).split(path41.sep).join("/");
44720
+ item.latestSnapshotPath = path43.relative(root, snapshot.snapshotPath).split(path43.sep).join("/");
44556
44721
  item.latestFetchStatus = snapshot.status;
44557
44722
  item.latestFetchAt = snapshot.fetchedAt;
44558
44723
  item.latestContentHash = snapshot.contentHash;
@@ -44599,7 +44764,7 @@ async function ingestReferences(options = {}) {
44599
44764
  });
44600
44765
  }
44601
44766
  }
44602
- fs42.writeFileSync(manifestPath2, `${JSON.stringify(manifest, null, 2)}
44767
+ fs44.writeFileSync(manifestPath2, `${JSON.stringify(manifest, null, 2)}
44603
44768
  `, "utf-8");
44604
44769
  if (options.reindex && client) {
44605
44770
  await client.reindex({ kind: "doc", mode: "incremental" });
@@ -44651,8 +44816,8 @@ async function referencesIngestCommand(options) {
44651
44816
  }
44652
44817
 
44653
44818
  // src/commands/policy-ledger-sync.ts
44654
- var fs43 = __toESM(require("fs"));
44655
- var path42 = __toESM(require("path"));
44819
+ var fs45 = __toESM(require("fs"));
44820
+ var path44 = __toESM(require("path"));
44656
44821
  var POLICY_LEDGER_SYNC_REPORT_VERSION = "snipara.workflow_policy_ledger_sync.v0";
44657
44822
  function buildPolicyLedgerSyncReport(options = {}) {
44658
44823
  const cwd = options.cwd ?? process.cwd();
@@ -44719,7 +44884,7 @@ function collectPolicyLedgerSyncArtifacts(cwd = process.cwd()) {
44719
44884
  applyState: applyItem?.state ?? "manual_follow_up_required",
44720
44885
  humanChoice: record2.response.choice,
44721
44886
  summary: record2.request.evidence.summary,
44722
- sourcePath: path42.join(
44887
+ sourcePath: path44.join(
44723
44888
  ".snipara",
44724
44889
  "decisions",
44725
44890
  "resolved",
@@ -44729,10 +44894,10 @@ function collectPolicyLedgerSyncArtifacts(cwd = process.cwd()) {
44729
44894
  payload: record2
44730
44895
  };
44731
44896
  });
44732
- const applyArtifacts = readJsonFiles(path42.join(cwd, DECISION_APPLY_RELATIVE_DIR), cwd).map(
44897
+ const applyArtifacts = readJsonFiles(path44.join(cwd, DECISION_APPLY_RELATIVE_DIR), cwd).map(
44733
44898
  ({ parsed, relativePath: relativePath2 }) => ({
44734
44899
  kind: "apply_receipt",
44735
- requestId: stringField(parsed, "requestId") ?? path42.basename(relativePath2, ".json"),
44900
+ requestId: stringField(parsed, "requestId") ?? path44.basename(relativePath2, ".json"),
44736
44901
  fingerprint: stringField(parsed, "fingerprint"),
44737
44902
  title: stringField(parsed, "question") ?? stringField(parsed, "decision") ?? "Applied decision",
44738
44903
  status: statusForChoiceClass(stringField(parsed, "choiceClass")),
@@ -44744,10 +44909,10 @@ function collectPolicyLedgerSyncArtifacts(cwd = process.cwd()) {
44744
44909
  payload: parsed
44745
44910
  })
44746
44911
  );
44747
- const draftArtifacts = readJsonFiles(path42.join(cwd, POLICY_DRAFT_RELATIVE_DIR), cwd).map(
44912
+ const draftArtifacts = readJsonFiles(path44.join(cwd, POLICY_DRAFT_RELATIVE_DIR), cwd).map(
44748
44913
  ({ parsed, relativePath: relativePath2 }) => ({
44749
44914
  kind: "policy_draft",
44750
- requestId: stringField(parsed, "requestId") ?? path42.basename(relativePath2, ".json"),
44915
+ requestId: stringField(parsed, "requestId") ?? path44.basename(relativePath2, ".json"),
44751
44916
  fingerprint: stringField(parsed, "fingerprint"),
44752
44917
  title: stringField(parsed, "title") ?? "Policy draft",
44753
44918
  status: "modified",
@@ -44799,12 +44964,12 @@ function statusForChoiceClass(choiceClass) {
44799
44964
  return "modified";
44800
44965
  }
44801
44966
  function readJsonFiles(directory, cwd) {
44802
- if (!fs43.existsSync(directory)) {
44967
+ if (!fs45.existsSync(directory)) {
44803
44968
  return [];
44804
44969
  }
44805
- return fs43.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
44806
- const filePath = path42.join(directory, fileName);
44807
- const parsed = JSON.parse(fs43.readFileSync(filePath, "utf8"));
44970
+ return fs45.readdirSync(directory).filter((fileName) => fileName.endsWith(".json")).sort().map((fileName) => {
44971
+ const filePath = path44.join(directory, fileName);
44972
+ const parsed = JSON.parse(fs45.readFileSync(filePath, "utf8"));
44808
44973
  return { parsed, relativePath: toProjectRelativePath5(filePath, cwd) };
44809
44974
  });
44810
44975
  }
@@ -44813,8 +44978,8 @@ function stringField(value, key) {
44813
44978
  return typeof field === "string" && field.trim() ? field : void 0;
44814
44979
  }
44815
44980
  function toProjectRelativePath5(absolutePath, cwd) {
44816
- const relative15 = path42.relative(cwd, absolutePath).replace(/\\/g, "/");
44817
- return relative15.startsWith(".") ? relative15 : `.${path42.sep}${relative15}`.replace(/\\/g, "/");
44981
+ const relative15 = path44.relative(cwd, absolutePath).replace(/\\/g, "/");
44982
+ return relative15.startsWith(".") ? relative15 : `.${path44.sep}${relative15}`.replace(/\\/g, "/");
44818
44983
  }
44819
44984
 
44820
44985
  // src/commands/htask.ts
@@ -45399,8 +45564,24 @@ program.command("post-tool").description("Track file access (PostToolUse hook)")
45399
45564
  packResult: Boolean(options.packResult)
45400
45565
  });
45401
45566
  });
45402
- program.command("session-end").description("Persist session context (Stop hook)").action(async () => {
45403
- await sessionEndCommand();
45567
+ program.command("session-end").description("Persist a session checkpoint with a verifiable journal receipt (Stop hook)").option("--summary <summary>", "Bounded session summary to preserve").option("--summary-stdin", "Read the session summary from stdin").option("--files <files...>", "Files represented by this checkpoint").option("--session-id <sessionId>", "Host session id; do not rotate the workspace session").option("--retry <receipt>", "Retry a retained local checkpoint receipt").option("--json", "Print the persistence receipt as JSON").action(async (options) => {
45568
+ if (options.retry && (options.summary || options.summaryStdin || options.files)) {
45569
+ throw new Error("--retry cannot be combined with new checkpoint content");
45570
+ }
45571
+ let summary = options.summary;
45572
+ if (options.summaryStdin) {
45573
+ if (summary !== void 0) throw new Error("Choose --summary or --summary-stdin");
45574
+ const chunks = [];
45575
+ let bytes = 0;
45576
+ for await (const chunk of process.stdin) {
45577
+ const buffer = Buffer.from(chunk);
45578
+ bytes += buffer.length;
45579
+ if (bytes > 128e3) throw new Error("Session summary exceeds 128000 bytes");
45580
+ chunks.push(buffer);
45581
+ }
45582
+ summary = Buffer.concat(chunks).toString("utf8");
45583
+ }
45584
+ await sessionEndCommand({ ...options, summary });
45404
45585
  });
45405
45586
  program.command("session").description("Session management").addCommand(
45406
45587
  new import_commander.Command("status").description("Show session status").action(async () => {