@hasna/todos 0.11.69 → 0.11.70

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
@@ -24961,6 +24961,294 @@ function listCyclesWithStats(options = {}, db) {
24961
24961
  };
24962
24962
  });
24963
24963
  }
24964
+ // src/lib/plan-artifacts.ts
24965
+ init_database();
24966
+ import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
24967
+ import { join as join10, resolve as resolve10 } from "path";
24968
+ var PLAN_MARKDOWN_SCHEMA = "hasna.todos.plan/v1";
24969
+ function assertSafePathSegment(value, label) {
24970
+ const trimmed = value.trim();
24971
+ if (!trimmed || trimmed === "." || trimmed === ".." || trimmed.includes("/") || trimmed.includes("\\")) {
24972
+ throw new Error(`Invalid ${label} for plan artifact path`);
24973
+ }
24974
+ if (!/^[A-Za-z0-9._-]+$/.test(trimmed)) {
24975
+ throw new Error(`Invalid ${label} for plan artifact path`);
24976
+ }
24977
+ return trimmed;
24978
+ }
24979
+ function frontmatterScalar(value) {
24980
+ return JSON.stringify(value);
24981
+ }
24982
+ function parseFrontmatterScalar(value) {
24983
+ const trimmed = value.trim();
24984
+ if (trimmed === "null")
24985
+ return null;
24986
+ try {
24987
+ const parsed = JSON.parse(trimmed);
24988
+ if (parsed === null || typeof parsed === "string")
24989
+ return parsed;
24990
+ } catch {}
24991
+ return trimmed.replace(/^["']|["']$/g, "") || null;
24992
+ }
24993
+ function markdownEscape(text) {
24994
+ return text.replace(/<!--[\s\S]*?-->/g, "").trim();
24995
+ }
24996
+ function markdownLine(text) {
24997
+ return markdownEscape(text).replace(/\s+/g, " ").trim();
24998
+ }
24999
+ function projectSlugMatches(project, ref) {
25000
+ const normalized = slugify(ref);
25001
+ return Boolean(normalized) && (project.task_list_id === normalized || slugify(project.name) === normalized);
25002
+ }
25003
+ function resolvePlanArtifactProject(input) {
25004
+ const db = input.db || getDatabase();
25005
+ const ref = input.project_id || input.project_ref;
25006
+ if (!ref)
25007
+ throw new Error("Plan artifacts require a project id or project reference");
25008
+ const byPath = getProjectByPath(resolve10(ref), db);
25009
+ if (byPath)
25010
+ return byPath;
25011
+ const resolvedId = resolvePartialId(db, "projects", ref);
25012
+ if (resolvedId) {
25013
+ const project2 = getProject(resolvedId, db);
25014
+ if (project2)
25015
+ return project2;
25016
+ }
25017
+ const project = listProjects(db).find((candidate) => projectSlugMatches(candidate, ref));
25018
+ if (project)
25019
+ return project;
25020
+ throw new Error(`Project not found for plan artifacts: ${ref}`);
25021
+ }
25022
+ function resolvePlanArtifactPaths(input) {
25023
+ const project = resolvePlanArtifactProject(input);
25024
+ const projectId = assertSafePathSegment(project.id, "project id");
25025
+ const projectRoot = resolve10(project.path);
25026
+ const directory = join10(projectRoot, ".hasna", "todos", "plans", projectId);
25027
+ const planId = input.plan_id ? assertSafePathSegment(input.plan_id, "plan id") : null;
25028
+ return {
25029
+ project_id: project.id,
25030
+ project_root: projectRoot,
25031
+ directory,
25032
+ file_path: planId ? join10(directory, `${planId}.md`) : directory
25033
+ };
25034
+ }
25035
+ function buildPlanArtifactSnapshot(plan, tasks = [], artifactUpdatedAt = new Date().toISOString()) {
25036
+ if (!plan.project_id)
25037
+ throw new Error("Plan artifacts require a project-scoped plan");
25038
+ const taskReferences = tasks.map((task2) => ({
25039
+ task_id: task2.id,
25040
+ title: task2.title,
25041
+ status: task2.status,
25042
+ priority: task2.priority
25043
+ }));
25044
+ const body = renderPlanArtifactBody(plan, taskReferences);
25045
+ return {
25046
+ metadata: {
25047
+ schema: PLAN_MARKDOWN_SCHEMA,
25048
+ plan_id: plan.id,
25049
+ project_id: plan.project_id,
25050
+ task_list_id: plan.task_list_id ?? null,
25051
+ agent_id: plan.agent_id ?? null,
25052
+ stable_id: plan.id,
25053
+ name: plan.name,
25054
+ status: plan.status,
25055
+ created_at: plan.created_at,
25056
+ updated_at: plan.updated_at,
25057
+ artifact_updated_at: artifactUpdatedAt
25058
+ },
25059
+ task_references: taskReferences,
25060
+ body
25061
+ };
25062
+ }
25063
+ function renderPlanArtifactBody(plan, tasks) {
25064
+ const lines = [`# ${markdownLine(plan.name) || plan.id}`, ""];
25065
+ if (plan.description?.trim()) {
25066
+ lines.push(markdownEscape(plan.description), "");
25067
+ }
25068
+ lines.push("## Tasks", "");
25069
+ if (tasks.length === 0) {
25070
+ lines.push("_No tasks are currently attached to this plan._", "");
25071
+ } else {
25072
+ for (const task2 of tasks) {
25073
+ const check = task2.status === "completed" ? "x" : " ";
25074
+ lines.push(`- [${check}] ${markdownLine(task2.title) || task2.task_id}`);
25075
+ lines.push(` <!-- todos: task_id=${task2.task_id} status=${task2.status} priority=${task2.priority} -->`);
25076
+ }
25077
+ lines.push("");
25078
+ }
25079
+ return lines.join(`
25080
+ `);
25081
+ }
25082
+ function renderPlanArtifactMarkdown(snapshot) {
25083
+ const metadata = snapshot.metadata;
25084
+ const lines = [
25085
+ "---",
25086
+ `schema: ${frontmatterScalar(metadata.schema)}`,
25087
+ `plan_id: ${frontmatterScalar(metadata.plan_id)}`,
25088
+ `project_id: ${frontmatterScalar(metadata.project_id)}`,
25089
+ `task_list_id: ${frontmatterScalar(metadata.task_list_id)}`,
25090
+ `agent_id: ${frontmatterScalar(metadata.agent_id)}`,
25091
+ `stable_id: ${frontmatterScalar(metadata.stable_id)}`,
25092
+ `name: ${frontmatterScalar(metadata.name)}`,
25093
+ `status: ${frontmatterScalar(metadata.status)}`,
25094
+ `created_at: ${frontmatterScalar(metadata.created_at)}`,
25095
+ `updated_at: ${frontmatterScalar(metadata.updated_at)}`,
25096
+ `artifact_updated_at: ${frontmatterScalar(metadata.artifact_updated_at)}`,
25097
+ "---",
25098
+ "",
25099
+ snapshot.body
25100
+ ];
25101
+ return `${lines.join(`
25102
+ `).replace(/\n{3,}/g, `
25103
+
25104
+ `).trimEnd()}
25105
+ `;
25106
+ }
25107
+ function parsePlanArtifactMarkdown(markdown) {
25108
+ const match = markdown.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
25109
+ if (!match)
25110
+ throw new Error("Invalid plan artifact: missing frontmatter");
25111
+ const rawMetadata = {};
25112
+ for (const line of match[1].split(/\r?\n/)) {
25113
+ const separator = line.indexOf(":");
25114
+ if (separator === -1)
25115
+ continue;
25116
+ const key = line.slice(0, separator).trim();
25117
+ const value = line.slice(separator + 1);
25118
+ rawMetadata[key] = parseFrontmatterScalar(value);
25119
+ }
25120
+ if (rawMetadata.schema !== PLAN_MARKDOWN_SCHEMA) {
25121
+ throw new Error(`Unsupported plan artifact schema: ${rawMetadata.schema ?? "unknown"}`);
25122
+ }
25123
+ const required = ["plan_id", "project_id", "stable_id", "name", "status", "created_at", "updated_at", "artifact_updated_at"];
25124
+ for (const key of required) {
25125
+ if (!rawMetadata[key])
25126
+ throw new Error(`Invalid plan artifact: missing ${key}`);
25127
+ }
25128
+ const body = match[2] ?? "";
25129
+ return {
25130
+ metadata: {
25131
+ schema: PLAN_MARKDOWN_SCHEMA,
25132
+ plan_id: rawMetadata.plan_id,
25133
+ project_id: rawMetadata.project_id,
25134
+ task_list_id: rawMetadata.task_list_id ?? null,
25135
+ agent_id: rawMetadata.agent_id ?? null,
25136
+ stable_id: rawMetadata.stable_id,
25137
+ name: rawMetadata.name,
25138
+ status: rawMetadata.status,
25139
+ created_at: rawMetadata.created_at,
25140
+ updated_at: rawMetadata.updated_at,
25141
+ artifact_updated_at: rawMetadata.artifact_updated_at
25142
+ },
25143
+ task_references: parseTaskReferences(body),
25144
+ body
25145
+ };
25146
+ }
25147
+ function parseTaskReferences(body) {
25148
+ const references = [];
25149
+ const taskLine2 = /^\s*-\s+\[[ xX]\]\s+(.+)$/;
25150
+ const metadataLine = /<!--\s*todos:\s*task_id=([A-Za-z0-9._-]+)\s+status=([A-Za-z_]+)\s+priority=([A-Za-z_]+)\s*-->/;
25151
+ const lines = body.split(/\r?\n/);
25152
+ for (let index = 0;index < lines.length; index++) {
25153
+ const titleMatch = lines[index].match(taskLine2);
25154
+ if (!titleMatch)
25155
+ continue;
25156
+ const metadataMatch = lines[index + 1]?.match(metadataLine);
25157
+ if (!metadataMatch)
25158
+ continue;
25159
+ references.push({
25160
+ task_id: metadataMatch[1],
25161
+ title: titleMatch[1].trim(),
25162
+ status: metadataMatch[2],
25163
+ priority: metadataMatch[3]
25164
+ });
25165
+ }
25166
+ return references;
25167
+ }
25168
+ function writePlanArtifact(plan, db) {
25169
+ if (!plan.project_id)
25170
+ return null;
25171
+ const d = db || getDatabase();
25172
+ const tasks = listTasks({ plan_id: plan.id, include_archived: true }, d);
25173
+ const paths = resolvePlanArtifactPaths({ project_id: plan.project_id, plan_id: plan.id, db: d });
25174
+ const snapshot = buildPlanArtifactSnapshot(plan, tasks);
25175
+ mkdirSync8(paths.directory, { recursive: true });
25176
+ writeFileSync6(paths.file_path, renderPlanArtifactMarkdown(snapshot), "utf8");
25177
+ return { path: paths.file_path, snapshot };
25178
+ }
25179
+ function readPlanArtifact(plan, db) {
25180
+ if (!plan.project_id)
25181
+ return null;
25182
+ const d = db || getDatabase();
25183
+ const paths = resolvePlanArtifactPaths({ project_id: plan.project_id, plan_id: plan.id, db: d });
25184
+ if (!existsSync9(paths.file_path))
25185
+ return null;
25186
+ const markdown = readFileSync7(paths.file_path, "utf8");
25187
+ return {
25188
+ path: paths.file_path,
25189
+ markdown,
25190
+ ...parsePlanArtifactMarkdown(markdown)
25191
+ };
25192
+ }
25193
+ function inspectPlanArtifact(plan, db) {
25194
+ if (!plan.project_id)
25195
+ return null;
25196
+ const d = db || getDatabase();
25197
+ const paths = resolvePlanArtifactPaths({ project_id: plan.project_id, plan_id: plan.id, db: d });
25198
+ if (!existsSync9(paths.file_path)) {
25199
+ return {
25200
+ path: paths.file_path,
25201
+ exists: false,
25202
+ parse_error: null,
25203
+ metadata: null,
25204
+ task_references: [],
25205
+ conflicts: []
25206
+ };
25207
+ }
25208
+ try {
25209
+ const artifact = parsePlanArtifactMarkdown(readFileSync7(paths.file_path, "utf8"));
25210
+ return {
25211
+ path: paths.file_path,
25212
+ exists: true,
25213
+ parse_error: null,
25214
+ metadata: artifact.metadata,
25215
+ task_references: artifact.task_references,
25216
+ conflicts: comparePlanArtifact(plan, artifact, listTasks({ plan_id: plan.id, include_archived: true }, d))
25217
+ };
25218
+ } catch (error) {
25219
+ return {
25220
+ path: paths.file_path,
25221
+ exists: true,
25222
+ parse_error: error instanceof Error ? error.message : String(error),
25223
+ metadata: null,
25224
+ task_references: [],
25225
+ conflicts: []
25226
+ };
25227
+ }
25228
+ }
25229
+ function comparePlanArtifact(plan, artifact, tasks) {
25230
+ const conflicts = [];
25231
+ compare("plan_id", plan.id, artifact.metadata.plan_id, conflicts);
25232
+ compare("project_id", plan.project_id ?? null, artifact.metadata.project_id, conflicts);
25233
+ compare("name", plan.name, artifact.metadata.name, conflicts);
25234
+ compare("status", plan.status, artifact.metadata.status, conflicts);
25235
+ compare("updated_at", plan.updated_at, artifact.metadata.updated_at, conflicts);
25236
+ const dbTaskIds = tasks.map((task2) => task2.id).sort();
25237
+ const artifactTaskIds = artifact.task_references.map((task2) => task2.task_id).sort();
25238
+ if (dbTaskIds.join(",") !== artifactTaskIds.join(",")) {
25239
+ conflicts.push({
25240
+ field: "task_references",
25241
+ database: dbTaskIds.join(",") || null,
25242
+ artifact: artifactTaskIds.join(",") || null
25243
+ });
25244
+ }
25245
+ return conflicts;
25246
+ }
25247
+ function compare(field2, database, artifact, conflicts) {
25248
+ if ((database ?? null) !== (artifact ?? null)) {
25249
+ conflicts.push({ field: field2, database: database ?? null, artifact: artifact ?? null });
25250
+ }
25251
+ }
24964
25252
  // src/db/project-knowledge.ts
24965
25253
  init_database();
24966
25254
 
@@ -25989,8 +26277,8 @@ function renderRetrospectiveMarkdown(record) {
25989
26277
  }
25990
26278
  // src/lib/project-bootstrap.ts
25991
26279
  init_database();
25992
- import { existsSync as existsSync9, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
25993
- import { basename as basename2, dirname as dirname7, resolve as resolve10 } from "path";
26280
+ import { existsSync as existsSync10, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
26281
+ import { basename as basename2, dirname as dirname7, resolve as resolve11 } from "path";
25994
26282
  function safeStat(path) {
25995
26283
  try {
25996
26284
  return statSync3(path);
@@ -25999,7 +26287,7 @@ function safeStat(path) {
25999
26287
  }
26000
26288
  }
26001
26289
  function canonicalPath(input) {
26002
- const resolved = resolve10(input);
26290
+ const resolved = resolve11(input);
26003
26291
  const stats2 = safeStat(resolved);
26004
26292
  if (stats2?.isFile())
26005
26293
  return dirname7(resolved);
@@ -26008,7 +26296,7 @@ function canonicalPath(input) {
26008
26296
  function findUp(start, marker) {
26009
26297
  let current = canonicalPath(start);
26010
26298
  while (true) {
26011
- if (existsSync9(resolve10(current, marker)))
26299
+ if (existsSync10(resolve11(current, marker)))
26012
26300
  return current;
26013
26301
  const parent = dirname7(current);
26014
26302
  if (parent === current)
@@ -26019,11 +26307,11 @@ function findUp(start, marker) {
26019
26307
  function readPackageJson2(path) {
26020
26308
  if (!path)
26021
26309
  return null;
26022
- const file = resolve10(path, "package.json");
26023
- if (!existsSync9(file))
26310
+ const file = resolve11(path, "package.json");
26311
+ if (!existsSync10(file))
26024
26312
  return null;
26025
26313
  try {
26026
- const parsed = JSON.parse(readFileSync7(file, "utf-8"));
26314
+ const parsed = JSON.parse(readFileSync8(file, "utf-8"));
26027
26315
  return parsed && typeof parsed === "object" ? parsed : null;
26028
26316
  } catch {
26029
26317
  return null;
@@ -26042,7 +26330,7 @@ function workspaceMarker(root, rootPackage) {
26042
26330
  if (rootPackage?.workspaces)
26043
26331
  markers.push("package.json#workspaces");
26044
26332
  for (const marker of ["pnpm-workspace.yaml", "turbo.json", "nx.json", "lerna.json", "rush.json", "bun.lock", "bun.lockb"]) {
26045
- if (existsSync9(resolve10(root, marker)))
26333
+ if (existsSync10(resolve11(root, marker)))
26046
26334
  markers.push(marker);
26047
26335
  }
26048
26336
  const kind = markers.find((marker) => marker !== "bun.lock" && marker !== "bun.lockb") ?? null;
@@ -26535,21 +26823,21 @@ var gatherTrainingData = async (options = {}) => {
26535
26823
  };
26536
26824
  // src/lib/model-config.ts
26537
26825
  init_sync_utils();
26538
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
26539
- import { join as join10 } from "path";
26826
+ import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
26827
+ import { join as join11 } from "path";
26540
26828
  var DEFAULT_MODEL = "gpt-4o-mini";
26541
26829
  function getConfigDir() {
26542
26830
  return getTodosGlobalDir();
26543
26831
  }
26544
26832
  function getConfigPath2() {
26545
- return join10(getConfigDir(), "config.json");
26833
+ return join11(getConfigDir(), "config.json");
26546
26834
  }
26547
26835
  function readConfig() {
26548
26836
  const configPath = getConfigPath2();
26549
- if (!existsSync10(configPath))
26837
+ if (!existsSync11(configPath))
26550
26838
  return {};
26551
26839
  try {
26552
- const raw = readFileSync8(configPath, "utf-8");
26840
+ const raw = readFileSync9(configPath, "utf-8");
26553
26841
  return JSON.parse(raw);
26554
26842
  } catch {
26555
26843
  return {};
@@ -26557,10 +26845,10 @@ function readConfig() {
26557
26845
  }
26558
26846
  function writeConfig(config) {
26559
26847
  const configDir = getConfigDir();
26560
- if (!existsSync10(configDir)) {
26561
- mkdirSync8(configDir, { recursive: true });
26848
+ if (!existsSync11(configDir)) {
26849
+ mkdirSync9(configDir, { recursive: true });
26562
26850
  }
26563
- writeFileSync6(getConfigPath2(), JSON.stringify(config, null, 2) + `
26851
+ writeFileSync7(getConfigPath2(), JSON.stringify(config, null, 2) + `
26564
26852
  `, "utf-8");
26565
26853
  }
26566
26854
  function getActiveModel() {
@@ -27282,7 +27570,7 @@ CLI equivalent: \`${r.equivalent_cli}\`
27282
27570
  `);
27283
27571
  }
27284
27572
  // src/lib/verification-providers.ts
27285
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
27573
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
27286
27574
  init_database();
27287
27575
  init_config();
27288
27576
  init_redaction();
@@ -27393,7 +27681,7 @@ function classifyLog(text) {
27393
27681
  async function sleep2(ms) {
27394
27682
  if (ms <= 0)
27395
27683
  return;
27396
- await new Promise((resolve11) => setTimeout(resolve11, ms));
27684
+ await new Promise((resolve12) => setTimeout(resolve12, ms));
27397
27685
  }
27398
27686
  async function runCommandProvider(provider, input) {
27399
27687
  const commandTemplate = input.command || provider.command;
@@ -27448,7 +27736,7 @@ Timed out after ${provider.timeout_ms}ms`);
27448
27736
  };
27449
27737
  }
27450
27738
  function runCiLogProvider(input) {
27451
- const text = input.log_text ?? (input.log_path && existsSync11(input.log_path) ? readFileSync9(input.log_path, "utf-8") : "");
27739
+ const text = input.log_text ?? (input.log_path && existsSync12(input.log_path) ? readFileSync10(input.log_path, "utf-8") : "");
27452
27740
  return {
27453
27741
  status: classifyLog(text),
27454
27742
  attempts: 1,
@@ -27460,7 +27748,7 @@ function runBrowserProvider(input) {
27460
27748
  if (!input.artifact_path) {
27461
27749
  return { status: "unknown", attempts: 1, exit_code: null, output_summary: "browser provider needs a screenshot or artifact path" };
27462
27750
  }
27463
- if (!existsSync11(input.artifact_path)) {
27751
+ if (!existsSync12(input.artifact_path)) {
27464
27752
  return { status: "failed", attempts: 1, exit_code: null, output_summary: `artifact not found: ${input.artifact_path}` };
27465
27753
  }
27466
27754
  return {
@@ -27624,7 +27912,7 @@ function listVerificationRecords(filter = {}, db) {
27624
27912
  }
27625
27913
  // src/lib/verification-evidence.ts
27626
27914
  init_database();
27627
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
27915
+ import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync10 } from "fs";
27628
27916
  import { dirname as dirname8 } from "path";
27629
27917
  var VERIFICATION_EVIDENCE_SCHEMA = "todos.verification_evidence.v1";
27630
27918
  function getMachineId3() {
@@ -27745,15 +28033,15 @@ function exportVerificationEvidence(filter = {}, db) {
27745
28033
  };
27746
28034
  }
27747
28035
  function writeVerificationExport(bundle, path) {
27748
- mkdirSync9(dirname8(path), { recursive: true });
27749
- writeFileSync7(path, JSON.stringify(bundle, null, 2), "utf8");
28036
+ mkdirSync10(dirname8(path), { recursive: true });
28037
+ writeFileSync8(path, JSON.stringify(bundle, null, 2), "utf8");
27750
28038
  }
27751
28039
  // src/lib/policy-packs.ts
27752
- import { relative as relative3, resolve as resolve11 } from "path";
28040
+ import { relative as relative3, resolve as resolve12 } from "path";
27753
28041
  init_database();
27754
28042
  init_config();
27755
28043
  function normalizePath3(path) {
27756
- return resolve11(path);
28044
+ return resolve12(path);
27757
28045
  }
27758
28046
  function unique4(values) {
27759
28047
  return Array.from(new Set((values || []).map((value) => value.trim()).filter(Boolean)));
@@ -27808,7 +28096,7 @@ function commandMatches(commands, pattern) {
27808
28096
  }
27809
28097
  function pathMatches(paths, pattern, root) {
27810
28098
  return paths.filter((path) => {
27811
- const candidate = path.startsWith("/") ? path : resolve11(root, path);
28099
+ const candidate = path.startsWith("/") ? path : resolve12(root, path);
27812
28100
  if (!isPathInside3(root, candidate))
27813
28101
  return matchesPattern3(path, pattern);
27814
28102
  return matchesPattern3(path, pattern) || matchesPattern3(relative3(root, candidate), pattern);
@@ -28099,21 +28387,21 @@ function resourceDiagnostics() {
28099
28387
  };
28100
28388
  }
28101
28389
  // src/lib/sandbox-profiles.ts
28102
- import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync10 } from "fs";
28103
- import { join as join11, dirname as dirname9 } from "path";
28390
+ import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync9, mkdirSync as mkdirSync11 } from "fs";
28391
+ import { join as join12, dirname as dirname9 } from "path";
28104
28392
  var SANDBOX_PROFILE_VERSION = "todos.sandbox-profile.v1";
28105
28393
  function getProfilesPath() {
28106
28394
  if (process.env["TODOS_SANDBOX_PROFILES_PATH"]) {
28107
28395
  return process.env["TODOS_SANDBOX_PROFILES_PATH"];
28108
28396
  }
28109
- const localDir = join11(process.cwd(), ".todos");
28110
- const local = join11(localDir, "sandbox-profiles.json");
28111
- if (existsSync12(localDir))
28397
+ const localDir = join12(process.cwd(), ".todos");
28398
+ const local = join12(localDir, "sandbox-profiles.json");
28399
+ if (existsSync13(localDir))
28112
28400
  return local;
28113
- if (existsSync12(local))
28401
+ if (existsSync13(local))
28114
28402
  return local;
28115
28403
  const home = process.env["HOME"] || "~";
28116
- return join11(home, ".hasna", "todos", "sandbox-profiles.json");
28404
+ return join12(home, ".hasna", "todos", "sandbox-profiles.json");
28117
28405
  }
28118
28406
  var cached2 = null;
28119
28407
  function resetSandboxProfileCache() {
@@ -28145,11 +28433,11 @@ function loadSandboxProfiles() {
28145
28433
  if (cached2)
28146
28434
  return cached2;
28147
28435
  const path = getProfilesPath();
28148
- if (!existsSync12(path)) {
28436
+ if (!existsSync13(path)) {
28149
28437
  cached2 = getDefaultSandboxProfiles();
28150
28438
  return cached2;
28151
28439
  }
28152
- const parsed = JSON.parse(readFileSync10(path, "utf8"));
28440
+ const parsed = JSON.parse(readFileSync11(path, "utf8"));
28153
28441
  cached2 = parsed.profiles?.length ? parsed.profiles : getDefaultSandboxProfiles();
28154
28442
  return cached2;
28155
28443
  }
@@ -28158,8 +28446,8 @@ function getSandboxProfile(name) {
28158
28446
  }
28159
28447
  function saveSandboxProfiles(profiles) {
28160
28448
  const path = getProfilesPath();
28161
- mkdirSync10(dirname9(path), { recursive: true });
28162
- writeFileSync8(path, JSON.stringify({ schema_version: SANDBOX_PROFILE_VERSION, profiles }, null, 2));
28449
+ mkdirSync11(dirname9(path), { recursive: true });
28450
+ writeFileSync9(path, JSON.stringify({ schema_version: SANDBOX_PROFILE_VERSION, profiles }, null, 2));
28163
28451
  cached2 = profiles;
28164
28452
  }
28165
28453
  function commandMatchesAllowlist(command, allow) {
@@ -28518,9 +28806,9 @@ function getDefaultAgentAdapters() {
28518
28806
  }
28519
28807
  function resetAgentAdapterCache() {}
28520
28808
  // src/lib/git-traceability.ts
28521
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
28809
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
28522
28810
  import { spawnSync as spawnSync2 } from "child_process";
28523
- import { resolve as resolve12 } from "path";
28811
+ import { resolve as resolve13 } from "path";
28524
28812
  var GIT_TRACEABILITY_SCHEMA_VERSION = "todos.git_traceability.v1";
28525
28813
  function runGit(args, cwd) {
28526
28814
  const result = spawnSync2("git", args, { cwd, encoding: "utf8" });
@@ -28563,11 +28851,11 @@ function inspectGitCommit(sha, cwd) {
28563
28851
  };
28564
28852
  }
28565
28853
  function loadCiSnapshot(path) {
28566
- const target = path ? resolve12(path) : resolve12(process.cwd(), ".todos", "ci-snapshot.json");
28567
- if (!existsSync13(target))
28854
+ const target = path ? resolve13(path) : resolve13(process.cwd(), ".todos", "ci-snapshot.json");
28855
+ if (!existsSync14(target))
28568
28856
  return null;
28569
28857
  try {
28570
- const parsed = JSON.parse(readFileSync11(target, "utf8"));
28858
+ const parsed = JSON.parse(readFileSync12(target, "utf8"));
28571
28859
  return { ...parsed, captured_at: parsed.captured_at ?? new Date().toISOString() };
28572
28860
  } catch {
28573
28861
  return null;
@@ -28660,8 +28948,8 @@ function formatTraceabilityReport(report) {
28660
28948
  `);
28661
28949
  }
28662
28950
  // src/lib/mention-resolver.ts
28663
- import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync4 } from "fs";
28664
- import { basename as basename3, isAbsolute, join as join12, relative as relative4, resolve as resolve13, sep as sep2 } from "path";
28951
+ import { existsSync as existsSync15, readdirSync as readdirSync2, readFileSync as readFileSync13, statSync as statSync4 } from "fs";
28952
+ import { basename as basename3, isAbsolute, join as join13, relative as relative4, resolve as resolve14, sep as sep2 } from "path";
28665
28953
  init_database();
28666
28954
  var PREFIXES = {
28667
28955
  file: "file",
@@ -28737,7 +29025,7 @@ function backlink(kind, key, label, target = key) {
28737
29025
  return { kind, key, label, target };
28738
29026
  }
28739
29027
  function normalizeWorkspace(workspace) {
28740
- return resolve13(workspace || process.cwd());
29028
+ return resolve14(workspace || process.cwd());
28741
29029
  }
28742
29030
  function isInside(root, absolutePath) {
28743
29031
  const rel = relative4(root, absolutePath);
@@ -28805,14 +29093,14 @@ function resolveFile(parsed, workspace) {
28805
29093
  resolution.warnings.push("path is empty or escapes the workspace");
28806
29094
  return resolution;
28807
29095
  }
28808
- const absolutePath = resolve13(workspace, relPath);
29096
+ const absolutePath = resolve14(workspace, relPath);
28809
29097
  if (!isInside(workspace, absolutePath)) {
28810
29098
  resolution.path = relPath;
28811
29099
  resolution.warnings.push("path escapes the workspace");
28812
29100
  return resolution;
28813
29101
  }
28814
29102
  resolution.path = relPath;
28815
- if (!existsSync14(absolutePath)) {
29103
+ if (!existsSync15(absolutePath)) {
28816
29104
  resolution.warnings.push("file does not exist in the local workspace");
28817
29105
  return resolution;
28818
29106
  }
@@ -28822,7 +29110,7 @@ function resolveFile(parsed, workspace) {
28822
29110
  return resolution;
28823
29111
  }
28824
29112
  if (parsed.line !== undefined) {
28825
- const lineCount = readFileSync12(absolutePath, "utf-8").split(/\r?\n/).length;
29113
+ const lineCount = readFileSync13(absolutePath, "utf-8").split(/\r?\n/).length;
28826
29114
  if (parsed.line < 1 || parsed.line > lineCount) {
28827
29115
  resolution.warnings.push(`line ${parsed.line} is outside the file range 1-${lineCount}`);
28828
29116
  return resolution;
@@ -28845,7 +29133,7 @@ function walkSourceFiles(root, current = root, files = []) {
28845
29133
  if (SKIP_DIRS.has(entry2.name))
28846
29134
  continue;
28847
29135
  }
28848
- const absolutePath = join12(current, entry2.name);
29136
+ const absolutePath = join13(current, entry2.name);
28849
29137
  if (entry2.isDirectory()) {
28850
29138
  if (!SKIP_DIRS.has(entry2.name))
28851
29139
  walkSourceFiles(root, absolutePath, files);
@@ -28875,7 +29163,7 @@ function resolveSymbol(parsed, workspace, maxMatches) {
28875
29163
  const pattern = symbolPattern(name);
28876
29164
  const matches = [];
28877
29165
  for (const file of walkSourceFiles(workspace)) {
28878
- const lines = readFileSync12(file, "utf-8").split(/\r?\n/);
29166
+ const lines = readFileSync13(file, "utf-8").split(/\r?\n/);
28879
29167
  for (let index = 0;index < lines.length; index += 1) {
28880
29168
  const line = lines[index];
28881
29169
  const found = pattern.exec(line);
@@ -30725,7 +31013,7 @@ function getAdapterDocsFingerprint() {
30725
31013
  }
30726
31014
  // src/lib/inbox-intake.ts
30727
31015
  init_database();
30728
- import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
31016
+ import { existsSync as existsSync16, readFileSync as readFileSync14 } from "fs";
30729
31017
  import { basename as basename4 } from "path";
30730
31018
  import { createHash as createHash11 } from "crypto";
30731
31019
  init_secret_redaction();
@@ -30771,9 +31059,9 @@ function loadRawContent(input) {
30771
31059
  }
30772
31060
  }
30773
31061
  if (input.file_path) {
30774
- if (!existsSync15(input.file_path))
31062
+ if (!existsSync16(input.file_path))
30775
31063
  throw new Error(`File not found: ${input.file_path}`);
30776
- const raw = readFileSync13(input.file_path, "utf8");
31064
+ const raw = readFileSync14(input.file_path, "utf8");
30777
31065
  const name = basename4(input.file_path).toLowerCase();
30778
31066
  const source_type2 = input.source_type ?? (name.includes("ci") || name.endsWith(".log") ? "ci_log" : "file");
30779
31067
  return {
@@ -31389,7 +31677,7 @@ function formatNlIntakePreviewText(preview) {
31389
31677
  }
31390
31678
  // src/lib/issue-importers.ts
31391
31679
  init_database();
31392
- import { existsSync as existsSync16, readFileSync as readFileSync14 } from "fs";
31680
+ import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
31393
31681
  var ISSUE_IMPORT_SCHEMA = "todos.issue_import.v1";
31394
31682
  var ISSUE_SOURCES = ["github", "linear", "jira", "auto"];
31395
31683
  var GITHUB_LABEL_PRIORITY = {
@@ -31608,9 +31896,9 @@ function parseIssueExport(data, source9 = "auto") {
31608
31896
  return normalized;
31609
31897
  }
31610
31898
  function loadIssueExportFromFile(path) {
31611
- if (!existsSync16(path))
31899
+ if (!existsSync17(path))
31612
31900
  throw new Error(`File not found: ${path}`);
31613
- return JSON.parse(readFileSync14(path, "utf8"));
31901
+ return JSON.parse(readFileSync15(path, "utf8"));
31614
31902
  }
31615
31903
  function loadIssueExportInput(input) {
31616
31904
  if (input.file_path) {
@@ -31768,8 +32056,8 @@ todos import issues ./linear.json --source linear --dry-run
31768
32056
  // src/lib/run-records.ts
31769
32057
  init_database();
31770
32058
  init_secret_redaction();
31771
- import { existsSync as existsSync17, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9 } from "fs";
31772
- import { join as join13, dirname as dirname10 } from "path";
32059
+ import { existsSync as existsSync18, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "fs";
32060
+ import { join as join14, dirname as dirname10 } from "path";
31773
32061
  var RUN_RECORD_SCHEMA = "todos.run_record.v1";
31774
32062
  var RUN_RECORD_STATUSES = ["active", "completed", "failed", "archived"];
31775
32063
  function parseJsonArray3(raw, fallback = []) {
@@ -31962,9 +32250,9 @@ function buildRunReplayBundle(id, db) {
31962
32250
  }
31963
32251
  function exportRunReplay(id, outputPath, db) {
31964
32252
  const bundle = buildRunReplayBundle(id, db);
31965
- const path = outputPath ?? join13(process.cwd(), ".todos", "replays", `${id.slice(0, 8)}.json`);
31966
- mkdirSync11(dirname10(path), { recursive: true });
31967
- writeFileSync9(path, JSON.stringify(bundle, null, 2));
32253
+ const path = outputPath ?? join14(process.cwd(), ".todos", "replays", `${id.slice(0, 8)}.json`);
32254
+ mkdirSync12(dirname10(path), { recursive: true });
32255
+ writeFileSync10(path, JSON.stringify(bundle, null, 2));
31968
32256
  const d = db || getDatabase();
31969
32257
  d.run(`UPDATE run_records SET replay_bundle = ?, updated_at = ? WHERE id = ?`, [path, now(), id]);
31970
32258
  return { path, bundle };
@@ -32002,16 +32290,16 @@ function formatRunRecordMarkdown(record) {
32002
32290
  `;
32003
32291
  }
32004
32292
  function getDefaultReplayDir() {
32005
- const local = join13(process.cwd(), ".todos", "replays");
32006
- if (existsSync17(join13(process.cwd(), ".todos")))
32293
+ const local = join14(process.cwd(), ".todos", "replays");
32294
+ if (existsSync18(join14(process.cwd(), ".todos")))
32007
32295
  return local;
32008
32296
  const home = process.env["HOME"] || "~";
32009
- return join13(home, ".hasna", "todos", "replays");
32297
+ return join14(home, ".hasna", "todos", "replays");
32010
32298
  }
32011
32299
  // src/lib/release-checks.ts
32012
32300
  init_secret_redaction();
32013
- import { existsSync as existsSync18, readFileSync as readFileSync15, readdirSync as readdirSync3, statSync as statSync5 } from "fs";
32014
- import { join as join14, relative as relative5 } from "path";
32301
+ import { existsSync as existsSync19, readFileSync as readFileSync16, readdirSync as readdirSync3, statSync as statSync5 } from "fs";
32302
+ import { join as join15, relative as relative5 } from "path";
32015
32303
  var RELEASE_CHECK_SCHEMA = "todos.release_check.v1";
32016
32304
  var FORBIDDEN_DIST_PATTERNS = [
32017
32305
  {
@@ -32024,16 +32312,16 @@ var FORBIDDEN_DIST_PATTERNS = [
32024
32312
  ];
32025
32313
  var REQUIRED_BINS = ["todos", "todos-mcp", "todos-serve"];
32026
32314
  function readPackageJson3(root) {
32027
- const path = join14(root, "package.json");
32028
- if (!existsSync18(path))
32315
+ const path = join15(root, "package.json");
32316
+ if (!existsSync19(path))
32029
32317
  throw new Error(`package.json not found in ${root}`);
32030
- return JSON.parse(readFileSync15(path, "utf8"));
32318
+ return JSON.parse(readFileSync16(path, "utf8"));
32031
32319
  }
32032
32320
  function walkFiles(dir, acc = []) {
32033
- if (!existsSync18(dir))
32321
+ if (!existsSync19(dir))
32034
32322
  return acc;
32035
32323
  for (const entry2 of readdirSync3(dir)) {
32036
- const full = join14(dir, entry2);
32324
+ const full = join15(dir, entry2);
32037
32325
  const st = statSync5(full);
32038
32326
  if (st.isDirectory())
32039
32327
  walkFiles(full, acc);
@@ -32051,8 +32339,8 @@ function auditPackageContents(root) {
32051
32339
  checks.push({ id: "files_dist", severity: "error", message: "package.json files must include dist" });
32052
32340
  }
32053
32341
  for (const pattern of files) {
32054
- const target = join14(root, pattern);
32055
- if (!existsSync18(target)) {
32342
+ const target = join15(root, pattern);
32343
+ if (!existsSync19(target)) {
32056
32344
  checks.push({ id: `files_missing_${pattern}`, severity: "error", message: `Published file path missing: ${pattern}` });
32057
32345
  }
32058
32346
  }
@@ -32066,8 +32354,8 @@ function auditPackageContents(root) {
32066
32354
  checks.push({ id: `bin_${name}`, severity: "error", message: `Missing bin entry: ${name}` });
32067
32355
  continue;
32068
32356
  }
32069
- const binPath = join14(root, rel);
32070
- if (!existsSync18(binPath)) {
32357
+ const binPath = join15(root, rel);
32358
+ if (!existsSync19(binPath)) {
32071
32359
  checks.push({ id: `bin_path_${name}`, severity: "error", message: `Bin file missing: ${rel}` });
32072
32360
  } else {
32073
32361
  checks.push({ id: `bin_ok_${name}`, severity: "info", message: `Bin present: ${name} \u2192 ${rel}` });
@@ -32084,8 +32372,8 @@ function auditPackageContents(root) {
32084
32372
  }
32085
32373
  function scanDistArtifacts(root) {
32086
32374
  const checks = [];
32087
- const distDir = join14(root, "dist");
32088
- if (!existsSync18(distDir)) {
32375
+ const distDir = join15(root, "dist");
32376
+ if (!existsSync19(distDir)) {
32089
32377
  checks.push({ id: "dist_missing", severity: "error", message: "dist/ directory not found \u2014 run bun run build" });
32090
32378
  return checks;
32091
32379
  }
@@ -32093,7 +32381,7 @@ function scanDistArtifacts(root) {
32093
32381
  const rel = relative5(root, file);
32094
32382
  let content;
32095
32383
  try {
32096
- content = readFileSync15(file, "utf8");
32384
+ content = readFileSync16(file, "utf8");
32097
32385
  } catch {
32098
32386
  continue;
32099
32387
  }
@@ -32391,15 +32679,15 @@ function renderReleaseNotesMarkdown(document) {
32391
32679
  // src/lib/db-backup.ts
32392
32680
  init_database();
32393
32681
  init_migrations();
32394
- import { existsSync as existsSync19, copyFileSync, mkdirSync as mkdirSync12, readFileSync as readFileSync16, statSync as statSync6, writeFileSync as writeFileSync10, unlinkSync } from "fs";
32395
- import { dirname as dirname11, join as join15, resolve as resolve14 } from "path";
32682
+ import { existsSync as existsSync20, copyFileSync, mkdirSync as mkdirSync13, readFileSync as readFileSync17, statSync as statSync6, writeFileSync as writeFileSync11, unlinkSync } from "fs";
32683
+ import { dirname as dirname11, join as join16, resolve as resolve15 } from "path";
32396
32684
  import { Database as Database3 } from "bun:sqlite";
32397
32685
  var DB_BACKUP_SCHEMA = "todos.db_backup.v1";
32398
32686
  function resolveDbPath(dbPath) {
32399
32687
  if (dbPath)
32400
- return resolve14(dbPath);
32688
+ return resolve15(dbPath);
32401
32689
  if (process.env["TODOS_DB_PATH"] && process.env["TODOS_DB_PATH"] !== ":memory:") {
32402
- return resolve14(process.env["TODOS_DB_PATH"]);
32690
+ return resolve15(process.env["TODOS_DB_PATH"]);
32403
32691
  }
32404
32692
  const db = getDatabase();
32405
32693
  const filename = db.filename;
@@ -32409,9 +32697,9 @@ function resolveDbPath(dbPath) {
32409
32697
  }
32410
32698
  function backupDatabase(outputPath, sourcePath) {
32411
32699
  const source9 = resolveDbPath(sourcePath);
32412
- if (!existsSync19(source9))
32700
+ if (!existsSync20(source9))
32413
32701
  throw new Error(`Database not found: ${source9}`);
32414
- mkdirSync12(dirname11(outputPath), { recursive: true });
32702
+ mkdirSync13(dirname11(outputPath), { recursive: true });
32415
32703
  closeDatabase();
32416
32704
  const src = new Database3(source9);
32417
32705
  try {
@@ -32419,7 +32707,7 @@ function backupDatabase(outputPath, sourcePath) {
32419
32707
  } catch {}
32420
32708
  const image = src.serialize();
32421
32709
  src.close();
32422
- writeFileSync10(outputPath, image);
32710
+ writeFileSync11(outputPath, image);
32423
32711
  const method = "file_copy";
32424
32712
  const bytes = statSync6(outputPath).size;
32425
32713
  return {
@@ -32432,14 +32720,14 @@ function backupDatabase(outputPath, sourcePath) {
32432
32720
  };
32433
32721
  }
32434
32722
  function restoreDatabase(backupPath, targetPath) {
32435
- if (!existsSync19(backupPath))
32723
+ if (!existsSync20(backupPath))
32436
32724
  throw new Error(`Backup not found: ${backupPath}`);
32437
32725
  const integrity = checkDatabaseIntegrity(backupPath);
32438
32726
  if (!integrity.ok) {
32439
32727
  throw new Error(`Backup failed integrity check: ${integrity.errors.join("; ")}`);
32440
32728
  }
32441
- const target = targetPath ? resolve14(targetPath) : resolveDbPath();
32442
- mkdirSync12(dirname11(target), { recursive: true });
32729
+ const target = targetPath ? resolve15(targetPath) : resolveDbPath();
32730
+ mkdirSync13(dirname11(target), { recursive: true });
32443
32731
  const staging = `${target}.restore.tmp`;
32444
32732
  copyFileSync(backupPath, staging);
32445
32733
  copyFileSync(staging, target);
@@ -32457,9 +32745,9 @@ function restoreDatabase(backupPath, targetPath) {
32457
32745
  };
32458
32746
  }
32459
32747
  function checkDatabaseIntegrity(dbPath) {
32460
- const path = dbPath ? resolve14(dbPath) : resolveDbPath();
32748
+ const path = dbPath ? resolve15(dbPath) : resolveDbPath();
32461
32749
  const errors = [];
32462
- if (!existsSync19(path)) {
32750
+ if (!existsSync20(path)) {
32463
32751
  return {
32464
32752
  schema_version: DB_BACKUP_SCHEMA,
32465
32753
  path,
@@ -32522,7 +32810,7 @@ function checkDatabaseIntegrity(dbPath) {
32522
32810
  };
32523
32811
  }
32524
32812
  function compactDatabase(dbPath) {
32525
- const path = dbPath ? resolve14(dbPath) : resolveDbPath();
32813
+ const path = dbPath ? resolve15(dbPath) : resolveDbPath();
32526
32814
  const before = statSync6(path).size;
32527
32815
  const db = new Database3(path);
32528
32816
  db.exec("VACUUM");
@@ -32532,7 +32820,7 @@ function compactDatabase(dbPath) {
32532
32820
  return { path, bytes_before: before, bytes_after: after };
32533
32821
  }
32534
32822
  function migrationDryRun(dbPath) {
32535
- const path = dbPath ? resolve14(dbPath) : resolveDbPath();
32823
+ const path = dbPath ? resolve15(dbPath) : resolveDbPath();
32536
32824
  const db = new Database3(path, { readonly: true });
32537
32825
  let current = 0;
32538
32826
  try {
@@ -32556,16 +32844,16 @@ function migrationDryRun(dbPath) {
32556
32844
  };
32557
32845
  }
32558
32846
  function defaultBackupPath(dbPath) {
32559
- const base = dbPath ? dirname11(resolve14(dbPath)) : dirname11(resolveDbPath());
32847
+ const base = dbPath ? dirname11(resolve15(dbPath)) : dirname11(resolveDbPath());
32560
32848
  const stamp = new Date().toISOString().replace(/[:.]/g, "-");
32561
- return join15(base, "backups", `todos-${stamp}.db`);
32849
+ return join16(base, "backups", `todos-${stamp}.db`);
32562
32850
  }
32563
32851
  function readBackupManifest(backupPath) {
32564
32852
  const manifestPath = `${backupPath}.json`;
32565
- if (!existsSync19(manifestPath))
32853
+ if (!existsSync20(manifestPath))
32566
32854
  return null;
32567
32855
  try {
32568
- return JSON.parse(readFileSync16(manifestPath, "utf8"));
32856
+ return JSON.parse(readFileSync17(manifestPath, "utf8"));
32569
32857
  } catch {
32570
32858
  return null;
32571
32859
  }
@@ -32575,8 +32863,8 @@ function writeBackupManifest(backupPath, result) {
32575
32863
  writeFileSyncSafe(manifestPath, JSON.stringify(result, null, 2));
32576
32864
  }
32577
32865
  function writeFileSyncSafe(path, content) {
32578
- mkdirSync12(dirname11(path), { recursive: true });
32579
- writeFileSync10(path, content);
32866
+ mkdirSync13(dirname11(path), { recursive: true });
32867
+ writeFileSync11(path, content);
32580
32868
  }
32581
32869
  // src/lib/json-schemas.ts
32582
32870
  var JSON_SCHEMA_CATALOG_VERSION = "todos.json_schema_catalog.v1";
@@ -33081,17 +33369,17 @@ ${SCHEMA_ENTITIES.map((e) => `- **${e}**: \`${JSON_SCHEMAS[e].schema_version}\``
33081
33369
  `;
33082
33370
  }
33083
33371
  function exportSchemasToDirectory(dir) {
33084
- const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync11 } = __require("fs");
33085
- const { join: join16 } = __require("path");
33086
- mkdirSync13(dir, { recursive: true });
33372
+ const { mkdirSync: mkdirSync14, writeFileSync: writeFileSync12 } = __require("fs");
33373
+ const { join: join17 } = __require("path");
33374
+ mkdirSync14(dir, { recursive: true });
33087
33375
  const written = [];
33088
33376
  for (const entity of SCHEMA_ENTITIES) {
33089
- const path = join16(dir, `${entity}.${JSON_SCHEMAS[entity].schema_version.replace(/\./g, "-")}.json`);
33090
- writeFileSync11(path, JSON.stringify(JSON_SCHEMAS[entity], null, 2));
33377
+ const path = join17(dir, `${entity}.${JSON_SCHEMAS[entity].schema_version.replace(/\./g, "-")}.json`);
33378
+ writeFileSync12(path, JSON.stringify(JSON_SCHEMAS[entity], null, 2));
33091
33379
  written.push(path);
33092
33380
  }
33093
- const catalogPath = join16(dir, "catalog.json");
33094
- writeFileSync11(catalogPath, JSON.stringify({
33381
+ const catalogPath = join17(dir, "catalog.json");
33382
+ writeFileSync12(catalogPath, JSON.stringify({
33095
33383
  catalog_version: JSON_SCHEMA_CATALOG_VERSION,
33096
33384
  semver: SCHEMA_SEMVER,
33097
33385
  entities: listJsonSchemas(),
@@ -33990,7 +34278,7 @@ function getReminderDocs() {
33990
34278
  }
33991
34279
  // src/lib/import-export-bridge.ts
33992
34280
  init_database();
33993
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, mkdirSync as mkdirSync13 } from "fs";
34281
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
33994
34282
  import { dirname as dirname12 } from "path";
33995
34283
  init_secret_redaction();
33996
34284
  var BUNDLE_SCHEMA = "todos.bundle.v1";
@@ -34399,11 +34687,11 @@ function importBundle(bundle, options = {}, db) {
34399
34687
  return result;
34400
34688
  }
34401
34689
  function writeBundleFile(bundle, path) {
34402
- mkdirSync13(dirname12(path), { recursive: true });
34403
- writeFileSync11(path, JSON.stringify(bundle, null, 2), "utf8");
34690
+ mkdirSync14(dirname12(path), { recursive: true });
34691
+ writeFileSync12(path, JSON.stringify(bundle, null, 2), "utf8");
34404
34692
  }
34405
34693
  function readBundleFile(path) {
34406
- const raw = JSON.parse(readFileSync17(path, "utf8"));
34694
+ const raw = JSON.parse(readFileSync18(path, "utf8"));
34407
34695
  const validation = validateBundle(raw);
34408
34696
  if (!validation.valid)
34409
34697
  throw new Error(`Invalid bundle file: ${validation.errors.join("; ")}`);
@@ -34879,7 +35167,7 @@ function createPlanWithSteps(name, steps, opts = {}, db) {
34879
35167
  }
34880
35168
  // src/lib/handoff-packets.ts
34881
35169
  init_database();
34882
- import { writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
35170
+ import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync15 } from "fs";
34883
35171
  import { dirname as dirname13 } from "path";
34884
35172
  var HANDOFF_PACKET_SCHEMA = "todos.handoff_packet.v1";
34885
35173
  function summarizeTask2(t) {
@@ -35054,8 +35342,8 @@ function formatHandoffPacket(packet, format = "json") {
35054
35342
  function exportHandoffPacket(input = {}, path, db) {
35055
35343
  const packet = createHandoffPacket(input, db);
35056
35344
  if (path) {
35057
- mkdirSync14(dirname13(path), { recursive: true });
35058
- writeFileSync12(path, formatHandoffPacket(packet, "json"), "utf8");
35345
+ mkdirSync15(dirname13(path), { recursive: true });
35346
+ writeFileSync13(path, formatHandoffPacket(packet, "json"), "utf8");
35059
35347
  }
35060
35348
  return packet;
35061
35349
  }
@@ -35658,8 +35946,8 @@ function generateCliReferenceMarkdown() {
35658
35946
  }
35659
35947
  // src/db/builtin-templates.ts
35660
35948
  init_database();
35661
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync13 } from "fs";
35662
- import { join as join16 } from "path";
35949
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
35950
+ import { join as join17 } from "path";
35663
35951
  var BUILTIN_TEMPLATE_LIBRARY_VERSION = "2026-05-21";
35664
35952
  var BUILTIN_TEMPLATE_LIBRARY_SOURCE = "bundled-local-template-library";
35665
35953
  var TEMPLATE_LIBRARY_SCHEMA = "todos.template_library.v1";
@@ -35932,11 +36220,11 @@ function exportBuiltinTemplateFiles() {
35932
36220
  }));
35933
36221
  }
35934
36222
  function writeBuiltinTemplateFiles(directory) {
35935
- mkdirSync15(directory, { recursive: true });
36223
+ mkdirSync16(directory, { recursive: true });
35936
36224
  const files = [];
35937
36225
  for (const entry2 of exportBuiltinTemplateFiles()) {
35938
- const path = join16(directory, entry2.filename);
35939
- writeFileSync13(path, `${JSON.stringify(entry2.template, null, 2)}
36226
+ const path = join17(directory, entry2.filename);
36227
+ writeFileSync14(path, `${JSON.stringify(entry2.template, null, 2)}
35940
36228
  `, "utf-8");
35941
36229
  files.push(path);
35942
36230
  }
@@ -35979,7 +36267,7 @@ function initBuiltinTemplates(db) {
35979
36267
  }
35980
36268
  // src/lib/template-library.ts
35981
36269
  init_database();
35982
- import { writeFileSync as writeFileSync14, readFileSync as readFileSync18, mkdirSync as mkdirSync16 } from "fs";
36270
+ import { writeFileSync as writeFileSync15, readFileSync as readFileSync19, mkdirSync as mkdirSync17 } from "fs";
35983
36271
  import { dirname as dirname14 } from "path";
35984
36272
  function listTemplateLibrary(db) {
35985
36273
  const d = db || getDatabase();
@@ -36022,8 +36310,8 @@ function exportTemplateLibraryCatalog(path, db) {
36022
36310
  templates: listTemplateLibrary(db)
36023
36311
  };
36024
36312
  if (path) {
36025
- mkdirSync16(dirname14(path), { recursive: true });
36026
- writeFileSync14(path, JSON.stringify(catalog, null, 2), "utf8");
36313
+ mkdirSync17(dirname14(path), { recursive: true });
36314
+ writeFileSync15(path, JSON.stringify(catalog, null, 2), "utf8");
36027
36315
  }
36028
36316
  return catalog;
36029
36317
  }
@@ -36040,7 +36328,7 @@ function exportInstalledTemplate(name, db) {
36040
36328
  }
36041
36329
  function importTemplateFromFile(path, db) {
36042
36330
  const d = db || getDatabase();
36043
- const raw = JSON.parse(readFileSync18(path, "utf8"));
36331
+ const raw = JSON.parse(readFileSync19(path, "utf8"));
36044
36332
  const payload = raw.template ?? raw;
36045
36333
  const created = importTemplate(payload, d);
36046
36334
  return { id: created.id, name: created.name };
@@ -36218,9 +36506,9 @@ todos machines topology # full diagnostic report
36218
36506
  }
36219
36507
  // src/lib/environment-snapshots.ts
36220
36508
  import { createHash as createHash12 } from "crypto";
36221
- import { existsSync as existsSync20, readFileSync as readFileSync19, statSync as statSync7 } from "fs";
36509
+ import { existsSync as existsSync21, readFileSync as readFileSync20, statSync as statSync7 } from "fs";
36222
36510
  import { hostname as hostname3, platform, arch } from "os";
36223
- import { dirname as dirname15, join as join17, resolve as resolve15 } from "path";
36511
+ import { dirname as dirname15, join as join18, resolve as resolve16 } from "path";
36224
36512
  import { tmpdir as tmpdir3 } from "os";
36225
36513
  init_database();
36226
36514
  init_redaction();
@@ -36245,20 +36533,20 @@ function sha2565(value) {
36245
36533
  return createHash12("sha256").update(value).digest("hex");
36246
36534
  }
36247
36535
  function fileRecord(root, relativePath) {
36248
- const path = join17(root, relativePath);
36249
- if (!existsSync20(path))
36536
+ const path = join18(root, relativePath);
36537
+ if (!existsSync21(path))
36250
36538
  return null;
36251
36539
  const stat = statSync7(path);
36252
36540
  if (!stat.isFile())
36253
36541
  return null;
36254
- const content = readFileSync19(path);
36542
+ const content = readFileSync20(path);
36255
36543
  return { path: relativePath, sha256: sha2565(content), size_bytes: content.length };
36256
36544
  }
36257
36545
  function manifestRecord(root, relativePath) {
36258
36546
  const base = fileRecord(root, relativePath);
36259
36547
  if (!base)
36260
36548
  return null;
36261
- const parsed = readJsonFile(join17(root, relativePath));
36549
+ const parsed = readJsonFile(join18(root, relativePath));
36262
36550
  if (!parsed)
36263
36551
  return { ...base, redacted: {} };
36264
36552
  const redacted = redactValue({
@@ -36353,15 +36641,15 @@ function commandEnv(env, includeValues) {
36353
36641
  function defaultSnapshotDir() {
36354
36642
  const dbPath = getDatabasePath();
36355
36643
  if (dbPath === ":memory:" || dbPath.startsWith("file::memory:"))
36356
- return join17(tmpdir3(), "hasna-todos", "environment-snapshots");
36357
- return join17(dirname15(resolve15(dbPath)), "environment-snapshots");
36644
+ return join18(tmpdir3(), "hasna-todos", "environment-snapshots");
36645
+ return join18(dirname15(resolve16(dbPath)), "environment-snapshots");
36358
36646
  }
36359
36647
  function snapshotWithId(snapshot) {
36360
36648
  const digest = sha2565(JSON.stringify(snapshot)).slice(0, 24);
36361
36649
  return { id: `env_${digest}`, ...snapshot };
36362
36650
  }
36363
36651
  function captureEnvironmentSnapshot(input = {}) {
36364
- const root = resolve15(input.root || process.cwd());
36652
+ const root = resolve16(input.root || process.cwd());
36365
36653
  const env = input.env || process.env;
36366
36654
  const warnings = [];
36367
36655
  const manifests = MANIFEST_FILES.map((file) => manifestRecord(root, file)).filter((file) => Boolean(file));
@@ -36401,13 +36689,13 @@ function captureEnvironmentSnapshot(input = {}) {
36401
36689
  });
36402
36690
  }
36403
36691
  function writeEnvironmentSnapshot(snapshot, outputPath) {
36404
- const path = outputPath ? resolve15(outputPath) : join17(defaultSnapshotDir(), `${snapshot.id}.json`);
36692
+ const path = outputPath ? resolve16(outputPath) : join18(defaultSnapshotDir(), `${snapshot.id}.json`);
36405
36693
  ensureDir2(dirname15(path));
36406
36694
  writeJsonFile(path, snapshot);
36407
36695
  return path;
36408
36696
  }
36409
36697
  function readEnvironmentSnapshot(path) {
36410
- const snapshot = readJsonFile(resolve15(path));
36698
+ const snapshot = readJsonFile(resolve16(path));
36411
36699
  if (!snapshot || snapshot.schema_version !== 1 || typeof snapshot.id !== "string") {
36412
36700
  throw new Error(`Invalid environment snapshot: ${path}`);
36413
36701
  }
@@ -36493,8 +36781,8 @@ function compareEnvironmentSnapshotFiles(leftPath, rightPath) {
36493
36781
  // src/lib/decision-records.ts
36494
36782
  init_database();
36495
36783
  import { createHash as createHash13 } from "crypto";
36496
- import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
36497
- import { dirname as dirname16, join as join18 } from "path";
36784
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
36785
+ import { dirname as dirname16, join as join19 } from "path";
36498
36786
  var DECISION_RECORD_SCHEMA = "todos.decision_record.v1";
36499
36787
  var KNOWLEDGE_SNAPSHOT_SCHEMA = "todos.knowledge_snapshot.v1";
36500
36788
  var DECISION_STATUSES = ["proposed", "accepted", "deprecated", "superseded", "rejected"];
@@ -36724,9 +37012,9 @@ function exportDecisionRecord(id, outputPath, format = "markdown", db) {
36724
37012
  if (!record)
36725
37013
  throw new Error(`Decision record not found: ${id}`);
36726
37014
  const content = format === "markdown" ? formatDecisionRecordMarkdown(record) : JSON.stringify(record, null, 2);
36727
- const path = outputPath ?? join18(process.cwd(), ".todos", "decisions", `${record.short_ref}.${format === "markdown" ? "md" : "json"}`);
36728
- mkdirSync17(dirname16(path), { recursive: true });
36729
- writeFileSync15(path, content, "utf8");
37015
+ const path = outputPath ?? join19(process.cwd(), ".todos", "decisions", `${record.short_ref}.${format === "markdown" ? "md" : "json"}`);
37016
+ mkdirSync18(dirname16(path), { recursive: true });
37017
+ writeFileSync16(path, content, "utf8");
36730
37018
  return { path, content };
36731
37019
  }
36732
37020
  function buildKnowledgeSnapshotPayload(input, db) {
@@ -36872,9 +37160,9 @@ function exportKnowledgeSnapshot(id, outputPath, format = "markdown", db) {
36872
37160
  throw new Error(`Knowledge snapshot not found: ${id}`);
36873
37161
  const content = format === "markdown" ? formatKnowledgeSnapshotMarkdown(record) : JSON.stringify(record, null, 2);
36874
37162
  const slug = record.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
36875
- const path = outputPath ?? join18(process.cwd(), ".todos", "knowledge", `${slug || record.id.slice(0, 8)}.${format === "markdown" ? "md" : "json"}`);
36876
- mkdirSync17(dirname16(path), { recursive: true });
36877
- writeFileSync15(path, content, "utf8");
37163
+ const path = outputPath ?? join19(process.cwd(), ".todos", "knowledge", `${slug || record.id.slice(0, 8)}.${format === "markdown" ? "md" : "json"}`);
37164
+ mkdirSync18(dirname16(path), { recursive: true });
37165
+ writeFileSync16(path, content, "utf8");
36878
37166
  return { path, content };
36879
37167
  }
36880
37168
  function getDecisionRecordsDocs() {
@@ -36900,7 +37188,7 @@ Schema versions:
36900
37188
  }
36901
37189
  // src/lib/report-exports.ts
36902
37190
  init_database();
36903
- import { writeFileSync as writeFileSync16, mkdirSync as mkdirSync18 } from "fs";
37191
+ import { writeFileSync as writeFileSync17, mkdirSync as mkdirSync19 } from "fs";
36904
37192
  import { dirname as dirname17 } from "path";
36905
37193
  init_secret_redaction();
36906
37194
  var REPORT_EXPORT_SCHEMA = "todos.report_export.v1";
@@ -37133,8 +37421,8 @@ function formatReportExport(data, format) {
37133
37421
  return format === "html" ? formatReportHtml(data) : formatReportMarkdown(data);
37134
37422
  }
37135
37423
  function writeReportExport(data, format, path) {
37136
- mkdirSync18(dirname17(path), { recursive: true });
37137
- writeFileSync16(path, formatReportExport(data, format), "utf8");
37424
+ mkdirSync19(dirname17(path), { recursive: true });
37425
+ writeFileSync17(path, formatReportExport(data, format), "utf8");
37138
37426
  }
37139
37427
  function exportReport(input, db) {
37140
37428
  const data = buildReportExportData(input, db);
@@ -37167,8 +37455,8 @@ todos report export --kind retrospective --days 14 --format markdown --out retro
37167
37455
  `;
37168
37456
  }
37169
37457
  // src/lib/command-aliases.ts
37170
- import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync17, mkdirSync as mkdirSync19 } from "fs";
37171
- import { join as join19 } from "path";
37458
+ import { existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync18, mkdirSync as mkdirSync20 } from "fs";
37459
+ import { join as join20 } from "path";
37172
37460
  var COMMAND_ALIASES_SCHEMA = "todos.command_aliases.v1";
37173
37461
  var RESERVED = new Set([...listTopLevelCommands(), "help", "version", "alias", "shortcuts"]);
37174
37462
  var BUILTIN_SHORTCUTS = [
@@ -37187,7 +37475,7 @@ var BUILTIN_SHORTCUTS = [
37187
37475
  { pattern: /^reports?$/, argv: ["report", "docs"], explain: "Report export documentation" }
37188
37476
  ];
37189
37477
  function aliasesPath(cwd = process.cwd()) {
37190
- return join19(cwd, ".todos", "aliases.json");
37478
+ return join20(cwd, ".todos", "aliases.json");
37191
37479
  }
37192
37480
  function emptyStore() {
37193
37481
  return { schema_version: COMMAND_ALIASES_SCHEMA, aliases: {}, updated_at: new Date(0).toISOString() };
@@ -37204,9 +37492,9 @@ function validateAliasName(name) {
37204
37492
  }
37205
37493
  function loadAliasStore(cwd) {
37206
37494
  const path = aliasesPath(cwd);
37207
- if (!existsSync21(path))
37495
+ if (!existsSync22(path))
37208
37496
  return emptyStore();
37209
- const parsed = JSON.parse(readFileSync20(path, "utf8"));
37497
+ const parsed = JSON.parse(readFileSync21(path, "utf8"));
37210
37498
  if (parsed.schema_version !== COMMAND_ALIASES_SCHEMA) {
37211
37499
  throw new Error(`Unsupported alias store schema: ${parsed.schema_version}`);
37212
37500
  }
@@ -37214,9 +37502,9 @@ function loadAliasStore(cwd) {
37214
37502
  }
37215
37503
  function saveAliasStore(store, cwd) {
37216
37504
  const path = aliasesPath(cwd);
37217
- mkdirSync19(join19(path, ".."), { recursive: true });
37505
+ mkdirSync20(join20(path, ".."), { recursive: true });
37218
37506
  store.updated_at = new Date().toISOString();
37219
- writeFileSync17(path, JSON.stringify(store, null, 2), "utf8");
37507
+ writeFileSync18(path, JSON.stringify(store, null, 2), "utf8");
37220
37508
  }
37221
37509
  function parseArgv(command) {
37222
37510
  const argv = [];
@@ -37862,18 +38150,18 @@ function createBranchWorkPlan(input, db) {
37862
38150
  }
37863
38151
  // src/lib/user-scaffolds.ts
37864
38152
  init_database();
37865
- import { existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync18, mkdirSync as mkdirSync20 } from "fs";
37866
- import { join as join20 } from "path";
38153
+ import { existsSync as existsSync23, readFileSync as readFileSync22, writeFileSync as writeFileSync19, mkdirSync as mkdirSync21 } from "fs";
38154
+ import { join as join21 } from "path";
37867
38155
  var USER_SCAFFOLD_SCHEMA = "todos.user_scaffold.v1";
37868
38156
  var SCAFFOLD_KINDS = ["task", "project", "plan", "checklist", "contract", "verification_policy"];
37869
38157
  function storeDir(cwd = process.cwd()) {
37870
- return join20(cwd, ".todos", "scaffolds");
38158
+ return join21(cwd, ".todos", "scaffolds");
37871
38159
  }
37872
38160
  function storePath(cwd) {
37873
- return join20(storeDir(cwd), "store.json");
38161
+ return join21(storeDir(cwd), "store.json");
37874
38162
  }
37875
38163
  function versionsDir(cwd) {
37876
- return join20(storeDir(cwd), "versions");
38164
+ return join21(storeDir(cwd), "versions");
37877
38165
  }
37878
38166
  function slugify5(name) {
37879
38167
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -37883,23 +38171,23 @@ function emptyStore2() {
37883
38171
  }
37884
38172
  function loadUserScaffoldStore(cwd) {
37885
38173
  const path = storePath(cwd);
37886
- if (!existsSync22(path))
38174
+ if (!existsSync23(path))
37887
38175
  return emptyStore2();
37888
- const parsed = JSON.parse(readFileSync21(path, "utf8"));
38176
+ const parsed = JSON.parse(readFileSync22(path, "utf8"));
37889
38177
  if (parsed.schema_version !== USER_SCAFFOLD_SCHEMA) {
37890
38178
  throw new Error(`Unsupported scaffold store schema: ${parsed.schema_version}`);
37891
38179
  }
37892
38180
  return parsed;
37893
38181
  }
37894
38182
  function saveUserScaffoldStore(store, cwd) {
37895
- mkdirSync20(storeDir(cwd), { recursive: true });
38183
+ mkdirSync21(storeDir(cwd), { recursive: true });
37896
38184
  store.updated_at = now();
37897
- writeFileSync18(storePath(cwd), JSON.stringify(store, null, 2), "utf8");
38185
+ writeFileSync19(storePath(cwd), JSON.stringify(store, null, 2), "utf8");
37898
38186
  }
37899
38187
  function snapshotVersion(scaffold, cwd) {
37900
- mkdirSync20(versionsDir(cwd), { recursive: true });
37901
- const path = join20(versionsDir(cwd), `${scaffold.id}-v${scaffold.version}.json`);
37902
- writeFileSync18(path, JSON.stringify(scaffold, null, 2), "utf8");
38188
+ mkdirSync21(versionsDir(cwd), { recursive: true });
38189
+ const path = join21(versionsDir(cwd), `${scaffold.id}-v${scaffold.version}.json`);
38190
+ writeFileSync19(path, JSON.stringify(scaffold, null, 2), "utf8");
37903
38191
  }
37904
38192
  function listUserScaffolds(kind, cwd) {
37905
38193
  const store = loadUserScaffoldStore(cwd);
@@ -38145,7 +38433,7 @@ function listLinkedTemplates(db, cwd) {
38145
38433
  // src/lib/agent-workflow-demo.ts
38146
38434
  init_database();
38147
38435
  import { mkdtempSync } from "fs";
38148
- import { join as join21 } from "path";
38436
+ import { join as join22 } from "path";
38149
38437
  import { tmpdir as tmpdir4 } from "os";
38150
38438
  var AGENT_WORKFLOW_DEMO_SCHEMA = "todos.agent_workflow_demo.v1";
38151
38439
  var DEMO_DEFAULT_AGENT = "demoagent";
@@ -38161,7 +38449,7 @@ function setupEphemeralDemoDb(options = {}) {
38161
38449
  if (options.db_path) {
38162
38450
  db_path = options.db_path;
38163
38451
  } else if (options.persist) {
38164
- db_path = join21(mkdtempSync(join21(tmpdir4(), "todos-demo-")), "todos.db");
38452
+ db_path = join22(mkdtempSync(join22(tmpdir4(), "todos-demo-")), "todos.db");
38165
38453
  } else {
38166
38454
  db_path = ":memory:";
38167
38455
  }
@@ -40486,18 +40774,18 @@ function runSearchView(idOrName, db) {
40486
40774
  return { ...runSavedSearch(view.filters, view.scope, d), view };
40487
40775
  }
40488
40776
  // src/lib/claude-tasks.ts
40489
- import { existsSync as existsSync23, readFileSync as readFileSync22, readdirSync as readdirSync4, writeFileSync as writeFileSync19 } from "fs";
40490
- import { join as join22 } from "path";
40777
+ import { existsSync as existsSync24, readFileSync as readFileSync23, readdirSync as readdirSync4, writeFileSync as writeFileSync20 } from "fs";
40778
+ import { join as join23 } from "path";
40491
40779
  init_config();
40492
40780
  init_sync_utils();
40493
40781
  function getTaskListDir(taskListId) {
40494
- return join22(HOME, ".claude", "tasks", taskListId);
40782
+ return join23(HOME, ".claude", "tasks", taskListId);
40495
40783
  }
40496
40784
  function readClaudeTask(dir, filename) {
40497
- return readJsonFile(join22(dir, filename));
40785
+ return readJsonFile(join23(dir, filename));
40498
40786
  }
40499
40787
  function writeClaudeTask(dir, task2) {
40500
- writeJsonFile(join22(dir, `${task2.id}.json`), task2);
40788
+ writeJsonFile(join23(dir, `${task2.id}.json`), task2);
40501
40789
  }
40502
40790
  function toClaudeStatus(status) {
40503
40791
  if (status === "pending" || status === "in_progress" || status === "completed") {
@@ -40509,14 +40797,14 @@ function toSqliteStatus(status) {
40509
40797
  return status;
40510
40798
  }
40511
40799
  function readPrefixCounter(dir) {
40512
- const path = join22(dir, ".prefix-counter");
40513
- if (!existsSync23(path))
40800
+ const path = join23(dir, ".prefix-counter");
40801
+ if (!existsSync24(path))
40514
40802
  return 0;
40515
- const val = parseInt(readFileSync22(path, "utf-8").trim(), 10);
40803
+ const val = parseInt(readFileSync23(path, "utf-8").trim(), 10);
40516
40804
  return isNaN(val) ? 0 : val;
40517
40805
  }
40518
40806
  function writePrefixCounter(dir, value) {
40519
- writeFileSync19(join22(dir, ".prefix-counter"), String(value));
40807
+ writeFileSync20(join23(dir, ".prefix-counter"), String(value));
40520
40808
  }
40521
40809
  function formatPrefixedSubject(title, prefix, counter) {
40522
40810
  const padded = String(counter).padStart(5, "0");
@@ -40543,7 +40831,7 @@ function taskToClaudeTask(task2, claudeTaskId, existingMeta) {
40543
40831
  }
40544
40832
  function pushToClaudeTaskList(taskListId, projectId, options = {}) {
40545
40833
  const dir = getTaskListDir(taskListId);
40546
- if (!existsSync23(dir))
40834
+ if (!existsSync24(dir))
40547
40835
  ensureDir2(dir);
40548
40836
  const filter = {};
40549
40837
  if (projectId)
@@ -40552,7 +40840,7 @@ function pushToClaudeTaskList(taskListId, projectId, options = {}) {
40552
40840
  const existingByTodosId = new Map;
40553
40841
  const files = listJsonFiles(dir);
40554
40842
  for (const f of files) {
40555
- const path = join22(dir, f);
40843
+ const path = join23(dir, f);
40556
40844
  const ct = readClaudeTask(dir, f);
40557
40845
  if (ct?.metadata?.["todos_id"]) {
40558
40846
  existingByTodosId.set(ct.metadata["todos_id"], { task: ct, mtimeMs: getFileMtimeMs(path) });
@@ -40639,7 +40927,7 @@ function pushToClaudeTaskList(taskListId, projectId, options = {}) {
40639
40927
  }
40640
40928
  function pullFromClaudeTaskList(taskListId, projectId, options = {}) {
40641
40929
  const dir = getTaskListDir(taskListId);
40642
- if (!existsSync23(dir)) {
40930
+ if (!existsSync24(dir)) {
40643
40931
  return { pushed: 0, pulled: 0, errors: [`Task list directory not found: ${dir}`] };
40644
40932
  }
40645
40933
  const files = readdirSync4(dir).filter((f) => f.endsWith(".json"));
@@ -40659,7 +40947,7 @@ function pullFromClaudeTaskList(taskListId, projectId, options = {}) {
40659
40947
  }
40660
40948
  for (const f of files) {
40661
40949
  try {
40662
- const filePath = join22(dir, f);
40950
+ const filePath = join23(dir, f);
40663
40951
  const ct = readClaudeTask(dir, f);
40664
40952
  if (!ct)
40665
40953
  continue;
@@ -40727,22 +41015,22 @@ function syncClaudeTaskList(taskListId, projectId, options = {}) {
40727
41015
  }
40728
41016
 
40729
41017
  // src/lib/agent-tasks.ts
40730
- import { existsSync as existsSync24 } from "fs";
40731
- import { join as join23 } from "path";
41018
+ import { existsSync as existsSync25 } from "fs";
41019
+ import { join as join24 } from "path";
40732
41020
  init_sync_utils();
40733
41021
  init_config();
40734
41022
  function agentBaseDir(agent) {
40735
41023
  const key = `TODOS_${agent.toUpperCase()}_TASKS_DIR`;
40736
- return process.env[key] || getAgentTasksDir(agent) || process.env["TODOS_AGENT_TASKS_DIR"] || join23(getTodosGlobalDir(), "agents");
41024
+ return process.env[key] || getAgentTasksDir(agent) || process.env["TODOS_AGENT_TASKS_DIR"] || join24(getTodosGlobalDir(), "agents");
40737
41025
  }
40738
41026
  function getTaskListDir2(agent, taskListId) {
40739
- return join23(agentBaseDir(agent), agent, taskListId);
41027
+ return join24(agentBaseDir(agent), agent, taskListId);
40740
41028
  }
40741
41029
  function readAgentTask(dir, filename) {
40742
- return readJsonFile(join23(dir, filename));
41030
+ return readJsonFile(join24(dir, filename));
40743
41031
  }
40744
41032
  function writeAgentTask(dir, task2) {
40745
- writeJsonFile(join23(dir, `${task2.id}.json`), task2);
41033
+ writeJsonFile(join24(dir, `${task2.id}.json`), task2);
40746
41034
  }
40747
41035
  function taskToAgentTask(task2, externalId, existingMeta) {
40748
41036
  return {
@@ -40767,7 +41055,7 @@ function metadataKey(agent) {
40767
41055
  }
40768
41056
  function pushToAgentTaskList(agent, taskListId, projectId, options = {}) {
40769
41057
  const dir = getTaskListDir2(agent, taskListId);
40770
- if (!existsSync24(dir))
41058
+ if (!existsSync25(dir))
40771
41059
  ensureDir2(dir);
40772
41060
  const filter = {};
40773
41061
  if (projectId)
@@ -40776,7 +41064,7 @@ function pushToAgentTaskList(agent, taskListId, projectId, options = {}) {
40776
41064
  const existingByTodosId = new Map;
40777
41065
  const files = listJsonFiles(dir);
40778
41066
  for (const f of files) {
40779
- const path = join23(dir, f);
41067
+ const path = join24(dir, f);
40780
41068
  const at = readAgentTask(dir, f);
40781
41069
  if (at?.metadata?.["todos_id"]) {
40782
41070
  existingByTodosId.set(at.metadata["todos_id"], { task: at, mtimeMs: getFileMtimeMs(path) });
@@ -40850,7 +41138,7 @@ function pushToAgentTaskList(agent, taskListId, projectId, options = {}) {
40850
41138
  }
40851
41139
  function pullFromAgentTaskList(agent, taskListId, projectId, options = {}) {
40852
41140
  const dir = getTaskListDir2(agent, taskListId);
40853
- if (!existsSync24(dir)) {
41141
+ if (!existsSync25(dir)) {
40854
41142
  return { pushed: 0, pulled: 0, errors: [`Task list directory not found: ${dir}`] };
40855
41143
  }
40856
41144
  const files = listJsonFiles(dir);
@@ -40869,7 +41157,7 @@ function pullFromAgentTaskList(agent, taskListId, projectId, options = {}) {
40869
41157
  }
40870
41158
  for (const f of files) {
40871
41159
  try {
40872
- const filePath = join23(dir, f);
41160
+ const filePath = join24(dir, f);
40873
41161
  const at = readAgentTask(dir, f);
40874
41162
  if (!at)
40875
41163
  continue;
@@ -41007,9 +41295,9 @@ function syncWithAgents(agents, taskListIdByAgent, projectId, direction = "both"
41007
41295
  return { pushed, pulled, errors };
41008
41296
  }
41009
41297
  // src/lib/extract.ts
41010
- import { existsSync as existsSync25, readFileSync as readFileSync23, statSync as statSync8 } from "fs";
41298
+ import { existsSync as existsSync26, readFileSync as readFileSync24, statSync as statSync8 } from "fs";
41011
41299
  import { createHash as createHash14 } from "crypto";
41012
- import { relative as relative6, resolve as resolve16, join as join24 } from "path";
41300
+ import { relative as relative6, resolve as resolve17, join as join25 } from "path";
41013
41301
  var EXTRACT_TAGS = ["TODO", "FIXME", "HACK", "XXX", "BUG", "NOTE"];
41014
41302
  var DEFAULT_EXTENSIONS = new Set([
41015
41303
  ".ts",
@@ -41079,12 +41367,12 @@ function normalizePathForMatch(value) {
41079
41367
  return value.replace(/\\/g, "/").replace(/^\.\//, "");
41080
41368
  }
41081
41369
  function readGitignorePatterns(basePath) {
41082
- const root = statSync8(basePath).isFile() ? resolve16(basePath, "..") : basePath;
41083
- const gitignorePath = join24(root, ".gitignore");
41084
- if (!existsSync25(gitignorePath))
41370
+ const root = statSync8(basePath).isFile() ? resolve17(basePath, "..") : basePath;
41371
+ const gitignorePath = join25(root, ".gitignore");
41372
+ if (!existsSync26(gitignorePath))
41085
41373
  return [];
41086
41374
  try {
41087
- return readFileSync23(gitignorePath, "utf-8").split(`
41375
+ return readFileSync24(gitignorePath, "utf-8").split(`
41088
41376
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#") && !line.startsWith("!"));
41089
41377
  } catch {
41090
41378
  return [];
@@ -41215,7 +41503,7 @@ function collectFiles(basePath, extensions, excludes, respectGitignore) {
41215
41503
  return files.sort();
41216
41504
  }
41217
41505
  function buildCodebaseIndex(options) {
41218
- const basePath = resolve16(options.path);
41506
+ const basePath = resolve17(options.path);
41219
41507
  const tags = options.patterns || [...EXTRACT_TAGS];
41220
41508
  const extensions = options.extensions ? new Set(options.extensions.map((e) => e.startsWith(".") ? e : `.${e}`)) : DEFAULT_EXTENSIONS;
41221
41509
  const excludes = options.exclude || [];
@@ -41223,10 +41511,10 @@ function buildCodebaseIndex(options) {
41223
41511
  const files = collectFiles(basePath, extensions, excludes, respectGitignore);
41224
41512
  const indexed = [];
41225
41513
  for (const file of files) {
41226
- const fullPath = statSync8(basePath).isFile() ? basePath : join24(basePath, file);
41514
+ const fullPath = statSync8(basePath).isFile() ? basePath : join25(basePath, file);
41227
41515
  try {
41228
- const source9 = readFileSync23(fullPath, "utf-8");
41229
- const relPath = statSync8(basePath).isFile() ? relative6(resolve16(basePath, ".."), fullPath) : file;
41516
+ const source9 = readFileSync24(fullPath, "utf-8");
41517
+ const relPath = statSync8(basePath).isFile() ? relative6(resolve17(basePath, ".."), fullPath) : file;
41230
41518
  indexed.push({
41231
41519
  file: relPath,
41232
41520
  checksum: stableHash(source9).slice(0, 24),
@@ -41246,7 +41534,7 @@ function buildCodebaseIndex(options) {
41246
41534
  };
41247
41535
  }
41248
41536
  function extractTodos(options, db) {
41249
- const basePath = resolve16(options.path);
41537
+ const basePath = resolve17(options.path);
41250
41538
  const tags = options.patterns || [...EXTRACT_TAGS];
41251
41539
  const extensions = options.extensions ? new Set(options.extensions.map((e) => e.startsWith(".") ? e : `.${e}`)) : DEFAULT_EXTENSIONS;
41252
41540
  const excludes = options.exclude || [];
@@ -41254,10 +41542,10 @@ function extractTodos(options, db) {
41254
41542
  const files = collectFiles(basePath, extensions, excludes, respectGitignore);
41255
41543
  const allComments = [];
41256
41544
  for (const file of files) {
41257
- const fullPath = statSync8(basePath).isFile() ? basePath : join24(basePath, file);
41545
+ const fullPath = statSync8(basePath).isFile() ? basePath : join25(basePath, file);
41258
41546
  try {
41259
- const source9 = readFileSync23(fullPath, "utf-8");
41260
- const relPath = statSync8(basePath).isFile() ? relative6(resolve16(basePath, ".."), fullPath) : file;
41547
+ const source9 = readFileSync24(fullPath, "utf-8");
41548
+ const relPath = statSync8(basePath).isFile() ? relative6(resolve17(basePath, ".."), fullPath) : file;
41261
41549
  const comments = extractFromSource(source9, relPath, tags);
41262
41550
  allComments.push(...comments);
41263
41551
  } catch {}
@@ -41351,7 +41639,7 @@ async function watchSourceTodos(options, onRun) {
41351
41639
  const interval = Math.max(100, options.interval_ms || 2000);
41352
41640
  const once = options.once !== false && (!options.max_runs || options.max_runs <= 1);
41353
41641
  const maxRuns = options.max_runs ?? (once ? 1 : Number.POSITIVE_INFINITY);
41354
- const root = resolve16(options.path);
41642
+ const root = resolve17(options.path);
41355
41643
  const runs = [];
41356
41644
  let previous = new Map;
41357
41645
  for (let runNumber = 1;runNumber <= maxRuns; runNumber++) {
@@ -41962,7 +42250,7 @@ function renderWorkflowStatesMarkdown(states = listWorkflowStates()) {
41962
42250
  // src/lib/agent-replay-simulator.ts
41963
42251
  init_redaction();
41964
42252
  import { createHash as createHash15 } from "crypto";
41965
- import { readFileSync as readFileSync24 } from "fs";
42253
+ import { readFileSync as readFileSync25 } from "fs";
41966
42254
  function isObject(value) {
41967
42255
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
41968
42256
  }
@@ -42195,7 +42483,7 @@ function simulateAgentReplay(input, options = {}) {
42195
42483
  };
42196
42484
  }
42197
42485
  function simulateAgentReplayFile(path, options = {}) {
42198
- const parsed = JSON.parse(readFileSync24(path, "utf8"));
42486
+ const parsed = JSON.parse(readFileSync25(path, "utf8"));
42199
42487
  return simulateAgentReplay(parsed, options);
42200
42488
  }
42201
42489
  function renderAgentReplaySimulationMarkdown(simulation) {
@@ -42223,8 +42511,8 @@ function renderAgentReplaySimulationMarkdown(simulation) {
42223
42511
  // src/lib/local-extensions.ts
42224
42512
  init_config();
42225
42513
  import { createHash as createHash16, createVerify } from "crypto";
42226
- import { existsSync as existsSync26, readdirSync as readdirSync5, readFileSync as readFileSync25, statSync as statSync9 } from "fs";
42227
- import { basename as basename5, join as join25, resolve as resolve17 } from "path";
42514
+ import { existsSync as existsSync27, readdirSync as readdirSync5, readFileSync as readFileSync26, statSync as statSync9 } from "fs";
42515
+ import { basename as basename5, join as join26, resolve as resolve18 } from "path";
42228
42516
  init_redaction();
42229
42517
  function isObject2(value) {
42230
42518
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -42306,7 +42594,7 @@ function normalizeManifest(input) {
42306
42594
  };
42307
42595
  }
42308
42596
  function parseJson(path) {
42309
- return JSON.parse(readFileSync25(path, "utf8"));
42597
+ return JSON.parse(readFileSync26(path, "utf8"));
42310
42598
  }
42311
42599
  function sha2566(bytes) {
42312
42600
  return `sha256:${createHash16("sha256").update(bytes).digest("hex")}`;
@@ -42504,14 +42792,14 @@ function verifyExtensionSignature(input) {
42504
42792
  return verifier.verify(input.public_key, decodeSignature(input.signature));
42505
42793
  }
42506
42794
  function inspectExtensionSource(source9) {
42507
- const resolved = resolve17(source9);
42508
- if (!existsSync26(resolved))
42795
+ const resolved = resolve18(source9);
42796
+ if (!existsSync27(resolved))
42509
42797
  throw new Error(`extension source not found: ${source9}`);
42510
42798
  const stat = statSync9(resolved);
42511
- const manifestPath = stat.isDirectory() ? [join25(resolved, "todos.extension.json"), join25(resolved, "extension.json")].find(existsSync26) : resolved;
42799
+ const manifestPath = stat.isDirectory() ? [join26(resolved, "todos.extension.json"), join26(resolved, "extension.json")].find(existsSync27) : resolved;
42512
42800
  if (!manifestPath)
42513
42801
  throw new Error(`extension directory ${source9} is missing todos.extension.json`);
42514
- const raw = readFileSync25(manifestPath);
42802
+ const raw = readFileSync26(manifestPath);
42515
42803
  const parsed = parseJson(manifestPath);
42516
42804
  const bundle = isObject2(parsed) && isObject2(parsed["manifest"]);
42517
42805
  const manifest = normalizeManifest(bundle ? parsed["manifest"] : parsed);
@@ -42602,26 +42890,26 @@ function testExtensionCompatibility(sourceOrManifest) {
42602
42890
  function projectExtensionSources(projectPath) {
42603
42891
  if (!projectPath)
42604
42892
  return [];
42605
- const root = resolve17(projectPath);
42893
+ const root = resolve18(projectPath);
42606
42894
  const candidates = [
42607
- join25(root, "todos.extension.json"),
42608
- join25(root, ".todos", "todos.extension.json")
42895
+ join26(root, "todos.extension.json"),
42896
+ join26(root, ".todos", "todos.extension.json")
42609
42897
  ];
42610
- const extensionDir = join25(root, ".todos", "extensions");
42611
- if (existsSync26(extensionDir)) {
42898
+ const extensionDir = join26(root, ".todos", "extensions");
42899
+ if (existsSync27(extensionDir)) {
42612
42900
  for (const entry2 of readdirSync5(extensionDir)) {
42613
42901
  if (entry2.startsWith("."))
42614
42902
  continue;
42615
- const full = join25(extensionDir, entry2);
42903
+ const full = join26(extensionDir, entry2);
42616
42904
  if (statSync9(full).isDirectory() || entry2.endsWith(".json"))
42617
42905
  candidates.push(full);
42618
42906
  }
42619
42907
  }
42620
- return candidates.filter(existsSync26);
42908
+ return candidates.filter(existsSync27);
42621
42909
  }
42622
42910
  function discoverLocalExtensions(options = {}) {
42623
42911
  const config = loadConfig();
42624
- const projectPath = options.project_path ? resolve17(options.project_path) : null;
42912
+ const projectPath = options.project_path ? resolve18(options.project_path) : null;
42625
42913
  const configuredSources = [
42626
42914
  ...config.extension_sources || [],
42627
42915
  ...projectPath ? config.project_overrides?.[projectPath]?.extension_sources || [] : []
@@ -42629,7 +42917,7 @@ function discoverLocalExtensions(options = {}) {
42629
42917
  const sources = Array.from(new Set([
42630
42918
  ...configuredSources,
42631
42919
  ...projectExtensionSources(projectPath || undefined)
42632
- ])).map((source9) => projectPath && !source9.startsWith("/") ? resolve17(projectPath, source9) : resolve17(source9));
42920
+ ])).map((source9) => projectPath && !source9.startsWith("/") ? resolve18(projectPath, source9) : resolve18(source9));
42633
42921
  const warnings = [];
42634
42922
  const discovered = [];
42635
42923
  for (const source9 of sources) {
@@ -43478,7 +43766,7 @@ function resolveMissingTaskFindings(input, db) {
43478
43766
  init_redaction();
43479
43767
 
43480
43768
  // src/lib/retention-cleanup.ts
43481
- import { existsSync as existsSync27, unlinkSync as unlinkSync2 } from "fs";
43769
+ import { existsSync as existsSync28, unlinkSync as unlinkSync2 } from "fs";
43482
43770
  init_database();
43483
43771
  var RETENTION_CLEANUP_CONFIRMATION = "delete-local-retention-data";
43484
43772
  var ALL_SCOPES = ["comments", "runs", "verifications", "expired_artifacts"];
@@ -43690,7 +43978,7 @@ function applyRetentionCleanup(input, db) {
43690
43978
  for (const artifact of report.candidates.artifact_files) {
43691
43979
  try {
43692
43980
  const path = artifactStorePath(artifact.relative_path);
43693
- if (!existsSync27(path)) {
43981
+ if (!existsSync28(path)) {
43694
43982
  report.warnings.push(`stored artifact already missing: ${artifact.relative_path}`);
43695
43983
  continue;
43696
43984
  }
@@ -43928,8 +44216,8 @@ function renderScalePerformanceReportMarkdown(report) {
43928
44216
  init_database();
43929
44217
  init_migrations();
43930
44218
  init_schema();
43931
- import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync28, mkdirSync as mkdirSync21, statSync as statSync10 } from "fs";
43932
- import { basename as basename6, dirname as dirname18, join as join26 } from "path";
44219
+ import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync29, mkdirSync as mkdirSync22, statSync as statSync10 } from "fs";
44220
+ import { basename as basename6, dirname as dirname18, join as join27 } from "path";
43933
44221
  var REQUIRED_TABLES2 = [
43934
44222
  "_migrations",
43935
44223
  "projects",
@@ -44036,7 +44324,7 @@ function findMissingProjectRoots(db) {
44036
44324
  continue;
44037
44325
  if (!row.path.startsWith("/"))
44038
44326
  continue;
44039
- if (!existsSync28(row.path))
44327
+ if (!existsSync29(row.path))
44040
44328
  missing++;
44041
44329
  }
44042
44330
  return missing;
@@ -44096,16 +44384,16 @@ function databasePermissionsAreUnsafe(dbPath) {
44096
44384
  function createBackup(dbPath) {
44097
44385
  if (dbPath === ":memory:" || dbPath.startsWith("file::memory:"))
44098
44386
  return;
44099
- if (!existsSync28(dbPath))
44387
+ if (!existsSync29(dbPath))
44100
44388
  return;
44101
44389
  const stamp = now().replace(/[:.]/g, "-");
44102
- const backupDir = join26(dirname18(dbPath), `${basename6(dbPath)}.backup-${stamp}`);
44390
+ const backupDir = join27(dirname18(dbPath), `${basename6(dbPath)}.backup-${stamp}`);
44103
44391
  const files = [];
44104
- mkdirSync21(backupDir, { recursive: true });
44392
+ mkdirSync22(backupDir, { recursive: true });
44105
44393
  for (const source9 of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
44106
- if (!existsSync28(source9))
44394
+ if (!existsSync29(source9))
44107
44395
  continue;
44108
- const target = join26(backupDir, basename6(source9));
44396
+ const target = join27(backupDir, basename6(source9));
44109
44397
  copyFileSync2(source9, target);
44110
44398
  files.push(target);
44111
44399
  }
@@ -44769,6 +45057,7 @@ export {
44769
45057
  writeVerificationExport,
44770
45058
  writeSdkIntegrationFixtures,
44771
45059
  writeReportExport,
45060
+ writePlanArtifact,
44772
45061
  writeOnboardingFixtureFiles,
44773
45062
  writeLocalBackupFile,
44774
45063
  writeEnvironmentSnapshot,
@@ -44935,6 +45224,8 @@ export {
44935
45224
  resolveTaskRunId,
44936
45225
  resolvePlanRef,
44937
45226
  resolvePlanId,
45227
+ resolvePlanArtifactProject,
45228
+ resolvePlanArtifactPaths,
44938
45229
  resolvePartialId,
44939
45230
  resolveMissingTaskFindings,
44940
45231
  resolveMentions,
@@ -44965,6 +45256,7 @@ export {
44965
45256
  renderReleaseNotesMarkdown,
44966
45257
  renderReleaseCompatibilityMarkdown,
44967
45258
  renderPlanningForecastMarkdown,
45259
+ renderPlanArtifactMarkdown,
44968
45260
  renderLocalUsageLedgerMarkdown,
44969
45261
  renderLocalSnapshotMarkdown,
44970
45262
  renderLocalReportMarkdown,
@@ -45022,6 +45314,7 @@ export {
45022
45314
  recordFilesTouched,
45023
45315
  recordEnvironmentSnapshot,
45024
45316
  readTesterIssueReportsPayload,
45317
+ readPlanArtifact,
45025
45318
  readLocalBackupFile,
45026
45319
  readEnvironmentSnapshot,
45027
45320
  readBundleFile,
@@ -45051,6 +45344,7 @@ export {
45051
45344
  parseStorageMode,
45052
45345
  parseRecurrenceRule,
45053
45346
  parseQuietHours,
45347
+ parsePlanArtifactMarkdown,
45054
45348
  parseNaturalLanguageTask,
45055
45349
  parseIssueExport,
45056
45350
  parseGoalCommand,
@@ -45202,6 +45496,7 @@ export {
45202
45496
  isAgentConflict,
45203
45497
  installTemplateLibrary,
45204
45498
  installLocalExtension,
45499
+ inspectPlanArtifact,
45205
45500
  inspectGitCommit,
45206
45501
  inspectExtensionSource,
45207
45502
  initBuiltinTemplates,
@@ -45675,6 +45970,7 @@ export {
45675
45970
  buildRunReplayBundle,
45676
45971
  buildResourceSnapshot,
45677
45972
  buildReportExportData,
45973
+ buildPlanArtifactSnapshot,
45678
45974
  buildMcpToolGroups,
45679
45975
  buildMachineTopologyReport,
45680
45976
  buildKnowledgeSnapshotPayload,
@@ -45800,6 +46096,7 @@ export {
45800
46096
  ProjectNotFoundError,
45801
46097
  PlanNotFoundError,
45802
46098
  PLAN_STATUSES,
46099
+ PLAN_MARKDOWN_SCHEMA,
45803
46100
  PLAN_EXECUTION_SCHEMA,
45804
46101
  PLAN_EXECUTION_MODES,
45805
46102
  PARITY_SCHEMA_VERSION,