@cleocode/cleo 2026.5.0 → 2026.5.1
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.
|
@@ -13,8 +13,13 @@
|
|
|
13
13
|
* when a task touches symbols with CRITICAL impact risk. The acknowledgment is
|
|
14
14
|
* audited to `.cleo/audit/nexus-risk-ack.jsonl`.
|
|
15
15
|
*
|
|
16
|
+
* As of T1632, `cleo complete <epicId>` is REJECTED with E_EPIC_HAS_PENDING_CHILDREN
|
|
17
|
+
* when the epic has pending or active children. Pass `--override-reason "<reason>"`
|
|
18
|
+
* to bypass (audited to `.cleo/audit/premature-close.jsonl`).
|
|
19
|
+
*
|
|
16
20
|
* @task T4461
|
|
17
21
|
* @task T832
|
|
22
|
+
* @task T1632
|
|
18
23
|
* @adr ADR-051
|
|
19
24
|
* @epic T4454
|
|
20
25
|
*/
|
|
@@ -45,5 +50,9 @@ export declare const completeCommand: import("citty").CommandDef<{
|
|
|
45
50
|
readonly type: "string";
|
|
46
51
|
readonly description: "Reason for acknowledging CRITICAL impact risk (bypasses nexusImpact gate)";
|
|
47
52
|
};
|
|
53
|
+
readonly 'override-reason': {
|
|
54
|
+
readonly type: "string";
|
|
55
|
+
readonly description: "Reason for bypassing E_EPIC_HAS_PENDING_CHILDREN guard (audited to .cleo/audit/premature-close.jsonl)";
|
|
56
|
+
};
|
|
48
57
|
}>;
|
|
49
58
|
//# sourceMappingURL=complete.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/complete.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/complete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAMH;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;EA8D1B,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -416,6 +416,7 @@ var init_exit_codes = __esm({
|
|
|
416
416
|
ExitCode2[ExitCode2["VERIFICATION_LOCKED"] = 46] = "VERIFICATION_LOCKED";
|
|
417
417
|
ExitCode2[ExitCode2["ROUND_MISMATCH"] = 47] = "ROUND_MISMATCH";
|
|
418
418
|
ExitCode2[ExitCode2["AC_LOCKED"] = 48] = "AC_LOCKED";
|
|
419
|
+
ExitCode2[ExitCode2["EPIC_HAS_PENDING_CHILDREN"] = 49] = "EPIC_HAS_PENDING_CHILDREN";
|
|
419
420
|
ExitCode2[ExitCode2["CONTEXT_WARNING"] = 50] = "CONTEXT_WARNING";
|
|
420
421
|
ExitCode2[ExitCode2["CONTEXT_CAUTION"] = 51] = "CONTEXT_CAUTION";
|
|
421
422
|
ExitCode2[ExitCode2["CONTEXT_CRITICAL"] = 52] = "CONTEXT_CRITICAL";
|
|
@@ -465,6 +466,7 @@ var init_exit_codes = __esm({
|
|
|
465
466
|
ExitCode2[ExitCode2["ALREADY_EXISTS"] = 101] = "ALREADY_EXISTS";
|
|
466
467
|
ExitCode2[ExitCode2["NO_CHANGE"] = 102] = "NO_CHANGE";
|
|
467
468
|
ExitCode2[ExitCode2["TESTS_SKIPPED"] = 103] = "TESTS_SKIPPED";
|
|
469
|
+
ExitCode2[ExitCode2["DUPLICATE_TASK_LIKELY"] = 105] = "DUPLICATE_TASK_LIKELY";
|
|
468
470
|
ExitCode2[ExitCode2["LAFS_VIOLATION"] = 104] = "LAFS_VIOLATION";
|
|
469
471
|
return ExitCode2;
|
|
470
472
|
})(ExitCode || {});
|
|
@@ -24218,7 +24220,9 @@ var init_tasks3 = __esm({
|
|
|
24218
24220
|
// T944: orthogonal axes — role is the canonical wire field (ADR-057 D2)
|
|
24219
24221
|
role: params.role,
|
|
24220
24222
|
scope: params.scope,
|
|
24221
|
-
severity: params.severity
|
|
24223
|
+
severity: params.severity,
|
|
24224
|
+
// T1633: BRAIN duplicate-bypass flag
|
|
24225
|
+
forceDuplicate: params.forceDuplicate
|
|
24222
24226
|
}),
|
|
24223
24227
|
"add"
|
|
24224
24228
|
);
|
|
@@ -24260,7 +24264,11 @@ var init_tasks3 = __esm({
|
|
|
24260
24264
|
"complete"
|
|
24261
24265
|
);
|
|
24262
24266
|
}
|
|
24263
|
-
const result = await completeTaskStrict(projectRoot, params.taskId,
|
|
24267
|
+
const result = await completeTaskStrict(projectRoot, params.taskId, {
|
|
24268
|
+
notes: params.notes,
|
|
24269
|
+
overrideReason: params.overrideReason,
|
|
24270
|
+
acknowledgeRisk: params.acknowledgeRisk
|
|
24271
|
+
});
|
|
24264
24272
|
setImmediate(async () => {
|
|
24265
24273
|
try {
|
|
24266
24274
|
const { trackMemoryUsage } = await import("@cleocode/core/internal");
|
|
@@ -26882,6 +26890,19 @@ var addCommand = defineCommand({
|
|
|
26882
26890
|
severity: {
|
|
26883
26891
|
type: "string",
|
|
26884
26892
|
description: "Bug severity (P0|P1|P2|P3) \u2014 only valid with --role bug (T944)"
|
|
26893
|
+
},
|
|
26894
|
+
/**
|
|
26895
|
+
* Bypass the E_DUPLICATE_TASK_LIKELY rejection guard.
|
|
26896
|
+
*
|
|
26897
|
+
* When passed, `cleo add` proceeds even if BRAIN similarity scoring
|
|
26898
|
+
* determines the task is very likely a duplicate (score >= 0.92).
|
|
26899
|
+
* The bypass is audited to `.cleo/audit/duplicate-bypass.jsonl`.
|
|
26900
|
+
*
|
|
26901
|
+
* @task T1633
|
|
26902
|
+
*/
|
|
26903
|
+
"force-duplicate": {
|
|
26904
|
+
type: "boolean",
|
|
26905
|
+
description: "Bypass BRAIN duplicate-task rejection (audited to .cleo/audit/duplicate-bypass.jsonl) (T1633)"
|
|
26885
26906
|
}
|
|
26886
26907
|
},
|
|
26887
26908
|
async run({ args, cmd }) {
|
|
@@ -26916,6 +26937,7 @@ var addCommand = defineCommand({
|
|
|
26916
26937
|
params["role"] = params["role"] ?? args.kind;
|
|
26917
26938
|
if (args.scope !== void 0) params["scope"] = args.scope;
|
|
26918
26939
|
if (args.severity !== void 0) params["severity"] = args.severity;
|
|
26940
|
+
if (args["force-duplicate"] !== void 0) params["forceDuplicate"] = args["force-duplicate"];
|
|
26919
26941
|
const inferred = await inferTaskAddParams(getProjectRoot18(), {
|
|
26920
26942
|
title: args.title,
|
|
26921
26943
|
description: args.description ?? args.desc,
|
|
@@ -33013,6 +33035,10 @@ var completeCommand = defineCommand({
|
|
|
33013
33035
|
"acknowledge-risk": {
|
|
33014
33036
|
type: "string",
|
|
33015
33037
|
description: "Reason for acknowledging CRITICAL impact risk (bypasses nexusImpact gate)"
|
|
33038
|
+
},
|
|
33039
|
+
"override-reason": {
|
|
33040
|
+
type: "string",
|
|
33041
|
+
description: "Reason for bypassing E_EPIC_HAS_PENDING_CHILDREN guard (audited to .cleo/audit/premature-close.jsonl)"
|
|
33016
33042
|
}
|
|
33017
33043
|
},
|
|
33018
33044
|
async run({ args }) {
|
|
@@ -33021,7 +33047,8 @@ var completeCommand = defineCommand({
|
|
|
33021
33047
|
notes: args.notes,
|
|
33022
33048
|
changeset: args.changeset,
|
|
33023
33049
|
verificationNote: args["verification-note"],
|
|
33024
|
-
acknowledgeRisk: args["acknowledge-risk"]
|
|
33050
|
+
acknowledgeRisk: args["acknowledge-risk"],
|
|
33051
|
+
overrideReason: args["override-reason"]
|
|
33025
33052
|
});
|
|
33026
33053
|
if (!response.success) {
|
|
33027
33054
|
handleRawError(response, { command: "complete", operation: "tasks.complete" });
|
|
@@ -34000,30 +34027,88 @@ var currentCommand = defineCommand({
|
|
|
34000
34027
|
import { homedir as homedir2 } from "node:os";
|
|
34001
34028
|
import { join as join9 } from "node:path";
|
|
34002
34029
|
import { getGCDaemonStatus, spawnGCDaemon, stopGCDaemon } from "@cleocode/core/gc/daemon.js";
|
|
34003
|
-
|
|
34030
|
+
import { getSentientDaemonStatus } from "@cleocode/core/sentient";
|
|
34031
|
+
async function showDaemonStatus(cleoDir, projectRoot, json2) {
|
|
34004
34032
|
try {
|
|
34005
|
-
const
|
|
34006
|
-
|
|
34033
|
+
const gcStatus = await getGCDaemonStatus(cleoDir);
|
|
34034
|
+
let hygieneLastRunAt = null;
|
|
34035
|
+
let hygieneSummary = null;
|
|
34036
|
+
let hygieneStats = {
|
|
34037
|
+
projectsChecked: 0,
|
|
34038
|
+
projectsHealthy: 0,
|
|
34039
|
+
tempGcCandidates: 0,
|
|
34040
|
+
duplicateEpicGroups: 0,
|
|
34041
|
+
worktreesPruned: 0
|
|
34042
|
+
};
|
|
34043
|
+
try {
|
|
34044
|
+
const sentientStatus = await getSentientDaemonStatus(projectRoot);
|
|
34045
|
+
hygieneLastRunAt = sentientStatus.hygieneLastRunAt;
|
|
34046
|
+
hygieneSummary = sentientStatus.hygieneSummary;
|
|
34047
|
+
hygieneStats = sentientStatus.hygieneStats;
|
|
34048
|
+
} catch {
|
|
34049
|
+
}
|
|
34050
|
+
const result = {
|
|
34051
|
+
success: true,
|
|
34052
|
+
data: {
|
|
34053
|
+
gc: gcStatus,
|
|
34054
|
+
hygiene: {
|
|
34055
|
+
lastRunAt: hygieneLastRunAt,
|
|
34056
|
+
summary: hygieneSummary,
|
|
34057
|
+
stats: hygieneStats
|
|
34058
|
+
}
|
|
34059
|
+
}
|
|
34060
|
+
};
|
|
34007
34061
|
if (json2) {
|
|
34008
34062
|
process.stdout.write(JSON.stringify(result) + "\n");
|
|
34009
34063
|
} else {
|
|
34010
|
-
const runningStr =
|
|
34011
|
-
process.stdout.write(`Daemon: ${runningStr}
|
|
34064
|
+
const runningStr = gcStatus.running ? `running (PID ${gcStatus.pid})` : "stopped";
|
|
34065
|
+
process.stdout.write(`GC Daemon: ${runningStr}
|
|
34012
34066
|
`);
|
|
34013
|
-
process.stdout.write(`Started at:
|
|
34067
|
+
process.stdout.write(`Started at: ${gcStatus.startedAt ?? "never"}
|
|
34014
34068
|
`);
|
|
34015
|
-
process.stdout.write(`Last GC run:
|
|
34069
|
+
process.stdout.write(`Last GC run: ${gcStatus.lastRunAt ?? "never"}
|
|
34016
34070
|
`);
|
|
34017
|
-
const diskStr =
|
|
34018
|
-
process.stdout.write(`Disk used:
|
|
34071
|
+
const diskStr = gcStatus.lastDiskUsedPct !== null ? `${gcStatus.lastDiskUsedPct.toFixed(1)}%` : "unknown";
|
|
34072
|
+
process.stdout.write(`Disk used: ${diskStr}
|
|
34019
34073
|
`);
|
|
34020
|
-
if (
|
|
34074
|
+
if (gcStatus.escalationNeeded) {
|
|
34021
34075
|
process.stdout.write(
|
|
34022
34076
|
`
|
|
34023
34077
|
WARNING: Disk threshold breached. Run 'cleo gc run' to reclaim space.
|
|
34024
34078
|
`
|
|
34025
34079
|
);
|
|
34026
34080
|
}
|
|
34081
|
+
process.stdout.write(`
|
|
34082
|
+
Hygiene Loop (cross-project):
|
|
34083
|
+
`);
|
|
34084
|
+
process.stdout.write(` Last run: ${hygieneLastRunAt ?? "never"}
|
|
34085
|
+
`);
|
|
34086
|
+
process.stdout.write(` Summary: ${hygieneSummary ?? "not yet run"}
|
|
34087
|
+
`);
|
|
34088
|
+
if (hygieneStats.projectsChecked > 0) {
|
|
34089
|
+
process.stdout.write(
|
|
34090
|
+
` Projects: ${hygieneStats.projectsHealthy}/${hygieneStats.projectsChecked} healthy
|
|
34091
|
+
`
|
|
34092
|
+
);
|
|
34093
|
+
if (hygieneStats.tempGcCandidates > 0) {
|
|
34094
|
+
process.stdout.write(
|
|
34095
|
+
` Temp GC: ${hygieneStats.tempGcCandidates} candidate(s) pending approval
|
|
34096
|
+
`
|
|
34097
|
+
);
|
|
34098
|
+
}
|
|
34099
|
+
if (hygieneStats.duplicateEpicGroups > 0) {
|
|
34100
|
+
process.stdout.write(
|
|
34101
|
+
` Duplicate epics: ${hygieneStats.duplicateEpicGroups} group(s) detected
|
|
34102
|
+
`
|
|
34103
|
+
);
|
|
34104
|
+
}
|
|
34105
|
+
if (hygieneStats.worktreesPruned > 0) {
|
|
34106
|
+
process.stdout.write(
|
|
34107
|
+
` Worktrees: ${hygieneStats.worktreesPruned} stale worktree(s) pruned
|
|
34108
|
+
`
|
|
34109
|
+
);
|
|
34110
|
+
}
|
|
34111
|
+
}
|
|
34027
34112
|
}
|
|
34028
34113
|
} catch (err) {
|
|
34029
34114
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -34144,7 +34229,7 @@ var stopCommand3 = defineCommand({
|
|
|
34144
34229
|
var statusCommand4 = defineCommand({
|
|
34145
34230
|
meta: {
|
|
34146
34231
|
name: "status",
|
|
34147
|
-
description: "Show daemon running state, PID, last GC run, and
|
|
34232
|
+
description: "Show daemon running state, PID, last GC run, disk usage, and cross-project hygiene summary"
|
|
34148
34233
|
},
|
|
34149
34234
|
args: {
|
|
34150
34235
|
"cleo-dir": {
|
|
@@ -34158,7 +34243,7 @@ var statusCommand4 = defineCommand({
|
|
|
34158
34243
|
},
|
|
34159
34244
|
async run({ args }) {
|
|
34160
34245
|
const cleoDir = args["cleo-dir"] ?? join9(homedir2(), ".cleo");
|
|
34161
|
-
await showDaemonStatus(cleoDir, args.json ?? false);
|
|
34246
|
+
await showDaemonStatus(cleoDir, process.cwd(), args.json ?? false);
|
|
34162
34247
|
}
|
|
34163
34248
|
});
|
|
34164
34249
|
var daemonCommand = defineCommand({
|
|
@@ -34184,7 +34269,7 @@ var daemonCommand = defineCommand({
|
|
|
34184
34269
|
async run({ args, cmd, rawArgs }) {
|
|
34185
34270
|
if (isSubCommandDispatch(rawArgs, cmd.subCommands)) return;
|
|
34186
34271
|
const cleoDir = args["cleo-dir"] ?? join9(homedir2(), ".cleo");
|
|
34187
|
-
await showDaemonStatus(cleoDir, args.json ?? false);
|
|
34272
|
+
await showDaemonStatus(cleoDir, process.cwd(), args.json ?? false);
|
|
34188
34273
|
}
|
|
34189
34274
|
});
|
|
34190
34275
|
|
|
@@ -34199,6 +34284,10 @@ var dashCommand = defineCommand({
|
|
|
34199
34284
|
"blocked-limit": {
|
|
34200
34285
|
type: "string",
|
|
34201
34286
|
description: "Max blocked tasks to show"
|
|
34287
|
+
},
|
|
34288
|
+
"no-hygiene": {
|
|
34289
|
+
type: "boolean",
|
|
34290
|
+
description: "Suppress the hygiene section note"
|
|
34202
34291
|
}
|
|
34203
34292
|
},
|
|
34204
34293
|
async run({ args }) {
|
|
@@ -34211,6 +34300,11 @@ var dashCommand = defineCommand({
|
|
|
34211
34300
|
},
|
|
34212
34301
|
{ command: "dash" }
|
|
34213
34302
|
);
|
|
34303
|
+
if (!args["no-hygiene"]) {
|
|
34304
|
+
process.stdout.write(
|
|
34305
|
+
"\n--- Sentient Hygiene (T1636) ---\nBackground scan runs every 4h (dream cycle). Run `cleo memory digest --hygiene` to see the latest hygiene observations (orphan tasks, top-level tasks without an epic, content defects, premature-close leaks).\n"
|
|
34306
|
+
);
|
|
34307
|
+
}
|
|
34214
34308
|
}
|
|
34215
34309
|
});
|
|
34216
34310
|
|
|
@@ -40266,21 +40360,49 @@ var backfillCommand3 = defineCommand({
|
|
|
40266
40360
|
await showUsage(cmd);
|
|
40267
40361
|
}
|
|
40268
40362
|
});
|
|
40269
|
-
var digestCommand =
|
|
40270
|
-
|
|
40271
|
-
|
|
40363
|
+
var digestCommand = defineCommand({
|
|
40364
|
+
meta: {
|
|
40365
|
+
name: "digest",
|
|
40366
|
+
description: "Summarized top-N brain observations for session briefing (T1006). Pass --hygiene to show latest hygiene scan results from the sentient background loop (T1636)."
|
|
40367
|
+
},
|
|
40272
40368
|
args: {
|
|
40273
40369
|
limit: {
|
|
40274
40370
|
type: "string",
|
|
40275
40371
|
description: "Maximum number of observations to include (default: 10)."
|
|
40372
|
+
},
|
|
40373
|
+
hygiene: {
|
|
40374
|
+
type: "boolean",
|
|
40375
|
+
description: "Show only hygiene observations (hygiene:orphan, hygiene:top-level-orphan, hygiene:content-defect, hygiene:premature-close-leak) from the sentient background loop (T1636)."
|
|
40376
|
+
},
|
|
40377
|
+
json: {
|
|
40378
|
+
type: "boolean",
|
|
40379
|
+
description: "Output as JSON"
|
|
40276
40380
|
}
|
|
40277
40381
|
},
|
|
40278
|
-
|
|
40279
|
-
|
|
40280
|
-
|
|
40281
|
-
|
|
40282
|
-
|
|
40283
|
-
|
|
40382
|
+
async run({ args }) {
|
|
40383
|
+
if (args.hygiene) {
|
|
40384
|
+
await dispatchFromCli(
|
|
40385
|
+
"query",
|
|
40386
|
+
"memory",
|
|
40387
|
+
"find",
|
|
40388
|
+
{
|
|
40389
|
+
query: "hygiene:",
|
|
40390
|
+
limit: args.limit !== void 0 ? parseInt(args.limit, 10) : 20
|
|
40391
|
+
},
|
|
40392
|
+
{ command: "memory-hygiene-digest", operation: "memory.find" }
|
|
40393
|
+
);
|
|
40394
|
+
} else {
|
|
40395
|
+
await dispatchFromCli(
|
|
40396
|
+
"query",
|
|
40397
|
+
"memory",
|
|
40398
|
+
"digest",
|
|
40399
|
+
{
|
|
40400
|
+
...args["limit"] !== void 0 && { limit: parseInt(args["limit"], 10) }
|
|
40401
|
+
},
|
|
40402
|
+
{ command: "memory-digest", operation: "memory.digest" }
|
|
40403
|
+
);
|
|
40404
|
+
}
|
|
40405
|
+
}
|
|
40284
40406
|
});
|
|
40285
40407
|
var recentCommand = makeMemorySubcommand({
|
|
40286
40408
|
name: "recent",
|
|
@@ -48696,7 +48818,7 @@ async function runPostUpdateDiagnostics(opts) {
|
|
|
48696
48818
|
import { join as join16 } from "node:path";
|
|
48697
48819
|
import { cwd as processCwd } from "node:process";
|
|
48698
48820
|
import {
|
|
48699
|
-
getSentientDaemonStatus,
|
|
48821
|
+
getSentientDaemonStatus as getSentientDaemonStatus2,
|
|
48700
48822
|
resumeSentientDaemon,
|
|
48701
48823
|
SENTIENT_STATE_FILE,
|
|
48702
48824
|
spawnSentientDaemon,
|
|
@@ -48754,7 +48876,7 @@ var startSub = defineCommand({
|
|
|
48754
48876
|
const jsonMode = args.json === true;
|
|
48755
48877
|
const dryRun = args["dry-run"] === true;
|
|
48756
48878
|
try {
|
|
48757
|
-
const existing = await
|
|
48879
|
+
const existing = await getSentientDaemonStatus2(projectRoot);
|
|
48758
48880
|
if (existing.running && existing.pid) {
|
|
48759
48881
|
emitSuccess(
|
|
48760
48882
|
{ running: true, pid: existing.pid, message: "daemon already running" },
|
|
@@ -48822,7 +48944,7 @@ var statusSub = defineCommand({
|
|
|
48822
48944
|
const projectRoot = resolveProjectRoot4(args.project);
|
|
48823
48945
|
const jsonMode = args.json === true;
|
|
48824
48946
|
try {
|
|
48825
|
-
const status = await
|
|
48947
|
+
const status = await getSentientDaemonStatus2(projectRoot);
|
|
48826
48948
|
if (jsonMode) {
|
|
48827
48949
|
process.stdout.write(`${JSON.stringify({ success: true, data: status })}
|
|
48828
48950
|
`);
|
|
@@ -49334,7 +49456,7 @@ var sentientCommand = defineCommand({
|
|
|
49334
49456
|
const projectRoot = resolveProjectRoot4(args.project);
|
|
49335
49457
|
const jsonMode = args.json === true;
|
|
49336
49458
|
try {
|
|
49337
|
-
const status = await
|
|
49459
|
+
const status = await getSentientDaemonStatus2(projectRoot);
|
|
49338
49460
|
if (jsonMode) {
|
|
49339
49461
|
process.stdout.write(`${JSON.stringify({ success: true, data: status })}
|
|
49340
49462
|
`);
|