@cleocode/cleo 2026.5.120 → 2026.5.121

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
@@ -1730,7 +1730,7 @@ var init_branch_lock = __esm({
1730
1730
 
1731
1731
  // packages/contracts/src/changesets.ts
1732
1732
  import { z as z3 } from "zod";
1733
- var CHANGESET_KINDS, TASK_ID_RE, ChangesetEntrySchema;
1733
+ var CHANGESET_KINDS, CHANGESET_RELEASE_NOTE_SECTIONS, CHANGESET_RELEASE_NOTE_AUDIENCES, CHANGESET_RELEASE_NOTE_SCOPES, nonEmptyReleaseNoteText, nonEmptyReleaseNoteList, ChangesetReleaseNotesMetadataSchema, TASK_ID_RE, ChangesetEntrySchema;
1734
1734
  var init_changesets = __esm({
1735
1735
  "packages/contracts/src/changesets.ts"() {
1736
1736
  "use strict";
@@ -1744,10 +1744,60 @@ var init_changesets = __esm({
1744
1744
  "chore",
1745
1745
  "breaking"
1746
1746
  ];
1747
+ CHANGESET_RELEASE_NOTE_SECTIONS = [
1748
+ "added",
1749
+ "changed",
1750
+ "fixed",
1751
+ "deprecated",
1752
+ "removed",
1753
+ "security",
1754
+ "breaking"
1755
+ ];
1756
+ CHANGESET_RELEASE_NOTE_AUDIENCES = [
1757
+ "users",
1758
+ "operators",
1759
+ "developers",
1760
+ "maintainers"
1761
+ ];
1762
+ CHANGESET_RELEASE_NOTE_SCOPES = [
1763
+ "project",
1764
+ "package",
1765
+ "component",
1766
+ "docs",
1767
+ "ops",
1768
+ "security"
1769
+ ];
1770
+ nonEmptyReleaseNoteText = z3.string().min(1, "release-note metadata text must be non-empty");
1771
+ nonEmptyReleaseNoteList = z3.array(nonEmptyReleaseNoteText).min(1, "release-note metadata list must contain at least one item");
1772
+ ChangesetReleaseNotesMetadataSchema = z3.object({
1773
+ /** Keep-a-Changelog style section/category override. */
1774
+ section: z3.enum(CHANGESET_RELEASE_NOTE_SECTIONS).optional(),
1775
+ /** Intended readers for the note. */
1776
+ audience: z3.array(z3.enum(CHANGESET_RELEASE_NOTE_AUDIENCES)).min(1).optional(),
1777
+ /** Release-note scope. */
1778
+ scope: z3.enum(CHANGESET_RELEASE_NOTE_SCOPES).optional(),
1779
+ /** Package/project/component targets affected by this entry. */
1780
+ targets: nonEmptyReleaseNoteList.optional(),
1781
+ /** User- or operator-visible impact statement. */
1782
+ impact: nonEmptyReleaseNoteText.optional(),
1783
+ /** Deterministic migration/action text, separate from breaking changes. */
1784
+ migration: nonEmptyReleaseNoteText.optional(),
1785
+ /** Deprecation detail for Deprecated sections. */
1786
+ deprecation: nonEmptyReleaseNoteText.optional(),
1787
+ /** Security detail for Security sections. */
1788
+ security: nonEmptyReleaseNoteText.optional(),
1789
+ /** Operator-facing rollout/verification note. */
1790
+ operatorNotes: nonEmptyReleaseNoteText.optional(),
1791
+ /** Explicit inclusion toggle for future release-scope filters. */
1792
+ includeInChangelog: z3.boolean().optional()
1793
+ }).strict();
1747
1794
  TASK_ID_RE = /^(T\d+(-[A-Z][A-Za-z0-9]*)?|E-\d+(-[A-Z][A-Za-z0-9]*)?)$/;
1748
1795
  ChangesetEntrySchema = z3.object({
1749
- /** Filename slug (without the `.md` extension). */
1750
- id: z3.string().min(1, "id must be non-empty").regex(/^[a-z0-9][a-z0-9-]*$/, "id must be kebab-case (lowercase, digits, hyphens)"),
1796
+ /** Filename identifier (without the `.md` extension); lowercase kebab-case for new files, legacy uppercase task IDs accepted. */
1797
+ id: z3.string().min(1, "id must be non-empty").regex(
1798
+ /^[A-Za-z0-9][A-Za-z0-9-]*$/,
1799
+ "id must contain only ASCII letters, digits, and hyphens"
1800
+ ),
1751
1801
  /** One or more CLEO task IDs this change is anchored to. */
1752
1802
  tasks: z3.array(z3.string().regex(TASK_ID_RE, "task ID must match T#### or E-#### format")).min(1, "tasks must contain at least one task ID"),
1753
1803
  /** Type of change. */
@@ -1759,7 +1809,9 @@ var init_changesets = __esm({
1759
1809
  /** Markdown body — longer-form explanation. */
1760
1810
  notes: z3.string().optional(),
1761
1811
  /** Migration note. Required iff `kind === 'breaking'`. */
1762
- breaking: z3.string().optional()
1812
+ breaking: z3.string().optional(),
1813
+ /** Structured author-provided metadata for deterministic release notes. */
1814
+ releaseNotes: ChangesetReleaseNotesMetadataSchema.optional()
1763
1815
  }).refine((entry) => entry.kind !== "breaking" || (entry.breaking?.length ?? 0) > 0, {
1764
1816
  message: "breaking entries must include a non-empty `breaking` migration note",
1765
1817
  path: ["breaking"]
@@ -9367,6 +9419,35 @@ var init_operations_registry = __esm({
9367
9419
  }
9368
9420
  ]
9369
9421
  },
9422
+ // release query: validate-changelog (T9937 / Saga T9862 — canonical CHANGELOG
9423
+ // header validator that replaces the brittle inline grep step in
9424
+ // .github/workflows/release.yml). Read-only — exposed only under the query
9425
+ // gateway because no DB or filesystem mutation occurs.
9426
+ {
9427
+ gateway: "query",
9428
+ domain: "release",
9429
+ operation: "validate-changelog",
9430
+ description: "release.validate-changelog (query) \u2014 validate that CHANGELOG.md contains the canonical `## [VERSION]` header per ADR-028 \xA72.5. Replaces the brittle inline grep in .github/workflows/release.yml (T9937 / Saga T9862).",
9431
+ tier: 1,
9432
+ idempotent: true,
9433
+ sessionRequired: false,
9434
+ requiredParams: ["version"],
9435
+ params: [
9436
+ {
9437
+ name: "version",
9438
+ type: "string",
9439
+ required: true,
9440
+ description: "Release version (accepts v2026.5.94 or 2026.5.94)",
9441
+ cli: { positional: true }
9442
+ },
9443
+ {
9444
+ name: "changelogPath",
9445
+ type: "string",
9446
+ required: false,
9447
+ description: "Override the CHANGELOG file path (default: <projectRoot>/CHANGELOG.md)"
9448
+ }
9449
+ ]
9450
+ },
9370
9451
  // ---------------------------------------------------------------------------
9371
9452
  // Provenance domain — `cleo provenance` CLI surface (T9528 · Phase 2 of T9493)
9372
9453
  // ---------------------------------------------------------------------------
@@ -10546,7 +10627,7 @@ var init_errors = __esm({
10546
10627
 
10547
10628
  // packages/contracts/src/evidence-atom-schema.ts
10548
10629
  import { z as z6 } from "zod";
10549
- var commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS;
10630
+ var commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS, ATOM_EXAMPLES;
10550
10631
  var init_evidence_atom_schema = __esm({
10551
10632
  "packages/contracts/src/evidence-atom-schema.ts"() {
10552
10633
  "use strict";
@@ -10621,6 +10702,18 @@ var init_evidence_atom_schema = __esm({
10621
10702
  cleanupDone: { oneOf: [["note"]] },
10622
10703
  nexusImpact: { oneOf: [["tool"], ["note"]] }
10623
10704
  });
10705
+ ATOM_EXAMPLES = Object.freeze({
10706
+ commit: "commit:<sha>",
10707
+ files: "files:path/a.ts,path/b.ts",
10708
+ "test-run": "test-run:/tmp/vitest-out.json",
10709
+ tool: "tool:test",
10710
+ url: "url:https://example.com/docs",
10711
+ note: "note:<short description>",
10712
+ decision: "decision:D-arch-001",
10713
+ pr: "pr:357",
10714
+ "loc-drop": "loc-drop:<fromLines>:<toLines>",
10715
+ "callsite-coverage": "callsite-coverage:<symbolName>:<relativeSourcePath>"
10716
+ });
10624
10717
  }
10625
10718
  });
10626
10719
 
@@ -13807,6 +13900,7 @@ __export(engine_exports, {
13807
13900
  taskWorkHistory: () => taskWorkHistory,
13808
13901
  tasksAddBatchOp: () => tasksAddBatchOp,
13809
13902
  validateBatchValidate: () => coreBatchValidate,
13903
+ validateChangelog: () => validateChangelog,
13810
13904
  validateCoherenceCheck: () => coreCoherenceCheck,
13811
13905
  validateComplianceRecord: () => coreComplianceRecord,
13812
13906
  validateComplianceSummary: () => coreComplianceSummary,
@@ -14032,6 +14126,7 @@ import {
14032
14126
  taskUnclaim,
14033
14127
  taskUpdate,
14034
14128
  taskWorkHistory,
14129
+ validateChangelog,
14035
14130
  validateGateVerify,
14036
14131
  validateProtocolArchitectureDecision,
14037
14132
  validateProtocolArtifactPublish,
@@ -27401,16 +27496,16 @@ async function orchestrateRejectOp(params) {
27401
27496
  async function orchestrateClassify(request, context, projectRoot) {
27402
27497
  try {
27403
27498
  const { getCleoCantWorkflowsDir } = await import("@cleocode/core/internal");
27404
- const { readFileSync: readFileSync21, readdirSync: readdirSync3, existsSync: existsSync19 } = await import("node:fs");
27405
- const { join: join37 } = await import("node:path");
27499
+ const { readFileSync: readFileSync21, readdirSync: readdirSync3, existsSync: existsSync20 } = await import("node:fs");
27500
+ const { join: join38 } = await import("node:path");
27406
27501
  const workflowsDir = getCleoCantWorkflowsDir();
27407
27502
  const combined = `${request} ${context ?? ""}`.toLowerCase();
27408
27503
  const matches = [];
27409
- if (existsSync19(workflowsDir)) {
27504
+ if (existsSync20(workflowsDir)) {
27410
27505
  const files = readdirSync3(workflowsDir).filter((f) => f.endsWith(".cant"));
27411
27506
  for (const file of files) {
27412
27507
  try {
27413
- const src = readFileSync21(join37(workflowsDir, file), "utf-8");
27508
+ const src = readFileSync21(join38(workflowsDir, file), "utf-8");
27414
27509
  const teamMatch = /^team\s+(\S+):/m.exec(src);
27415
27510
  if (!teamMatch) continue;
27416
27511
  const teamName = teamMatch[1];
@@ -27425,12 +27520,12 @@ async function orchestrateClassify(request, context, projectRoot) {
27425
27520
  }
27426
27521
  }
27427
27522
  }
27428
- const localCantDir = join37(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
27429
- if (existsSync19(localCantDir)) {
27523
+ const localCantDir = join38(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
27524
+ if (existsSync20(localCantDir)) {
27430
27525
  const files = readdirSync3(localCantDir).filter((f) => f.endsWith(".cant"));
27431
27526
  for (const file of files) {
27432
27527
  try {
27433
- const src = readFileSync21(join37(localCantDir, file), "utf-8");
27528
+ const src = readFileSync21(join38(localCantDir, file), "utf-8");
27434
27529
  const teamMatch = /^team\s+(\S+):/m.exec(src);
27435
27530
  if (!teamMatch) continue;
27436
27531
  const teamName = teamMatch[1];
@@ -27622,11 +27717,11 @@ async function orchestrateAnalyzeParallelSafety(taskIds, projectRoot) {
27622
27717
  };
27623
27718
  }
27624
27719
  }
27625
- async function handleWorktreeComplete(taskId, projectRoot, resolve8) {
27720
+ async function handleWorktreeComplete(taskId, projectRoot, resolve9) {
27626
27721
  try {
27627
27722
  const { completeWorktreeForTask } = await import("@cleocode/core/internal");
27628
27723
  const result = completeWorktreeForTask(taskId, projectRoot, {
27629
- resolve: resolve8 ?? "auto"
27724
+ resolve: resolve9 ?? "auto"
27630
27725
  });
27631
27726
  if (result.outcome === "conflict") {
27632
27727
  return {
@@ -28306,10 +28401,10 @@ var init_orchestrate2 = __esm({
28306
28401
  startTime
28307
28402
  );
28308
28403
  const rawResolve = params.resolve;
28309
- const resolve8 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
28404
+ const resolve9 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
28310
28405
  const p = {
28311
28406
  taskId: params.taskId,
28312
- ...resolve8 !== void 0 ? { resolve: resolve8 } : {}
28407
+ ...resolve9 !== void 0 ? { resolve: resolve9 } : {}
28313
28408
  };
28314
28409
  return wrapResult(
28315
28410
  await coreOps2["worktree.complete"](p),
@@ -29450,6 +29545,65 @@ var init_release2 = __esm({
29450
29545
  startTime
29451
29546
  );
29452
29547
  }
29548
+ // release.validate-changelog — canonical CHANGELOG.md header validator
29549
+ // (T9937 / Saga T9862). Replaces the brittle `grep -qF "## [VERSION]"`
29550
+ // step in .github/workflows/release.yml. Read-only.
29551
+ //
29552
+ // The core verb returns a plain `ValidateChangelogResult` envelope
29553
+ // (NOT an EngineResult discriminated union) so direct SDK consumers
29554
+ // can branch on `result.valid`. At the dispatch boundary we translate
29555
+ // `valid=false` into `E_CHANGELOG_MISSING_SECTION` so the CLI emits a
29556
+ // non-zero exit code — exactly the behaviour CI workflows depend on
29557
+ // (the legacy `grep -qF "## [VERSION]" || exit 1` had the same
29558
+ // contract).
29559
+ case "validate-changelog": {
29560
+ const version = typeof params?.version === "string" ? params.version : void 0;
29561
+ if (!version)
29562
+ return errorResult(
29563
+ "query",
29564
+ "release",
29565
+ operation,
29566
+ "E_INVALID_INPUT",
29567
+ "version is required",
29568
+ startTime
29569
+ );
29570
+ const typed = {
29571
+ version,
29572
+ projectRoot: getProjectRoot14(),
29573
+ ...typeof params?.changelogPath === "string" ? { changelogPath: params.changelogPath } : {}
29574
+ };
29575
+ const validation = await validateChangelog(typed);
29576
+ if (validation.valid) {
29577
+ return wrapResult(
29578
+ { success: true, data: validation },
29579
+ "query",
29580
+ "release",
29581
+ operation,
29582
+ startTime
29583
+ );
29584
+ }
29585
+ return wrapResult(
29586
+ {
29587
+ success: false,
29588
+ error: {
29589
+ code: "E_CHANGELOG_MISSING_SECTION",
29590
+ message: validation.reason ?? `CHANGELOG.md missing canonical header for v${validation.normalizedVersion}`,
29591
+ details: {
29592
+ version: validation.version,
29593
+ normalizedVersion: validation.normalizedVersion,
29594
+ changelogPath: validation.changelogPath,
29595
+ headerFound: validation.headerFound
29596
+ },
29597
+ fix: `Run \`cleo release plan v${validation.normalizedVersion}\` locally to write the section, then re-push.`,
29598
+ exitCode: 1
29599
+ }
29600
+ },
29601
+ "query",
29602
+ "release",
29603
+ operation,
29604
+ startTime
29605
+ );
29606
+ }
29453
29607
  default:
29454
29608
  return unsupportedOp("query", "release", operation, startTime);
29455
29609
  }
@@ -29617,7 +29771,7 @@ var init_release2 = __esm({
29617
29771
  /** Return declared operations for introspection and registry validation. */
29618
29772
  getSupportedOperations() {
29619
29773
  return {
29620
- query: ["gate", "ivtr-suggest"],
29774
+ query: ["gate", "ivtr-suggest", "validate-changelog"],
29621
29775
  mutate: ["gate", "ivtr-suggest", "reconcile", "plan", "open"]
29622
29776
  };
29623
29777
  }
@@ -30769,7 +30923,13 @@ var init_tasks2 = __esm({
30769
30923
  // T944/T9072: kind filter
30770
30924
  kind: params.kind,
30771
30925
  // T9905: unified urgency surface
30772
- urgent: params.urgent
30926
+ urgent: params.urgent,
30927
+ // T9904: label filter — `cleo find --label <name>` (closes GH#393).
30928
+ label: params.label,
30929
+ // T10108: parent filter — `cleo find --parent <id>`. Saga-aware via
30930
+ // resolveSagaMemberIds (ADR-073 §1) so saga members surface through
30931
+ // the same routing as `cleo list --parent`.
30932
+ parent: params.parent
30773
30933
  }),
30774
30934
  "find"
30775
30935
  );
@@ -33500,7 +33660,7 @@ function wrapParseError(rawInput, parseErr, sourceLabel) {
33500
33660
  return new Error(`Invalid JSON in ${sourceLabel}: ${parseErr.message} (got: ${snippet2})`);
33501
33661
  }
33502
33662
  function readStdinJson(stdin2) {
33503
- return new Promise((resolve8, reject) => {
33663
+ return new Promise((resolve9, reject) => {
33504
33664
  const chunks = [];
33505
33665
  stdin2.on("data", (chunk) => {
33506
33666
  chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
@@ -33511,7 +33671,7 @@ function readStdinJson(stdin2) {
33511
33671
  stdin2.on("end", () => {
33512
33672
  const raw = Buffer.concat(chunks).toString("utf8");
33513
33673
  try {
33514
- resolve8(JSON.parse(raw));
33674
+ resolve9(JSON.parse(raw));
33515
33675
  } catch (err) {
33516
33676
  reject(wrapParseError(raw, err, "stdin"));
33517
33677
  }
@@ -34740,12 +34900,12 @@ var init_agent = __esm({
34740
34900
  transportConfig: {},
34741
34901
  isActive: true
34742
34902
  });
34743
- const { existsSync: existsSync19, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
34744
- const { join: join37 } = await import("node:path");
34745
- const cantDir = join37(CLEO_DIR_NAME, AGENTS_SUBDIR);
34746
- const cantPath = join37(cantDir, `${agentId}.cant`);
34903
+ const { existsSync: existsSync20, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
34904
+ const { join: join38 } = await import("node:path");
34905
+ const cantDir = join38(CLEO_DIR_NAME, AGENTS_SUBDIR);
34906
+ const cantPath = join38(cantDir, `${agentId}.cant`);
34747
34907
  let cantScaffolded = false;
34748
- if (!existsSync19(cantPath)) {
34908
+ if (!existsSync20(cantPath)) {
34749
34909
  mkdirSync7(cantDir, { recursive: true });
34750
34910
  const role = classification ?? "specialist";
34751
34911
  const cantContent = `---
@@ -34805,7 +34965,7 @@ agent ${agentId}:
34805
34965
  data: {
34806
34966
  agentId: credential.agentId,
34807
34967
  displayName: credential.displayName,
34808
- cantFile: cantScaffolded ? cantPath : existsSync19(cantPath) ? cantPath : null,
34968
+ cantFile: cantScaffolded ? cantPath : existsSync20(cantPath) ? cantPath : null,
34809
34969
  cantScaffolded
34810
34970
  }
34811
34971
  },
@@ -34924,8 +35084,8 @@ agent ${agentId}:
34924
35084
  try {
34925
35085
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
34926
35086
  const { createRuntime } = await import("@cleocode/runtime");
34927
- const { existsSync: existsSync19, readFileSync: readFileSync21 } = await import("node:fs");
34928
- const { join: join37 } = await import("node:path");
35087
+ const { existsSync: existsSync20, readFileSync: readFileSync21 } = await import("node:fs");
35088
+ const { join: join38 } = await import("node:path");
34929
35089
  await openCleoDb("tasks");
34930
35090
  const registry = new AgentRegistryAccessor(getProjectRoot24());
34931
35091
  const credential = await registry.get(args.agentId);
@@ -34945,8 +35105,8 @@ agent ${agentId}:
34945
35105
  }
34946
35106
  let profile = null;
34947
35107
  let cantValidation = null;
34948
- const cantPath = args.cant ?? join37(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34949
- if (existsSync19(cantPath)) {
35108
+ const cantPath = args.cant ?? join38(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
35109
+ if (existsSync20(cantPath)) {
34950
35110
  profile = readFileSync21(cantPath, "utf-8");
34951
35111
  try {
34952
35112
  const cantModule = await import("@cleocode/cant");
@@ -35470,8 +35630,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35470
35630
  try {
35471
35631
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
35472
35632
  const { createRuntime } = await import("@cleocode/runtime");
35473
- const { existsSync: existsSync19 } = await import("node:fs");
35474
- const { join: join37 } = await import("node:path");
35633
+ const { existsSync: existsSync20 } = await import("node:fs");
35634
+ const { join: join38 } = await import("node:path");
35475
35635
  await openCleoDb("tasks");
35476
35636
  const registry = new AgentRegistryAccessor(getProjectRoot24());
35477
35637
  const credential = await registry.get(args.agentId);
@@ -35488,8 +35648,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35488
35648
  }
35489
35649
  await registry.update(args.agentId, { isActive: true });
35490
35650
  await registry.markUsed(args.agentId);
35491
- const cantPath = join37(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
35492
- const hasProfile = existsSync19(cantPath);
35651
+ const cantPath = join38(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
35652
+ const hasProfile = existsSync20(cantPath);
35493
35653
  const runtime = await createRuntime(registry, {
35494
35654
  agentId: args.agentId,
35495
35655
  pollIntervalMs: 5e3,
@@ -36285,10 +36445,10 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36285
36445
  async run({ args }) {
36286
36446
  let tempDir = null;
36287
36447
  try {
36288
- const { existsSync: existsSync19 } = await import("node:fs");
36289
- const { basename, resolve: resolve8 } = await import("node:path");
36290
- const resolvedPath = resolve8(args.path);
36291
- if (!existsSync19(resolvedPath)) {
36448
+ const { existsSync: existsSync20 } = await import("node:fs");
36449
+ const { basename, resolve: resolve9 } = await import("node:path");
36450
+ const resolvedPath = resolve9(args.path);
36451
+ if (!existsSync20(resolvedPath)) {
36292
36452
  cliOutput(
36293
36453
  {
36294
36454
  success: false,
@@ -36413,11 +36573,11 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36413
36573
  },
36414
36574
  async run({ args }) {
36415
36575
  try {
36416
- const { existsSync: existsSync19, statSync } = await import("node:fs");
36417
- const { resolve: resolve8, basename, dirname: dirname12 } = await import("node:path");
36576
+ const { existsSync: existsSync20, statSync } = await import("node:fs");
36577
+ const { resolve: resolve9, basename, dirname: dirname12 } = await import("node:path");
36418
36578
  const { execFileSync: execFileSync5 } = await import("node:child_process");
36419
- const resolvedDir = resolve8(args.dir);
36420
- if (!existsSync19(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
36579
+ const resolvedDir = resolve9(args.dir);
36580
+ if (!existsSync20(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
36421
36581
  cliOutput(
36422
36582
  {
36423
36583
  success: false,
@@ -36431,9 +36591,9 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36431
36591
  process.exitCode = 4;
36432
36592
  return;
36433
36593
  }
36434
- const { join: join37 } = await import("node:path");
36435
- const personaPath = join37(resolvedDir, "persona.cant");
36436
- if (!existsSync19(personaPath)) {
36594
+ const { join: join38 } = await import("node:path");
36595
+ const personaPath = join38(resolvedDir, "persona.cant");
36596
+ if (!existsSync20(personaPath)) {
36437
36597
  cliOutput(
36438
36598
  {
36439
36599
  success: false,
@@ -36449,7 +36609,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36449
36609
  }
36450
36610
  const agentName = basename(resolvedDir);
36451
36611
  const archiveName = `${agentName}.cantz`;
36452
- const archivePath = resolve8(archiveName);
36612
+ const archivePath = resolve9(archiveName);
36453
36613
  const parentDir = dirname12(resolvedDir);
36454
36614
  try {
36455
36615
  execFileSync5("zip", ["-r", archivePath, agentName], {
@@ -36480,7 +36640,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36480
36640
  if (entry.isFile()) {
36481
36641
  fileCount++;
36482
36642
  } else if (entry.isDirectory()) {
36483
- countFiles(join37(dirPath, entry.name));
36643
+ countFiles(join38(dirPath, entry.name));
36484
36644
  }
36485
36645
  }
36486
36646
  };
@@ -36728,17 +36888,17 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
36728
36888
  },
36729
36889
  async run({ args }) {
36730
36890
  try {
36731
- const { existsSync: existsSync19, readFileSync: readFileSync21, mkdirSync: mkdirSync7 } = await import("node:fs");
36732
- const { resolve: resolve8, join: join37 } = await import("node:path");
36733
- const specPath = resolve8(args.spec);
36734
- if (!existsSync19(specPath)) {
36891
+ const { existsSync: existsSync20, readFileSync: readFileSync21, mkdirSync: mkdirSync7 } = await import("node:fs");
36892
+ const { resolve: resolve9, join: join38 } = await import("node:path");
36893
+ const specPath = resolve9(args.spec);
36894
+ if (!existsSync20(specPath)) {
36735
36895
  cliError(`spec file not found: ${specPath}`, 4, { name: "E_NOT_FOUND" });
36736
36896
  process.exitCode = 4;
36737
36897
  return;
36738
36898
  }
36739
36899
  const specContent = readFileSync21(specPath, "utf-8");
36740
36900
  const projectRoot = getProjectRoot24();
36741
- const outputDir = args["output-dir"] ? resolve8(args["output-dir"]) : join37(projectRoot, ".cleo", "cant", "agents");
36901
+ const outputDir = args["output-dir"] ? resolve9(args["output-dir"]) : join38(projectRoot, ".cleo", "cant", "agents");
36742
36902
  mkdirSync7(outputDir, { recursive: true });
36743
36903
  if (args["dry-run"]) {
36744
36904
  cliOutput(
@@ -37489,8 +37649,8 @@ function detectAuthType(provider, token) {
37489
37649
  async function promptYesNo(question) {
37490
37650
  const rl = createInterface({ input: process.stdin, output: process.stderr });
37491
37651
  try {
37492
- const answer = await new Promise((resolve8) => {
37493
- rl.question(question, (a) => resolve8(a));
37652
+ const answer = await new Promise((resolve9) => {
37653
+ rl.question(question, (a) => resolve9(a));
37494
37654
  });
37495
37655
  const clean = answer.trim().toLowerCase();
37496
37656
  return clean === "y" || clean === "yes";
@@ -38426,12 +38586,12 @@ async function promptPassphrase() {
38426
38586
  "Cannot prompt for passphrase: stdin is not a TTY. Set the CLEO_BACKUP_PASSPHRASE environment variable for non-interactive use."
38427
38587
  );
38428
38588
  }
38429
- return new Promise((resolve8) => {
38589
+ return new Promise((resolve9) => {
38430
38590
  process.stdout.write("Passphrase: ");
38431
38591
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
38432
38592
  rl.question("", (answer) => {
38433
38593
  rl.close();
38434
- resolve8(answer.trim());
38594
+ resolve9(answer.trim());
38435
38595
  });
38436
38596
  });
38437
38597
  }
@@ -39541,11 +39701,11 @@ var init_caamp = __esm({
39541
39701
  }
39542
39702
  if (args["dry-run"]) {
39543
39703
  const { parseCaampBlocks } = await import("@cleocode/caamp");
39544
- const { existsSync: existsSync19 } = await import("node:fs");
39704
+ const { existsSync: existsSync20 } = await import("node:fs");
39545
39705
  const { readFile: readFile8 } = await import("node:fs/promises");
39546
39706
  const dryResults = [];
39547
39707
  for (const filePath of filePaths) {
39548
- if (!existsSync19(filePath)) {
39708
+ if (!existsSync20(filePath)) {
39549
39709
  dryResults.push({ filePath, exists: false, blockCount: 0, wouldRemove: 0 });
39550
39710
  continue;
39551
39711
  }
@@ -40600,11 +40760,11 @@ var init_check2 = __esm({
40600
40760
  },
40601
40761
  async run({ args }) {
40602
40762
  const { spawnSync } = await import("node:child_process");
40603
- const { existsSync: existsSync19 } = await import("node:fs");
40604
- const { join: join37, resolve: resolve8 } = await import("node:path");
40763
+ const { existsSync: existsSync20 } = await import("node:fs");
40764
+ const { join: join38, resolve: resolve9 } = await import("node:path");
40605
40765
  const strict = Boolean(args.strict);
40606
40766
  const jsonOnly = Boolean(args.json);
40607
- const repoRoot = resolve8(process.cwd());
40767
+ const repoRoot = resolve9(process.cwd());
40608
40768
  const gates = [
40609
40769
  {
40610
40770
  id: "gate-1",
@@ -40641,8 +40801,8 @@ var init_check2 = __esm({
40641
40801
  const results = [];
40642
40802
  let anyFailed = false;
40643
40803
  for (const gate of gates) {
40644
- const scriptPath = join37(repoRoot, gate.script);
40645
- if (!existsSync19(scriptPath)) {
40804
+ const scriptPath = join38(repoRoot, gate.script);
40805
+ if (!existsSync20(scriptPath)) {
40646
40806
  results.push({
40647
40807
  id: gate.id,
40648
40808
  task: gate.task,
@@ -40957,9 +41117,9 @@ var init_code = __esm({
40957
41117
  async run({ args }) {
40958
41118
  await requireTreeSitter();
40959
41119
  const { smartOutline } = await import("@cleocode/core/internal");
40960
- const { join: join37 } = await import("node:path");
41120
+ const { join: join38 } = await import("node:path");
40961
41121
  const root = process.cwd();
40962
- const absPath = args.file.startsWith("/") ? args.file : join37(root, args.file);
41122
+ const absPath = args.file.startsWith("/") ? args.file : join38(root, args.file);
40963
41123
  const result = smartOutline(absPath, root);
40964
41124
  if (result.errors.length > 0 && result.symbols.length === 0) {
40965
41125
  cliError(result.errors.join(", "), 1, { name: "E_OUTLINE_FAILED" });
@@ -41050,9 +41210,9 @@ var init_code = __esm({
41050
41210
  async run({ args }) {
41051
41211
  await requireTreeSitter();
41052
41212
  const { smartUnfold } = await import("@cleocode/core/internal");
41053
- const { join: join37 } = await import("node:path");
41213
+ const { join: join38 } = await import("node:path");
41054
41214
  const root = process.cwd();
41055
- const absPath = args.file.startsWith("/") ? args.file : join37(root, args.file);
41215
+ const absPath = args.file.startsWith("/") ? args.file : join38(root, args.file);
41056
41216
  const result = smartUnfold(absPath, args.symbol, root);
41057
41217
  if (!result.found) {
41058
41218
  const errs = result.errors.length > 0 ? `: ${result.errors.join(", ")}` : "";
@@ -47343,6 +47503,254 @@ ${this.prefix}: \u2717 ${message}
47343
47503
  }
47344
47504
  });
47345
47505
 
47506
+ // packages/cleo/src/cli/commands/doctor-release-readiness.ts
47507
+ import { existsSync as existsSync13 } from "node:fs";
47508
+ import { join as join22, resolve as resolve6 } from "node:path";
47509
+ async function runCheck(name, cmd, args, cwd) {
47510
+ const { spawnSync } = await import("node:child_process");
47511
+ const start = Date.now();
47512
+ const result = spawnSync(cmd, args, {
47513
+ encoding: "utf8",
47514
+ stdio: ["ignore", "pipe", "pipe"],
47515
+ cwd
47516
+ });
47517
+ const durationMs = Date.now() - start;
47518
+ const passed = result.status === 0;
47519
+ return {
47520
+ name,
47521
+ status: passed ? "pass" : "fail",
47522
+ exitCode: result.status,
47523
+ durationMs,
47524
+ stdout: (result.stdout ?? "").trim(),
47525
+ stderr: (result.stderr ?? "").trim()
47526
+ };
47527
+ }
47528
+ var doctorReleaseReadinessCommand;
47529
+ var init_doctor_release_readiness = __esm({
47530
+ "packages/cleo/src/cli/commands/doctor-release-readiness.ts"() {
47531
+ "use strict";
47532
+ init_define_cli_command();
47533
+ init_renderers();
47534
+ doctorReleaseReadinessCommand = defineCommand({
47535
+ meta: {
47536
+ name: "release-readiness",
47537
+ description: "Pre-flight release readiness check \u2014 lint matrix + changelog + changeset + npm OIDC + tag-trigger sanity (T10458)"
47538
+ },
47539
+ args: {
47540
+ json: { type: "boolean", description: "Output as JSON" },
47541
+ human: { type: "boolean", description: "Force human-readable output" },
47542
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
47543
+ },
47544
+ async run({ args }) {
47545
+ const isHuman = args.human === true || !!process.stdout.isTTY && args.json !== true;
47546
+ const repoRoot = resolve6(process.cwd());
47547
+ const startTotal = Date.now();
47548
+ const checks = [];
47549
+ const biomePath = join22(repoRoot, "node_modules", ".bin", "biome");
47550
+ const biomeAvailable = existsSync13(biomePath);
47551
+ if (biomeAvailable) {
47552
+ checks.push(await runCheck("biome-lint", biomePath, ["ci", "."], repoRoot));
47553
+ } else {
47554
+ checks.push({
47555
+ name: "biome-lint",
47556
+ status: "skip",
47557
+ exitCode: null,
47558
+ durationMs: 0,
47559
+ stdout: "",
47560
+ stderr: "biome not found in node_modules/.bin \u2014 skipping"
47561
+ });
47562
+ }
47563
+ const changesetLintScript = join22(repoRoot, "scripts", "lint-changesets.mjs");
47564
+ if (existsSync13(changesetLintScript)) {
47565
+ checks.push(await runCheck("changeset-lint", "node", [changesetLintScript], repoRoot));
47566
+ } else {
47567
+ checks.push({
47568
+ name: "changeset-lint",
47569
+ status: "skip",
47570
+ exitCode: null,
47571
+ durationMs: 0,
47572
+ stdout: "",
47573
+ stderr: "scripts/lint-changesets.mjs not found \u2014 skipping"
47574
+ });
47575
+ }
47576
+ const changelogPath = join22(repoRoot, "CHANGELOG.md");
47577
+ const changelogExists = existsSync13(changelogPath);
47578
+ const changelogCheck = {
47579
+ name: "changelog-exists",
47580
+ status: changelogExists ? "pass" : "fail",
47581
+ exitCode: changelogExists ? 0 : 1,
47582
+ durationMs: 0,
47583
+ stdout: changelogExists ? `Found ${changelogPath}` : "",
47584
+ stderr: changelogExists ? "" : `CHANGELOG.md not found at ${changelogPath}`
47585
+ };
47586
+ checks.push(changelogCheck);
47587
+ const packageJsonPath = join22(repoRoot, "package.json");
47588
+ let oidcCheck;
47589
+ if (existsSync13(packageJsonPath)) {
47590
+ try {
47591
+ const pkg = JSON.parse(
47592
+ await import("node:fs").then((m) => m.readFileSync(packageJsonPath, "utf8"))
47593
+ );
47594
+ const hasPublishConfig = typeof pkg.publishConfig === "object" && pkg.publishConfig !== null;
47595
+ const accessPublic = hasPublishConfig && pkg.publishConfig.access === "public";
47596
+ oidcCheck = {
47597
+ name: "npm-oidc-sanity",
47598
+ status: accessPublic ? "pass" : "fail",
47599
+ exitCode: accessPublic ? 0 : 1,
47600
+ durationMs: 0,
47601
+ stdout: accessPublic ? "package.json has publishConfig.access=public" : "",
47602
+ stderr: accessPublic ? "" : "package.json missing publishConfig.access=public \u2014 required for npm OIDC Trusted Publishing"
47603
+ };
47604
+ } catch {
47605
+ oidcCheck = {
47606
+ name: "npm-oidc-sanity",
47607
+ status: "fail",
47608
+ exitCode: 1,
47609
+ durationMs: 0,
47610
+ stdout: "",
47611
+ stderr: "Failed to parse package.json"
47612
+ };
47613
+ }
47614
+ } else {
47615
+ oidcCheck = {
47616
+ name: "npm-oidc-sanity",
47617
+ status: "fail",
47618
+ exitCode: 1,
47619
+ durationMs: 0,
47620
+ stdout: "",
47621
+ stderr: "package.json not found"
47622
+ };
47623
+ }
47624
+ checks.push(oidcCheck);
47625
+ const tagWorkflowPath = join22(repoRoot, ".github", "workflows", "auto-tag-on-release-merge.yml");
47626
+ const tagWorkflowExists = existsSync13(tagWorkflowPath);
47627
+ let tagTriggerCheck;
47628
+ if (tagWorkflowExists) {
47629
+ try {
47630
+ const content = await import("node:fs").then(
47631
+ (m) => m.readFileSync(tagWorkflowPath, "utf8")
47632
+ );
47633
+ const hasName = content.includes("name:");
47634
+ const hasOnTrigger = content.includes("on:") || content.includes("pull_request:");
47635
+ const valid = hasName && hasOnTrigger;
47636
+ tagTriggerCheck = {
47637
+ name: "tag-trigger-sanity",
47638
+ status: valid ? "pass" : "fail",
47639
+ exitCode: valid ? 0 : 1,
47640
+ durationMs: 0,
47641
+ stdout: valid ? `Valid workflow at ${tagWorkflowPath}` : "",
47642
+ stderr: valid ? "" : "auto-tag-on-release-merge.yml appears malformed"
47643
+ };
47644
+ } catch {
47645
+ tagTriggerCheck = {
47646
+ name: "tag-trigger-sanity",
47647
+ status: "fail",
47648
+ exitCode: 1,
47649
+ durationMs: 0,
47650
+ stdout: "",
47651
+ stderr: "Failed to read auto-tag-on-release-merge.yml"
47652
+ };
47653
+ }
47654
+ } else {
47655
+ tagTriggerCheck = {
47656
+ name: "tag-trigger-sanity",
47657
+ status: "fail",
47658
+ exitCode: 1,
47659
+ durationMs: 0,
47660
+ stdout: "",
47661
+ stderr: `.github/workflows/auto-tag-on-release-merge.yml not found`
47662
+ };
47663
+ }
47664
+ checks.push(tagTriggerCheck);
47665
+ const tsconfigPath = join22(repoRoot, "tsconfig.json");
47666
+ if (existsSync13(tsconfigPath)) {
47667
+ const tscPath = join22(repoRoot, "node_modules", ".bin", "tsc");
47668
+ if (existsSync13(tscPath)) {
47669
+ checks.push(await runCheck("typecheck", tscPath, ["--noEmit"], repoRoot));
47670
+ } else {
47671
+ checks.push({
47672
+ name: "typecheck",
47673
+ status: "skip",
47674
+ exitCode: null,
47675
+ durationMs: 0,
47676
+ stdout: "",
47677
+ stderr: "tsc not found in node_modules/.bin \u2014 skipping"
47678
+ });
47679
+ }
47680
+ } else {
47681
+ checks.push({
47682
+ name: "typecheck",
47683
+ status: "skip",
47684
+ exitCode: null,
47685
+ durationMs: 0,
47686
+ stdout: "",
47687
+ stderr: "tsconfig.json not found \u2014 skipping"
47688
+ });
47689
+ }
47690
+ const fastLintScripts = [
47691
+ { name: "contracts-dep-lint", script: "scripts/lint-contracts-dep.mjs" },
47692
+ { name: "format-error-lint", script: "scripts/lint-format-error-misuse.mjs" },
47693
+ { name: "json-stream-lint", script: "scripts/lint-json-stream-hygiene.mjs" }
47694
+ ];
47695
+ for (const lint of fastLintScripts) {
47696
+ const scriptPath = join22(repoRoot, lint.script);
47697
+ if (existsSync13(scriptPath)) {
47698
+ checks.push(await runCheck(lint.name, "node", [scriptPath], repoRoot));
47699
+ } else {
47700
+ checks.push({
47701
+ name: lint.name,
47702
+ status: "skip",
47703
+ exitCode: null,
47704
+ durationMs: 0,
47705
+ stdout: "",
47706
+ stderr: `${lint.script} not found \u2014 skipping`
47707
+ });
47708
+ }
47709
+ }
47710
+ const passCount = checks.filter((c) => c.status === "pass").length;
47711
+ const failCount = checks.filter((c) => c.status === "fail").length;
47712
+ const skipCount = checks.filter((c) => c.status === "skip").length;
47713
+ const totalDurationMs = Date.now() - startTotal;
47714
+ const ready = failCount === 0;
47715
+ const result = {
47716
+ ready,
47717
+ checks,
47718
+ summary: {
47719
+ pass: passCount,
47720
+ fail: failCount,
47721
+ skip: skipCount,
47722
+ total: checks.length,
47723
+ durationMs: totalDurationMs
47724
+ }
47725
+ };
47726
+ if (isHuman && args.json !== true) {
47727
+ humanLine("\nRelease Readiness Check (T10458)\n");
47728
+ humanLine(`${"\u2500".repeat(60)}`);
47729
+ for (const c of checks) {
47730
+ const icon = c.status === "pass" ? "PASS" : c.status === "fail" ? "FAIL" : "SKIP";
47731
+ humanLine(` [${icon}] ${c.name} (${c.durationMs}ms)`);
47732
+ if (c.status === "fail" && c.stderr) {
47733
+ const lines = c.stderr.split("\n").slice(0, 3);
47734
+ for (const line of lines) {
47735
+ humanLine(` ${line}`);
47736
+ }
47737
+ }
47738
+ }
47739
+ humanLine(`${"\u2500".repeat(60)}`);
47740
+ humanLine(` Result: ${passCount} passed, ${failCount} failed, ${skipCount} skipped`);
47741
+ humanLine(` Total time: ${totalDurationMs}ms`);
47742
+ humanLine(` Ready: ${ready ? "YES" : "NO"}
47743
+ `);
47744
+ }
47745
+ cliOutput(result, { command: "doctor", operation: "doctor.release-readiness" });
47746
+ if (!ready) {
47747
+ process.exitCode = 1;
47748
+ }
47749
+ }
47750
+ });
47751
+ }
47752
+ });
47753
+
47346
47754
  // packages/cleo/src/cli/commands/migrate-agents-v2.ts
47347
47755
  var migrate_agents_v2_exports = {};
47348
47756
  __export(migrate_agents_v2_exports, {
@@ -47353,8 +47761,8 @@ __export(migrate_agents_v2_exports, {
47353
47761
  walkAgentsDir: () => walkAgentsDir
47354
47762
  });
47355
47763
  import { createHash as createHash2 } from "node:crypto";
47356
- import { appendFileSync as appendFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync13 } from "node:fs";
47357
- import { join as join22 } from "node:path";
47764
+ import { appendFileSync as appendFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync13 } from "node:fs";
47765
+ import { join as join23 } from "node:path";
47358
47766
  import { getProjectRoot as getProjectRoot41, installAgentFromCant } from "@cleocode/core/internal";
47359
47767
  import { openCleoDb as openCleoDb2 } from "@cleocode/core/store/open-cleo-db";
47360
47768
  function sha256Hex(bytes) {
@@ -47374,15 +47782,15 @@ function extractAgentName(source) {
47374
47782
  return headerMatch[1] ?? null;
47375
47783
  }
47376
47784
  function appendAuditLog(projectRoot, entry) {
47377
- const auditPath = join22(projectRoot, AUDIT_LOG_RELATIVE);
47378
- const auditDir = join22(auditPath, "..");
47379
- if (!existsSync13(auditDir)) {
47785
+ const auditPath = join23(projectRoot, AUDIT_LOG_RELATIVE);
47786
+ const auditDir = join23(auditPath, "..");
47787
+ if (!existsSync14(auditDir)) {
47380
47788
  mkdirSync3(auditDir, { recursive: true });
47381
47789
  }
47382
47790
  appendFileSync2(auditPath, JSON.stringify(entry) + "\n", "utf8");
47383
47791
  }
47384
47792
  function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
47385
- if (!existsSync13(scanDir)) return;
47793
+ if (!existsSync14(scanDir)) return;
47386
47794
  let files;
47387
47795
  try {
47388
47796
  files = readdirSync2(scanDir).filter((f) => f.endsWith(".cant"));
@@ -47393,7 +47801,7 @@ function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
47393
47801
  return;
47394
47802
  }
47395
47803
  for (const filename of files) {
47396
- const cantPath = join22(scanDir, filename);
47804
+ const cantPath = join23(scanDir, filename);
47397
47805
  const relPath = cantPath.replace(`${projectRoot}/`, "");
47398
47806
  let sourceBytes;
47399
47807
  let sourceText;
@@ -47490,9 +47898,9 @@ async function runMigrateAgentsV2(projectRoot, verbose = true) {
47490
47898
  const { db: _sdDb } = await openCleoDb2("signaldock");
47491
47899
  const db = _sdDb;
47492
47900
  try {
47493
- const canonicalDir = join22(projectRoot, ".cleo", "cant", "agents");
47901
+ const canonicalDir = join23(projectRoot, ".cleo", "cant", "agents");
47494
47902
  walkAgentsDir(db, canonicalDir, projectRoot, summary, verbose);
47495
- const legacyDir = join22(projectRoot, ".cleo", "agents");
47903
+ const legacyDir = join23(projectRoot, ".cleo", "agents");
47496
47904
  walkAgentsDir(db, legacyDir, projectRoot, summary, verbose);
47497
47905
  } finally {
47498
47906
  db.close();
@@ -47500,8 +47908,8 @@ async function runMigrateAgentsV2(projectRoot, verbose = true) {
47500
47908
  return summary;
47501
47909
  }
47502
47910
  function readMigrationConflicts(projectRoot) {
47503
- const auditPath = join22(projectRoot, AUDIT_LOG_RELATIVE);
47504
- if (!existsSync13(auditPath)) return [];
47911
+ const auditPath = join23(projectRoot, AUDIT_LOG_RELATIVE);
47912
+ if (!existsSync14(auditPath)) return [];
47505
47913
  let raw;
47506
47914
  try {
47507
47915
  raw = readFileSync13(auditPath, "utf8");
@@ -47585,7 +47993,7 @@ __export(doctor_exports, {
47585
47993
  doctorCommand: () => doctorCommand2
47586
47994
  });
47587
47995
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
47588
- import { join as join23 } from "node:path";
47996
+ import { join as join24 } from "node:path";
47589
47997
  import { getProjectRoot as getProjectRoot42, pushWarning as pushWarning4 } from "@cleocode/core";
47590
47998
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
47591
47999
  import {
@@ -47625,8 +48033,8 @@ async function scanTestFixturesInProd(projectRoot) {
47625
48033
  }
47626
48034
  async function quarantineTestFixtures(projectRoot, matches) {
47627
48035
  if (matches.length === 0) return 0;
47628
- const cleoDir = join23(projectRoot, ".cleo");
47629
- const quarantineDir = join23(
48036
+ const cleoDir = join24(projectRoot, ".cleo");
48037
+ const quarantineDir = join24(
47630
48038
  cleoDir,
47631
48039
  "quarantine",
47632
48040
  `fixture-scan-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`
@@ -47634,7 +48042,7 @@ async function quarantineTestFixtures(projectRoot, matches) {
47634
48042
  mkdirSync4(quarantineDir, { recursive: true });
47635
48043
  const manifest = matches.map((m) => ({ ...m, quarantinedAt: (/* @__PURE__ */ new Date()).toISOString() }));
47636
48044
  writeFileSync4(
47637
- join23(quarantineDir, "manifest.jsonl"),
48045
+ join24(quarantineDir, "manifest.jsonl"),
47638
48046
  manifest.map((m) => JSON.stringify(m)).join("\n") + "\n"
47639
48047
  );
47640
48048
  const { getNativeDb } = await import("@cleocode/core/store/sqlite.js");
@@ -47705,6 +48113,7 @@ var init_doctor = __esm({
47705
48113
  init_doctor_db_substrate();
47706
48114
  init_doctor_legacy_backups();
47707
48115
  init_doctor_projects();
48116
+ init_doctor_release_readiness();
47708
48117
  init_migrate_agents_v2();
47709
48118
  FIXTURE_ID_PATTERNS = [/^E\d+$/, /^T\d+EP$/];
47710
48119
  FIXTURE_TITLE_KEYWORDS = [
@@ -47719,7 +48128,9 @@ var init_doctor = __esm({
47719
48128
  // T10307 / Saga T10281 / Epic T10282 — DB-substrate walker
47720
48129
  "db-substrate": doctorDbSubstrateCommand,
47721
48130
  // T10309 / Saga T10281 / Epic T10282 — Legacy-backup walker
47722
- "legacy-backups": doctorLegacyBackupsCommand
48131
+ "legacy-backups": doctorLegacyBackupsCommand,
48132
+ // T10458 / Saga T10431 / Epic T10436 — Release-readiness preflight
48133
+ "release-readiness": doctorReleaseReadinessCommand
47723
48134
  },
47724
48135
  args: {
47725
48136
  detailed: {
@@ -48208,8 +48619,8 @@ var init_doctor = __esm({
48208
48619
  );
48209
48620
  return;
48210
48621
  }
48211
- const archiveDir = join23(projectRoot, ".cleo", "backups");
48212
- const auditLogPath = join23(projectRoot, ".cleo", "audit", "worktree-prune.jsonl");
48622
+ const archiveDir = join24(projectRoot, ".cleo", "backups");
48623
+ const auditLogPath = join24(projectRoot, ".cleo", "audit", "worktree-prune.jsonl");
48213
48624
  const result = await pruneWorktreeOrphans(orphans, {
48214
48625
  archiveDir,
48215
48626
  auditLogPath,
@@ -48373,7 +48784,7 @@ __export(event_exports, {
48373
48784
  orchestratorCommand: () => orchestratorCommand
48374
48785
  });
48375
48786
  import { readdir as readdir2 } from "node:fs/promises";
48376
- import { join as join24 } from "node:path";
48787
+ import { join as join25 } from "node:path";
48377
48788
  import { cwd as processCwd } from "node:process";
48378
48789
  import { appendEvent } from "@cleocode/core/events/event-bus.js";
48379
48790
  function resolveProjectRoot3(arg) {
@@ -48496,7 +48907,7 @@ var init_event = __esm({
48496
48907
  const agentIdFilter = args.agent;
48497
48908
  const showAll = args.all === true;
48498
48909
  const lines = parseInt(args.lines ?? "20", 10);
48499
- const eventsDir = join24(projectRoot, ".cleo", "agent-events");
48910
+ const eventsDir = join25(projectRoot, ".cleo", "agent-events");
48500
48911
  try {
48501
48912
  let files = [];
48502
48913
  try {
@@ -48534,7 +48945,7 @@ var init_event = __esm({
48534
48945
  for (const file of filesToTail) {
48535
48946
  const agentId = file.replace(".jsonl", "");
48536
48947
  const { readFileSync: readFileSync21 } = await import("node:fs");
48537
- const content = readFileSync21(join24(eventsDir, file), "utf-8");
48948
+ const content = readFileSync21(join25(eventsDir, file), "utf-8");
48538
48949
  const eventLines = content.trim().split("\n").filter(Boolean);
48539
48950
  const tail = eventLines.slice(-lines);
48540
48951
  if (jsonMode) {
@@ -48604,7 +49015,7 @@ var init_event = __esm({
48604
49015
  const epicFilter = args.epic;
48605
49016
  const follow = args.follow === true;
48606
49017
  const lines = parseInt(args.lines ?? "50", 10);
48607
- const eventsDir = join24(projectRoot, ".cleo", "agent-events");
49018
+ const eventsDir = join25(projectRoot, ".cleo", "agent-events");
48608
49019
  let files = [];
48609
49020
  try {
48610
49021
  const entries = await readdir2(eventsDir);
@@ -48630,7 +49041,7 @@ var init_event = __esm({
48630
49041
  const agentId = file.replace(".jsonl", "");
48631
49042
  try {
48632
49043
  const { readFileSync: readFileSync21 } = await import("node:fs");
48633
- const content = readFileSync21(join24(eventsDir, file), "utf-8");
49044
+ const content = readFileSync21(join25(eventsDir, file), "utf-8");
48634
49045
  const eventLines = content.trim().split("\n").filter(Boolean);
48635
49046
  const tail = eventLines.slice(-lines);
48636
49047
  if (jsonMode) {
@@ -49109,6 +49520,33 @@ var init_find = __esm({
49109
49520
  type: "boolean",
49110
49521
  description: "Surface urgent work across both axes: priority IN (critical,high) OR severity IN (P0,P1) (T9905)",
49111
49522
  alias: "u"
49523
+ },
49524
+ /**
49525
+ * Filter by label — `cleo find --label <name>` returns every task
49526
+ * whose `labels[]` includes the given value. Closes GH#393 and gives
49527
+ * `find` parity with the positional `cleo labels <name>` surface.
49528
+ * @task T9904
49529
+ */
49530
+ label: {
49531
+ type: "string",
49532
+ description: "Filter by label \u2014 return tasks whose labels[] includes this value (T9904)"
49533
+ },
49534
+ /**
49535
+ * Filter by parent task ID — `cleo find --parent <id>` returns only
49536
+ * tasks whose `parentId` matches. Mirrors the `--parent` axis on
49537
+ * `cleo list`. When the parent target is a Saga (Epic with
49538
+ * `label='saga'`), routing goes through `task_relations.type='groups'`
49539
+ * member IDs (ADR-073 §1) — same path as `cleo list --parent`.
49540
+ *
49541
+ * Closes T10108 — pre-fix the flag was missing entirely AND empty-string
49542
+ * queries bypassed every filter via `fuzzyScore('', '<title>')===80`.
49543
+ *
49544
+ * @task T10108
49545
+ * @saga T9862
49546
+ */
49547
+ parent: {
49548
+ type: "string",
49549
+ description: "Filter by parent task ID \u2014 Saga-aware via task_relations groups (ADR-073 \xA71) (T10108)"
49112
49550
  }
49113
49551
  },
49114
49552
  async run({ args }) {
@@ -49127,6 +49565,8 @@ var init_find = __esm({
49127
49565
  if (args.verbose !== void 0) params["verbose"] = args.verbose;
49128
49566
  if (args.kind !== void 0) params["kind"] = args.kind;
49129
49567
  if (args.urgent !== void 0) params["urgent"] = args.urgent;
49568
+ if (args.label !== void 0) params["label"] = args.label;
49569
+ if (args.parent !== void 0) params["parent"] = args.parent;
49130
49570
  const response = await dispatchRaw("query", "tasks", "find", params);
49131
49571
  if (!response.success) {
49132
49572
  handleRawError(response, { command: "find", operation: "tasks.find" });
@@ -49193,7 +49633,7 @@ __export(gc_exports, {
49193
49633
  gcCommand: () => gcCommand
49194
49634
  });
49195
49635
  import { homedir as homedir4, tmpdir } from "node:os";
49196
- import { join as join25 } from "node:path";
49636
+ import { join as join26 } from "node:path";
49197
49637
  import { pruneOrphanTempDirs, pruneOrphanWorktrees } from "@cleocode/core/gc/cleanup.js";
49198
49638
  import { runGC } from "@cleocode/core/gc/runner.js";
49199
49639
  import { readGCState } from "@cleocode/core/gc/state.js";
@@ -49276,7 +49716,7 @@ var init_gc = __esm({
49276
49716
  },
49277
49717
  async run({ args }) {
49278
49718
  const cleoDir = resolveLegacyCleoDir3(args["cleo-dir"]);
49279
- const statePath = join25(cleoDir, "gc-state.json");
49719
+ const statePath = join26(cleoDir, "gc-state.json");
49280
49720
  try {
49281
49721
  const state = await readGCState(statePath);
49282
49722
  const diskStr = state.lastDiskUsedPct !== null ? `${state.lastDiskUsedPct.toFixed(1)}%` : "unknown";
@@ -49329,8 +49769,8 @@ var init_gc = __esm({
49329
49769
  }
49330
49770
  },
49331
49771
  async run({ args }) {
49332
- const xdgData = process.env["XDG_DATA_HOME"] ?? join25(homedir4(), ".local", "share");
49333
- const worktreesRoot = args["worktrees-root"] ?? join25(xdgData, "cleo", "worktrees");
49772
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join26(homedir4(), ".local", "share");
49773
+ const worktreesRoot = args["worktrees-root"] ?? join26(xdgData, "cleo", "worktrees");
49334
49774
  const projectHash = args["project-hash"];
49335
49775
  const dryRun = args["dry-run"];
49336
49776
  const preserveRaw = args["preserve-tasks"];
@@ -50542,8 +50982,8 @@ __export(init_exports, {
50542
50982
  getWorkflowTemplatesDir: () => getWorkflowTemplatesDir2,
50543
50983
  initCommand: () => initCommand2
50544
50984
  });
50545
- import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
50546
- import { join as join26 } from "node:path";
50985
+ import { existsSync as existsSync15, readFileSync as readFileSync14 } from "node:fs";
50986
+ import { join as join27 } from "node:path";
50547
50987
  import { fileURLToPath as fileURLToPath6 } from "node:url";
50548
50988
  import {
50549
50989
  CleoError as CleoError4,
@@ -50556,11 +50996,11 @@ import { getTemplatesByKind } from "@cleocode/core/templates/registry";
50556
50996
  function getGitignoreTemplate() {
50557
50997
  try {
50558
50998
  const thisFile = fileURLToPath6(import.meta.url);
50559
- const packageRoot = join26(thisFile, "..", "..", "..", "..");
50560
- const localTemplatePath = join26(packageRoot, "templates", "cleo-gitignore");
50561
- const monorepoTemplatePath = join26(packageRoot, "..", "..", "templates", "cleo-gitignore");
50562
- const templatePath = existsSync14(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
50563
- if (existsSync14(templatePath)) {
50999
+ const packageRoot = join27(thisFile, "..", "..", "..", "..");
51000
+ const localTemplatePath = join27(packageRoot, "templates", "cleo-gitignore");
51001
+ const monorepoTemplatePath = join27(packageRoot, "..", "..", "templates", "cleo-gitignore");
51002
+ const templatePath = existsSync15(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
51003
+ if (existsSync15(templatePath)) {
50564
51004
  return readFileSync14(templatePath, "utf-8");
50565
51005
  }
50566
51006
  } catch {
@@ -51172,7 +51612,17 @@ var init_labels = __esm({
51172
51612
  labelsCommand = defineCommand({
51173
51613
  meta: {
51174
51614
  name: "labels",
51175
- description: "List all labels with counts or show tasks with specific label"
51615
+ description: "List all labels (no args), or show tasks for a label (cleo labels <name>)"
51616
+ },
51617
+ args: {
51618
+ // Optional positional — when present, dispatches to tasks.list with the
51619
+ // label filter; when absent, falls through to the legacy label.list path.
51620
+ // Required:false keeps the bare `cleo labels` invocation working.
51621
+ name: {
51622
+ type: "positional",
51623
+ description: "Label name to filter tasks by (omit to list all labels)",
51624
+ required: false
51625
+ }
51176
51626
  },
51177
51627
  subCommands: {
51178
51628
  list: listCommand10,
@@ -51180,9 +51630,16 @@ var init_labels = __esm({
51180
51630
  stats: statsCommand2
51181
51631
  },
51182
51632
  async run(ctx) {
51183
- if (!ctx.rawArgs.some((a) => ["list", "show", "stats"].includes(a))) {
51184
- await dispatchFromCli("query", "tasks", "label.list", {}, { command: "labels" });
51633
+ const rawArgs = ctx.rawArgs ?? [];
51634
+ if (rawArgs.some((a) => ["list", "show", "stats"].includes(a))) {
51635
+ return;
51636
+ }
51637
+ const name = ctx.args.name;
51638
+ if (typeof name === "string" && name.length > 0) {
51639
+ await dispatchFromCli("query", "tasks", "list", { label: name }, { command: "labels" });
51640
+ return;
51185
51641
  }
51642
+ await dispatchFromCli("query", "tasks", "label.list", {}, { command: "labels" });
51186
51643
  }
51187
51644
  });
51188
51645
  }
@@ -51960,7 +52417,7 @@ async function _headlessPkceFlow(provider, authUrl) {
51960
52417
  ` After approving, paste the full redirect URL (http://localhost?code=\u2026&state=\u2026):
51961
52418
  `
51962
52419
  );
51963
- return new Promise((resolve8, reject) => {
52420
+ return new Promise((resolve9, reject) => {
51964
52421
  let buf = "";
51965
52422
  process.stdin.setEncoding("utf8");
51966
52423
  process.stdin.once("data", (chunk) => {
@@ -51972,7 +52429,7 @@ async function _headlessPkceFlow(provider, authUrl) {
51972
52429
  reject(new Error('Redirect URL is missing the "code" parameter'));
51973
52430
  return;
51974
52431
  }
51975
- resolve8(code);
52432
+ resolve9(code);
51976
52433
  } catch {
51977
52434
  reject(new Error(`Invalid redirect URL: ${buf}`));
51978
52435
  }
@@ -51980,7 +52437,7 @@ async function _headlessPkceFlow(provider, authUrl) {
51980
52437
  });
51981
52438
  }
51982
52439
  async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
51983
- return new Promise((resolve8) => {
52440
+ return new Promise((resolve9) => {
51984
52441
  const server = createServer2((req, res) => {
51985
52442
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
51986
52443
  const code = url.searchParams.get("code");
@@ -51990,7 +52447,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
51990
52447
  if (error) {
51991
52448
  res.end(`<h1>Authorization failed</h1><p>${error}</p><p>You may close this tab.</p>`);
51992
52449
  server.close();
51993
- resolve8({
52450
+ resolve9({
51994
52451
  error: {
51995
52452
  code: "E_PKCE_AUTH_DENIED",
51996
52453
  codeName: "E_PKCE_AUTH_DENIED",
@@ -52002,7 +52459,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
52002
52459
  if (!code || state !== expectedState) {
52003
52460
  res.end("<h1>Invalid callback</h1><p>You may close this tab.</p>");
52004
52461
  server.close();
52005
- resolve8({
52462
+ resolve9({
52006
52463
  error: {
52007
52464
  code: "E_PKCE_INVALID_CALLBACK",
52008
52465
  codeName: "E_PKCE_INVALID_CALLBACK",
@@ -52013,7 +52470,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
52013
52470
  }
52014
52471
  res.end("<h1>Authorized</h1><p>You may close this tab and return to your terminal.</p>");
52015
52472
  server.close();
52016
- resolve8({ code });
52473
+ resolve9({ code });
52017
52474
  });
52018
52475
  server.listen(port, "localhost", () => {
52019
52476
  process.stderr.write("\n");
@@ -52146,7 +52603,7 @@ function _generateState() {
52146
52603
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
52147
52604
  }
52148
52605
  function _findFreePort() {
52149
- return new Promise((resolve8, reject) => {
52606
+ return new Promise((resolve9, reject) => {
52150
52607
  const srv = createServer2();
52151
52608
  srv.listen(0, "localhost", () => {
52152
52609
  const addr = srv.address();
@@ -52156,7 +52613,7 @@ function _findFreePort() {
52156
52613
  return;
52157
52614
  }
52158
52615
  const port = addr.port;
52159
- srv.close(() => resolve8(port));
52616
+ srv.close(() => resolve9(port));
52160
52617
  });
52161
52618
  srv.on("error", reject);
52162
52619
  });
@@ -52778,14 +53235,14 @@ async function readStdin() {
52778
53235
  if (process.stdin.isTTY) {
52779
53236
  return "";
52780
53237
  }
52781
- return new Promise((resolve8, reject) => {
53238
+ return new Promise((resolve9, reject) => {
52782
53239
  let data = "";
52783
53240
  process.stdin.setEncoding("utf-8");
52784
53241
  process.stdin.on("data", (chunk) => {
52785
53242
  data += chunk;
52786
53243
  });
52787
53244
  process.stdin.on("end", () => {
52788
- resolve8(data.trim());
53245
+ resolve9(data.trim());
52789
53246
  });
52790
53247
  process.stdin.on("error", reject);
52791
53248
  });
@@ -56354,13 +56811,13 @@ var init_nexus3 = __esm({
56354
56811
  if (!skipPrompt) {
56355
56812
  const { createInterface: createInterface5 } = await import("node:readline");
56356
56813
  const rl = createInterface5({ input: process.stdin, output: process.stdout });
56357
- const confirmed = await new Promise((resolve8) => {
56814
+ const confirmed = await new Promise((resolve9) => {
56358
56815
  rl.question(
56359
56816
  `
56360
56817
  [nexus] Delete ${matchCount} project(s) from the registry? [y/N] `,
56361
56818
  (answer) => {
56362
56819
  rl.close();
56363
- resolve8(answer.trim().toLowerCase() === "y");
56820
+ resolve9(answer.trim().toLowerCase() === "y");
56364
56821
  }
56365
56822
  );
56366
56823
  });
@@ -60032,7 +60489,7 @@ __export(release_exports, {
60032
60489
  releaseCommand: () => releaseCommand
60033
60490
  });
60034
60491
  import { release as release3 } from "@cleocode/core";
60035
- var listCommand19, showCommand10, cancelCommand2, rollbackCommand, rollbackFullCommand, prStatusCommand, channelCommand, planCommand3, openCommand2, reconcileCommand4, releaseCommand;
60492
+ var listCommand19, showCommand10, cancelCommand2, rollbackCommand, rollbackFullCommand, prStatusCommand, channelCommand, validateChangelogCommand, planCommand3, openCommand2, reconcileCommand4, releaseCommand;
60036
60493
  var init_release3 = __esm({
60037
60494
  "packages/cleo/src/cli/commands/release.ts"() {
60038
60495
  "use strict";
@@ -60181,6 +60638,36 @@ var init_release3 = __esm({
60181
60638
  await dispatchFromCli("query", "pipeline", "release.channel.show", {}, { command: "release" });
60182
60639
  }
60183
60640
  });
60641
+ validateChangelogCommand = defineCommand({
60642
+ meta: {
60643
+ name: "validate-changelog",
60644
+ description: "Validate that CHANGELOG.md contains the canonical `## [VERSION]` header (T9937)"
60645
+ },
60646
+ args: {
60647
+ version: {
60648
+ type: "positional",
60649
+ description: "Release version (accepts v2026.5.94 or 2026.5.94)",
60650
+ required: true
60651
+ },
60652
+ path: {
60653
+ type: "string",
60654
+ description: "Override the CHANGELOG file path (default: <projectRoot>/CHANGELOG.md)",
60655
+ required: false
60656
+ }
60657
+ },
60658
+ async run({ args }) {
60659
+ await dispatchFromCli(
60660
+ "query",
60661
+ "release",
60662
+ "validate-changelog",
60663
+ {
60664
+ version: args.version,
60665
+ ...typeof args.path === "string" && args.path.length > 0 ? { changelogPath: args.path } : {}
60666
+ },
60667
+ { command: "release" }
60668
+ );
60669
+ }
60670
+ });
60184
60671
  planCommand3 = defineCommand({
60185
60672
  meta: {
60186
60673
  name: "plan",
@@ -60221,9 +60708,17 @@ var init_release3 = __esm({
60221
60708
  "no-changelog": {
60222
60709
  type: "boolean",
60223
60710
  description: "Skip CHANGELOG.md auto-write (default: write/replace the ## [<version>] section). (T9838)"
60711
+ },
60712
+ "skip-readiness": {
60713
+ type: "boolean",
60714
+ description: "Skip the release-readiness preflight check (default: run check). Use only in emergency. (T10459)"
60224
60715
  }
60225
60716
  },
60226
60717
  async run({ args }) {
60718
+ if (args["skip-readiness"] !== true) {
60719
+ const { runSpawnReadinessHygieneCli } = await import("@cleocode/core/hygiene/validate-spawn-readiness.js");
60720
+ await runSpawnReadinessHygieneCli();
60721
+ }
60227
60722
  await dispatchFromCli(
60228
60723
  "mutate",
60229
60724
  "release",
@@ -60344,7 +60839,9 @@ var init_release3 = __esm({
60344
60839
  cancel: cancelCommand2,
60345
60840
  "pr-status": prStatusCommand,
60346
60841
  channel: channelCommand,
60347
- "rollback-full": rollbackFullCommand
60842
+ "rollback-full": rollbackFullCommand,
60843
+ // T9937 — canonical CHANGELOG.md header validator (Saga T9862).
60844
+ "validate-changelog": validateChangelogCommand
60348
60845
  },
60349
60846
  async run({ cmd, rawArgs }) {
60350
60847
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -61572,7 +62069,7 @@ __export(revert_exports, {
61572
62069
  revertCommand: () => revertCommand
61573
62070
  });
61574
62071
  import { readFile as readFile5 } from "node:fs/promises";
61575
- import { join as join27 } from "node:path";
62072
+ import { join as join28 } from "node:path";
61576
62073
  import { cwd as processCwd2 } from "node:process";
61577
62074
  import { E_RECEIPT_NOT_FOUND } from "@cleocode/core/sentient/chain-walker.js";
61578
62075
  import { SENTIENT_STATE_FILE } from "@cleocode/core/sentient/daemon.js";
@@ -61625,7 +62122,7 @@ async function loadOwnerAttestation(attestationFilePath) {
61625
62122
  return obj;
61626
62123
  }
61627
62124
  async function loadOwnerPubkeys(projectRoot) {
61628
- const path6 = join27(projectRoot, OWNER_PUBKEYS_FILE);
62125
+ const path6 = join28(projectRoot, OWNER_PUBKEYS_FILE);
61629
62126
  try {
61630
62127
  const raw = await readFile5(path6, "utf-8");
61631
62128
  const parsed = JSON.parse(raw);
@@ -61709,7 +62206,7 @@ var init_revert = __esm({
61709
62206
  if (attestation && allowedPubkeys.size > 0 && !allowedPubkeys.has(attestation.ownerPubkey)) {
61710
62207
  emitFailure2(
61711
62208
  E_OWNER_ATTESTATION_REQUIRED,
61712
- `Attestation pubkey "${attestation.ownerPubkey}" is not in the owner allowlist at ${join27(projectRoot, OWNER_PUBKEYS_FILE)}`,
62209
+ `Attestation pubkey "${attestation.ownerPubkey}" is not in the owner allowlist at ${join28(projectRoot, OWNER_PUBKEYS_FILE)}`,
61713
62210
  jsonMode
61714
62211
  );
61715
62212
  }
@@ -61762,7 +62259,7 @@ ${lines}`
61762
62259
  identity,
61763
62260
  includeHuman
61764
62261
  });
61765
- const statePath = join27(projectRoot, SENTIENT_STATE_FILE);
62262
+ const statePath = join28(projectRoot, SENTIENT_STATE_FILE);
61766
62263
  const state = await readSentientState(statePath);
61767
62264
  emitSuccess(
61768
62265
  {
@@ -62296,7 +62793,7 @@ __export(self_update_exports, {
62296
62793
  });
62297
62794
  import { execFile } from "node:child_process";
62298
62795
  import { readFile as readFile6 } from "node:fs/promises";
62299
- import { join as join28 } from "node:path";
62796
+ import { join as join29 } from "node:path";
62300
62797
  import * as readline2 from "node:readline";
62301
62798
  import { promisify } from "node:util";
62302
62799
  import {
@@ -62311,7 +62808,7 @@ import {
62311
62808
  async function getCurrentVersion() {
62312
62809
  const cleoHome = getCleoHome4();
62313
62810
  try {
62314
- const content = await readFile6(join28(cleoHome, "VERSION"), "utf-8");
62811
+ const content = await readFile6(join29(cleoHome, "VERSION"), "utf-8");
62315
62812
  return (content.split("\n")[0] ?? "unknown").trim();
62316
62813
  } catch {
62317
62814
  return "unknown";
@@ -62365,7 +62862,7 @@ async function writeRuntimeVersionMetadata(mode, source, version) {
62365
62862
  ];
62366
62863
  await import("node:fs/promises").then(
62367
62864
  ({ writeFile: writeFile4, mkdir: mkdir5 }) => mkdir5(cleoHome, { recursive: true }).then(
62368
- () => writeFile4(join28(cleoHome, "VERSION"), `${lines.join("\n")}
62865
+ () => writeFile4(join29(cleoHome, "VERSION"), `${lines.join("\n")}
62369
62866
  `, "utf-8")
62370
62867
  )
62371
62868
  );
@@ -62403,11 +62900,11 @@ async function runPostUpdateDiagnostics(opts) {
62403
62900
  input: process.stdin,
62404
62901
  output: process.stdout
62405
62902
  });
62406
- shouldMigrate = await new Promise((resolve8) => {
62903
+ shouldMigrate = await new Promise((resolve9) => {
62407
62904
  rl.question(" Do you want to run the upgrade now? [Y/n] ", (answer) => {
62408
62905
  rl.close();
62409
62906
  const clean = answer.trim().toLowerCase();
62410
- resolve8(clean === "" || clean === "y" || clean === "yes");
62907
+ resolve9(clean === "" || clean === "y" || clean === "yes");
62411
62908
  });
62412
62909
  });
62413
62910
  }
@@ -62778,7 +63275,7 @@ __export(sentient_exports, {
62778
63275
  promptAcceptExecution: () => promptAcceptExecution,
62779
63276
  sentientCommand: () => sentientCommand
62780
63277
  });
62781
- import { join as join29 } from "node:path";
63278
+ import { join as join30 } from "node:path";
62782
63279
  import { cwd as processCwd3, stdin, stdout } from "node:process";
62783
63280
  import { createInterface as createInterface3 } from "node:readline/promises";
62784
63281
  import {
@@ -62867,7 +63364,7 @@ var init_sentient3 = __esm({
62867
63364
  return;
62868
63365
  }
62869
63366
  if (dryRun) {
62870
- const statePath2 = join29(projectRoot, SENTIENT_STATE_FILE2);
63367
+ const statePath2 = join30(projectRoot, SENTIENT_STATE_FILE2);
62871
63368
  const outcome = await safeRunTick({ projectRoot, statePath: statePath2, dryRun: true });
62872
63369
  emitSuccess2(
62873
63370
  { dryRun: true, outcome },
@@ -62983,7 +63480,7 @@ Logs: ${logPath}`
62983
63480
  const jsonMode = args.json === true;
62984
63481
  const dryRun = args["dry-run"] === true;
62985
63482
  try {
62986
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63483
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
62987
63484
  const outcome = await safeRunTick({ projectRoot, statePath, dryRun });
62988
63485
  emitSuccess2(
62989
63486
  { outcome, dryRun },
@@ -63075,7 +63572,7 @@ Logs: ${logPath}`
63075
63572
  return;
63076
63573
  }
63077
63574
  await db.update(tasks).set({ status: "pending", updatedAt: now }).where(eq2(tasks.id, id)).run();
63078
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63575
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63079
63576
  const state = await readSentientState2(statePath);
63080
63577
  await patchSentientState(statePath, {
63081
63578
  tier2Stats: {
@@ -63171,7 +63668,7 @@ Logs: ${logPath}`
63171
63668
  return;
63172
63669
  }
63173
63670
  await db.update(tasks).set({ status: "cancelled", cancellationReason: reason, cancelledAt: now, updatedAt: now }).where(eq2(tasks.id, id)).run();
63174
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63671
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63175
63672
  const state = await readSentientState2(statePath);
63176
63673
  await patchSentientState(statePath, {
63177
63674
  tier2Stats: {
@@ -63216,7 +63713,7 @@ Logs: ${logPath}`
63216
63713
  const projectRoot = resolveProjectRoot6(args.project);
63217
63714
  const jsonMode = args.json === true;
63218
63715
  try {
63219
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63716
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63220
63717
  const outcome = await safeRunProposeTick({ projectRoot, statePath });
63221
63718
  emitSuccess2(
63222
63719
  { outcome },
@@ -63236,7 +63733,7 @@ Logs: ${logPath}`
63236
63733
  const projectRoot = resolveProjectRoot6(args.project);
63237
63734
  const jsonMode = args.json === true;
63238
63735
  try {
63239
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63736
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63240
63737
  const updated = await patchSentientState(statePath, { tier2Enabled: true });
63241
63738
  emitSuccess2({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals enabled");
63242
63739
  } catch (err) {
@@ -63255,7 +63752,7 @@ Logs: ${logPath}`
63255
63752
  const projectRoot = resolveProjectRoot6(args.project);
63256
63753
  const jsonMode = args.json === true;
63257
63754
  try {
63258
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63755
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63259
63756
  const updated = await patchSentientState(statePath, { tier2Enabled: false });
63260
63757
  emitSuccess2({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals disabled");
63261
63758
  } catch (err) {
@@ -63286,7 +63783,7 @@ Logs: ${logPath}`
63286
63783
  const projectRoot = resolveProjectRoot6(args.project);
63287
63784
  const jsonMode = args.json === true;
63288
63785
  try {
63289
- const statePath = join29(projectRoot, SENTIENT_STATE_FILE2);
63786
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
63290
63787
  const state = await readSentientState2(statePath);
63291
63788
  emitSuccess2(
63292
63789
  {
@@ -63934,7 +64431,7 @@ async function promptOwnerAuthPassword(sessionName) {
63934
64431
  terminal: true
63935
64432
  });
63936
64433
  process.stderr.write(`[cleo] Enter owner-auth password for session "${sessionName}": `);
63937
- const password = await new Promise((resolve8) => {
64434
+ const password = await new Promise((resolve9) => {
63938
64435
  if (process.stdin.setRawMode) {
63939
64436
  process.stdin.setRawMode(
63940
64437
  true
@@ -63952,10 +64449,10 @@ async function promptOwnerAuthPassword(sessionName) {
63952
64449
  );
63953
64450
  }
63954
64451
  process.stderr.write("\n");
63955
- resolve8(pw);
64452
+ resolve9(pw);
63956
64453
  } else if (ch === "") {
63957
64454
  process.stderr.write("\n[cleo] Cancelled.\n");
63958
- resolve8("");
64455
+ resolve9("");
63959
64456
  } else if (ch === "\x7F" || ch === "\b") {
63960
64457
  pw = pw.slice(0, -1);
63961
64458
  } else {
@@ -66990,12 +67487,12 @@ var init_telemetry2 = __esm({
66990
67487
 
66991
67488
  // packages/cleo/src/cli/commands/templates/lib.ts
66992
67489
  import { readFileSync as readFileSync15 } from "node:fs";
66993
- import { isAbsolute as isAbsolute3, resolve as resolve6 } from "node:path";
67490
+ import { isAbsolute as isAbsolute3, resolve as resolve7 } from "node:path";
66994
67491
  import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
66995
67492
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
66996
67493
  function resolveProjectRoot7(raw) {
66997
67494
  if (typeof raw === "string" && raw.length > 0) {
66998
- return isAbsolute3(raw) ? raw : resolve6(process.cwd(), raw);
67495
+ return isAbsolute3(raw) ? raw : resolve7(process.cwd(), raw);
66999
67496
  }
67000
67497
  return getProjectRoot50();
67001
67498
  }
@@ -67016,8 +67513,8 @@ var init_lib = __esm({
67016
67513
  });
67017
67514
 
67018
67515
  // packages/cleo/src/cli/commands/templates/diff.ts
67019
- import { existsSync as existsSync15, readFileSync as readFileSync16 } from "node:fs";
67020
- import { join as join30 } from "node:path";
67516
+ import { existsSync as existsSync16, readFileSync as readFileSync16 } from "node:fs";
67517
+ import { join as join31 } from "node:path";
67021
67518
  import { getTemplateById } from "@cleocode/core/templates/registry";
67022
67519
  function unifiedDiff(a, b) {
67023
67520
  const aLines = a.length === 0 ? [] : a.split("\n");
@@ -67087,7 +67584,7 @@ var init_diff = __esm({
67087
67584
  let rendered;
67088
67585
  try {
67089
67586
  projectRoot = resolveProjectRoot7(args["project"]);
67090
- installPath = join30(projectRoot, entry.installPath);
67587
+ installPath = join31(projectRoot, entry.installPath);
67091
67588
  const source = readTemplateSource(entry);
67092
67589
  rendered = applySubstitution(entry, source).rendered;
67093
67590
  } catch (err) {
@@ -67098,7 +67595,7 @@ var init_diff = __esm({
67098
67595
  process.exit(1 /* GENERAL_ERROR */);
67099
67596
  return;
67100
67597
  }
67101
- if (!existsSync15(installPath)) {
67598
+ if (!existsSync16(installPath)) {
67102
67599
  const missingResult = {
67103
67600
  id,
67104
67601
  installPath,
@@ -67137,8 +67634,8 @@ ${unifiedDiff("", rendered)}`
67137
67634
  });
67138
67635
 
67139
67636
  // packages/cleo/src/cli/commands/templates/install.ts
67140
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync17, writeFileSync as writeFileSync5 } from "node:fs";
67141
- import { dirname as dirname9, join as join31 } from "node:path";
67637
+ import { existsSync as existsSync17, mkdirSync as mkdirSync5, readFileSync as readFileSync17, writeFileSync as writeFileSync5 } from "node:fs";
67638
+ import { dirname as dirname9, join as join32 } from "node:path";
67142
67639
  import { getTemplateById as getTemplateById2 } from "@cleocode/core/templates/registry";
67143
67640
  var templatesInstallCommand;
67144
67641
  var init_install = __esm({
@@ -67192,7 +67689,7 @@ var init_install = __esm({
67192
67689
  let substituted;
67193
67690
  try {
67194
67691
  projectRoot = resolveProjectRoot7(args["project"]);
67195
- installPath = join31(projectRoot, entry.installPath);
67692
+ installPath = join32(projectRoot, entry.installPath);
67196
67693
  const source = readTemplateSource(entry);
67197
67694
  const sub = applySubstitution(entry, source);
67198
67695
  rendered = sub.rendered;
@@ -67205,7 +67702,7 @@ var init_install = __esm({
67205
67702
  process.exit(1 /* GENERAL_ERROR */);
67206
67703
  return;
67207
67704
  }
67208
- if (existsSync16(installPath)) {
67705
+ if (existsSync17(installPath)) {
67209
67706
  const current = readFileSync17(installPath, "utf8");
67210
67707
  if (current === rendered) {
67211
67708
  const noopResult = {
@@ -67354,8 +67851,8 @@ var init_show3 = __esm({
67354
67851
  });
67355
67852
 
67356
67853
  // packages/cleo/src/cli/commands/templates/upgrade.ts
67357
- import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "node:fs";
67358
- import { dirname as dirname10, join as join32 } from "node:path";
67854
+ import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "node:fs";
67855
+ import { dirname as dirname10, join as join33 } from "node:path";
67359
67856
  import { getTemplateById as getTemplateById4 } from "@cleocode/core/templates/registry";
67360
67857
  var templatesUpgradeCommand;
67361
67858
  var init_upgrade2 = __esm({
@@ -67417,7 +67914,7 @@ var init_upgrade2 = __esm({
67417
67914
  let rendered;
67418
67915
  try {
67419
67916
  projectRoot = resolveProjectRoot7(args["project"]);
67420
- installPath = join32(projectRoot, entry.installPath);
67917
+ installPath = join33(projectRoot, entry.installPath);
67421
67918
  const source = readTemplateSource(entry);
67422
67919
  rendered = applySubstitution(entry, source).rendered;
67423
67920
  } catch (err) {
@@ -67430,7 +67927,7 @@ var init_upgrade2 = __esm({
67430
67927
  }
67431
67928
  const previewOnly = args["diff"] === true;
67432
67929
  const accept = args["accept"] === true;
67433
- const current = existsSync17(installPath) ? readFileSync18(installPath, "utf8") : null;
67930
+ const current = existsSync18(installPath) ? readFileSync18(installPath, "utf8") : null;
67434
67931
  const diffBody = current === null ? "" : current === rendered ? "" : unifiedDiff(current, rendered);
67435
67932
  let outcome;
67436
67933
  let reason;
@@ -67980,7 +68477,7 @@ __export(transcript_exports, {
67980
68477
  transcriptCommand: () => transcriptCommand
67981
68478
  });
67982
68479
  import { homedir as homedir6 } from "node:os";
67983
- import { join as join33 } from "node:path";
68480
+ import { join as join34 } from "node:path";
67984
68481
  import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
67985
68482
  import {
67986
68483
  parseDurationMs,
@@ -68034,7 +68531,7 @@ var init_transcript = __esm({
68034
68531
  }
68035
68532
  return;
68036
68533
  }
68037
- const projectsDir = args["projects-dir"] ?? join33(homedir6(), ".claude", "projects");
68534
+ const projectsDir = args["projects-dir"] ?? join34(homedir6(), ".claude", "projects");
68038
68535
  try {
68039
68536
  const result = await scanTranscripts(projectsDir);
68040
68537
  cliOutput(
@@ -68340,7 +68837,7 @@ var init_transcript = __esm({
68340
68837
  process.exit(2);
68341
68838
  return;
68342
68839
  }
68343
- const projectsDir = args["projects-dir"] ?? join33(homedir6(), ".claude", "projects");
68840
+ const projectsDir = args["projects-dir"] ?? join34(homedir6(), ".claude", "projects");
68344
68841
  try {
68345
68842
  const pruneResult = await pruneTranscripts({
68346
68843
  olderThanMs,
@@ -68872,7 +69369,7 @@ var upgrade_exports = {};
68872
69369
  __export(upgrade_exports, {
68873
69370
  upgradeCommand: () => upgradeCommand
68874
69371
  });
68875
- import { resolve as resolve7 } from "node:path";
69372
+ import { resolve as resolve8 } from "node:path";
68876
69373
  import { CleoError as CleoError10, diagnoseUpgrade, runUpgrade as runUpgrade2, upgradeWorkflows as upgradeWorkflows2 } from "@cleocode/core/internal";
68877
69374
  var workflowsSubcommand, upgradeCommand;
68878
69375
  var init_upgrade3 = __esm({
@@ -68912,7 +69409,7 @@ var init_upgrade3 = __esm({
68912
69409
  const dryRun = args["dry-run"] === true || args.check === true;
68913
69410
  const force = args.force === true && !dryRun;
68914
69411
  const result = await upgradeWorkflows2({
68915
- projectRoot: resolve7(process.cwd()),
69412
+ projectRoot: resolve8(process.cwd()),
68916
69413
  templatesDir: getWorkflowTemplatesDir2(),
68917
69414
  dryRun,
68918
69415
  force
@@ -69173,15 +69670,15 @@ __export(web_exports, {
69173
69670
  });
69174
69671
  import { execFileSync as execFileSync4, spawn as spawn3 } from "node:child_process";
69175
69672
  import { mkdir as mkdir4, open, readFile as readFile7, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
69176
- import { join as join34 } from "node:path";
69673
+ import { join as join35 } from "node:path";
69177
69674
  import { CleoError as CleoError11, formatError as formatError5, getCleoHome as getCleoHome5 } from "@cleocode/core";
69178
69675
  function getWebPaths() {
69179
69676
  const cleoHome = getCleoHome5();
69180
69677
  return {
69181
- pidFile: join34(cleoHome, "web-server.pid"),
69182
- configFile: join34(cleoHome, "web-server.json"),
69183
- logDir: join34(cleoHome, "logs"),
69184
- logFile: join34(cleoHome, "logs", "web-server.log")
69678
+ pidFile: join35(cleoHome, "web-server.pid"),
69679
+ configFile: join35(cleoHome, "web-server.json"),
69680
+ logDir: join35(cleoHome, "logs"),
69681
+ logFile: join35(cleoHome, "logs", "web-server.log")
69185
69682
  };
69186
69683
  }
69187
69684
  function isProcessRunning(pid) {
@@ -69220,7 +69717,7 @@ async function startWebServer(port, host) {
69220
69717
  throw new CleoError11(1 /* GENERAL_ERROR */, `Server already running (PID: ${status.pid})`);
69221
69718
  }
69222
69719
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
69223
- const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join34(projectRoot, "packages", "studio", "build");
69720
+ const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join35(projectRoot, "packages", "studio", "build");
69224
69721
  await mkdir4(logDir, { recursive: true });
69225
69722
  await writeFile3(
69226
69723
  configFile,
@@ -69230,7 +69727,7 @@ async function startWebServer(port, host) {
69230
69727
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
69231
69728
  })
69232
69729
  );
69233
- const webIndexPath = join34(studioDir, "index.js");
69730
+ const webIndexPath = join35(studioDir, "index.js");
69234
69731
  try {
69235
69732
  await stat2(webIndexPath);
69236
69733
  } catch {
@@ -69278,7 +69775,7 @@ Logs: ${logFile}`
69278
69775
  }
69279
69776
  } catch {
69280
69777
  }
69281
- await new Promise((resolve8) => setTimeout(resolve8, 500));
69778
+ await new Promise((resolve9) => setTimeout(resolve9, 500));
69282
69779
  }
69283
69780
  if (!started) {
69284
69781
  try {
@@ -69355,7 +69852,7 @@ var init_web = __esm({
69355
69852
  }
69356
69853
  for (let i = 0; i < 60; i++) {
69357
69854
  if (!isProcessRunning(status.pid)) break;
69358
- await new Promise((resolve8) => setTimeout(resolve8, 500));
69855
+ await new Promise((resolve9) => setTimeout(resolve9, 500));
69359
69856
  }
69360
69857
  if (isProcessRunning(status.pid)) {
69361
69858
  try {
@@ -69407,7 +69904,7 @@ var init_web = __esm({
69407
69904
  }
69408
69905
  for (let i = 0; i < 60; i++) {
69409
69906
  if (!isProcessRunning(status.pid)) break;
69410
- await new Promise((resolve8) => setTimeout(resolve8, 500));
69907
+ await new Promise((resolve9) => setTimeout(resolve9, 500));
69411
69908
  }
69412
69909
  if (isProcessRunning(status.pid)) {
69413
69910
  try {
@@ -69505,12 +70002,12 @@ __export(worktree_exports, {
69505
70002
  import readline4 from "node:readline";
69506
70003
  import { getProjectRoot as getProjectRoot53, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
69507
70004
  async function promptYesNo2(question) {
69508
- return new Promise((resolve8) => {
70005
+ return new Promise((resolve9) => {
69509
70006
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
69510
70007
  rl.question(`${question} [y/N]: `, (answer) => {
69511
70008
  rl.close();
69512
70009
  const trimmed = answer.trim().toLowerCase();
69513
- resolve8(trimmed === "y" || trimmed === "yes");
70010
+ resolve9(trimmed === "y" || trimmed === "yes");
69514
70011
  });
69515
70012
  });
69516
70013
  }
@@ -69844,7 +70341,7 @@ init_dist();
69844
70341
  init_field_context();
69845
70342
  init_format_context();
69846
70343
  import { readFileSync as readFileSync20 } from "node:fs";
69847
- import { dirname as dirname11, join as join36 } from "node:path";
70344
+ import { dirname as dirname11, join as join37 } from "node:path";
69848
70345
  import { fileURLToPath as fileURLToPath7 } from "node:url";
69849
70346
 
69850
70347
  // packages/cleo/src/cli/generated/command-manifest.ts
@@ -70290,7 +70787,7 @@ var COMMAND_MANIFEST = [
70290
70787
  {
70291
70788
  exportName: "labelsCommand",
70292
70789
  name: "labels",
70293
- description: "List all labels with counts or show tasks with specific label",
70790
+ description: "List all labels (no args), or show tasks for a label (cleo labels <name>)",
70294
70791
  load: async () => (await Promise.resolve().then(() => (init_labels(), labels_exports))).labelsCommand
70295
70792
  },
70296
70793
  {
@@ -70858,14 +71355,14 @@ function lazyCommand(meta, loader2) {
70858
71355
  init_did_you_mean();
70859
71356
 
70860
71357
  // packages/cleo/src/cli/lib/first-run-detection.ts
70861
- import { existsSync as existsSync18 } from "node:fs";
70862
- import { join as join35 } from "node:path";
71358
+ import { existsSync as existsSync19 } from "node:fs";
71359
+ import { join as join36 } from "node:path";
70863
71360
  async function detectFirstRun() {
70864
71361
  const envKey = process.env["ANTHROPIC_API_KEY"];
70865
71362
  if (typeof envKey === "string" && envKey.length > 0) return false;
70866
71363
  const { getCleoPlatformPaths } = await import("@cleocode/paths");
70867
- const configPath = join35(getCleoPlatformPaths().config, "config.json");
70868
- if (existsSync18(configPath)) return false;
71364
+ const configPath = join36(getCleoPlatformPaths().config, "config.json");
71365
+ if (existsSync19(configPath)) return false;
70869
71366
  try {
70870
71367
  const { getCredentialPool } = await import("@cleocode/core/llm/credential-pool.js");
70871
71368
  const pool = getCredentialPool();
@@ -70876,7 +71373,7 @@ async function detectFirstRun() {
70876
71373
  return true;
70877
71374
  }
70878
71375
  function waitForEnterOrTimeout(timeoutMs) {
70879
- return new Promise((resolve8) => {
71376
+ return new Promise((resolve9) => {
70880
71377
  let resolved = false;
70881
71378
  const finish = () => {
70882
71379
  if (resolved) return;
@@ -70888,7 +71385,7 @@ function waitForEnterOrTimeout(timeoutMs) {
70888
71385
  process.stdin.pause();
70889
71386
  } catch {
70890
71387
  }
70891
- resolve8();
71388
+ resolve9();
70892
71389
  };
70893
71390
  const onData = (chunk) => {
70894
71391
  const s = typeof chunk === "string" ? chunk : chunk.toString("utf8");
@@ -70984,7 +71481,7 @@ Or via NodeSource: https://github.com/nodesource/distributions
70984
71481
  }
70985
71482
  }
70986
71483
  function getPackageVersion() {
70987
- const pkgPath = join36(dirname11(fileURLToPath7(import.meta.url)), "../../package.json");
71484
+ const pkgPath = join37(dirname11(fileURLToPath7(import.meta.url)), "../../package.json");
70988
71485
  const pkg = JSON.parse(readFileSync20(pkgPath, "utf-8"));
70989
71486
  return pkg.version;
70990
71487
  }