@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 +676 -179
- package/dist/cli/index.js.map +3 -3
- package/package.json +11 -11
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
|
|
1750
|
-
id: z3.string().min(1, "id must be non-empty").regex(
|
|
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:
|
|
27405
|
-
const { join:
|
|
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 (
|
|
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(
|
|
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 =
|
|
27429
|
-
if (
|
|
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(
|
|
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,
|
|
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:
|
|
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
|
|
28404
|
+
const resolve9 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
|
|
28310
28405
|
const p = {
|
|
28311
28406
|
taskId: params.taskId,
|
|
28312
|
-
...
|
|
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((
|
|
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
|
-
|
|
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:
|
|
34744
|
-
const { join:
|
|
34745
|
-
const cantDir =
|
|
34746
|
-
const cantPath =
|
|
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 (!
|
|
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 :
|
|
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:
|
|
34928
|
-
const { join:
|
|
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 ??
|
|
34949
|
-
if (
|
|
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:
|
|
35474
|
-
const { join:
|
|
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 =
|
|
35492
|
-
const hasProfile =
|
|
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:
|
|
36289
|
-
const { basename, resolve:
|
|
36290
|
-
const resolvedPath =
|
|
36291
|
-
if (!
|
|
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:
|
|
36417
|
-
const { resolve:
|
|
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 =
|
|
36420
|
-
if (!
|
|
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:
|
|
36435
|
-
const personaPath =
|
|
36436
|
-
if (!
|
|
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 =
|
|
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(
|
|
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:
|
|
36732
|
-
const { resolve:
|
|
36733
|
-
const specPath =
|
|
36734
|
-
if (!
|
|
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"] ?
|
|
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((
|
|
37493
|
-
rl.question(question, (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((
|
|
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
|
-
|
|
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:
|
|
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 (!
|
|
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:
|
|
40604
|
-
const { join:
|
|
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 =
|
|
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 =
|
|
40645
|
-
if (!
|
|
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:
|
|
41120
|
+
const { join: join38 } = await import("node:path");
|
|
40961
41121
|
const root = process.cwd();
|
|
40962
|
-
const absPath = args.file.startsWith("/") ? 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:
|
|
41213
|
+
const { join: join38 } = await import("node:path");
|
|
41054
41214
|
const root = process.cwd();
|
|
41055
|
-
const absPath = args.file.startsWith("/") ? 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
|
|
47357
|
-
import { join as
|
|
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 =
|
|
47378
|
-
const auditDir =
|
|
47379
|
-
if (!
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
47901
|
+
const canonicalDir = join23(projectRoot, ".cleo", "cant", "agents");
|
|
47494
47902
|
walkAgentsDir(db, canonicalDir, projectRoot, summary, verbose);
|
|
47495
|
-
const legacyDir =
|
|
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 =
|
|
47504
|
-
if (!
|
|
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
|
|
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 =
|
|
47629
|
-
const quarantineDir =
|
|
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
|
-
|
|
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 =
|
|
48212
|
-
const auditLogPath =
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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"] ??
|
|
49333
|
-
const worktreesRoot = args["worktrees-root"] ??
|
|
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
|
|
50546
|
-
import { join as
|
|
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 =
|
|
50560
|
-
const localTemplatePath =
|
|
50561
|
-
const monorepoTemplatePath =
|
|
50562
|
-
const templatePath =
|
|
50563
|
-
if (
|
|
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
|
|
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
|
-
|
|
51184
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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((
|
|
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(() =>
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 ${
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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((
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
64452
|
+
resolve9(pw);
|
|
63956
64453
|
} else if (ch === "") {
|
|
63957
64454
|
process.stderr.write("\n[cleo] Cancelled.\n");
|
|
63958
|
-
|
|
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
|
|
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 :
|
|
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
|
|
67020
|
-
import { join as
|
|
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 =
|
|
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 (!
|
|
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
|
|
67141
|
-
import { dirname as dirname9, join as
|
|
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 =
|
|
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 (
|
|
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
|
|
67358
|
-
import { dirname as dirname10, join as
|
|
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 =
|
|
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 =
|
|
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
|
|
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"] ??
|
|
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"] ??
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
69182
|
-
configFile:
|
|
69183
|
-
logDir:
|
|
69184
|
-
logFile:
|
|
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"] ??
|
|
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 =
|
|
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((
|
|
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((
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
70862
|
-
import { join as
|
|
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 =
|
|
70868
|
-
if (
|
|
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((
|
|
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
|
-
|
|
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 =
|
|
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
|
}
|