@cleocode/cleo 2026.5.59 → 2026.5.61
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 +215 -21
- package/dist/cli/index.js.map +2 -2
- package/package.json +10 -10
package/dist/cli/index.js
CHANGED
|
@@ -23340,8 +23340,8 @@ async function loadPlaybookByName(name) {
|
|
|
23340
23340
|
return null;
|
|
23341
23341
|
}
|
|
23342
23342
|
try {
|
|
23343
|
-
const { getProjectRoot:
|
|
23344
|
-
const projectRoot = __playbookRuntimeOverrides.projectRoot ??
|
|
23343
|
+
const { getProjectRoot: getProjectRoot34 } = await import("@cleocode/core/internal");
|
|
23344
|
+
const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot34();
|
|
23345
23345
|
const resolved = resolvePlaybook(name, {
|
|
23346
23346
|
projectRoot,
|
|
23347
23347
|
globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
|
|
@@ -23385,8 +23385,8 @@ async function acquireDb() {
|
|
|
23385
23385
|
async function buildDefaultDispatcher() {
|
|
23386
23386
|
if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
|
|
23387
23387
|
const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
23388
|
-
const { getProjectRoot:
|
|
23389
|
-
const projectRoot =
|
|
23388
|
+
const { getProjectRoot: getProjectRoot34 } = await import("@cleocode/core/internal");
|
|
23389
|
+
const projectRoot = getProjectRoot34();
|
|
23390
23390
|
return {
|
|
23391
23391
|
async dispatch(input) {
|
|
23392
23392
|
try {
|
|
@@ -23576,8 +23576,8 @@ var init_playbook2 = __esm({
|
|
|
23576
23576
|
projectRoot = __playbookRuntimeOverrides.projectRoot;
|
|
23577
23577
|
} else {
|
|
23578
23578
|
try {
|
|
23579
|
-
const { getProjectRoot:
|
|
23580
|
-
projectRoot =
|
|
23579
|
+
const { getProjectRoot: getProjectRoot34 } = await import("@cleocode/core/internal");
|
|
23580
|
+
projectRoot = getProjectRoot34();
|
|
23581
23581
|
} catch {
|
|
23582
23582
|
projectRoot = void 0;
|
|
23583
23583
|
}
|
|
@@ -23641,14 +23641,14 @@ var init_playbook2 = __esm({
|
|
|
23641
23641
|
const dispatcher = await buildDefaultDispatcher();
|
|
23642
23642
|
let result;
|
|
23643
23643
|
try {
|
|
23644
|
-
const { getProjectRoot:
|
|
23644
|
+
const { getProjectRoot: getProjectRoot34 } = await import("@cleocode/core/internal");
|
|
23645
23645
|
const opts = {
|
|
23646
23646
|
db,
|
|
23647
23647
|
playbook: parsed.definition,
|
|
23648
23648
|
playbookHash: parsed.sourceHash,
|
|
23649
23649
|
initialContext,
|
|
23650
23650
|
dispatcher,
|
|
23651
|
-
projectRoot:
|
|
23651
|
+
projectRoot: getProjectRoot34()
|
|
23652
23652
|
};
|
|
23653
23653
|
if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
|
|
23654
23654
|
opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
|
|
@@ -27163,7 +27163,9 @@ var init_tasks3 = __esm({
|
|
|
27163
27163
|
scope: params.scope,
|
|
27164
27164
|
severity: params.severity,
|
|
27165
27165
|
// T1633: BRAIN duplicate-bypass flag
|
|
27166
|
-
forceDuplicate: params.forceDuplicate
|
|
27166
|
+
forceDuplicate: params.forceDuplicate,
|
|
27167
|
+
// T9218 / ADR-070: mandatory verifier for high-consequence tasks
|
|
27168
|
+
verifier: params.verifier
|
|
27167
27169
|
}),
|
|
27168
27170
|
"add"
|
|
27169
27171
|
);
|
|
@@ -28537,11 +28539,11 @@ var init_security = __esm({
|
|
|
28537
28539
|
});
|
|
28538
28540
|
|
|
28539
28541
|
// packages/cleo/src/dispatch/middleware/sanitizer.ts
|
|
28540
|
-
function createSanitizer(
|
|
28542
|
+
function createSanitizer(getProjectRoot34) {
|
|
28541
28543
|
return async (req, next) => {
|
|
28542
28544
|
if (req.params) {
|
|
28543
28545
|
try {
|
|
28544
|
-
const root =
|
|
28546
|
+
const root = getProjectRoot34 ? getProjectRoot34() : void 0;
|
|
28545
28547
|
req.params = sanitizeParams(req.params, root, {
|
|
28546
28548
|
domain: req.domain,
|
|
28547
28549
|
operation: req.operation
|
|
@@ -29396,6 +29398,19 @@ var init_add = __esm({
|
|
|
29396
29398
|
"depends-waiver": {
|
|
29397
29399
|
type: "string",
|
|
29398
29400
|
description: "Justification for creating a critical-priority task without --depends (T1856). Records waiver in task metadata."
|
|
29401
|
+
},
|
|
29402
|
+
/**
|
|
29403
|
+
* Path to an existing verifier script (T9218 / ADR-070).
|
|
29404
|
+
*
|
|
29405
|
+
* Required when creating tasks with priority=critical, size=large, or
|
|
29406
|
+
* type=epic. The path must point to an existing .mjs file. Omitting
|
|
29407
|
+
* this on high-consequence tasks causes rejection with E_VERIFIER_REQUIRED.
|
|
29408
|
+
*
|
|
29409
|
+
* Use `cleo verify backfill <taskId>` to generate a stub after creation.
|
|
29410
|
+
*/
|
|
29411
|
+
verifier: {
|
|
29412
|
+
type: "string",
|
|
29413
|
+
description: "Path to existing verifier script for this task (required for priority=critical, size=large, type=epic) (T9218 / ADR-070)"
|
|
29399
29414
|
}
|
|
29400
29415
|
},
|
|
29401
29416
|
async run({ args, cmd }) {
|
|
@@ -29429,6 +29444,7 @@ var init_add = __esm({
|
|
|
29429
29444
|
if (args.scope !== void 0) params["scope"] = args.scope;
|
|
29430
29445
|
if (args.severity !== void 0) params["severity"] = args.severity;
|
|
29431
29446
|
if (args["force-duplicate"] !== void 0) params["forceDuplicate"] = args["force-duplicate"];
|
|
29447
|
+
if (args.verifier !== void 0) params["verifier"] = args.verifier;
|
|
29432
29448
|
if (args.priority === "critical" && !args.depends && args["depends-waiver"] === void 0) {
|
|
29433
29449
|
cliError(
|
|
29434
29450
|
'Critical-priority tasks must declare at least one dependency (--depends) or provide a waiver (--depends-waiver "<reason>").',
|
|
@@ -33809,9 +33825,9 @@ var init_backup = __esm({
|
|
|
33809
33825
|
},
|
|
33810
33826
|
async run({ args }) {
|
|
33811
33827
|
const scope = args.scope;
|
|
33812
|
-
const { packBundle, getProjectRoot:
|
|
33828
|
+
const { packBundle, getProjectRoot: getProjectRoot34 } = await import("@cleocode/core/internal");
|
|
33813
33829
|
const includesProject = scope === "project" || scope === "all";
|
|
33814
|
-
const projectRoot = includesProject ?
|
|
33830
|
+
const projectRoot = includesProject ? getProjectRoot34() : void 0;
|
|
33815
33831
|
let passphrase;
|
|
33816
33832
|
if (args.encrypt === true) {
|
|
33817
33833
|
passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
|
|
@@ -45315,7 +45331,7 @@ var init_nexus4 = __esm({
|
|
|
45315
45331
|
const repoPath = args.path ? path3.resolve(args.path) : process.cwd();
|
|
45316
45332
|
humanInfo(`[nexus] Analyzing: ${repoPath}${isIncremental ? " (incremental)" : ""}`);
|
|
45317
45333
|
try {
|
|
45318
|
-
const [{ getNexusDb, nexusSchema }, { runPipeline }, { getProjectRoot:
|
|
45334
|
+
const [{ getNexusDb, nexusSchema }, { runPipeline }, { getProjectRoot: getProjectRoot34 }, { eq: eq2 }] = await Promise.all([
|
|
45319
45335
|
import("@cleocode/core/store/nexus-sqlite"),
|
|
45320
45336
|
import("@cleocode/nexus/pipeline"),
|
|
45321
45337
|
import("@cleocode/core/internal"),
|
|
@@ -45395,7 +45411,7 @@ var init_nexus4 = __esm({
|
|
|
45395
45411
|
extensions: { duration_ms: durationMs }
|
|
45396
45412
|
}
|
|
45397
45413
|
);
|
|
45398
|
-
void
|
|
45414
|
+
void getProjectRoot34;
|
|
45399
45415
|
} catch (err) {
|
|
45400
45416
|
const msg = err instanceof Error ? err.message : String(err);
|
|
45401
45417
|
cliError(
|
|
@@ -52829,8 +52845,8 @@ var init_session4 = __esm({
|
|
|
52829
52845
|
"audit-scope": { type: "string", description: "Audit log scope (global|local)" }
|
|
52830
52846
|
},
|
|
52831
52847
|
async run({ args }) {
|
|
52832
|
-
const { detectSessionDrift, getProjectRoot:
|
|
52833
|
-
const projectRoot = await
|
|
52848
|
+
const { detectSessionDrift, getProjectRoot: getProjectRoot34 } = await import("@cleocode/core");
|
|
52849
|
+
const projectRoot = await getProjectRoot34();
|
|
52834
52850
|
const scope = args["audit-scope"] === "local" ? "local" : "global";
|
|
52835
52851
|
const report = await detectSessionDrift({ projectRoot, auditScope: scope });
|
|
52836
52852
|
cliOutput(report, { command: "session drift", operation: "session.drift" });
|
|
@@ -55243,11 +55259,13 @@ var init_upgrade = __esm({
|
|
|
55243
55259
|
// packages/cleo/src/cli/commands/verify.ts
|
|
55244
55260
|
var verify_exports = {};
|
|
55245
55261
|
__export(verify_exports, {
|
|
55262
|
+
backfillCommand: () => backfillCommand3,
|
|
55246
55263
|
verifyCommand: () => verifyCommand3
|
|
55247
55264
|
});
|
|
55248
55265
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
55249
55266
|
import { existsSync as existsSync14 } from "node:fs";
|
|
55250
55267
|
import { join as join22, resolve as resolve6 } from "node:path";
|
|
55268
|
+
import { generateVerifierStub, getProjectRoot as getProjectRoot33, writeVerifierStub } from "@cleocode/core";
|
|
55251
55269
|
function resolveVerifierScript2(taskId, projectRoot) {
|
|
55252
55270
|
const id = taskId.toLowerCase();
|
|
55253
55271
|
const candidates = [
|
|
@@ -55269,12 +55287,173 @@ function runVerifier(verifierPath) {
|
|
|
55269
55287
|
stderr: result.stderr ?? ""
|
|
55270
55288
|
};
|
|
55271
55289
|
}
|
|
55272
|
-
|
|
55290
|
+
async function backfillSingle(taskId, projectRoot, force) {
|
|
55291
|
+
const response = await dispatchRaw("query", "tasks", "show", { taskId });
|
|
55292
|
+
if (!response.success) {
|
|
55293
|
+
process.stderr.write(
|
|
55294
|
+
`Error: could not fetch task ${taskId}: ${response.error?.message ?? "unknown error"}
|
|
55295
|
+
`
|
|
55296
|
+
);
|
|
55297
|
+
process.exitCode = 1;
|
|
55298
|
+
return;
|
|
55299
|
+
}
|
|
55300
|
+
const task = response.data?.task;
|
|
55301
|
+
if (!task) {
|
|
55302
|
+
process.stderr.write(`Error: task ${taskId} not found.
|
|
55303
|
+
`);
|
|
55304
|
+
process.exitCode = 1;
|
|
55305
|
+
return;
|
|
55306
|
+
}
|
|
55307
|
+
const existing = resolveVerifierScript2(taskId, projectRoot);
|
|
55308
|
+
if (existing && !force) {
|
|
55309
|
+
process.stderr.write(
|
|
55310
|
+
`Error: verifier already exists: ${existing}
|
|
55311
|
+
Use --force to overwrite. (T9218 idempotency guard)
|
|
55312
|
+
`
|
|
55313
|
+
);
|
|
55314
|
+
process.exitCode = 1;
|
|
55315
|
+
return;
|
|
55316
|
+
}
|
|
55317
|
+
try {
|
|
55318
|
+
const source = generateVerifierStub(
|
|
55319
|
+
task
|
|
55320
|
+
);
|
|
55321
|
+
const outPath = writeVerifierStub(taskId, source, projectRoot, force);
|
|
55322
|
+
process.stdout.write(`Generated: ${outPath}
|
|
55323
|
+
`);
|
|
55324
|
+
process.stdout.write(
|
|
55325
|
+
`
|
|
55326
|
+
Next steps:
|
|
55327
|
+
1. Replace each \`fail('STUB \u2014 ...')\` block with a real check.
|
|
55328
|
+
2. Verify manually: node ${outPath}
|
|
55329
|
+
3. When the script exits 0: cleo verify ${taskId} --acceptance-check
|
|
55330
|
+
`
|
|
55331
|
+
);
|
|
55332
|
+
} catch (err) {
|
|
55333
|
+
const msg = err.message ?? String(err);
|
|
55334
|
+
process.stderr.write(`Error generating verifier for ${taskId}: ${msg}
|
|
55335
|
+
`);
|
|
55336
|
+
process.exitCode = 1;
|
|
55337
|
+
}
|
|
55338
|
+
}
|
|
55339
|
+
async function backfillAllPending(projectRoot, force) {
|
|
55340
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55341
|
+
const pending = [];
|
|
55342
|
+
const queries = [
|
|
55343
|
+
dispatchRaw("query", "tasks", "list", { priority: "critical", limit: 200 }),
|
|
55344
|
+
dispatchRaw("query", "tasks", "list", { size: "large", limit: 200 }),
|
|
55345
|
+
dispatchRaw("query", "tasks", "list", { type: "epic", limit: 200 })
|
|
55346
|
+
];
|
|
55347
|
+
const results = await Promise.all(queries);
|
|
55348
|
+
for (const response of results) {
|
|
55349
|
+
if (!response.success) continue;
|
|
55350
|
+
const tasks = response.data?.tasks ?? [];
|
|
55351
|
+
for (const t of tasks) {
|
|
55352
|
+
const id = String(t.id ?? "");
|
|
55353
|
+
if (!id || seen.has(id)) continue;
|
|
55354
|
+
seen.add(id);
|
|
55355
|
+
pending.push(t);
|
|
55356
|
+
}
|
|
55357
|
+
}
|
|
55358
|
+
const lacking = pending.filter((t) => {
|
|
55359
|
+
const id = String(t.id ?? "");
|
|
55360
|
+
return !resolveVerifierScript2(id, projectRoot);
|
|
55361
|
+
});
|
|
55362
|
+
if (lacking.length === 0) {
|
|
55363
|
+
process.stdout.write(
|
|
55364
|
+
"All critical/large/epic tasks already have verifier scripts. Nothing to do.\n"
|
|
55365
|
+
);
|
|
55366
|
+
return;
|
|
55367
|
+
}
|
|
55368
|
+
process.stdout.write(
|
|
55369
|
+
`Found ${lacking.length} task(s) lacking a verifier script. Generating stubs...
|
|
55370
|
+
|
|
55371
|
+
`
|
|
55372
|
+
);
|
|
55373
|
+
let succeeded = 0;
|
|
55374
|
+
let skipped = 0;
|
|
55375
|
+
let failed = 0;
|
|
55376
|
+
for (const task of lacking) {
|
|
55377
|
+
const id = String(task.id ?? "");
|
|
55378
|
+
try {
|
|
55379
|
+
const source = generateVerifierStub(
|
|
55380
|
+
task
|
|
55381
|
+
);
|
|
55382
|
+
const outPath = writeVerifierStub(id, source, projectRoot, force);
|
|
55383
|
+
process.stdout.write(` [OK] ${id} \u2192 ${outPath}
|
|
55384
|
+
`);
|
|
55385
|
+
succeeded++;
|
|
55386
|
+
} catch (err) {
|
|
55387
|
+
const msg = err.message ?? String(err);
|
|
55388
|
+
if (msg.includes("verifier already exists")) {
|
|
55389
|
+
process.stdout.write(
|
|
55390
|
+
` [SKIP] ${id}: verifier already exists (use --force to overwrite)
|
|
55391
|
+
`
|
|
55392
|
+
);
|
|
55393
|
+
skipped++;
|
|
55394
|
+
} else {
|
|
55395
|
+
process.stderr.write(` [FAIL] ${id}: ${msg}
|
|
55396
|
+
`);
|
|
55397
|
+
failed++;
|
|
55398
|
+
}
|
|
55399
|
+
}
|
|
55400
|
+
}
|
|
55401
|
+
process.stdout.write(
|
|
55402
|
+
`
|
|
55403
|
+
Done: ${succeeded} generated, ${skipped} skipped (already exist), ${failed} failed.
|
|
55404
|
+
`
|
|
55405
|
+
);
|
|
55406
|
+
process.stdout.write(
|
|
55407
|
+
`
|
|
55408
|
+
Next steps for each generated file:
|
|
55409
|
+
1. Replace each \`fail('STUB \u2014 ...')\` block with a real check.
|
|
55410
|
+
2. node scripts/verify-<id>.mjs (must exit 0 before cleo complete)
|
|
55411
|
+
`
|
|
55412
|
+
);
|
|
55413
|
+
if (failed > 0) {
|
|
55414
|
+
process.exitCode = 1;
|
|
55415
|
+
}
|
|
55416
|
+
}
|
|
55417
|
+
var backfillCommand3, verifyCommand3;
|
|
55273
55418
|
var init_verify = __esm({
|
|
55274
55419
|
"packages/cleo/src/cli/commands/verify.ts"() {
|
|
55275
55420
|
"use strict";
|
|
55276
55421
|
init_dist();
|
|
55277
55422
|
init_cli();
|
|
55423
|
+
backfillCommand3 = defineCommand({
|
|
55424
|
+
meta: {
|
|
55425
|
+
name: "backfill",
|
|
55426
|
+
description: "Auto-generate a verifier stub from AC text for a task lacking one (T9218 / ADR-070)"
|
|
55427
|
+
},
|
|
55428
|
+
args: {
|
|
55429
|
+
taskId: {
|
|
55430
|
+
type: "positional",
|
|
55431
|
+
description: "Task ID to generate a verifier stub for (e.g. T9213). Omit when using --all-pending.",
|
|
55432
|
+
required: false
|
|
55433
|
+
},
|
|
55434
|
+
"all-pending": {
|
|
55435
|
+
type: "boolean",
|
|
55436
|
+
description: "Process all critical/large/epic tasks that lack a verifier script (T9218)"
|
|
55437
|
+
},
|
|
55438
|
+
force: {
|
|
55439
|
+
type: "boolean",
|
|
55440
|
+
description: "Overwrite an existing verifier without error (idempotency override)"
|
|
55441
|
+
}
|
|
55442
|
+
},
|
|
55443
|
+
async run({ args, cmd }) {
|
|
55444
|
+
const projectRoot = getProjectRoot33();
|
|
55445
|
+
const force = !!args.force;
|
|
55446
|
+
if (args["all-pending"]) {
|
|
55447
|
+
await backfillAllPending(projectRoot, force);
|
|
55448
|
+
return;
|
|
55449
|
+
}
|
|
55450
|
+
if (!args.taskId) {
|
|
55451
|
+
await showUsage(cmd);
|
|
55452
|
+
return;
|
|
55453
|
+
}
|
|
55454
|
+
await backfillSingle(String(args.taskId), projectRoot, force);
|
|
55455
|
+
}
|
|
55456
|
+
});
|
|
55278
55457
|
verifyCommand3 = defineCommand({
|
|
55279
55458
|
meta: { name: "verify", description: "View or modify verification gates for a task" },
|
|
55280
55459
|
args: {
|
|
@@ -55327,6 +55506,21 @@ var init_verify = __esm({
|
|
|
55327
55506
|
await showUsage(cmd);
|
|
55328
55507
|
return;
|
|
55329
55508
|
}
|
|
55509
|
+
if (args.taskId === "backfill") {
|
|
55510
|
+
const remainingArgs = process.argv.slice(process.argv.indexOf("backfill") + 1);
|
|
55511
|
+
const taskIdArg = remainingArgs.find((a) => !a.startsWith("-"));
|
|
55512
|
+
const allPending = remainingArgs.includes("--all-pending");
|
|
55513
|
+
const force = remainingArgs.includes("--force");
|
|
55514
|
+
const projectRoot = getProjectRoot33();
|
|
55515
|
+
if (allPending) {
|
|
55516
|
+
await backfillAllPending(projectRoot, force);
|
|
55517
|
+
} else if (taskIdArg) {
|
|
55518
|
+
await backfillSingle(taskIdArg, projectRoot, force);
|
|
55519
|
+
} else {
|
|
55520
|
+
await showUsage(cmd);
|
|
55521
|
+
}
|
|
55522
|
+
return;
|
|
55523
|
+
}
|
|
55330
55524
|
const acceptanceCheckRaw = args["acceptance-check"];
|
|
55331
55525
|
const shouldRunAcceptanceCheck = acceptanceCheckRaw !== void 0 && acceptanceCheckRaw !== false;
|
|
55332
55526
|
if (shouldRunAcceptanceCheck) {
|
|
@@ -56890,7 +57084,7 @@ async function runStartupMaintenance() {
|
|
|
56890
57084
|
detectAndRemoveStrayProjectNexus,
|
|
56891
57085
|
getGlobalSalt,
|
|
56892
57086
|
getLogger: getLogger17,
|
|
56893
|
-
getProjectRoot:
|
|
57087
|
+
getProjectRoot: getProjectRoot34,
|
|
56894
57088
|
isCleanupMarkerSet,
|
|
56895
57089
|
migrateSignaldockToConduit,
|
|
56896
57090
|
needsSignaldockToConduitMigration,
|
|
@@ -56899,7 +57093,7 @@ async function runStartupMaintenance() {
|
|
|
56899
57093
|
} = await import("@cleocode/core/internal");
|
|
56900
57094
|
let projectRootForCleanup = "";
|
|
56901
57095
|
try {
|
|
56902
|
-
projectRootForCleanup =
|
|
57096
|
+
projectRootForCleanup = getProjectRoot34();
|
|
56903
57097
|
} catch {
|
|
56904
57098
|
}
|
|
56905
57099
|
if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
|
|
@@ -56919,7 +57113,7 @@ async function runStartupMaintenance() {
|
|
|
56919
57113
|
const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
|
|
56920
57114
|
if (!isInitInvocation) {
|
|
56921
57115
|
try {
|
|
56922
|
-
const _projectRootForMigration =
|
|
57116
|
+
const _projectRootForMigration = getProjectRoot34();
|
|
56923
57117
|
if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
|
|
56924
57118
|
const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
|
|
56925
57119
|
if (migrationResult.status === "failed") {
|