@cleocode/cleo 2026.5.113 → 2026.5.114

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/cli/index.js CHANGED
@@ -12317,6 +12317,7 @@ var init_src2 = __esm({
12317
12317
  init_operations();
12318
12318
  init_nexus_scope_map();
12319
12319
  init_params();
12320
+ init_tasks();
12320
12321
  init_peer();
12321
12322
  init_evidence_atoms();
12322
12323
  init_plan();
@@ -26224,8 +26225,8 @@ async function loadPlaybookByName(name) {
26224
26225
  return null;
26225
26226
  }
26226
26227
  try {
26227
- const { getProjectRoot: getProjectRoot53 } = await import("@cleocode/core/internal");
26228
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot53();
26228
+ const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26229
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot54();
26229
26230
  const resolved = resolvePlaybook(name, {
26230
26231
  projectRoot,
26231
26232
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -26269,8 +26270,8 @@ async function acquireDb() {
26269
26270
  async function buildDefaultDispatcher() {
26270
26271
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
26271
26272
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
26272
- const { getProjectRoot: getProjectRoot53 } = await import("@cleocode/core/internal");
26273
- const projectRoot = getProjectRoot53();
26273
+ const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26274
+ const projectRoot = getProjectRoot54();
26274
26275
  return {
26275
26276
  async dispatch(input2) {
26276
26277
  try {
@@ -26460,8 +26461,8 @@ var init_playbook2 = __esm({
26460
26461
  projectRoot = __playbookRuntimeOverrides.projectRoot;
26461
26462
  } else {
26462
26463
  try {
26463
- const { getProjectRoot: getProjectRoot53 } = await import("@cleocode/core/internal");
26464
- projectRoot = getProjectRoot53();
26464
+ const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26465
+ projectRoot = getProjectRoot54();
26465
26466
  } catch {
26466
26467
  projectRoot = void 0;
26467
26468
  }
@@ -26525,14 +26526,14 @@ var init_playbook2 = __esm({
26525
26526
  const dispatcher = await buildDefaultDispatcher();
26526
26527
  let result;
26527
26528
  try {
26528
- const { getProjectRoot: getProjectRoot53 } = await import("@cleocode/core/internal");
26529
+ const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26529
26530
  const opts = {
26530
26531
  db,
26531
26532
  playbook: parsed.definition,
26532
26533
  playbookHash: parsed.sourceHash,
26533
26534
  initialContext,
26534
26535
  dispatcher,
26535
- projectRoot: getProjectRoot53()
26536
+ projectRoot: getProjectRoot54()
26536
26537
  };
26537
26538
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
26538
26539
  opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
@@ -26896,16 +26897,16 @@ async function orchestrateRejectOp(params) {
26896
26897
  async function orchestrateClassify(request, context, projectRoot) {
26897
26898
  try {
26898
26899
  const { getCleoCantWorkflowsDir } = await import("@cleocode/core/internal");
26899
- const { readFileSync: readFileSync18, readdirSync: readdirSync3, existsSync: existsSync17 } = await import("node:fs");
26900
- const { join: join34 } = await import("node:path");
26900
+ const { readFileSync: readFileSync21, readdirSync: readdirSync3, existsSync: existsSync19 } = await import("node:fs");
26901
+ const { join: join37 } = await import("node:path");
26901
26902
  const workflowsDir = getCleoCantWorkflowsDir();
26902
26903
  const combined = `${request} ${context ?? ""}`.toLowerCase();
26903
26904
  const matches = [];
26904
- if (existsSync17(workflowsDir)) {
26905
+ if (existsSync19(workflowsDir)) {
26905
26906
  const files = readdirSync3(workflowsDir).filter((f) => f.endsWith(".cant"));
26906
26907
  for (const file of files) {
26907
26908
  try {
26908
- const src = readFileSync18(join34(workflowsDir, file), "utf-8");
26909
+ const src = readFileSync21(join37(workflowsDir, file), "utf-8");
26909
26910
  const teamMatch = /^team\s+(\S+):/m.exec(src);
26910
26911
  if (!teamMatch) continue;
26911
26912
  const teamName = teamMatch[1];
@@ -26920,12 +26921,12 @@ async function orchestrateClassify(request, context, projectRoot) {
26920
26921
  }
26921
26922
  }
26922
26923
  }
26923
- const localCantDir = join34(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
26924
- if (existsSync17(localCantDir)) {
26924
+ const localCantDir = join37(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
26925
+ if (existsSync19(localCantDir)) {
26925
26926
  const files = readdirSync3(localCantDir).filter((f) => f.endsWith(".cant"));
26926
26927
  for (const file of files) {
26927
26928
  try {
26928
- const src = readFileSync18(join34(localCantDir, file), "utf-8");
26929
+ const src = readFileSync21(join37(localCantDir, file), "utf-8");
26929
26930
  const teamMatch = /^team\s+(\S+):/m.exec(src);
26930
26931
  if (!teamMatch) continue;
26931
26932
  const teamName = teamMatch[1];
@@ -27117,11 +27118,11 @@ async function orchestrateAnalyzeParallelSafety(taskIds, projectRoot) {
27117
27118
  };
27118
27119
  }
27119
27120
  }
27120
- async function handleWorktreeComplete(taskId, projectRoot, resolve7) {
27121
+ async function handleWorktreeComplete(taskId, projectRoot, resolve8) {
27121
27122
  try {
27122
27123
  const { completeWorktreeForTask } = await import("@cleocode/core/internal");
27123
27124
  const result = completeWorktreeForTask(taskId, projectRoot, {
27124
- resolve: resolve7 ?? "auto"
27125
+ resolve: resolve8 ?? "auto"
27125
27126
  });
27126
27127
  if (result.outcome === "conflict") {
27127
27128
  return {
@@ -27798,10 +27799,10 @@ var init_orchestrate2 = __esm({
27798
27799
  startTime
27799
27800
  );
27800
27801
  const rawResolve = params.resolve;
27801
- const resolve7 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
27802
+ const resolve8 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
27802
27803
  const p = {
27803
27804
  taskId: params.taskId,
27804
- ...resolve7 !== void 0 ? { resolve: resolve7 } : {}
27805
+ ...resolve8 !== void 0 ? { resolve: resolve8 } : {}
27805
27806
  };
27806
27807
  return wrapResult(
27807
27808
  await coreOps2["worktree.complete"](p),
@@ -32320,11 +32321,11 @@ var init_security = __esm({
32320
32321
  });
32321
32322
 
32322
32323
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
32323
- function createSanitizer(getProjectRoot53) {
32324
+ function createSanitizer(getProjectRoot54) {
32324
32325
  return async (req, next) => {
32325
32326
  if (req.params) {
32326
32327
  try {
32327
- const root = getProjectRoot53 ? getProjectRoot53() : void 0;
32328
+ const root = getProjectRoot54 ? getProjectRoot54() : void 0;
32328
32329
  req.params = sanitizeParams(req.params, root, {
32329
32330
  domain: req.domain,
32330
32331
  operation: req.operation
@@ -32857,18 +32858,77 @@ var init_adapter = __esm({
32857
32858
  }
32858
32859
  });
32859
32860
 
32861
+ // packages/cleo/src/cli/lib/collect-input.ts
32862
+ import { readFile as readFile2 } from "node:fs/promises";
32863
+ function wrapParseError(rawInput, parseErr, sourceLabel) {
32864
+ const snippet2 = rawInput.length > PARSE_ERROR_SNIPPET_MAX_LENGTH ? `${rawInput.slice(0, PARSE_ERROR_SNIPPET_MAX_LENGTH)}\u2026` : rawInput;
32865
+ return new Error(`Invalid JSON in ${sourceLabel}: ${parseErr.message} (got: ${snippet2})`);
32866
+ }
32867
+ function readStdinJson(stdin) {
32868
+ return new Promise((resolve8, reject) => {
32869
+ const chunks = [];
32870
+ stdin.on("data", (chunk) => {
32871
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
32872
+ });
32873
+ stdin.on("error", (err) => {
32874
+ reject(err);
32875
+ });
32876
+ stdin.on("end", () => {
32877
+ const raw = Buffer.concat(chunks).toString("utf8");
32878
+ try {
32879
+ resolve8(JSON.parse(raw));
32880
+ } catch (err) {
32881
+ reject(wrapParseError(raw, err, "stdin"));
32882
+ }
32883
+ });
32884
+ });
32885
+ }
32886
+ async function collectMutateInput(args, stdin) {
32887
+ if (typeof args.params === "string" && args.params.length > 0) {
32888
+ try {
32889
+ return JSON.parse(args.params);
32890
+ } catch (err) {
32891
+ throw wrapParseError(args.params, err, "--params");
32892
+ }
32893
+ }
32894
+ if (typeof args.file === "string" && args.file.length > 0) {
32895
+ const raw = await readFile2(args.file, "utf8");
32896
+ try {
32897
+ return JSON.parse(raw);
32898
+ } catch (err) {
32899
+ throw wrapParseError(raw, err, `--file ${args.file}`);
32900
+ }
32901
+ }
32902
+ if (stdin.isTTY !== true) {
32903
+ return readStdinJson(stdin);
32904
+ }
32905
+ if (args.positional !== void 0 && args.positional.length > 0) {
32906
+ return args.positional;
32907
+ }
32908
+ return void 0;
32909
+ }
32910
+ var PARSE_ERROR_SNIPPET_MAX_LENGTH;
32911
+ var init_collect_input = __esm({
32912
+ "packages/cleo/src/cli/lib/collect-input.ts"() {
32913
+ "use strict";
32914
+ PARSE_ERROR_SNIPPET_MAX_LENGTH = 80;
32915
+ }
32916
+ });
32917
+
32860
32918
  // packages/cleo/src/cli/commands/add-batch.ts
32861
32919
  var add_batch_exports = {};
32862
32920
  __export(add_batch_exports, {
32863
32921
  addBatchCommand: () => addBatchCommand
32864
32922
  });
32865
- import { existsSync as existsSync6, readFileSync as readFileSync8 } from "node:fs";
32923
+ import { INPUT_CONTRACTS, validateOperationInput } from "@cleocode/core";
32866
32924
  var addBatchCommand;
32867
32925
  var init_add_batch = __esm({
32868
32926
  "packages/cleo/src/cli/commands/add-batch.ts"() {
32869
32927
  "use strict";
32928
+ init_src2();
32870
32929
  init_dist();
32871
32930
  init_cli();
32931
+ init_collect_input();
32872
32932
  init_renderers();
32873
32933
  addBatchCommand = defineCommand({
32874
32934
  meta: {
@@ -32876,9 +32936,13 @@ var init_add_batch = __esm({
32876
32936
  description: "Create multiple tasks in a single atomic transaction from a JSON file"
32877
32937
  },
32878
32938
  args: {
32939
+ params: {
32940
+ type: "string",
32941
+ description: 'Inline JSON object: { "tasks": [...], "defaultParent"?: "...", "dryRun"?: bool } (T9917)'
32942
+ },
32879
32943
  file: {
32880
32944
  type: "string",
32881
- description: "Path to JSON file (array of task objects). Use - for stdin."
32945
+ description: "Path to JSON file (array of task objects, or full payload). Use - for stdin."
32882
32946
  },
32883
32947
  parent: {
32884
32948
  type: "string",
@@ -32890,66 +32954,86 @@ var init_add_batch = __esm({
32890
32954
  }
32891
32955
  },
32892
32956
  async run({ args }) {
32893
- const filePath = args.file;
32894
32957
  const defaultParent = args.parent;
32895
- const dryRun = args["dry-run"];
32958
+ const dryRunFlag = args["dry-run"];
32959
+ const paramsArg = args.params;
32960
+ const fileArg = args.file;
32961
+ const collectArgs = {};
32962
+ if (paramsArg !== void 0) collectArgs.params = paramsArg;
32963
+ if (fileArg !== void 0 && fileArg !== "-") collectArgs.file = fileArg;
32896
32964
  let raw;
32897
- if (!filePath || filePath === "-") {
32898
- const chunks = [];
32899
- for await (const chunk of process.stdin) chunks.push(chunk);
32900
- raw = Buffer.concat(chunks).toString("utf-8");
32901
- if (!raw.trim()) {
32902
- cliError(
32903
- "No input provided. Pass --file <path> or pipe JSON to stdin.",
32904
- "E_VALIDATION",
32905
- { name: "E_VALIDATION", fix: "cleo add-batch --file tasks.json" },
32906
- { operation: "tasks.add-batch" }
32907
- );
32908
- process.exitCode = 2;
32909
- return;
32910
- }
32965
+ try {
32966
+ raw = await collectMutateInput(
32967
+ collectArgs,
32968
+ process.stdin
32969
+ );
32970
+ } catch (err) {
32971
+ cliError(
32972
+ err.message,
32973
+ 6 /* VALIDATION_ERROR */,
32974
+ {
32975
+ name: "E_VALIDATION_FAILED",
32976
+ fix: "Verify the JSON syntax of your --params / --file / stdin input"
32977
+ },
32978
+ { operation: "tasks.add-batch" }
32979
+ );
32980
+ process.exitCode = 6 /* VALIDATION_ERROR */;
32981
+ return;
32982
+ }
32983
+ if (raw === void 0) {
32984
+ cliError(
32985
+ "No input provided. Pass --params <json>, --file <path>, or pipe JSON to stdin.",
32986
+ 6 /* VALIDATION_ERROR */,
32987
+ {
32988
+ name: "E_VALIDATION_FAILED",
32989
+ fix: "cleo add-batch --file tasks.json"
32990
+ },
32991
+ { operation: "tasks.add-batch" }
32992
+ );
32993
+ process.exitCode = 6 /* VALIDATION_ERROR */;
32994
+ return;
32995
+ }
32996
+ let payload;
32997
+ if (Array.isArray(raw)) {
32998
+ payload = { tasks: raw };
32999
+ } else if (raw !== null && typeof raw === "object" && Array.isArray(raw["tasks"])) {
33000
+ payload = { ...raw };
32911
33001
  } else {
32912
- if (!existsSync6(filePath)) {
32913
- cliError(
32914
- `File not found: ${filePath}`,
32915
- "E_NOT_FOUND",
32916
- { name: "E_NOT_FOUND", fix: `Verify the file path exists: ${filePath}` },
32917
- { operation: "tasks.add-batch" }
32918
- );
32919
- process.exitCode = 2;
32920
- return;
32921
- }
32922
- raw = readFileSync8(filePath, "utf-8");
33002
+ payload = { tasks: [raw] };
32923
33003
  }
32924
- let tasks;
32925
- try {
32926
- const parsed = JSON.parse(raw);
32927
- tasks = Array.isArray(parsed) ? parsed : [parsed];
32928
- } catch {
33004
+ if (defaultParent !== void 0 && payload["defaultParent"] === void 0) {
33005
+ payload["defaultParent"] = defaultParent;
33006
+ }
33007
+ if (dryRunFlag === true && payload["dryRun"] === void 0) {
33008
+ payload["dryRun"] = true;
33009
+ }
33010
+ const contract = INPUT_CONTRACTS["tasks.add-batch"];
33011
+ if (!contract) {
32929
33012
  cliError(
32930
- "Invalid JSON input. Expected an array of task objects.",
32931
- "E_VALIDATION",
32932
- { name: "E_VALIDATION", fix: "Ensure the input is a valid JSON array of task objects" },
33013
+ "tasks.add-batch contract missing from INPUT_CONTRACTS registry",
33014
+ 1 /* GENERAL_ERROR */,
33015
+ { name: "E_INTERNAL", fix: "This is a CLI bug \u2014 file an issue" },
32933
33016
  { operation: "tasks.add-batch" }
32934
33017
  );
32935
- process.exitCode = 2;
33018
+ process.exitCode = 1 /* GENERAL_ERROR */;
32936
33019
  return;
32937
33020
  }
32938
- if (tasks.length === 0) {
33021
+ const result = validateOperationInput(contract, payload);
33022
+ if (!result.ok) {
32939
33023
  cliError(
32940
- "No tasks in input.",
32941
- "E_VALIDATION",
32942
- { name: "E_VALIDATION", fix: "Provide at least one task object in the JSON array" },
33024
+ "tasks.add-batch failed: validation",
33025
+ 6 /* VALIDATION_ERROR */,
33026
+ {
33027
+ name: "E_VALIDATION_FAILED",
33028
+ fix: result.errors[0]?.fix ?? "Inspect the errors[] payload and correct the input",
33029
+ details: { errors: result.errors }
33030
+ },
32943
33031
  { operation: "tasks.add-batch" }
32944
33032
  );
32945
- process.exitCode = 2;
33033
+ process.exitCode = 6 /* VALIDATION_ERROR */;
32946
33034
  return;
32947
33035
  }
32948
- const response = await dispatchRaw("mutate", "tasks", "add-batch", {
32949
- tasks,
32950
- ...defaultParent && { defaultParent },
32951
- ...dryRun && { dryRun: true }
32952
- });
33036
+ const response = await dispatchRaw("mutate", "tasks", "add-batch", payload);
32953
33037
  if (!response.success) {
32954
33038
  cliError(
32955
33039
  response.error?.message ?? "Batch creation failed",
@@ -32977,7 +33061,9 @@ __export(add_exports, {
32977
33061
  import {
32978
33062
  appendSignedSeverityAttestation,
32979
33063
  getProjectRoot as getProjectRoot23,
32980
- inferTaskAddParams
33064
+ INPUT_CONTRACTS as INPUT_CONTRACTS2,
33065
+ inferTaskAddParams,
33066
+ validateOperationInput as validateOperationInput2
32981
33067
  } from "@cleocode/core";
32982
33068
  var addCommand;
32983
33069
  var init_add = __esm({
@@ -32986,6 +33072,7 @@ var init_add = __esm({
32986
33072
  init_src2();
32987
33073
  init_dist();
32988
33074
  init_cli();
33075
+ init_collect_input();
32989
33076
  init_renderers();
32990
33077
  addCommand = defineCommand({
32991
33078
  meta: {
@@ -32994,6 +33081,28 @@ var init_add = __esm({
32994
33081
  For 2+ tasks at once: cleo add-batch --file tasks.json (single transaction, atomic rollback)`
32995
33082
  },
32996
33083
  args: {
33084
+ /**
33085
+ * Schema-first input — supersedes all flag-based args when present.
33086
+ *
33087
+ * Accepts a JSON object that matches `INPUT_CONTRACTS['tasks.add']`.
33088
+ * When provided, the command short-circuits the flag-mapping path
33089
+ * entirely and goes straight to validate→dispatch.
33090
+ *
33091
+ * @task T9917
33092
+ */
33093
+ params: {
33094
+ type: "string",
33095
+ description: 'Inline JSON object matching INPUT_CONTRACTS["tasks.add"] (T9917). Overrides positional + flags.'
33096
+ },
33097
+ /**
33098
+ * Schema-first input from a JSON file. Same semantics as --params.
33099
+ *
33100
+ * @task T9917
33101
+ */
33102
+ "params-file": {
33103
+ type: "string",
33104
+ description: 'Path to JSON file matching INPUT_CONTRACTS["tasks.add"] (T9917).'
33105
+ },
32997
33106
  title: {
32998
33107
  type: "positional",
32999
33108
  description: "Task title (3\u2013500 characters)",
@@ -33156,6 +33265,72 @@ For 2+ tasks at once: cleo add-batch --file tasks.json (single transaction, atom
33156
33265
  }
33157
33266
  },
33158
33267
  async run({ args, cmd }) {
33268
+ const paramsArg = args.params;
33269
+ const paramsFileArg = args["params-file"];
33270
+ if (paramsArg !== void 0 || paramsFileArg !== void 0) {
33271
+ const collectArgs = {};
33272
+ if (paramsArg !== void 0) collectArgs.params = paramsArg;
33273
+ if (paramsFileArg !== void 0) collectArgs.file = paramsFileArg;
33274
+ let raw;
33275
+ try {
33276
+ raw = await collectMutateInput(
33277
+ collectArgs,
33278
+ process.stdin
33279
+ );
33280
+ } catch (err) {
33281
+ cliError(
33282
+ err.message,
33283
+ 6 /* VALIDATION_ERROR */,
33284
+ {
33285
+ name: "E_VALIDATION_FAILED",
33286
+ fix: "Verify the JSON syntax of your --params / --params-file input"
33287
+ },
33288
+ { operation: "tasks.add" }
33289
+ );
33290
+ process.exit(6 /* VALIDATION_ERROR */);
33291
+ return;
33292
+ }
33293
+ const contract = INPUT_CONTRACTS2["tasks.add"];
33294
+ if (!contract) {
33295
+ cliError(
33296
+ "tasks.add contract missing from INPUT_CONTRACTS registry",
33297
+ 1 /* GENERAL_ERROR */,
33298
+ { name: "E_INTERNAL", fix: "This is a CLI bug \u2014 file an issue" },
33299
+ { operation: "tasks.add" }
33300
+ );
33301
+ process.exit(1 /* GENERAL_ERROR */);
33302
+ return;
33303
+ }
33304
+ const validation = validateOperationInput2(contract, raw);
33305
+ if (!validation.ok) {
33306
+ cliError(
33307
+ "tasks.add failed: validation",
33308
+ 6 /* VALIDATION_ERROR */,
33309
+ {
33310
+ name: "E_VALIDATION_FAILED",
33311
+ fix: validation.errors[0]?.fix ?? "Inspect errors[] and correct the input",
33312
+ details: { errors: validation.errors }
33313
+ },
33314
+ { operation: "tasks.add" }
33315
+ );
33316
+ process.exit(6 /* VALIDATION_ERROR */);
33317
+ return;
33318
+ }
33319
+ const validatedPayload = raw;
33320
+ const response2 = await dispatchRaw("mutate", "tasks", "add", validatedPayload);
33321
+ if (!response2.success) {
33322
+ handleRawError(response2, { command: "add", operation: "tasks.add" });
33323
+ }
33324
+ const data2 = response2.data;
33325
+ const dataWarnings2 = data2?.warnings;
33326
+ if (dataWarnings2?.length) {
33327
+ for (const w of dataWarnings2) {
33328
+ humanWarn(`\u26A0 ${w}`);
33329
+ }
33330
+ }
33331
+ cliOutput(data2, { command: "add", operation: "tasks.add" });
33332
+ return;
33333
+ }
33159
33334
  if (!args.title) {
33160
33335
  await showUsage(cmd);
33161
33336
  return;
@@ -33930,13 +34105,13 @@ var init_agent = __esm({
33930
34105
  transportConfig: {},
33931
34106
  isActive: true
33932
34107
  });
33933
- const { existsSync: existsSync17, mkdirSync: mkdirSync5, writeFileSync: writeFileSync5 } = await import("node:fs");
33934
- const { join: join34 } = await import("node:path");
33935
- const cantDir = join34(CLEO_DIR_NAME, AGENTS_SUBDIR);
33936
- const cantPath = join34(cantDir, `${agentId}.cant`);
34108
+ const { existsSync: existsSync19, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
34109
+ const { join: join37 } = await import("node:path");
34110
+ const cantDir = join37(CLEO_DIR_NAME, AGENTS_SUBDIR);
34111
+ const cantPath = join37(cantDir, `${agentId}.cant`);
33937
34112
  let cantScaffolded = false;
33938
- if (!existsSync17(cantPath)) {
33939
- mkdirSync5(cantDir, { recursive: true });
34113
+ if (!existsSync19(cantPath)) {
34114
+ mkdirSync7(cantDir, { recursive: true });
33940
34115
  const role = classification ?? "specialist";
33941
34116
  const cantContent = `---
33942
34117
  kind: agent
@@ -33986,7 +34161,7 @@ agent ${agentId}:
33986
34161
  enforcement:
33987
34162
  1: TODO \u2014 what does this agent push back on?
33988
34163
  `;
33989
- writeFileSync5(cantPath, cantContent, "utf-8");
34164
+ writeFileSync7(cantPath, cantContent, "utf-8");
33990
34165
  cantScaffolded = true;
33991
34166
  }
33992
34167
  cliOutput(
@@ -33995,7 +34170,7 @@ agent ${agentId}:
33995
34170
  data: {
33996
34171
  agentId: credential.agentId,
33997
34172
  displayName: credential.displayName,
33998
- cantFile: cantScaffolded ? cantPath : existsSync17(cantPath) ? cantPath : null,
34173
+ cantFile: cantScaffolded ? cantPath : existsSync19(cantPath) ? cantPath : null,
33999
34174
  cantScaffolded
34000
34175
  }
34001
34176
  },
@@ -34114,8 +34289,8 @@ agent ${agentId}:
34114
34289
  try {
34115
34290
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
34116
34291
  const { createRuntime } = await import("@cleocode/runtime");
34117
- const { existsSync: existsSync17, readFileSync: readFileSync18 } = await import("node:fs");
34118
- const { join: join34 } = await import("node:path");
34292
+ const { existsSync: existsSync19, readFileSync: readFileSync21 } = await import("node:fs");
34293
+ const { join: join37 } = await import("node:path");
34119
34294
  await openCleoDb("tasks");
34120
34295
  const registry = new AgentRegistryAccessor(getProjectRoot24());
34121
34296
  const credential = await registry.get(args.agentId);
@@ -34135,9 +34310,9 @@ agent ${agentId}:
34135
34310
  }
34136
34311
  let profile = null;
34137
34312
  let cantValidation = null;
34138
- const cantPath = args.cant ?? join34(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34139
- if (existsSync17(cantPath)) {
34140
- profile = readFileSync18(cantPath, "utf-8");
34313
+ const cantPath = args.cant ?? join37(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34314
+ if (existsSync19(cantPath)) {
34315
+ profile = readFileSync21(cantPath, "utf-8");
34141
34316
  try {
34142
34317
  const cantModule = await import("@cleocode/cant");
34143
34318
  const validate = "validate" in cantModule ? cantModule.validate : null;
@@ -34660,8 +34835,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34660
34835
  try {
34661
34836
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
34662
34837
  const { createRuntime } = await import("@cleocode/runtime");
34663
- const { existsSync: existsSync17 } = await import("node:fs");
34664
- const { join: join34 } = await import("node:path");
34838
+ const { existsSync: existsSync19 } = await import("node:fs");
34839
+ const { join: join37 } = await import("node:path");
34665
34840
  await openCleoDb("tasks");
34666
34841
  const registry = new AgentRegistryAccessor(getProjectRoot24());
34667
34842
  const credential = await registry.get(args.agentId);
@@ -34678,8 +34853,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34678
34853
  }
34679
34854
  await registry.update(args.agentId, { isActive: true });
34680
34855
  await registry.markUsed(args.agentId);
34681
- const cantPath = join34(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34682
- const hasProfile = existsSync17(cantPath);
34856
+ const cantPath = join37(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34857
+ const hasProfile = existsSync19(cantPath);
34683
34858
  const runtime = await createRuntime(registry, {
34684
34859
  agentId: args.agentId,
34685
34860
  pollIntervalMs: 5e3,
@@ -35475,10 +35650,10 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35475
35650
  async run({ args }) {
35476
35651
  let tempDir = null;
35477
35652
  try {
35478
- const { existsSync: existsSync17 } = await import("node:fs");
35479
- const { basename, resolve: resolve7 } = await import("node:path");
35480
- const resolvedPath = resolve7(args.path);
35481
- if (!existsSync17(resolvedPath)) {
35653
+ const { existsSync: existsSync19 } = await import("node:fs");
35654
+ const { basename, resolve: resolve8 } = await import("node:path");
35655
+ const resolvedPath = resolve8(args.path);
35656
+ if (!existsSync19(resolvedPath)) {
35482
35657
  cliOutput(
35483
35658
  {
35484
35659
  success: false,
@@ -35603,11 +35778,11 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35603
35778
  },
35604
35779
  async run({ args }) {
35605
35780
  try {
35606
- const { existsSync: existsSync17, statSync } = await import("node:fs");
35607
- const { resolve: resolve7, basename, dirname: dirname10 } = await import("node:path");
35781
+ const { existsSync: existsSync19, statSync } = await import("node:fs");
35782
+ const { resolve: resolve8, basename, dirname: dirname12 } = await import("node:path");
35608
35783
  const { execFileSync: execFileSync4 } = await import("node:child_process");
35609
- const resolvedDir = resolve7(args.dir);
35610
- if (!existsSync17(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
35784
+ const resolvedDir = resolve8(args.dir);
35785
+ if (!existsSync19(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
35611
35786
  cliOutput(
35612
35787
  {
35613
35788
  success: false,
@@ -35621,9 +35796,9 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35621
35796
  process.exitCode = 4;
35622
35797
  return;
35623
35798
  }
35624
- const { join: join34 } = await import("node:path");
35625
- const personaPath = join34(resolvedDir, "persona.cant");
35626
- if (!existsSync17(personaPath)) {
35799
+ const { join: join37 } = await import("node:path");
35800
+ const personaPath = join37(resolvedDir, "persona.cant");
35801
+ if (!existsSync19(personaPath)) {
35627
35802
  cliOutput(
35628
35803
  {
35629
35804
  success: false,
@@ -35639,8 +35814,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35639
35814
  }
35640
35815
  const agentName = basename(resolvedDir);
35641
35816
  const archiveName = `${agentName}.cantz`;
35642
- const archivePath = resolve7(archiveName);
35643
- const parentDir = dirname10(resolvedDir);
35817
+ const archivePath = resolve8(archiveName);
35818
+ const parentDir = dirname12(resolvedDir);
35644
35819
  try {
35645
35820
  execFileSync4("zip", ["-r", archivePath, agentName], {
35646
35821
  cwd: parentDir,
@@ -35670,7 +35845,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35670
35845
  if (entry.isFile()) {
35671
35846
  fileCount++;
35672
35847
  } else if (entry.isDirectory()) {
35673
- countFiles(join34(dirPath, entry.name));
35848
+ countFiles(join37(dirPath, entry.name));
35674
35849
  }
35675
35850
  }
35676
35851
  };
@@ -35918,18 +36093,18 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35918
36093
  },
35919
36094
  async run({ args }) {
35920
36095
  try {
35921
- const { existsSync: existsSync17, readFileSync: readFileSync18, mkdirSync: mkdirSync5 } = await import("node:fs");
35922
- const { resolve: resolve7, join: join34 } = await import("node:path");
35923
- const specPath = resolve7(args.spec);
35924
- if (!existsSync17(specPath)) {
36096
+ const { existsSync: existsSync19, readFileSync: readFileSync21, mkdirSync: mkdirSync7 } = await import("node:fs");
36097
+ const { resolve: resolve8, join: join37 } = await import("node:path");
36098
+ const specPath = resolve8(args.spec);
36099
+ if (!existsSync19(specPath)) {
35925
36100
  cliError(`spec file not found: ${specPath}`, 4, { name: "E_NOT_FOUND" });
35926
36101
  process.exitCode = 4;
35927
36102
  return;
35928
36103
  }
35929
- const specContent = readFileSync18(specPath, "utf-8");
36104
+ const specContent = readFileSync21(specPath, "utf-8");
35930
36105
  const projectRoot = getProjectRoot24();
35931
- const outputDir = args["output-dir"] ? resolve7(args["output-dir"]) : join34(projectRoot, ".cleo", "cant", "agents");
35932
- mkdirSync5(outputDir, { recursive: true });
36106
+ const outputDir = args["output-dir"] ? resolve8(args["output-dir"]) : join37(projectRoot, ".cleo", "cant", "agents");
36107
+ mkdirSync7(outputDir, { recursive: true });
35933
36108
  if (args["dry-run"]) {
35934
36109
  cliOutput(
35935
36110
  {
@@ -36529,7 +36704,7 @@ var init_consent = __esm({
36529
36704
  });
36530
36705
 
36531
36706
  // packages/cleo/src/cli/commands/auth/list.ts
36532
- import { existsSync as existsSync7 } from "node:fs";
36707
+ import { existsSync as existsSync6 } from "node:fs";
36533
36708
  import { homedir as homedir2 } from "node:os";
36534
36709
  import { join as join9 } from "node:path";
36535
36710
  function formatExpiry(expiresAt) {
@@ -36609,7 +36784,7 @@ var init_list2 = __esm({
36609
36784
  return p !== 0 ? p : a2.label.localeCompare(b.label);
36610
36785
  });
36611
36786
  const claudeCredsPath = join9(homedir2(), ".claude", ".credentials.json");
36612
- const hint = existsSync7(claudeCredsPath) && entries.every((e) => e.source !== "claude-code") ? "Hint: Claude Code OAuth detected at ~/.claude/.credentials.json but consent is off. Run `cleo auth consent --enable-claude-code` to seed it into the pool." : null;
36787
+ const hint = existsSync6(claudeCredsPath) && entries.every((e) => e.source !== "claude-code") ? "Hint: Claude Code OAuth detected at ~/.claude/.credentials.json but consent is off. Run `cleo auth consent --enable-claude-code` to seed it into the pool." : null;
36613
36788
  cliOutput(
36614
36789
  { entries, ...hint !== null ? { hint } : {} },
36615
36790
  {
@@ -36623,7 +36798,7 @@ var init_list2 = __esm({
36623
36798
  });
36624
36799
 
36625
36800
  // packages/cleo/src/cli/commands/auth/migrate-project-secrets.ts
36626
- import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "node:fs";
36801
+ import { existsSync as existsSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "node:fs";
36627
36802
  import { join as join10 } from "node:path";
36628
36803
  import { createInterface } from "node:readline";
36629
36804
  function resolveProjectRootArg(arg) {
@@ -36679,8 +36854,8 @@ function detectAuthType(provider, token) {
36679
36854
  async function promptYesNo(question) {
36680
36855
  const rl = createInterface({ input: process.stdin, output: process.stderr });
36681
36856
  try {
36682
- const answer = await new Promise((resolve7) => {
36683
- rl.question(question, (a) => resolve7(a));
36857
+ const answer = await new Promise((resolve8) => {
36858
+ rl.question(question, (a) => resolve8(a));
36684
36859
  });
36685
36860
  const clean = answer.trim().toLowerCase();
36686
36861
  return clean === "y" || clean === "yes";
@@ -36690,7 +36865,7 @@ async function promptYesNo(question) {
36690
36865
  }
36691
36866
  async function runMigrateProjectSecrets(opts) {
36692
36867
  const configPath = projectConfigPath(opts.projectRoot);
36693
- if (!existsSync8(configPath)) {
36868
+ if (!existsSync7(configPath)) {
36694
36869
  return {
36695
36870
  configPath,
36696
36871
  backupPath: null,
@@ -36699,7 +36874,7 @@ async function runMigrateProjectSecrets(opts) {
36699
36874
  dryRun: opts.dryRun
36700
36875
  };
36701
36876
  }
36702
- const raw = readFileSync9(configPath, "utf-8");
36877
+ const raw = readFileSync8(configPath, "utf-8");
36703
36878
  let parsed;
36704
36879
  try {
36705
36880
  parsed = JSON.parse(raw);
@@ -37616,12 +37791,12 @@ async function promptPassphrase() {
37616
37791
  "Cannot prompt for passphrase: stdin is not a TTY. Set the CLEO_BACKUP_PASSPHRASE environment variable for non-interactive use."
37617
37792
  );
37618
37793
  }
37619
- return new Promise((resolve7) => {
37794
+ return new Promise((resolve8) => {
37620
37795
  process.stdout.write("Passphrase: ");
37621
37796
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
37622
37797
  rl.question("", (answer) => {
37623
37798
  rl.close();
37624
- resolve7(answer.trim());
37799
+ resolve8(answer.trim());
37625
37800
  });
37626
37801
  });
37627
37802
  }
@@ -37757,9 +37932,9 @@ var init_backup = __esm({
37757
37932
  async run({ args }) {
37758
37933
  const scope = args.scope;
37759
37934
  const { packBundle } = await import("@cleocode/core/store/backup-pack.js");
37760
- const { getProjectRoot: getProjectRoot53 } = await import("@cleocode/core");
37935
+ const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core");
37761
37936
  const includesProject = scope === "project" || scope === "all";
37762
- const projectRoot = includesProject ? getProjectRoot53() : void 0;
37937
+ const projectRoot = includesProject ? getProjectRoot54() : void 0;
37763
37938
  let passphrase;
37764
37939
  if (args.encrypt === true) {
37765
37940
  passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
@@ -37835,12 +38010,12 @@ var init_backup = __esm({
37835
38010
  },
37836
38011
  async run({ args }) {
37837
38012
  const bundlePath = args.bundle;
37838
- const { getProjectRoot: getProjectRoot53, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
38013
+ const { getProjectRoot: getProjectRoot54, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
37839
38014
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
37840
38015
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
37841
38016
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
37842
38017
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
37843
- const projectRoot = getProjectRoot53();
38018
+ const projectRoot = getProjectRoot54();
37844
38019
  if (args.force !== true) {
37845
38020
  const existing = checkForExistingData(projectRoot, getCleoHome6());
37846
38021
  if (existing.length > 0) {
@@ -38442,7 +38617,7 @@ var briefing_exports = {};
38442
38617
  __export(briefing_exports, {
38443
38618
  briefingCommand: () => briefingCommand
38444
38619
  });
38445
- import { existsSync as existsSync9, readFileSync as readFileSync10 } from "node:fs";
38620
+ import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
38446
38621
  import { join as join11 } from "node:path";
38447
38622
  import { pushWarning as pushWarning2 } from "@cleocode/core";
38448
38623
  import { resolveLegacyCleoDir } from "@cleocode/paths";
@@ -38475,7 +38650,7 @@ function renderForAdapter(sectionName, content, format) {
38475
38650
  }
38476
38651
  async function runBriefingInject(sectionName, formatStr) {
38477
38652
  const templatePath = resolveInjectionTemplatePath();
38478
- if (!existsSync9(templatePath)) {
38653
+ if (!existsSync8(templatePath)) {
38479
38654
  pushWarning2({
38480
38655
  code: "W_TEMPLATE_INJECT_FAILED",
38481
38656
  message: `CLEO-INJECTION.md not found at ${templatePath}`
@@ -38492,7 +38667,7 @@ async function runBriefingInject(sectionName, formatStr) {
38492
38667
  process.exitCode = 1;
38493
38668
  return;
38494
38669
  }
38495
- const content = readFileSync10(templatePath, "utf-8");
38670
+ const content = readFileSync9(templatePath, "utf-8");
38496
38671
  const section = extractSection(content, sectionName);
38497
38672
  if (section === null) {
38498
38673
  const available = INJECTION_SECTION_NAMES.join(", ");
@@ -38731,15 +38906,15 @@ var init_caamp = __esm({
38731
38906
  }
38732
38907
  if (args["dry-run"]) {
38733
38908
  const { parseCaampBlocks } = await import("@cleocode/caamp");
38734
- const { existsSync: existsSync17 } = await import("node:fs");
38735
- const { readFile: readFile7 } = await import("node:fs/promises");
38909
+ const { existsSync: existsSync19 } = await import("node:fs");
38910
+ const { readFile: readFile8 } = await import("node:fs/promises");
38736
38911
  const dryResults = [];
38737
38912
  for (const filePath of filePaths) {
38738
- if (!existsSync17(filePath)) {
38913
+ if (!existsSync19(filePath)) {
38739
38914
  dryResults.push({ filePath, exists: false, blockCount: 0, wouldRemove: 0 });
38740
38915
  continue;
38741
38916
  }
38742
- const content = await readFile7(filePath, "utf-8");
38917
+ const content = await readFile8(filePath, "utf-8");
38743
38918
  const blocks = parseCaampBlocks(content);
38744
38919
  const uniqueContents = new Set(blocks.map((b) => b.content));
38745
38920
  const wouldRemove = blocks.length - uniqueContents.size;
@@ -38833,13 +39008,13 @@ var cant_exports = {};
38833
39008
  __export(cant_exports, {
38834
39009
  cantCommand: () => cantCommand
38835
39010
  });
38836
- import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
39011
+ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "node:fs";
38837
39012
  import { dirname as dirname4, isAbsolute, join as join13, resolve as resolve3 } from "node:path";
38838
39013
  function resolveFilePath(file) {
38839
39014
  return isAbsolute(file) ? file : resolve3(process.cwd(), file);
38840
39015
  }
38841
39016
  function ensureExists(filePath, operation) {
38842
- if (existsSync10(filePath)) return true;
39017
+ if (existsSync9(filePath)) return true;
38843
39018
  cliError(`File not found: ${filePath}`, "E_FILE_READ");
38844
39019
  process.exitCode = 3;
38845
39020
  if (process.env["CLEO_DEBUG"]) humanWarn(`(operation: ${operation})`);
@@ -38989,7 +39164,7 @@ var init_cant = __esm({
38989
39164
  if (!ensureExists(filePath, "cant.migrate")) return;
38990
39165
  try {
38991
39166
  const mod = await loadMigrateEngine();
38992
- const content = readFileSync11(filePath, "utf-8");
39167
+ const content = readFileSync10(filePath, "utf-8");
38993
39168
  const result = mod.migrateMarkdown(content, filePath, {
38994
39169
  write: isWrite,
38995
39170
  verbose: isVerbose,
@@ -39055,7 +39230,7 @@ var chain_exports = {};
39055
39230
  __export(chain_exports, {
39056
39231
  chainCommand: () => chainCommand
39057
39232
  });
39058
- import { readFileSync as readFileSync12 } from "node:fs";
39233
+ import { readFileSync as readFileSync11 } from "node:fs";
39059
39234
  var showCommand3, listCommand5, addCommand3, instantiateCommand, advanceCommand, chainCommand;
39060
39235
  var init_chain = __esm({
39061
39236
  "packages/cleo/src/cli/commands/chain.ts"() {
@@ -39097,7 +39272,7 @@ var init_chain = __esm({
39097
39272
  }
39098
39273
  },
39099
39274
  async run({ args }) {
39100
- const chainJson = JSON.parse(readFileSync12(args.file, "utf-8"));
39275
+ const chainJson = JSON.parse(readFileSync11(args.file, "utf-8"));
39101
39276
  await dispatchFromCli(
39102
39277
  "mutate",
39103
39278
  "pipeline",
@@ -39178,7 +39353,7 @@ var changeset_exports = {};
39178
39353
  __export(changeset_exports, {
39179
39354
  changesetCommand: () => changesetCommand
39180
39355
  });
39181
- import { existsSync as existsSync11 } from "node:fs";
39356
+ import { existsSync as existsSync10 } from "node:fs";
39182
39357
  import { join as join14 } from "node:path";
39183
39358
  import {
39184
39359
  changesets,
@@ -39327,7 +39502,7 @@ var init_changeset = __esm({
39327
39502
  async run() {
39328
39503
  const projectRoot = getProjectRoot30();
39329
39504
  const dir = join14(projectRoot, ".changeset");
39330
- if (!existsSync11(dir)) {
39505
+ if (!existsSync10(dir)) {
39331
39506
  const empty = { entries: [], count: 0, dir, note: "no .changeset/ dir" };
39332
39507
  if (isHumanOutput()) {
39333
39508
  humanLine("No changeset entries found (.changeset/ directory absent).");
@@ -39497,10 +39672,10 @@ var init_check2 = __esm({
39497
39672
  }
39498
39673
  },
39499
39674
  async run({ args }) {
39500
- const { readFileSync: readFileSync18 } = await import("node:fs");
39675
+ const { readFileSync: readFileSync21 } = await import("node:fs");
39501
39676
  let chain;
39502
39677
  try {
39503
- chain = JSON.parse(readFileSync18(args.file, "utf8"));
39678
+ chain = JSON.parse(readFileSync21(args.file, "utf8"));
39504
39679
  } catch (err) {
39505
39680
  const message = err instanceof Error ? err.message : String(err);
39506
39681
  cliError(`Failed to read or parse chain file: ${message}`, 2, {
@@ -39790,11 +39965,11 @@ var init_check2 = __esm({
39790
39965
  },
39791
39966
  async run({ args }) {
39792
39967
  const { spawnSync } = await import("node:child_process");
39793
- const { existsSync: existsSync17 } = await import("node:fs");
39794
- const { join: join34, resolve: resolve7 } = await import("node:path");
39968
+ const { existsSync: existsSync19 } = await import("node:fs");
39969
+ const { join: join37, resolve: resolve8 } = await import("node:path");
39795
39970
  const strict = Boolean(args.strict);
39796
39971
  const jsonOnly = Boolean(args.json);
39797
- const repoRoot = resolve7(process.cwd());
39972
+ const repoRoot = resolve8(process.cwd());
39798
39973
  const gates = [
39799
39974
  {
39800
39975
  id: "gate-1",
@@ -39831,8 +40006,8 @@ var init_check2 = __esm({
39831
40006
  const results = [];
39832
40007
  let anyFailed = false;
39833
40008
  for (const gate of gates) {
39834
- const scriptPath = join34(repoRoot, gate.script);
39835
- if (!existsSync17(scriptPath)) {
40009
+ const scriptPath = join37(repoRoot, gate.script);
40010
+ if (!existsSync19(scriptPath)) {
39836
40011
  results.push({
39837
40012
  id: gate.id,
39838
40013
  task: gate.task,
@@ -40147,9 +40322,9 @@ var init_code = __esm({
40147
40322
  async run({ args }) {
40148
40323
  await requireTreeSitter();
40149
40324
  const { smartOutline } = await import("@cleocode/core/internal");
40150
- const { join: join34 } = await import("node:path");
40325
+ const { join: join37 } = await import("node:path");
40151
40326
  const root = process.cwd();
40152
- const absPath = args.file.startsWith("/") ? args.file : join34(root, args.file);
40327
+ const absPath = args.file.startsWith("/") ? args.file : join37(root, args.file);
40153
40328
  const result = smartOutline(absPath, root);
40154
40329
  if (result.errors.length > 0 && result.symbols.length === 0) {
40155
40330
  cliError(result.errors.join(", "), 1, { name: "E_OUTLINE_FAILED" });
@@ -40240,9 +40415,9 @@ var init_code = __esm({
40240
40415
  async run({ args }) {
40241
40416
  await requireTreeSitter();
40242
40417
  const { smartUnfold } = await import("@cleocode/core/internal");
40243
- const { join: join34 } = await import("node:path");
40418
+ const { join: join37 } = await import("node:path");
40244
40419
  const root = process.cwd();
40245
- const absPath = args.file.startsWith("/") ? args.file : join34(root, args.file);
40420
+ const absPath = args.file.startsWith("/") ? args.file : join37(root, args.file);
40246
40421
  const result = smartUnfold(absPath, args.symbol, root);
40247
40422
  if (!result.found) {
40248
40423
  const errs = result.errors.length > 0 ? `: ${result.errors.join(", ")}` : "";
@@ -41924,7 +42099,7 @@ var daemon_exports = {};
41924
42099
  __export(daemon_exports, {
41925
42100
  daemonCommand: () => daemonCommand
41926
42101
  });
41927
- import { existsSync as existsSync12 } from "node:fs";
42102
+ import { existsSync as existsSync11 } from "node:fs";
41928
42103
  import { join as join16 } from "node:path";
41929
42104
  import { fileURLToPath as fileURLToPath3 } from "node:url";
41930
42105
  import { getGCDaemonStatus, spawnGCDaemon, stopGCDaemon } from "@cleocode/core/gc/daemon.js";
@@ -41992,7 +42167,7 @@ async function showDaemonStatus(cleoDir, projectRoot) {
41992
42167
  function resolveDaemonInstallerScript() {
41993
42168
  const filePath = fileURLToPath3(import.meta.url);
41994
42169
  const candidate1 = join16(filePath, "..", "..", "..", "scripts", "install-daemon-service.mjs");
41995
- if (existsSync12(candidate1)) return candidate1;
42170
+ if (existsSync11(candidate1)) return candidate1;
41996
42171
  const candidate2 = join16(
41997
42172
  filePath,
41998
42173
  "..",
@@ -42913,12 +43088,12 @@ var detect_drift_exports = {};
42913
43088
  __export(detect_drift_exports, {
42914
43089
  detectDriftCommand: () => detectDriftCommand
42915
43090
  });
42916
- import { existsSync as existsSync13, readdirSync, readFileSync as readFileSync13 } from "node:fs";
43091
+ import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync12 } from "node:fs";
42917
43092
  import { dirname as dirname5, join as join17 } from "node:path";
42918
43093
  function findProjectRoot() {
42919
43094
  let currentDir = process.cwd();
42920
43095
  while (currentDir !== "/") {
42921
- if (existsSync13(join17(currentDir, "package.json"))) {
43096
+ if (existsSync12(join17(currentDir, "package.json"))) {
42922
43097
  return currentDir;
42923
43098
  }
42924
43099
  const parent = dirname5(currentDir);
@@ -42942,11 +43117,11 @@ var init_detect_drift = __esm({
42942
43117
  },
42943
43118
  async run() {
42944
43119
  const projectRoot = findProjectRoot();
42945
- const isCleoRepo = existsSync13(join17(projectRoot, "packages", "cleo", "src"));
43120
+ const isCleoRepo = existsSync12(join17(projectRoot, "packages", "cleo", "src"));
42946
43121
  const cleoSrcRoot = isCleoRepo ? join17(projectRoot, "packages", "cleo", "src") : join17(projectRoot, "src");
42947
43122
  const safeRead = (filePath) => {
42948
43123
  try {
42949
- return readFileSync13(filePath, "utf-8");
43124
+ return readFileSync12(filePath, "utf-8");
42950
43125
  } catch {
42951
43126
  return "";
42952
43127
  }
@@ -42958,7 +43133,7 @@ var init_detect_drift = __esm({
42958
43133
  recommendations: []
42959
43134
  };
42960
43135
  const injPath = join17(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
42961
- if (existsSync13(injPath)) {
43136
+ if (existsSync12(injPath)) {
42962
43137
  const content = safeRead(injPath);
42963
43138
  userResult.checks.push({
42964
43139
  name: "Agent injection",
@@ -43012,7 +43187,7 @@ var init_detect_drift = __esm({
43012
43187
  const specPath = join17(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
43013
43188
  const registryPath = join17(cleoSrcRoot, "dispatch", "registry.ts");
43014
43189
  const dispatchDomainsDir = join17(cleoSrcRoot, "dispatch", "domains");
43015
- if (!existsSync13(specPath)) {
43190
+ if (!existsSync12(specPath)) {
43016
43191
  addCheck("Gateway-to-spec sync", "fail", "CLEO-OPERATION-CONSTITUTION.md missing", [
43017
43192
  {
43018
43193
  severity: "error",
@@ -43022,7 +43197,7 @@ var init_detect_drift = __esm({
43022
43197
  recommendation: "Create docs/specs/CLEO-OPERATION-CONSTITUTION.md with canonical operation definitions"
43023
43198
  }
43024
43199
  ]);
43025
- } else if (!existsSync13(registryPath) || !existsSync13(dispatchDomainsDir)) {
43200
+ } else if (!existsSync12(registryPath) || !existsSync12(dispatchDomainsDir)) {
43026
43201
  addCheck("Gateway-to-spec sync", "fail", "Dispatch registry or domains missing", [
43027
43202
  {
43028
43203
  severity: "error",
@@ -43082,7 +43257,7 @@ var init_detect_drift = __esm({
43082
43257
  try {
43083
43258
  const cliDir = join17(cleoSrcRoot, "cli", "commands");
43084
43259
  const coreDir = isCleoRepo ? join17(projectRoot, "packages", "core", "src") : join17(projectRoot, "src", "core");
43085
- if (!existsSync13(cliDir)) {
43260
+ if (!existsSync12(cliDir)) {
43086
43261
  addCheck("CLI-to-core sync", "fail", "CLI commands directory missing", [
43087
43262
  {
43088
43263
  severity: "error",
@@ -43091,7 +43266,7 @@ var init_detect_drift = __esm({
43091
43266
  recommendation: "Verify TypeScript source structure is intact"
43092
43267
  }
43093
43268
  ]);
43094
- } else if (!existsSync13(coreDir)) {
43269
+ } else if (!existsSync12(coreDir)) {
43095
43270
  addCheck("CLI-to-core sync", "fail", "Core directory missing", [
43096
43271
  {
43097
43272
  severity: "error",
@@ -43109,7 +43284,7 @@ var init_detect_drift = __esm({
43109
43284
  }
43110
43285
  try {
43111
43286
  const domainsDir = join17(cleoSrcRoot, "dispatch", "domains");
43112
- if (!existsSync13(domainsDir)) {
43287
+ if (!existsSync12(domainsDir)) {
43113
43288
  addCheck("Domain handler coverage", "fail", "Dispatch domains directory missing", [
43114
43289
  {
43115
43290
  severity: "error",
@@ -43127,7 +43302,7 @@ var init_detect_drift = __esm({
43127
43302
  }
43128
43303
  try {
43129
43304
  const matrixPath = join17(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
43130
- if (!existsSync13(matrixPath)) {
43305
+ if (!existsSync12(matrixPath)) {
43131
43306
  addCheck("Capability matrix", "fail", "Capability matrix missing", [
43132
43307
  {
43133
43308
  severity: "error",
@@ -43144,7 +43319,7 @@ var init_detect_drift = __esm({
43144
43319
  }
43145
43320
  try {
43146
43321
  const schemaPath = join17(projectRoot, "src", "store", "schema.ts");
43147
- if (!existsSync13(schemaPath)) {
43322
+ if (!existsSync12(schemaPath)) {
43148
43323
  addCheck("Schema validation", "fail", "Schema definition missing", [
43149
43324
  {
43150
43325
  severity: "error",
@@ -43181,7 +43356,7 @@ var init_detect_drift = __esm({
43181
43356
  const visionPath = join17(projectRoot, "docs", "concepts", "CLEO-VISION.md");
43182
43357
  const specPath = join17(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
43183
43358
  const issues = [];
43184
- if (!existsSync13(visionPath)) {
43359
+ if (!existsSync12(visionPath)) {
43185
43360
  issues.push({
43186
43361
  severity: "error",
43187
43362
  category: "vision",
@@ -43190,7 +43365,7 @@ var init_detect_drift = __esm({
43190
43365
  recommendation: "Create docs/concepts/CLEO-VISION.md with project vision"
43191
43366
  });
43192
43367
  }
43193
- if (!existsSync13(specPath)) {
43368
+ if (!existsSync12(specPath)) {
43194
43369
  issues.push({
43195
43370
  severity: "error",
43196
43371
  category: "spec",
@@ -43235,7 +43410,7 @@ var init_detect_drift = __esm({
43235
43410
  }
43236
43411
  try {
43237
43412
  const injectionPath = join17(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
43238
- if (!existsSync13(injectionPath)) {
43413
+ if (!existsSync12(injectionPath)) {
43239
43414
  addCheck("Agent injection", "fail", "Agent injection template missing", [
43240
43415
  {
43241
43416
  severity: "error",
@@ -43265,7 +43440,7 @@ var init_detect_drift = __esm({
43265
43440
  }
43266
43441
  try {
43267
43442
  const exitCodesPath = join17(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
43268
- if (!existsSync13(exitCodesPath)) {
43443
+ if (!existsSync12(exitCodesPath)) {
43269
43444
  addCheck("Exit codes", "fail", "Exit codes definition missing", [
43270
43445
  {
43271
43446
  severity: "error",
@@ -43612,7 +43787,7 @@ var init_strict_args = __esm({
43612
43787
  });
43613
43788
 
43614
43789
  // packages/cleo/src/viewer/pidfile.ts
43615
- import { mkdir, readFile as readFile2, unlink, writeFile } from "node:fs/promises";
43790
+ import { mkdir, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
43616
43791
  import { dirname as dirname6, join as join18 } from "node:path";
43617
43792
  import { getCleoHome as getCleoHome2 } from "@cleocode/core/internal";
43618
43793
  function viewerPidFilePath() {
@@ -43626,7 +43801,7 @@ async function writeViewerPidFile(record) {
43626
43801
  }
43627
43802
  async function readViewerPidFile() {
43628
43803
  try {
43629
- const raw = await readFile2(viewerPidFilePath(), "utf8");
43804
+ const raw = await readFile3(viewerPidFilePath(), "utf8");
43630
43805
  const parsed = JSON.parse(raw);
43631
43806
  if (typeof parsed.pid === "number" && typeof parsed.port === "number" && typeof parsed.host === "string" && typeof parsed.projectRoot === "string" && typeof parsed.startedAt === "number") {
43632
43807
  return parsed;
@@ -44436,7 +44611,7 @@ var docs_exports = {};
44436
44611
  __export(docs_exports, {
44437
44612
  docsCommand: () => docsCommand
44438
44613
  });
44439
- import { appendFile, mkdir as mkdir2, readdir, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
44614
+ import { appendFile, mkdir as mkdir2, readdir, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
44440
44615
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
44441
44616
  import {
44442
44617
  buildDocsGraph,
@@ -44510,7 +44685,7 @@ async function runGapCheck(_projectRoot, filterId) {
44510
44685
  for (const file of reviewFiles) {
44511
44686
  if (filterId && !file.includes(filterId)) continue;
44512
44687
  const filePath = join21(reviewDir, file);
44513
- const content = await readFile3(filePath, "utf-8");
44688
+ const content = await readFile4(filePath, "utf-8");
44514
44689
  const taskMatch = file.match(/^(T\d+)/);
44515
44690
  const taskId = taskMatch ? taskMatch[1] : "UNKNOWN";
44516
44691
  const gaps = [];
@@ -44567,7 +44742,7 @@ var init_docs3 = __esm({
44567
44742
  addCommand5 = defineCommand({
44568
44743
  meta: {
44569
44744
  name: "add",
44570
- description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --type <kind> Taxonomy classification \u2014 run `cleo docs list-types` for kinds\n\nUnknown flags are rejected with E_UNKNOWN_FLAG + did-you-mean suggestions (T10359).'
44745
+ description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --type <kind> Taxonomy classification \u2014 run `cleo docs list-types` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 TODO(T10360): --type adr will auto-allocate adr-NNN-<title> from a --title flag.'
44571
44746
  },
44572
44747
  args: {
44573
44748
  "owner-id": {
@@ -46259,7 +46434,7 @@ __export(migrate_agents_v2_exports, {
46259
46434
  walkAgentsDir: () => walkAgentsDir
46260
46435
  });
46261
46436
  import { createHash as createHash2 } from "node:crypto";
46262
- import { appendFileSync as appendFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync14 } from "node:fs";
46437
+ import { appendFileSync as appendFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync13 } from "node:fs";
46263
46438
  import { join as join22 } from "node:path";
46264
46439
  import { getProjectRoot as getProjectRoot41, installAgentFromCant } from "@cleocode/core/internal";
46265
46440
  import { openCleoDb as openCleoDb2 } from "@cleocode/core/store/open-cleo-db";
@@ -46282,13 +46457,13 @@ function extractAgentName(source) {
46282
46457
  function appendAuditLog(projectRoot, entry) {
46283
46458
  const auditPath = join22(projectRoot, AUDIT_LOG_RELATIVE);
46284
46459
  const auditDir = join22(auditPath, "..");
46285
- if (!existsSync14(auditDir)) {
46460
+ if (!existsSync13(auditDir)) {
46286
46461
  mkdirSync3(auditDir, { recursive: true });
46287
46462
  }
46288
46463
  appendFileSync2(auditPath, JSON.stringify(entry) + "\n", "utf8");
46289
46464
  }
46290
46465
  function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
46291
- if (!existsSync14(scanDir)) return;
46466
+ if (!existsSync13(scanDir)) return;
46292
46467
  let files;
46293
46468
  try {
46294
46469
  files = readdirSync2(scanDir).filter((f) => f.endsWith(".cant"));
@@ -46304,7 +46479,7 @@ function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
46304
46479
  let sourceBytes;
46305
46480
  let sourceText;
46306
46481
  try {
46307
- sourceBytes = readFileSync14(cantPath);
46482
+ sourceBytes = readFileSync13(cantPath);
46308
46483
  sourceText = sourceBytes.toString("utf8");
46309
46484
  } catch (err) {
46310
46485
  const msg = err instanceof Error ? err.message : String(err);
@@ -46407,10 +46582,10 @@ async function runMigrateAgentsV2(projectRoot, verbose = true) {
46407
46582
  }
46408
46583
  function readMigrationConflicts(projectRoot) {
46409
46584
  const auditPath = join22(projectRoot, AUDIT_LOG_RELATIVE);
46410
- if (!existsSync14(auditPath)) return [];
46585
+ if (!existsSync13(auditPath)) return [];
46411
46586
  let raw;
46412
46587
  try {
46413
- raw = readFileSync14(auditPath, "utf8");
46588
+ raw = readFileSync13(auditPath, "utf8");
46414
46589
  } catch {
46415
46590
  return [];
46416
46591
  }
@@ -47439,8 +47614,8 @@ var init_event = __esm({
47439
47614
  }
47440
47615
  for (const file of filesToTail) {
47441
47616
  const agentId = file.replace(".jsonl", "");
47442
- const { readFileSync: readFileSync18 } = await import("node:fs");
47443
- const content = readFileSync18(join24(eventsDir, file), "utf-8");
47617
+ const { readFileSync: readFileSync21 } = await import("node:fs");
47618
+ const content = readFileSync21(join24(eventsDir, file), "utf-8");
47444
47619
  const eventLines = content.trim().split("\n").filter(Boolean);
47445
47620
  const tail = eventLines.slice(-lines);
47446
47621
  if (jsonMode) {
@@ -47535,8 +47710,8 @@ var init_event = __esm({
47535
47710
  const printAgentLog = async (file) => {
47536
47711
  const agentId = file.replace(".jsonl", "");
47537
47712
  try {
47538
- const { readFileSync: readFileSync18 } = await import("node:fs");
47539
- const content = readFileSync18(join24(eventsDir, file), "utf-8");
47713
+ const { readFileSync: readFileSync21 } = await import("node:fs");
47714
+ const content = readFileSync21(join24(eventsDir, file), "utf-8");
47540
47715
  const eventLines = content.trim().split("\n").filter(Boolean);
47541
47716
  const tail = eventLines.slice(-lines);
47542
47717
  if (jsonMode) {
@@ -49424,7 +49599,7 @@ __export(init_exports, {
49424
49599
  getWorkflowTemplatesDir: () => getWorkflowTemplatesDir2,
49425
49600
  initCommand: () => initCommand2
49426
49601
  });
49427
- import { existsSync as existsSync15, readFileSync as readFileSync15 } from "node:fs";
49602
+ import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
49428
49603
  import { join as join26 } from "node:path";
49429
49604
  import { fileURLToPath as fileURLToPath6 } from "node:url";
49430
49605
  import {
@@ -49440,9 +49615,9 @@ function getGitignoreTemplate() {
49440
49615
  const packageRoot = join26(thisFile, "..", "..", "..", "..");
49441
49616
  const localTemplatePath = join26(packageRoot, "templates", "cleo-gitignore");
49442
49617
  const monorepoTemplatePath = join26(packageRoot, "..", "..", "templates", "cleo-gitignore");
49443
- const templatePath = existsSync15(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
49444
- if (existsSync15(templatePath)) {
49445
- return readFileSync15(templatePath, "utf-8");
49618
+ const templatePath = existsSync14(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
49619
+ if (existsSync14(templatePath)) {
49620
+ return readFileSync14(templatePath, "utf-8");
49446
49621
  }
49447
49622
  } catch {
49448
49623
  }
@@ -50808,7 +50983,7 @@ async function _headlessPkceFlow(provider, authUrl) {
50808
50983
  ` After approving, paste the full redirect URL (http://localhost?code=\u2026&state=\u2026):
50809
50984
  `
50810
50985
  );
50811
- return new Promise((resolve7, reject) => {
50986
+ return new Promise((resolve8, reject) => {
50812
50987
  let buf = "";
50813
50988
  process.stdin.setEncoding("utf8");
50814
50989
  process.stdin.once("data", (chunk) => {
@@ -50820,7 +50995,7 @@ async function _headlessPkceFlow(provider, authUrl) {
50820
50995
  reject(new Error('Redirect URL is missing the "code" parameter'));
50821
50996
  return;
50822
50997
  }
50823
- resolve7(code);
50998
+ resolve8(code);
50824
50999
  } catch {
50825
51000
  reject(new Error(`Invalid redirect URL: ${buf}`));
50826
51001
  }
@@ -50828,7 +51003,7 @@ async function _headlessPkceFlow(provider, authUrl) {
50828
51003
  });
50829
51004
  }
50830
51005
  async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
50831
- return new Promise((resolve7) => {
51006
+ return new Promise((resolve8) => {
50832
51007
  const server = createServer2((req, res) => {
50833
51008
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
50834
51009
  const code = url.searchParams.get("code");
@@ -50838,7 +51013,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
50838
51013
  if (error) {
50839
51014
  res.end(`<h1>Authorization failed</h1><p>${error}</p><p>You may close this tab.</p>`);
50840
51015
  server.close();
50841
- resolve7({
51016
+ resolve8({
50842
51017
  error: {
50843
51018
  code: "E_PKCE_AUTH_DENIED",
50844
51019
  codeName: "E_PKCE_AUTH_DENIED",
@@ -50850,7 +51025,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
50850
51025
  if (!code || state !== expectedState) {
50851
51026
  res.end("<h1>Invalid callback</h1><p>You may close this tab.</p>");
50852
51027
  server.close();
50853
- resolve7({
51028
+ resolve8({
50854
51029
  error: {
50855
51030
  code: "E_PKCE_INVALID_CALLBACK",
50856
51031
  codeName: "E_PKCE_INVALID_CALLBACK",
@@ -50861,7 +51036,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
50861
51036
  }
50862
51037
  res.end("<h1>Authorized</h1><p>You may close this tab and return to your terminal.</p>");
50863
51038
  server.close();
50864
- resolve7({ code });
51039
+ resolve8({ code });
50865
51040
  });
50866
51041
  server.listen(port, "localhost", () => {
50867
51042
  process.stderr.write("\n");
@@ -50994,7 +51169,7 @@ function _generateState() {
50994
51169
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
50995
51170
  }
50996
51171
  function _findFreePort() {
50997
- return new Promise((resolve7, reject) => {
51172
+ return new Promise((resolve8, reject) => {
50998
51173
  const srv = createServer2();
50999
51174
  srv.listen(0, "localhost", () => {
51000
51175
  const addr = srv.address();
@@ -51004,7 +51179,7 @@ function _findFreePort() {
51004
51179
  return;
51005
51180
  }
51006
51181
  const port = addr.port;
51007
- srv.close(() => resolve7(port));
51182
+ srv.close(() => resolve8(port));
51008
51183
  });
51009
51184
  srv.on("error", reject);
51010
51185
  });
@@ -51626,14 +51801,14 @@ async function readStdin() {
51626
51801
  if (process.stdin.isTTY) {
51627
51802
  return "";
51628
51803
  }
51629
- return new Promise((resolve7, reject) => {
51804
+ return new Promise((resolve8, reject) => {
51630
51805
  let data = "";
51631
51806
  process.stdin.setEncoding("utf-8");
51632
51807
  process.stdin.on("data", (chunk) => {
51633
51808
  data += chunk;
51634
51809
  });
51635
51810
  process.stdin.on("end", () => {
51636
- resolve7(data.trim());
51811
+ resolve8(data.trim());
51637
51812
  });
51638
51813
  process.stdin.on("error", reject);
51639
51814
  });
@@ -55202,13 +55377,13 @@ var init_nexus3 = __esm({
55202
55377
  if (!skipPrompt) {
55203
55378
  const { createInterface: createInterface4 } = await import("node:readline");
55204
55379
  const rl = createInterface4({ input: process.stdin, output: process.stdout });
55205
- const confirmed = await new Promise((resolve7) => {
55380
+ const confirmed = await new Promise((resolve8) => {
55206
55381
  rl.question(
55207
55382
  `
55208
55383
  [nexus] Delete ${matchCount} project(s) from the registry? [y/N] `,
55209
55384
  (answer) => {
55210
55385
  rl.close();
55211
- resolve7(answer.trim().toLowerCase() === "y");
55386
+ resolve8(answer.trim().toLowerCase() === "y");
55212
55387
  }
55213
55388
  );
55214
55389
  });
@@ -55358,8 +55533,8 @@ var init_nexus3 = __esm({
55358
55533
  projectFilter
55359
55534
  });
55360
55535
  if (outputFile) {
55361
- const { writeFileSync: writeFileSync5 } = await import("node:fs");
55362
- writeFileSync5(outputFile, result.content, "utf-8");
55536
+ const { writeFileSync: writeFileSync7 } = await import("node:fs");
55537
+ writeFileSync7(outputFile, result.content, "utf-8");
55363
55538
  const durationMs = Date.now() - startTime;
55364
55539
  cliOutput(
55365
55540
  { outputFile, nodeCount: result.nodeCount, edgeCount: result.edgeCount },
@@ -60386,7 +60561,7 @@ var revert_exports = {};
60386
60561
  __export(revert_exports, {
60387
60562
  revertCommand: () => revertCommand
60388
60563
  });
60389
- import { readFile as readFile4 } from "node:fs/promises";
60564
+ import { readFile as readFile5 } from "node:fs/promises";
60390
60565
  import { join as join27 } from "node:path";
60391
60566
  import { cwd as processCwd2 } from "node:process";
60392
60567
  import { E_RECEIPT_NOT_FOUND } from "@cleocode/core/sentient/chain-walker.js";
@@ -60412,7 +60587,7 @@ async function loadOwnerAttestation(attestationFilePath) {
60412
60587
  let raw;
60413
60588
  if (attestationFilePath) {
60414
60589
  try {
60415
- raw = await readFile4(attestationFilePath, "utf-8");
60590
+ raw = await readFile5(attestationFilePath, "utf-8");
60416
60591
  } catch (err) {
60417
60592
  const message = err instanceof Error ? err.message : String(err);
60418
60593
  throw new Error(`Failed to read attestation file "${attestationFilePath}": ${message}`);
@@ -60442,7 +60617,7 @@ async function loadOwnerAttestation(attestationFilePath) {
60442
60617
  async function loadOwnerPubkeys(projectRoot) {
60443
60618
  const path6 = join27(projectRoot, OWNER_PUBKEYS_FILE);
60444
60619
  try {
60445
- const raw = await readFile4(path6, "utf-8");
60620
+ const raw = await readFile5(path6, "utf-8");
60446
60621
  const parsed = JSON.parse(raw);
60447
60622
  if (Array.isArray(parsed)) {
60448
60623
  return new Set(parsed.filter((k) => typeof k === "string"));
@@ -61110,7 +61285,7 @@ __export(self_update_exports, {
61110
61285
  selfUpdateCommand: () => selfUpdateCommand
61111
61286
  });
61112
61287
  import { execFile } from "node:child_process";
61113
- import { readFile as readFile5 } from "node:fs/promises";
61288
+ import { readFile as readFile6 } from "node:fs/promises";
61114
61289
  import { join as join28 } from "node:path";
61115
61290
  import * as readline2 from "node:readline";
61116
61291
  import { promisify } from "node:util";
@@ -61126,7 +61301,7 @@ import {
61126
61301
  async function getCurrentVersion() {
61127
61302
  const cleoHome = getCleoHome4();
61128
61303
  try {
61129
- const content = await readFile5(join28(cleoHome, "VERSION"), "utf-8");
61304
+ const content = await readFile6(join28(cleoHome, "VERSION"), "utf-8");
61130
61305
  return (content.split("\n")[0] ?? "unknown").trim();
61131
61306
  } catch {
61132
61307
  return "unknown";
@@ -61218,11 +61393,11 @@ async function runPostUpdateDiagnostics(opts) {
61218
61393
  input: process.stdin,
61219
61394
  output: process.stdout
61220
61395
  });
61221
- shouldMigrate = await new Promise((resolve7) => {
61396
+ shouldMigrate = await new Promise((resolve8) => {
61222
61397
  rl.question(" Do you want to run the upgrade now? [Y/n] ", (answer) => {
61223
61398
  rl.close();
61224
61399
  const clean = answer.trim().toLowerCase();
61225
- resolve7(clean === "" || clean === "y" || clean === "yes");
61400
+ resolve8(clean === "" || clean === "y" || clean === "yes");
61226
61401
  });
61227
61402
  });
61228
61403
  }
@@ -62666,7 +62841,7 @@ async function promptOwnerAuthPassword(sessionName) {
62666
62841
  terminal: true
62667
62842
  });
62668
62843
  process.stderr.write(`[cleo] Enter owner-auth password for session "${sessionName}": `);
62669
- const password = await new Promise((resolve7) => {
62844
+ const password = await new Promise((resolve8) => {
62670
62845
  if (process.stdin.setRawMode) {
62671
62846
  process.stdin.setRawMode(
62672
62847
  true
@@ -62684,10 +62859,10 @@ async function promptOwnerAuthPassword(sessionName) {
62684
62859
  );
62685
62860
  }
62686
62861
  process.stderr.write("\n");
62687
- resolve7(pw);
62862
+ resolve8(pw);
62688
62863
  } else if (ch === "") {
62689
62864
  process.stderr.write("\n[cleo] Cancelled.\n");
62690
- resolve7("");
62865
+ resolve8("");
62691
62866
  } else if (ch === "\x7F" || ch === "\b") {
62692
62867
  pw = pw.slice(0, -1);
62693
62868
  } else {
@@ -63067,8 +63242,8 @@ var init_session4 = __esm({
63067
63242
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
63068
63243
  },
63069
63244
  async run({ args }) {
63070
- const { detectSessionDrift, getProjectRoot: getProjectRoot53 } = await import("@cleocode/core");
63071
- const projectRoot = await getProjectRoot53();
63245
+ const { detectSessionDrift, getProjectRoot: getProjectRoot54 } = await import("@cleocode/core");
63246
+ const projectRoot = await getProjectRoot54();
63072
63247
  const scope = args["audit-scope"] === "local" ? "local" : "global";
63073
63248
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
63074
63249
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -64712,8 +64887,8 @@ var init_snapshot = __esm({
64712
64887
  handleRawError(response, { command: "snapshot", operation: "admin.export" });
64713
64888
  const data = response.data;
64714
64889
  if (data?.outputPath) {
64715
- const { readFile: readFile7 } = await import("node:fs/promises");
64716
- const content = await readFile7(data.outputPath, "utf-8");
64890
+ const { readFile: readFile8 } = await import("node:fs/promises");
64891
+ const content = await readFile8(data.outputPath, "utf-8");
64717
64892
  process.stdout.write(content);
64718
64893
  if (!content.endsWith("\n")) process.stdout.write("\n");
64719
64894
  }
@@ -65444,10 +65619,10 @@ var init_sync = __esm({
65444
65619
  }
65445
65620
  },
65446
65621
  async run({ args }) {
65447
- const { readFileSync: readFileSync18 } = await import("node:fs");
65622
+ const { readFileSync: readFileSync21 } = await import("node:fs");
65448
65623
  let externalTasks;
65449
65624
  try {
65450
- externalTasks = JSON.parse(readFileSync18(args.file, "utf8"));
65625
+ externalTasks = JSON.parse(readFileSync21(args.file, "utf8"));
65451
65626
  } catch (err) {
65452
65627
  const message = err instanceof Error ? err.message : String(err);
65453
65628
  cliError(`Failed to read or parse external tasks file: ${message}`, 2, {
@@ -65702,6 +65877,667 @@ var init_telemetry2 = __esm({
65702
65877
  }
65703
65878
  });
65704
65879
 
65880
+ // packages/cleo/src/cli/commands/templates/lib.ts
65881
+ import { readFileSync as readFileSync15 } from "node:fs";
65882
+ import { isAbsolute as isAbsolute3, resolve as resolve6 } from "node:path";
65883
+ import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
65884
+ import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
65885
+ function resolveProjectRoot7(raw) {
65886
+ if (typeof raw === "string" && raw.length > 0) {
65887
+ return isAbsolute3(raw) ? raw : resolve6(process.cwd(), raw);
65888
+ }
65889
+ return getProjectRoot50();
65890
+ }
65891
+ function readTemplateSource(entry) {
65892
+ const sourceAbsolute = resolveSourcePathAbsolute(entry);
65893
+ return readFileSync15(sourceAbsolute, "utf8");
65894
+ }
65895
+ function applySubstitution(entry, source) {
65896
+ if (entry.substitution === "static") {
65897
+ return { rendered: source, substituted: false };
65898
+ }
65899
+ return { rendered: source, substituted: false };
65900
+ }
65901
+ var init_lib = __esm({
65902
+ "packages/cleo/src/cli/commands/templates/lib.ts"() {
65903
+ "use strict";
65904
+ }
65905
+ });
65906
+
65907
+ // packages/cleo/src/cli/commands/templates/diff.ts
65908
+ import { existsSync as existsSync15, readFileSync as readFileSync16 } from "node:fs";
65909
+ import { join as join30 } from "node:path";
65910
+ import { getTemplateById } from "@cleocode/core/templates/registry";
65911
+ function unifiedDiff(a, b) {
65912
+ const aLines = a.length === 0 ? [] : a.split("\n");
65913
+ const bLines = b.length === 0 ? [] : b.split("\n");
65914
+ const out = [];
65915
+ const max = Math.max(aLines.length, bLines.length);
65916
+ for (let i = 0; i < max; i += 1) {
65917
+ const av = aLines[i];
65918
+ const bv = bLines[i];
65919
+ if (av === bv) {
65920
+ if (av !== void 0) out.push(` ${av}`);
65921
+ continue;
65922
+ }
65923
+ if (av !== void 0) out.push(`-${av}`);
65924
+ if (bv !== void 0) out.push(`+${bv}`);
65925
+ }
65926
+ return out.join("\n");
65927
+ }
65928
+ var templatesDiffCommand;
65929
+ var init_diff = __esm({
65930
+ "packages/cleo/src/cli/commands/templates/diff.ts"() {
65931
+ "use strict";
65932
+ init_src2();
65933
+ init_define_cli_command();
65934
+ init_renderers();
65935
+ init_lib();
65936
+ templatesDiffCommand = defineCommand({
65937
+ meta: {
65938
+ name: "diff",
65939
+ description: "Diff a template against its installed copy (exit 0 same, 1 different)"
65940
+ },
65941
+ args: {
65942
+ id: {
65943
+ type: "positional",
65944
+ required: true,
65945
+ description: "Template id (kebab-case)"
65946
+ },
65947
+ project: {
65948
+ type: "string",
65949
+ description: "Project root to diff against (default: detected project root)"
65950
+ },
65951
+ json: {
65952
+ type: "boolean",
65953
+ description: "Output as JSON"
65954
+ }
65955
+ },
65956
+ async run({ args }) {
65957
+ const id = String(args["id"] ?? "").trim();
65958
+ if (id.length === 0) {
65959
+ cliError(`templates diff failed: <id> is required`, 2 /* INVALID_INPUT */, {
65960
+ name: "E_TEMPLATES_DIFF_FAILED"
65961
+ });
65962
+ process.exit(2 /* INVALID_INPUT */);
65963
+ return;
65964
+ }
65965
+ const entry = getTemplateById(id);
65966
+ if (entry === void 0) {
65967
+ cliError(`templates diff failed: id "${id}" not found`, 4 /* NOT_FOUND */, {
65968
+ name: "E_NOT_FOUND",
65969
+ details: { id }
65970
+ });
65971
+ process.exit(4 /* NOT_FOUND */);
65972
+ return;
65973
+ }
65974
+ let projectRoot;
65975
+ let installPath;
65976
+ let rendered;
65977
+ try {
65978
+ projectRoot = resolveProjectRoot7(args["project"]);
65979
+ installPath = join30(projectRoot, entry.installPath);
65980
+ const source = readTemplateSource(entry);
65981
+ rendered = applySubstitution(entry, source).rendered;
65982
+ } catch (err) {
65983
+ const message = err instanceof Error ? err.message : String(err);
65984
+ cliError(`templates diff failed: ${message}`, 1 /* GENERAL_ERROR */, {
65985
+ name: "E_TEMPLATES_DIFF_FAILED"
65986
+ });
65987
+ process.exit(1 /* GENERAL_ERROR */);
65988
+ return;
65989
+ }
65990
+ if (!existsSync15(installPath)) {
65991
+ const missingResult = {
65992
+ id,
65993
+ installPath,
65994
+ same: false,
65995
+ missing: true,
65996
+ diff: `--- (missing) ${installPath}
65997
+ +++ (rendered) ${id}
65998
+ ${unifiedDiff("", rendered)}`
65999
+ };
66000
+ cliOutput(missingResult, {
66001
+ command: "templates-diff",
66002
+ operation: "templates.diff"
66003
+ });
66004
+ process.exit(1 /* GENERAL_ERROR */);
66005
+ return;
66006
+ }
66007
+ const current = readFileSync16(installPath, "utf8");
66008
+ const same = current === rendered;
66009
+ const result = {
66010
+ id,
66011
+ installPath,
66012
+ same,
66013
+ missing: false,
66014
+ diff: same ? "" : unifiedDiff(current, rendered)
66015
+ };
66016
+ cliOutput(result, {
66017
+ command: "templates-diff",
66018
+ operation: "templates.diff"
66019
+ });
66020
+ if (!same) {
66021
+ process.exit(1 /* GENERAL_ERROR */);
66022
+ }
66023
+ }
66024
+ });
66025
+ }
66026
+ });
66027
+
66028
+ // packages/cleo/src/cli/commands/templates/install.ts
66029
+ import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync17, writeFileSync as writeFileSync5 } from "node:fs";
66030
+ import { dirname as dirname9, join as join31 } from "node:path";
66031
+ import { getTemplateById as getTemplateById2 } from "@cleocode/core/templates/registry";
66032
+ var templatesInstallCommand;
66033
+ var init_install = __esm({
66034
+ "packages/cleo/src/cli/commands/templates/install.ts"() {
66035
+ "use strict";
66036
+ init_src2();
66037
+ init_define_cli_command();
66038
+ init_renderers();
66039
+ init_lib();
66040
+ templatesInstallCommand = defineCommand({
66041
+ meta: {
66042
+ name: "install",
66043
+ description: "Install a template into a project root (default: current project), idempotent"
66044
+ },
66045
+ args: {
66046
+ id: {
66047
+ type: "positional",
66048
+ required: true,
66049
+ description: "Template id (kebab-case)"
66050
+ },
66051
+ project: {
66052
+ type: "string",
66053
+ description: "Project root to install into (default: detected project root)"
66054
+ },
66055
+ json: {
66056
+ type: "boolean",
66057
+ description: "Output as JSON"
66058
+ }
66059
+ },
66060
+ async run({ args }) {
66061
+ const id = String(args["id"] ?? "").trim();
66062
+ if (id.length === 0) {
66063
+ cliError(`templates install failed: <id> is required`, 2 /* INVALID_INPUT */, {
66064
+ name: "E_TEMPLATES_INSTALL_FAILED"
66065
+ });
66066
+ process.exit(2 /* INVALID_INPUT */);
66067
+ return;
66068
+ }
66069
+ const entry = getTemplateById2(id);
66070
+ if (entry === void 0) {
66071
+ cliError(`templates install failed: id "${id}" not found`, 4 /* NOT_FOUND */, {
66072
+ name: "E_NOT_FOUND",
66073
+ details: { id }
66074
+ });
66075
+ process.exit(4 /* NOT_FOUND */);
66076
+ return;
66077
+ }
66078
+ let projectRoot;
66079
+ let installPath;
66080
+ let rendered;
66081
+ let substituted;
66082
+ try {
66083
+ projectRoot = resolveProjectRoot7(args["project"]);
66084
+ installPath = join31(projectRoot, entry.installPath);
66085
+ const source = readTemplateSource(entry);
66086
+ const sub = applySubstitution(entry, source);
66087
+ rendered = sub.rendered;
66088
+ substituted = sub.substituted;
66089
+ } catch (err) {
66090
+ const message = err instanceof Error ? err.message : String(err);
66091
+ cliError(`templates install failed: ${message}`, 1 /* GENERAL_ERROR */, {
66092
+ name: "E_TEMPLATES_INSTALL_FAILED"
66093
+ });
66094
+ process.exit(1 /* GENERAL_ERROR */);
66095
+ return;
66096
+ }
66097
+ if (existsSync16(installPath)) {
66098
+ const current = readFileSync17(installPath, "utf8");
66099
+ if (current === rendered) {
66100
+ const noopResult = {
66101
+ id,
66102
+ installPath,
66103
+ installed: false,
66104
+ noop: true,
66105
+ substituted
66106
+ };
66107
+ cliOutput(noopResult, {
66108
+ command: "templates-install",
66109
+ operation: "templates.install"
66110
+ });
66111
+ return;
66112
+ }
66113
+ }
66114
+ try {
66115
+ mkdirSync5(dirname9(installPath), { recursive: true });
66116
+ writeFileSync5(installPath, rendered, "utf8");
66117
+ } catch (err) {
66118
+ const message = err instanceof Error ? err.message : String(err);
66119
+ cliError(`templates install failed: ${message}`, 1 /* GENERAL_ERROR */, {
66120
+ name: "E_TEMPLATES_INSTALL_FAILED"
66121
+ });
66122
+ process.exit(1 /* GENERAL_ERROR */);
66123
+ return;
66124
+ }
66125
+ const result = {
66126
+ id,
66127
+ installPath,
66128
+ installed: true,
66129
+ noop: false,
66130
+ substituted
66131
+ };
66132
+ cliOutput(result, {
66133
+ command: "templates-install",
66134
+ operation: "templates.install"
66135
+ });
66136
+ }
66137
+ });
66138
+ }
66139
+ });
66140
+
66141
+ // packages/cleo/src/cli/commands/templates/list.ts
66142
+ import { getTemplateManifest, getTemplatesByKind } from "@cleocode/core/templates/registry";
66143
+ function parseTemplateKind(raw) {
66144
+ if (raw === void 0 || raw === "") return null;
66145
+ return TEMPLATE_KINDS.includes(raw) ? raw : null;
66146
+ }
66147
+ var templatesListCommand;
66148
+ var init_list4 = __esm({
66149
+ "packages/cleo/src/cli/commands/templates/list.ts"() {
66150
+ "use strict";
66151
+ init_src2();
66152
+ init_define_cli_command();
66153
+ init_renderers();
66154
+ templatesListCommand = defineCommand({
66155
+ meta: {
66156
+ name: "list",
66157
+ description: "List every template the registry knows about (optionally filtered by --kind)"
66158
+ },
66159
+ args: {
66160
+ kind: {
66161
+ type: "string",
66162
+ description: `Optional kind filter: ${TEMPLATE_KINDS.join(" | ")}`
66163
+ },
66164
+ json: {
66165
+ type: "boolean",
66166
+ description: "Output as JSON"
66167
+ }
66168
+ },
66169
+ async run({ args }) {
66170
+ const rawKind = args["kind"];
66171
+ const kind = parseTemplateKind(typeof rawKind === "string" ? rawKind : void 0);
66172
+ if (kind === null && rawKind !== void 0 && rawKind !== "") {
66173
+ cliError(
66174
+ `templates list failed: invalid --kind (must be ${TEMPLATE_KINDS.join("|")})`,
66175
+ 2 /* INVALID_INPUT */,
66176
+ { name: "E_TEMPLATES_LIST_FAILED" }
66177
+ );
66178
+ process.exit(2 /* INVALID_INPUT */);
66179
+ return;
66180
+ }
66181
+ const entries = kind === null ? getTemplateManifest() : getTemplatesByKind(kind);
66182
+ const result = { kind, entries };
66183
+ cliOutput(result, {
66184
+ command: "templates-list",
66185
+ operation: "templates.list"
66186
+ });
66187
+ }
66188
+ });
66189
+ }
66190
+ });
66191
+
66192
+ // packages/cleo/src/cli/commands/templates/show.ts
66193
+ import { getTemplateById as getTemplateById3 } from "@cleocode/core/templates/registry";
66194
+ var templatesShowCommand;
66195
+ var init_show3 = __esm({
66196
+ "packages/cleo/src/cli/commands/templates/show.ts"() {
66197
+ "use strict";
66198
+ init_src2();
66199
+ init_define_cli_command();
66200
+ init_renderers();
66201
+ templatesShowCommand = defineCommand({
66202
+ meta: {
66203
+ name: "show",
66204
+ description: "Print a single template manifest entry by id"
66205
+ },
66206
+ args: {
66207
+ id: {
66208
+ type: "positional",
66209
+ required: true,
66210
+ description: "Template id (kebab-case)"
66211
+ },
66212
+ json: {
66213
+ type: "boolean",
66214
+ description: "Output as JSON"
66215
+ }
66216
+ },
66217
+ async run({ args }) {
66218
+ const id = String(args["id"] ?? "").trim();
66219
+ if (id.length === 0) {
66220
+ cliError(`templates show failed: <id> is required`, 2 /* INVALID_INPUT */, {
66221
+ name: "E_TEMPLATES_SHOW_FAILED"
66222
+ });
66223
+ process.exit(2 /* INVALID_INPUT */);
66224
+ return;
66225
+ }
66226
+ const entry = getTemplateById3(id);
66227
+ if (entry === void 0) {
66228
+ cliError(`templates show failed: id "${id}" not found`, 4 /* NOT_FOUND */, {
66229
+ name: "E_NOT_FOUND",
66230
+ details: { id }
66231
+ });
66232
+ process.exit(4 /* NOT_FOUND */);
66233
+ return;
66234
+ }
66235
+ const result = { id, entry };
66236
+ cliOutput(result, {
66237
+ command: "templates-show",
66238
+ operation: "templates.show"
66239
+ });
66240
+ }
66241
+ });
66242
+ }
66243
+ });
66244
+
66245
+ // packages/cleo/src/cli/commands/templates/upgrade.ts
66246
+ import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "node:fs";
66247
+ import { dirname as dirname10, join as join32 } from "node:path";
66248
+ import { getTemplateById as getTemplateById4 } from "@cleocode/core/templates/registry";
66249
+ var templatesUpgradeCommand;
66250
+ var init_upgrade2 = __esm({
66251
+ "packages/cleo/src/cli/commands/templates/upgrade.ts"() {
66252
+ "use strict";
66253
+ init_src2();
66254
+ init_define_cli_command();
66255
+ init_renderers();
66256
+ init_diff();
66257
+ init_lib();
66258
+ templatesUpgradeCommand = defineCommand({
66259
+ meta: {
66260
+ name: "upgrade",
66261
+ description: "Re-install a template respecting its updateStrategy (overwrite | diff-prompt | immutable | manifest-merge)"
66262
+ },
66263
+ args: {
66264
+ id: {
66265
+ type: "positional",
66266
+ required: true,
66267
+ description: "Template id (kebab-case)"
66268
+ },
66269
+ project: {
66270
+ type: "string",
66271
+ description: "Project root to upgrade against (default: detected project root)"
66272
+ },
66273
+ diff: {
66274
+ type: "boolean",
66275
+ description: "Preview-only \u2014 print the diff without writing"
66276
+ },
66277
+ accept: {
66278
+ type: "boolean",
66279
+ description: "Apply when strategy is diff-prompt (no-op otherwise)"
66280
+ },
66281
+ json: {
66282
+ type: "boolean",
66283
+ description: "Output as JSON"
66284
+ }
66285
+ },
66286
+ async run({ args }) {
66287
+ const id = String(args["id"] ?? "").trim();
66288
+ if (id.length === 0) {
66289
+ cliError(`templates upgrade failed: <id> is required`, 2 /* INVALID_INPUT */, {
66290
+ name: "E_TEMPLATES_UPGRADE_FAILED"
66291
+ });
66292
+ process.exit(2 /* INVALID_INPUT */);
66293
+ return;
66294
+ }
66295
+ const entry = getTemplateById4(id);
66296
+ if (entry === void 0) {
66297
+ cliError(`templates upgrade failed: id "${id}" not found`, 4 /* NOT_FOUND */, {
66298
+ name: "E_NOT_FOUND",
66299
+ details: { id }
66300
+ });
66301
+ process.exit(4 /* NOT_FOUND */);
66302
+ return;
66303
+ }
66304
+ let projectRoot;
66305
+ let installPath;
66306
+ let rendered;
66307
+ try {
66308
+ projectRoot = resolveProjectRoot7(args["project"]);
66309
+ installPath = join32(projectRoot, entry.installPath);
66310
+ const source = readTemplateSource(entry);
66311
+ rendered = applySubstitution(entry, source).rendered;
66312
+ } catch (err) {
66313
+ const message = err instanceof Error ? err.message : String(err);
66314
+ cliError(`templates upgrade failed: ${message}`, 1 /* GENERAL_ERROR */, {
66315
+ name: "E_TEMPLATES_UPGRADE_FAILED"
66316
+ });
66317
+ process.exit(1 /* GENERAL_ERROR */);
66318
+ return;
66319
+ }
66320
+ const previewOnly = args["diff"] === true;
66321
+ const accept = args["accept"] === true;
66322
+ const current = existsSync17(installPath) ? readFileSync18(installPath, "utf8") : null;
66323
+ const diffBody = current === null ? "" : current === rendered ? "" : unifiedDiff(current, rendered);
66324
+ let outcome;
66325
+ let reason;
66326
+ let shouldWrite = false;
66327
+ if (entry.updateStrategy === "manifest-merge") {
66328
+ outcome = "not-supported";
66329
+ reason = "manifest-merge upgrade is not yet supported (T9886-followup)";
66330
+ } else if (entry.updateStrategy === "immutable") {
66331
+ outcome = "skipped";
66332
+ reason = current === null ? "immutable: not installed yet \u2014 use `install`" : "immutable: skipped per strategy";
66333
+ } else if (current !== null && current === rendered) {
66334
+ outcome = "noop";
66335
+ reason = "already current";
66336
+ } else if (entry.updateStrategy === "overwrite-on-bump") {
66337
+ if (previewOnly) {
66338
+ outcome = "skipped";
66339
+ reason = "preview-only (--diff)";
66340
+ } else {
66341
+ outcome = "overwritten";
66342
+ reason = current === null ? "fresh install" : "overwrite-on-bump";
66343
+ shouldWrite = true;
66344
+ }
66345
+ } else {
66346
+ if (previewOnly || !accept) {
66347
+ outcome = "skipped";
66348
+ reason = previewOnly ? "preview-only (--diff)" : "diff-prompt: pass --accept to apply";
66349
+ } else {
66350
+ outcome = "overwritten";
66351
+ reason = "diff-prompt: accepted";
66352
+ shouldWrite = true;
66353
+ }
66354
+ }
66355
+ if (shouldWrite) {
66356
+ try {
66357
+ mkdirSync6(dirname10(installPath), { recursive: true });
66358
+ writeFileSync6(installPath, rendered, "utf8");
66359
+ } catch (err) {
66360
+ const message = err instanceof Error ? err.message : String(err);
66361
+ cliError(`templates upgrade failed: ${message}`, 1 /* GENERAL_ERROR */, {
66362
+ name: "E_TEMPLATES_UPGRADE_FAILED"
66363
+ });
66364
+ process.exit(1 /* GENERAL_ERROR */);
66365
+ return;
66366
+ }
66367
+ }
66368
+ const result = {
66369
+ id,
66370
+ installPath,
66371
+ updateStrategy: entry.updateStrategy,
66372
+ outcome,
66373
+ reason,
66374
+ diff: diffBody
66375
+ };
66376
+ cliOutput(result, {
66377
+ command: "templates-upgrade",
66378
+ operation: "templates.upgrade"
66379
+ });
66380
+ }
66381
+ });
66382
+ }
66383
+ });
66384
+
66385
+ // packages/cleo/src/cli/commands/templates/validate.ts
66386
+ import {
66387
+ getInstalledStatus,
66388
+ getTemplateById as getTemplateById5,
66389
+ getTemplateManifest as getTemplateManifest2,
66390
+ resolveSourcePathAbsolute as resolveSourcePathAbsolute2
66391
+ } from "@cleocode/core/templates/registry";
66392
+ var templatesValidateCommand;
66393
+ var init_validate3 = __esm({
66394
+ "packages/cleo/src/cli/commands/templates/validate.ts"() {
66395
+ "use strict";
66396
+ init_src2();
66397
+ init_define_cli_command();
66398
+ init_renderers();
66399
+ init_lib();
66400
+ templatesValidateCommand = defineCommand({
66401
+ meta: {
66402
+ name: "validate",
66403
+ description: "Validate every registry entry (or one --id) against the live filesystem"
66404
+ },
66405
+ args: {
66406
+ id: {
66407
+ type: "string",
66408
+ description: "Validate a single entry by id (default: walk every entry)"
66409
+ },
66410
+ project: {
66411
+ type: "string",
66412
+ description: "Project root to probe install status against (default: detected)"
66413
+ },
66414
+ json: {
66415
+ type: "boolean",
66416
+ description: "Output as JSON"
66417
+ }
66418
+ },
66419
+ async run({ args }) {
66420
+ let projectRoot;
66421
+ try {
66422
+ projectRoot = resolveProjectRoot7(args["project"]);
66423
+ } catch (err) {
66424
+ const message = err instanceof Error ? err.message : String(err);
66425
+ cliError(`templates validate failed: ${message}`, 1 /* GENERAL_ERROR */, {
66426
+ name: "E_TEMPLATES_VALIDATE_FAILED"
66427
+ });
66428
+ process.exit(1 /* GENERAL_ERROR */);
66429
+ return;
66430
+ }
66431
+ const idFilter = typeof args["id"] === "string" && args["id"].length > 0 ? args["id"] : null;
66432
+ let targets;
66433
+ if (idFilter === null) {
66434
+ targets = getTemplateManifest2();
66435
+ } else {
66436
+ const entry = getTemplateById5(idFilter);
66437
+ if (entry === void 0) {
66438
+ cliError(`templates validate failed: id "${idFilter}" not found`, 4 /* NOT_FOUND */, {
66439
+ name: "E_NOT_FOUND",
66440
+ details: { id: idFilter }
66441
+ });
66442
+ process.exit(4 /* NOT_FOUND */);
66443
+ return;
66444
+ }
66445
+ targets = [entry];
66446
+ }
66447
+ const entries = targets.map((entry) => {
66448
+ const issues = [];
66449
+ let sourcePath = null;
66450
+ let sourceExists = false;
66451
+ try {
66452
+ sourcePath = resolveSourcePathAbsolute2(entry);
66453
+ sourceExists = true;
66454
+ } catch (err) {
66455
+ issues.push(`source: ${err instanceof Error ? err.message : String(err)}`);
66456
+ }
66457
+ let installed = false;
66458
+ let installPath = null;
66459
+ try {
66460
+ const status = getInstalledStatus(entry.id, projectRoot);
66461
+ installed = status.installed;
66462
+ installPath = status.path;
66463
+ } catch (err) {
66464
+ issues.push(`install: ${err instanceof Error ? err.message : String(err)}`);
66465
+ }
66466
+ return {
66467
+ id: entry.id,
66468
+ kind: entry.kind,
66469
+ sourceExists,
66470
+ sourcePath,
66471
+ installed,
66472
+ installPath,
66473
+ issues
66474
+ };
66475
+ });
66476
+ const ok = entries.every((e) => e.issues.length === 0);
66477
+ const result = {
66478
+ ok,
66479
+ count: entries.length,
66480
+ entries
66481
+ };
66482
+ cliOutput(result, {
66483
+ command: "templates-validate",
66484
+ operation: "templates.validate"
66485
+ });
66486
+ if (!ok) {
66487
+ process.exit(6 /* VALIDATION_ERROR */);
66488
+ }
66489
+ }
66490
+ });
66491
+ }
66492
+ });
66493
+
66494
+ // packages/cleo/src/cli/commands/templates/index.ts
66495
+ var init_templates = __esm({
66496
+ "packages/cleo/src/cli/commands/templates/index.ts"() {
66497
+ "use strict";
66498
+ init_diff();
66499
+ init_install();
66500
+ init_list4();
66501
+ init_show3();
66502
+ init_upgrade2();
66503
+ init_validate3();
66504
+ }
66505
+ });
66506
+
66507
+ // packages/cleo/src/cli/commands/templates.ts
66508
+ var templates_exports = {};
66509
+ __export(templates_exports, {
66510
+ templatesCommand: () => templatesCommand
66511
+ });
66512
+ var templatesCommand;
66513
+ var init_templates2 = __esm({
66514
+ "packages/cleo/src/cli/commands/templates.ts"() {
66515
+ "use strict";
66516
+ init_dist();
66517
+ init_define_cli_command();
66518
+ init_templates();
66519
+ templatesCommand = defineCommand({
66520
+ meta: {
66521
+ name: "templates",
66522
+ description: "TemplateManifest SSoT registry surface (list, show, install, upgrade, diff, validate)"
66523
+ },
66524
+ subCommands: {
66525
+ list: templatesListCommand,
66526
+ show: templatesShowCommand,
66527
+ install: templatesInstallCommand,
66528
+ upgrade: templatesUpgradeCommand,
66529
+ diff: templatesDiffCommand,
66530
+ validate: templatesValidateCommand
66531
+ },
66532
+ async run({ cmd, rawArgs }) {
66533
+ const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
66534
+ if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
66535
+ await showUsage(cmd);
66536
+ }
66537
+ });
66538
+ }
66539
+ });
66540
+
65705
66541
  // packages/cleo/src/cli/commands/testing.ts
65706
66542
  var testing_exports = {};
65707
66543
  __export(testing_exports, {
@@ -65833,12 +66669,12 @@ var token_exports = {};
65833
66669
  __export(token_exports, {
65834
66670
  tokenCommand: () => tokenCommand
65835
66671
  });
65836
- import { readFileSync as readFileSync16 } from "node:fs";
65837
- import { getProjectRoot as getProjectRoot50, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
66672
+ import { readFileSync as readFileSync19 } from "node:fs";
66673
+ import { getProjectRoot as getProjectRoot51, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
65838
66674
  function readPayload(args, textKey, fileKey) {
65839
66675
  const text = args[textKey];
65840
66676
  const file = args[fileKey];
65841
- if (file) return readFileSync16(file, "utf-8");
66677
+ if (file) return readFileSync19(file, "utf-8");
65842
66678
  return text;
65843
66679
  }
65844
66680
  var filterArgs, summaryCommand3, listCommand26, showCommand16, deleteCommand3, clearCommand2, estimateCommand, tokenCommand;
@@ -65998,7 +66834,7 @@ var init_token = __esm({
65998
66834
  domain: args.domain,
65999
66835
  operation: args.operation
66000
66836
  };
66001
- const result = args.record ? await recordTokenExchange2(getProjectRoot50(), input2) : await measureTokenExchange(input2);
66837
+ const result = args.record ? await recordTokenExchange2(getProjectRoot51(), input2) : await measureTokenExchange(input2);
66002
66838
  cliOutput(result, {
66003
66839
  command: "token",
66004
66840
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -66033,8 +66869,8 @@ __export(transcript_exports, {
66033
66869
  transcriptCommand: () => transcriptCommand
66034
66870
  });
66035
66871
  import { homedir as homedir6 } from "node:os";
66036
- import { join as join30 } from "node:path";
66037
- import { getProjectRoot as getProjectRoot51 } from "@cleocode/core";
66872
+ import { join as join33 } from "node:path";
66873
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
66038
66874
  import {
66039
66875
  parseDurationMs,
66040
66876
  pruneTranscripts,
@@ -66064,7 +66900,7 @@ var init_transcript = __esm({
66064
66900
  async run({ args }) {
66065
66901
  if (args.pending) {
66066
66902
  try {
66067
- const projectRoot = getProjectRoot51();
66903
+ const projectRoot = getProjectRoot52();
66068
66904
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
66069
66905
  const pending = await scanPendingTranscripts(projectRoot);
66070
66906
  cliOutput(
@@ -66087,7 +66923,7 @@ var init_transcript = __esm({
66087
66923
  }
66088
66924
  return;
66089
66925
  }
66090
- const projectsDir = args["projects-dir"] ?? join30(homedir6(), ".claude", "projects");
66926
+ const projectsDir = args["projects-dir"] ?? join33(homedir6(), ".claude", "projects");
66091
66927
  try {
66092
66928
  const result = await scanTranscripts(projectsDir);
66093
66929
  cliOutput(
@@ -66161,7 +66997,7 @@ var init_transcript = __esm({
66161
66997
  async run({ args }) {
66162
66998
  const tier = args.tier ?? "warm";
66163
66999
  const dryRun = args["dry-run"] ?? false;
66164
- const projectRoot = getProjectRoot51();
67000
+ const projectRoot = getProjectRoot52();
66165
67001
  try {
66166
67002
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
66167
67003
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -66273,7 +67109,7 @@ var init_transcript = __esm({
66273
67109
  const dryRun = args["dry-run"] ?? false;
66274
67110
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
66275
67111
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
66276
- const projectRoot = getProjectRoot51();
67112
+ const projectRoot = getProjectRoot52();
66277
67113
  try {
66278
67114
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
66279
67115
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -66393,7 +67229,7 @@ var init_transcript = __esm({
66393
67229
  process.exit(2);
66394
67230
  return;
66395
67231
  }
66396
- const projectsDir = args["projects-dir"] ?? join30(homedir6(), ".claude", "projects");
67232
+ const projectsDir = args["projects-dir"] ?? join33(homedir6(), ".claude", "projects");
66397
67233
  try {
66398
67234
  const pruneResult = await pruneTranscripts({
66399
67235
  olderThanMs,
@@ -66454,10 +67290,12 @@ __export(update_exports, {
66454
67290
  });
66455
67291
  import {
66456
67292
  appendSignedSeverityAttestation as appendSignedSeverityAttestation2,
67293
+ INPUT_CONTRACTS as INPUT_CONTRACTS3,
66457
67294
  isPipelineTransitionForward,
66458
67295
  isValidPipelineStage,
66459
67296
  parseAcceptanceCriteria as parseAcceptanceCriteria2,
66460
- TASK_PIPELINE_STAGES
67297
+ TASK_PIPELINE_STAGES,
67298
+ validateOperationInput as validateOperationInput3
66461
67299
  } from "@cleocode/core";
66462
67300
  var updateCommand2;
66463
67301
  var init_update = __esm({
@@ -66466,6 +67304,7 @@ var init_update = __esm({
66466
67304
  init_src2();
66467
67305
  init_dist();
66468
67306
  init_cli();
67307
+ init_collect_input();
66469
67308
  init_renderers();
66470
67309
  updateCommand2 = defineCommand({
66471
67310
  meta: {
@@ -66473,6 +67312,28 @@ var init_update = __esm({
66473
67312
  description: "Update a task. Safe under concurrent invocation \u2014 retries on SQLITE_BUSY up to 4 attempts (gh#391)."
66474
67313
  },
66475
67314
  args: {
67315
+ /**
67316
+ * Schema-first input — supersedes all flag-based args when present.
67317
+ *
67318
+ * Accepts a JSON object matching `INPUT_CONTRACTS['tasks.update']`.
67319
+ * The `taskId` MUST be present in the JSON payload (positional
67320
+ * `taskId` arg is ignored in this path).
67321
+ *
67322
+ * @task T9917
67323
+ */
67324
+ params: {
67325
+ type: "string",
67326
+ description: 'Inline JSON object matching INPUT_CONTRACTS["tasks.update"] (T9917). Overrides positional + flags.'
67327
+ },
67328
+ /**
67329
+ * Schema-first input from a JSON file. Same semantics as --params.
67330
+ *
67331
+ * @task T9917
67332
+ */
67333
+ "params-file": {
67334
+ type: "string",
67335
+ description: 'Path to JSON file matching INPUT_CONTRACTS["tasks.update"] (T9917).'
67336
+ },
66476
67337
  taskId: {
66477
67338
  type: "positional",
66478
67339
  description: "Task ID to update",
@@ -66671,6 +67532,78 @@ var init_update = __esm({
66671
67532
  }
66672
67533
  },
66673
67534
  async run({ args, cmd }) {
67535
+ const paramsArg = args.params;
67536
+ const paramsFileArg = args["params-file"];
67537
+ if (paramsArg !== void 0 || paramsFileArg !== void 0) {
67538
+ const collectArgs = {};
67539
+ if (paramsArg !== void 0) collectArgs.params = paramsArg;
67540
+ if (paramsFileArg !== void 0) collectArgs.file = paramsFileArg;
67541
+ let raw;
67542
+ try {
67543
+ raw = await collectMutateInput(
67544
+ collectArgs,
67545
+ process.stdin
67546
+ );
67547
+ } catch (err) {
67548
+ cliError(
67549
+ err.message,
67550
+ 6 /* VALIDATION_ERROR */,
67551
+ {
67552
+ name: "E_VALIDATION_FAILED",
67553
+ fix: "Verify the JSON syntax of your --params / --params-file input"
67554
+ },
67555
+ { operation: "tasks.update" }
67556
+ );
67557
+ process.exit(6 /* VALIDATION_ERROR */);
67558
+ return;
67559
+ }
67560
+ if (raw !== null && typeof raw === "object" && !Array.isArray(raw) && raw["taskId"] === void 0 && args.taskId !== void 0) {
67561
+ raw["taskId"] = args.taskId;
67562
+ }
67563
+ const contract = INPUT_CONTRACTS3["tasks.update"];
67564
+ if (!contract) {
67565
+ cliError(
67566
+ "tasks.update contract missing from INPUT_CONTRACTS registry",
67567
+ 1 /* GENERAL_ERROR */,
67568
+ { name: "E_INTERNAL", fix: "This is a CLI bug \u2014 file an issue" },
67569
+ { operation: "tasks.update" }
67570
+ );
67571
+ process.exit(1 /* GENERAL_ERROR */);
67572
+ return;
67573
+ }
67574
+ const validation = validateOperationInput3(contract, raw);
67575
+ if (!validation.ok) {
67576
+ cliError(
67577
+ "tasks.update failed: validation",
67578
+ 6 /* VALIDATION_ERROR */,
67579
+ {
67580
+ name: "E_VALIDATION_FAILED",
67581
+ fix: validation.errors[0]?.fix ?? "Inspect errors[] and correct the input",
67582
+ details: { errors: validation.errors }
67583
+ },
67584
+ { operation: "tasks.update" }
67585
+ );
67586
+ process.exit(6 /* VALIDATION_ERROR */);
67587
+ return;
67588
+ }
67589
+ const validatedPayload = raw;
67590
+ const response = await dispatchRaw("mutate", "tasks", "update", validatedPayload);
67591
+ if (!response.success) {
67592
+ cliError(
67593
+ response.error?.message ?? "Update failed",
67594
+ response.error?.code ?? "E_UPDATE_FAILED",
67595
+ {
67596
+ name: response.error?.code ?? "E_UPDATE_FAILED",
67597
+ fix: response.error?.fix ?? "Check task fields and try again"
67598
+ },
67599
+ { operation: "tasks.update" }
67600
+ );
67601
+ process.exit(1);
67602
+ return;
67603
+ }
67604
+ cliOutput(response.data, { command: "update", operation: "tasks.update" });
67605
+ return;
67606
+ }
66674
67607
  if (!args.taskId) {
66675
67608
  await showUsage(cmd);
66676
67609
  return;
@@ -66828,10 +67761,10 @@ var upgrade_exports = {};
66828
67761
  __export(upgrade_exports, {
66829
67762
  upgradeCommand: () => upgradeCommand
66830
67763
  });
66831
- import { resolve as resolve6 } from "node:path";
67764
+ import { resolve as resolve7 } from "node:path";
66832
67765
  import { CleoError as CleoError10, diagnoseUpgrade, runUpgrade as runUpgrade2, upgradeWorkflows as upgradeWorkflows2 } from "@cleocode/core/internal";
66833
67766
  var workflowsSubcommand, upgradeCommand;
66834
- var init_upgrade2 = __esm({
67767
+ var init_upgrade3 = __esm({
66835
67768
  "packages/cleo/src/cli/commands/upgrade.ts"() {
66836
67769
  "use strict";
66837
67770
  init_dist();
@@ -66868,7 +67801,7 @@ var init_upgrade2 = __esm({
66868
67801
  const dryRun = args["dry-run"] === true || args.check === true;
66869
67802
  const force = args.force === true && !dryRun;
66870
67803
  const result = await upgradeWorkflows2({
66871
- projectRoot: resolve6(process.cwd()),
67804
+ projectRoot: resolve7(process.cwd()),
66872
67805
  templatesDir: getWorkflowTemplatesDir2(),
66873
67806
  dryRun,
66874
67807
  force
@@ -67128,16 +68061,16 @@ __export(web_exports, {
67128
68061
  webCommand: () => webCommand
67129
68062
  });
67130
68063
  import { execFileSync as execFileSync3, spawn as spawn3 } from "node:child_process";
67131
- import { mkdir as mkdir4, open, readFile as readFile6, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
67132
- import { join as join31 } from "node:path";
68064
+ import { mkdir as mkdir4, open, readFile as readFile7, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
68065
+ import { join as join34 } from "node:path";
67133
68066
  import { CleoError as CleoError11, formatError as formatError6, getCleoHome as getCleoHome5 } from "@cleocode/core";
67134
68067
  function getWebPaths() {
67135
68068
  const cleoHome = getCleoHome5();
67136
68069
  return {
67137
- pidFile: join31(cleoHome, "web-server.pid"),
67138
- configFile: join31(cleoHome, "web-server.json"),
67139
- logDir: join31(cleoHome, "logs"),
67140
- logFile: join31(cleoHome, "logs", "web-server.log")
68070
+ pidFile: join34(cleoHome, "web-server.pid"),
68071
+ configFile: join34(cleoHome, "web-server.json"),
68072
+ logDir: join34(cleoHome, "logs"),
68073
+ logFile: join34(cleoHome, "logs", "web-server.log")
67141
68074
  };
67142
68075
  }
67143
68076
  function isProcessRunning(pid) {
@@ -67151,7 +68084,7 @@ function isProcessRunning(pid) {
67151
68084
  async function getStatus() {
67152
68085
  const { pidFile, configFile } = getWebPaths();
67153
68086
  try {
67154
- const pidStr = (await readFile6(pidFile, "utf-8")).trim();
68087
+ const pidStr = (await readFile7(pidFile, "utf-8")).trim();
67155
68088
  const pid = Number.parseInt(pidStr, 10);
67156
68089
  if (Number.isNaN(pid) || !isProcessRunning(pid)) {
67157
68090
  return { running: false, pid: null, port: null, host: null, url: null };
@@ -67159,7 +68092,7 @@ async function getStatus() {
67159
68092
  let port = DEFAULT_PORT;
67160
68093
  let host = DEFAULT_HOST;
67161
68094
  try {
67162
- const config = JSON.parse(await readFile6(configFile, "utf-8"));
68095
+ const config = JSON.parse(await readFile7(configFile, "utf-8"));
67163
68096
  port = config.port ?? DEFAULT_PORT;
67164
68097
  host = config.host ?? DEFAULT_HOST;
67165
68098
  } catch {
@@ -67176,7 +68109,7 @@ async function startWebServer(port, host) {
67176
68109
  throw new CleoError11(1 /* GENERAL_ERROR */, `Server already running (PID: ${status.pid})`);
67177
68110
  }
67178
68111
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
67179
- const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join31(projectRoot, "packages", "studio", "build");
68112
+ const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join34(projectRoot, "packages", "studio", "build");
67180
68113
  await mkdir4(logDir, { recursive: true });
67181
68114
  await writeFile3(
67182
68115
  configFile,
@@ -67186,7 +68119,7 @@ async function startWebServer(port, host) {
67186
68119
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
67187
68120
  })
67188
68121
  );
67189
- const webIndexPath = join31(studioDir, "index.js");
68122
+ const webIndexPath = join34(studioDir, "index.js");
67190
68123
  try {
67191
68124
  await stat2(webIndexPath);
67192
68125
  } catch {
@@ -67234,7 +68167,7 @@ Logs: ${logFile}`
67234
68167
  }
67235
68168
  } catch {
67236
68169
  }
67237
- await new Promise((resolve7) => setTimeout(resolve7, 500));
68170
+ await new Promise((resolve8) => setTimeout(resolve8, 500));
67238
68171
  }
67239
68172
  if (!started) {
67240
68173
  try {
@@ -67311,7 +68244,7 @@ var init_web = __esm({
67311
68244
  }
67312
68245
  for (let i = 0; i < 60; i++) {
67313
68246
  if (!isProcessRunning(status.pid)) break;
67314
- await new Promise((resolve7) => setTimeout(resolve7, 500));
68247
+ await new Promise((resolve8) => setTimeout(resolve8, 500));
67315
68248
  }
67316
68249
  if (isProcessRunning(status.pid)) {
67317
68250
  try {
@@ -67363,7 +68296,7 @@ var init_web = __esm({
67363
68296
  }
67364
68297
  for (let i = 0; i < 60; i++) {
67365
68298
  if (!isProcessRunning(status.pid)) break;
67366
- await new Promise((resolve7) => setTimeout(resolve7, 500));
68299
+ await new Promise((resolve8) => setTimeout(resolve8, 500));
67367
68300
  }
67368
68301
  if (isProcessRunning(status.pid)) {
67369
68302
  try {
@@ -67459,14 +68392,14 @@ __export(worktree_exports, {
67459
68392
  worktreeCommand: () => worktreeCommand
67460
68393
  });
67461
68394
  import readline4 from "node:readline";
67462
- import { getProjectRoot as getProjectRoot52, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
68395
+ import { getProjectRoot as getProjectRoot53, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
67463
68396
  async function promptYesNo2(question) {
67464
- return new Promise((resolve7) => {
68397
+ return new Promise((resolve8) => {
67465
68398
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
67466
68399
  rl.question(`${question} [y/N]: `, (answer) => {
67467
68400
  rl.close();
67468
68401
  const trimmed = answer.trim().toLowerCase();
67469
- resolve7(trimmed === "y" || trimmed === "yes");
68402
+ resolve8(trimmed === "y" || trimmed === "yes");
67470
68403
  });
67471
68404
  });
67472
68405
  }
@@ -67564,7 +68497,7 @@ var init_worktree3 = __esm({
67564
68497
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
67565
68498
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
67566
68499
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
67567
- const projectRoot = getProjectRoot52();
68500
+ const projectRoot = getProjectRoot53();
67568
68501
  const listResult = await listWorktrees2({
67569
68502
  projectRoot,
67570
68503
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -67799,8 +68732,8 @@ var init_worktree3 = __esm({
67799
68732
  init_dist();
67800
68733
  init_field_context();
67801
68734
  init_format_context();
67802
- import { readFileSync as readFileSync17 } from "node:fs";
67803
- import { dirname as dirname9, join as join33 } from "node:path";
68735
+ import { readFileSync as readFileSync20 } from "node:fs";
68736
+ import { dirname as dirname11, join as join36 } from "node:path";
67804
68737
  import { fileURLToPath as fileURLToPath7 } from "node:url";
67805
68738
 
67806
68739
  // packages/cleo/src/cli/generated/command-manifest.ts
@@ -68597,6 +69530,12 @@ var COMMAND_MANIFEST = [
68597
69530
  description: "Manage anonymous skills-usage telemetry (enable/disable/status)",
68598
69531
  load: async () => (await Promise.resolve().then(() => (init_telemetry2(), telemetry_exports))).telemetryCommand
68599
69532
  },
69533
+ {
69534
+ exportName: "templatesCommand",
69535
+ name: "templates",
69536
+ description: "TemplateManifest SSoT registry surface (list, show, install, upgrade, diff, validate)",
69537
+ load: async () => (await Promise.resolve().then(() => (init_templates2(), templates_exports))).templatesCommand
69538
+ },
68600
69539
  {
68601
69540
  exportName: "testingCommand",
68602
69541
  name: "testing",
@@ -68625,7 +69564,7 @@ var COMMAND_MANIFEST = [
68625
69564
  exportName: "upgradeCommand",
68626
69565
  name: "upgrade",
68627
69566
  description: "Unified project maintenance (storage migration, schema repair, structural fixes, doc refresh)",
68628
- load: async () => (await Promise.resolve().then(() => (init_upgrade2(), upgrade_exports))).upgradeCommand
69567
+ load: async () => (await Promise.resolve().then(() => (init_upgrade3(), upgrade_exports))).upgradeCommand
68629
69568
  },
68630
69569
  {
68631
69570
  exportName: "verifyCommand",
@@ -68808,14 +69747,14 @@ function lazyCommand(meta, loader2) {
68808
69747
  init_did_you_mean();
68809
69748
 
68810
69749
  // packages/cleo/src/cli/lib/first-run-detection.ts
68811
- import { existsSync as existsSync16 } from "node:fs";
68812
- import { join as join32 } from "node:path";
69750
+ import { existsSync as existsSync18 } from "node:fs";
69751
+ import { join as join35 } from "node:path";
68813
69752
  async function detectFirstRun() {
68814
69753
  const envKey = process.env["ANTHROPIC_API_KEY"];
68815
69754
  if (typeof envKey === "string" && envKey.length > 0) return false;
68816
69755
  const { getCleoPlatformPaths } = await import("@cleocode/paths");
68817
- const configPath = join32(getCleoPlatformPaths().config, "config.json");
68818
- if (existsSync16(configPath)) return false;
69756
+ const configPath = join35(getCleoPlatformPaths().config, "config.json");
69757
+ if (existsSync18(configPath)) return false;
68819
69758
  try {
68820
69759
  const { getCredentialPool } = await import("@cleocode/core/llm/credential-pool.js");
68821
69760
  const pool = getCredentialPool();
@@ -68826,7 +69765,7 @@ async function detectFirstRun() {
68826
69765
  return true;
68827
69766
  }
68828
69767
  function waitForEnterOrTimeout(timeoutMs) {
68829
- return new Promise((resolve7) => {
69768
+ return new Promise((resolve8) => {
68830
69769
  let resolved = false;
68831
69770
  const finish = () => {
68832
69771
  if (resolved) return;
@@ -68838,7 +69777,7 @@ function waitForEnterOrTimeout(timeoutMs) {
68838
69777
  process.stdin.pause();
68839
69778
  } catch {
68840
69779
  }
68841
- resolve7();
69780
+ resolve8();
68842
69781
  };
68843
69782
  const onData = (chunk) => {
68844
69783
  const s = typeof chunk === "string" ? chunk : chunk.toString("utf8");
@@ -68929,8 +69868,8 @@ Or via NodeSource: https://github.com/nodesource/distributions
68929
69868
  }
68930
69869
  }
68931
69870
  function getPackageVersion() {
68932
- const pkgPath = join33(dirname9(fileURLToPath7(import.meta.url)), "../../package.json");
68933
- const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
69871
+ const pkgPath = join36(dirname11(fileURLToPath7(import.meta.url)), "../../package.json");
69872
+ const pkg = JSON.parse(readFileSync20(pkgPath, "utf-8"));
68934
69873
  return pkg.version;
68935
69874
  }
68936
69875
  var CLI_VERSION = getPackageVersion();
@@ -69082,7 +70021,7 @@ async function runStartupMaintenance() {
69082
70021
  detectAndRemoveStrayProjectNexus,
69083
70022
  getGlobalSalt,
69084
70023
  getLogger: getLogger21,
69085
- getProjectRoot: getProjectRoot53,
70024
+ getProjectRoot: getProjectRoot54,
69086
70025
  isCleanupMarkerSet,
69087
70026
  migrateSignaldockToConduit,
69088
70027
  needsSignaldockToConduitMigration,
@@ -69091,7 +70030,7 @@ async function runStartupMaintenance() {
69091
70030
  } = await import("@cleocode/core/internal");
69092
70031
  let projectRootForCleanup = "";
69093
70032
  try {
69094
- projectRootForCleanup = getProjectRoot53();
70033
+ projectRootForCleanup = getProjectRoot54();
69095
70034
  } catch {
69096
70035
  }
69097
70036
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -69111,7 +70050,7 @@ async function runStartupMaintenance() {
69111
70050
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
69112
70051
  if (!isInitInvocation) {
69113
70052
  try {
69114
- const _projectRootForMigration = getProjectRoot53();
70053
+ const _projectRootForMigration = getProjectRoot54();
69115
70054
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
69116
70055
  const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
69117
70056
  if (migrationResult.status === "failed") {