@cleocode/cleo 2026.5.106 → 2026.5.108
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 +471 -2138
- package/dist/cli/index.js.map +3 -3
- package/package.json +11 -11
- package/templates/HANDOFF-REDIRECT-STUB.md +0 -37
- package/templates/hooks/commit-msg +0 -213
- package/templates/hooks/pre-push +0 -87
- package/templates/hooks/pre-push.t1595-extension.sh +0 -140
- package/templates/workflows/README.md +0 -157
- package/templates/workflows/release-fanout.yml.tmpl +0 -214
- package/templates/workflows/release-prepare.yml.tmpl +0 -296
- package/templates/workflows/release-publish.yml.tmpl +0 -388
- package/templates/workflows/release-rollback.yml.tmpl +0 -322
package/dist/cli/index.js
CHANGED
|
@@ -26,14 +26,14 @@ function isUppercase(char = "") {
|
|
|
26
26
|
if (NUMBER_CHAR_RE.test(char)) return;
|
|
27
27
|
return char !== char.toLowerCase();
|
|
28
28
|
}
|
|
29
|
-
function splitByCase(
|
|
29
|
+
function splitByCase(str2, separators) {
|
|
30
30
|
const splitters = separators ?? STR_SPLITTERS;
|
|
31
31
|
const parts = [];
|
|
32
|
-
if (!
|
|
32
|
+
if (!str2 || typeof str2 !== "string") return parts;
|
|
33
33
|
let buff = "";
|
|
34
34
|
let previousUpper;
|
|
35
35
|
let previousSplitter;
|
|
36
|
-
for (const char of
|
|
36
|
+
for (const char of str2) {
|
|
37
37
|
const isSplitter = splitters.includes(char);
|
|
38
38
|
if (isSplitter === true) {
|
|
39
39
|
parts.push(buff);
|
|
@@ -64,20 +64,20 @@ function splitByCase(str3, separators) {
|
|
|
64
64
|
parts.push(buff);
|
|
65
65
|
return parts;
|
|
66
66
|
}
|
|
67
|
-
function upperFirst(
|
|
68
|
-
return
|
|
67
|
+
function upperFirst(str2) {
|
|
68
|
+
return str2 ? str2[0].toUpperCase() + str2.slice(1) : "";
|
|
69
69
|
}
|
|
70
|
-
function lowerFirst(
|
|
71
|
-
return
|
|
70
|
+
function lowerFirst(str2) {
|
|
71
|
+
return str2 ? str2[0].toLowerCase() + str2.slice(1) : "";
|
|
72
72
|
}
|
|
73
|
-
function pascalCase(
|
|
74
|
-
return
|
|
73
|
+
function pascalCase(str2, opts) {
|
|
74
|
+
return str2 ? (Array.isArray(str2) ? str2 : splitByCase(str2)).map((p) => upperFirst(opts?.normalize ? p.toLowerCase() : p)).join("") : "";
|
|
75
75
|
}
|
|
76
|
-
function camelCase(
|
|
77
|
-
return lowerFirst(pascalCase(
|
|
76
|
+
function camelCase(str2, opts) {
|
|
77
|
+
return lowerFirst(pascalCase(str2 || "", opts));
|
|
78
78
|
}
|
|
79
|
-
function kebabCase(
|
|
80
|
-
return
|
|
79
|
+
function kebabCase(str2, joiner) {
|
|
80
|
+
return str2 ? (Array.isArray(str2) ? str2 : splitByCase(str2)).map((p) => p.toLowerCase()).join(joiner ?? "-") : "";
|
|
81
81
|
}
|
|
82
82
|
var NUMBER_CHAR_RE, STR_SPLITTERS;
|
|
83
83
|
var init_scule = __esm({
|
|
@@ -402,6 +402,9 @@ function getFormatContext() {
|
|
|
402
402
|
function isJsonFormat() {
|
|
403
403
|
return currentResolution.format === "json";
|
|
404
404
|
}
|
|
405
|
+
function isQuiet() {
|
|
406
|
+
return currentResolution.quiet;
|
|
407
|
+
}
|
|
405
408
|
var currentResolution;
|
|
406
409
|
var init_format_context = __esm({
|
|
407
410
|
"packages/cleo/src/cli/format-context.ts"() {
|
|
@@ -1076,6 +1079,123 @@ var init_braille = __esm({
|
|
|
1076
1079
|
}
|
|
1077
1080
|
});
|
|
1078
1081
|
|
|
1082
|
+
// packages/animations/src/render/tree.ts
|
|
1083
|
+
import { ascii, KindIcon, StatusIcon } from "@cleocode/contracts/render/icon.js";
|
|
1084
|
+
function renderTree(resp, opts) {
|
|
1085
|
+
if (!opts.ctx.enabled) return "";
|
|
1086
|
+
if (resp.tree.length === 0) return "";
|
|
1087
|
+
const useAscii = opts.asciiBoxDrawing ?? opts.ctx.inputs.noColor;
|
|
1088
|
+
const connectors = useAscii ? CONNECTOR_ASCII : CONNECTOR_UNICODE;
|
|
1089
|
+
const foldAt = opts.foldAt ?? DEFAULT_FOLD_AT;
|
|
1090
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
1091
|
+
let rootNode;
|
|
1092
|
+
for (const node of resp.tree) {
|
|
1093
|
+
if (node.parentId === null) {
|
|
1094
|
+
if (node.id === resp.root) rootNode = node;
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
const bucket = childrenByParent.get(node.parentId);
|
|
1098
|
+
if (bucket) bucket.push(node);
|
|
1099
|
+
else childrenByParent.set(node.parentId, [node]);
|
|
1100
|
+
}
|
|
1101
|
+
if (rootNode === void 0) return "";
|
|
1102
|
+
const lines = [];
|
|
1103
|
+
lines.push(formatRow(rootNode, "", useAscii));
|
|
1104
|
+
emitChildren(rootNode.id, [], childrenByParent, connectors, foldAt, useAscii, lines);
|
|
1105
|
+
return lines.join("\n");
|
|
1106
|
+
}
|
|
1107
|
+
function emitChildren(parentId, ancestorIsLast, childrenByParent, connectors, foldAt, useAscii, out) {
|
|
1108
|
+
const children = childrenByParent.get(parentId);
|
|
1109
|
+
if (children === void 0 || children.length === 0) return;
|
|
1110
|
+
const ancestorPrefix = ancestorIsLast.map((isLast) => isLast ? connectors.blank : connectors.vertical).join("");
|
|
1111
|
+
const shouldFold = children.length > foldAt;
|
|
1112
|
+
const visibleCount = shouldFold ? foldAt - 1 : children.length;
|
|
1113
|
+
const visible = children.slice(0, visibleCount);
|
|
1114
|
+
for (let i = 0; i < visible.length; i++) {
|
|
1115
|
+
const child = visible[i];
|
|
1116
|
+
if (child === void 0) continue;
|
|
1117
|
+
const isLastInBatch = !shouldFold && i === children.length - 1;
|
|
1118
|
+
const connector = isLastInBatch ? connectors.leaf : connectors.branch;
|
|
1119
|
+
out.push(formatRow(child, `${ancestorPrefix}${connector}`, useAscii));
|
|
1120
|
+
emitChildren(
|
|
1121
|
+
child.id,
|
|
1122
|
+
[...ancestorIsLast, isLastInBatch],
|
|
1123
|
+
childrenByParent,
|
|
1124
|
+
connectors,
|
|
1125
|
+
foldAt,
|
|
1126
|
+
useAscii,
|
|
1127
|
+
out
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
if (shouldFold) {
|
|
1131
|
+
const hidden = children.length - visibleCount;
|
|
1132
|
+
const sampleKind = children[0]?.kind ?? "task";
|
|
1133
|
+
const label = KIND_LABEL[sampleKind];
|
|
1134
|
+
out.push(
|
|
1135
|
+
`${ancestorPrefix}${connectors.leaf}\u2026 and ${hidden} more ${label} (run cleo tree ${parentId} to expand)`
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
function formatRow(node, prefix, useAscii) {
|
|
1140
|
+
const kindIcon = resolveKindIcon(node.kind, useAscii);
|
|
1141
|
+
const statusIcon = resolveStatusIcon(node.status, useAscii);
|
|
1142
|
+
return `${prefix}${kindIcon} ${node.title} ${statusIcon}`.trimEnd();
|
|
1143
|
+
}
|
|
1144
|
+
function resolveKindIcon(kind, useAscii) {
|
|
1145
|
+
const icon = KIND_BY_NODE_KIND[kind];
|
|
1146
|
+
return useAscii ? ascii(icon) : icon;
|
|
1147
|
+
}
|
|
1148
|
+
function resolveStatusIcon(status, useAscii) {
|
|
1149
|
+
const icon = STATUS_BY_NODE_STATUS[status];
|
|
1150
|
+
return useAscii ? ascii(icon) : icon;
|
|
1151
|
+
}
|
|
1152
|
+
var DEFAULT_FOLD_AT, CONNECTOR_UNICODE, CONNECTOR_ASCII, KIND_LABEL, KIND_BY_NODE_KIND, STATUS_BY_NODE_STATUS;
|
|
1153
|
+
var init_tree = __esm({
|
|
1154
|
+
"packages/animations/src/render/tree.ts"() {
|
|
1155
|
+
"use strict";
|
|
1156
|
+
DEFAULT_FOLD_AT = 50;
|
|
1157
|
+
CONNECTOR_UNICODE = Object.freeze({
|
|
1158
|
+
branch: "\u251C\u2500 ",
|
|
1159
|
+
leaf: "\u2514\u2500 ",
|
|
1160
|
+
vertical: "\u2502 ",
|
|
1161
|
+
blank: " "
|
|
1162
|
+
});
|
|
1163
|
+
CONNECTOR_ASCII = Object.freeze({
|
|
1164
|
+
branch: "+- ",
|
|
1165
|
+
leaf: "+- ",
|
|
1166
|
+
vertical: "| ",
|
|
1167
|
+
blank: " "
|
|
1168
|
+
});
|
|
1169
|
+
KIND_LABEL = {
|
|
1170
|
+
saga: "sagas",
|
|
1171
|
+
epic: "epics",
|
|
1172
|
+
task: "tasks",
|
|
1173
|
+
subtask: "subtasks"
|
|
1174
|
+
};
|
|
1175
|
+
KIND_BY_NODE_KIND = {
|
|
1176
|
+
saga: KindIcon.SAGA,
|
|
1177
|
+
epic: KindIcon.EPIC,
|
|
1178
|
+
task: KindIcon.TASK,
|
|
1179
|
+
subtask: KindIcon.SUBTASK
|
|
1180
|
+
};
|
|
1181
|
+
STATUS_BY_NODE_STATUS = {
|
|
1182
|
+
pending: StatusIcon.PENDING,
|
|
1183
|
+
in_progress: StatusIcon.ACTIVE,
|
|
1184
|
+
done: StatusIcon.DONE,
|
|
1185
|
+
blocked: StatusIcon.BLOCKED,
|
|
1186
|
+
cancelled: StatusIcon.CANCELLED,
|
|
1187
|
+
archived: StatusIcon.ARCHIVED
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
// packages/animations/src/render/index.ts
|
|
1193
|
+
var init_render = __esm({
|
|
1194
|
+
"packages/animations/src/render/index.ts"() {
|
|
1195
|
+
init_tree();
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1079
1199
|
// packages/animations/src/spinner-handle.ts
|
|
1080
1200
|
function ensureProcessExitListeners() {
|
|
1081
1201
|
if (exitListenersInstalled) return;
|
|
@@ -1188,6 +1308,7 @@ var init_spinner_handle = __esm({
|
|
|
1188
1308
|
var init_src = __esm({
|
|
1189
1309
|
"packages/animations/src/index.ts"() {
|
|
1190
1310
|
init_animate_context();
|
|
1311
|
+
init_render();
|
|
1191
1312
|
init_spinner_handle();
|
|
1192
1313
|
}
|
|
1193
1314
|
});
|
|
@@ -11006,20 +11127,20 @@ var init_table = __esm({
|
|
|
11006
11127
|
});
|
|
11007
11128
|
|
|
11008
11129
|
// packages/contracts/src/render/tree.ts
|
|
11009
|
-
var
|
|
11130
|
+
var init_tree2 = __esm({
|
|
11010
11131
|
"packages/contracts/src/render/tree.ts"() {
|
|
11011
11132
|
"use strict";
|
|
11012
11133
|
}
|
|
11013
11134
|
});
|
|
11014
11135
|
|
|
11015
11136
|
// packages/contracts/src/render/index.ts
|
|
11016
|
-
var
|
|
11137
|
+
var init_render2 = __esm({
|
|
11017
11138
|
"packages/contracts/src/render/index.ts"() {
|
|
11018
11139
|
"use strict";
|
|
11019
11140
|
init_envelope();
|
|
11020
11141
|
init_list();
|
|
11021
11142
|
init_table();
|
|
11022
|
-
|
|
11143
|
+
init_tree2();
|
|
11023
11144
|
}
|
|
11024
11145
|
});
|
|
11025
11146
|
|
|
@@ -11091,35 +11212,9 @@ var init_session_journal = __esm({
|
|
|
11091
11212
|
});
|
|
11092
11213
|
|
|
11093
11214
|
// packages/contracts/src/status-registry.ts
|
|
11094
|
-
var TASK_STATUS_SYMBOLS_UNICODE, TASK_STATUS_SYMBOLS_ASCII;
|
|
11095
11215
|
var init_status_registry = __esm({
|
|
11096
11216
|
"packages/contracts/src/status-registry.ts"() {
|
|
11097
11217
|
"use strict";
|
|
11098
|
-
TASK_STATUS_SYMBOLS_UNICODE = {
|
|
11099
|
-
pending: "\u25CB",
|
|
11100
|
-
// ○ not yet started
|
|
11101
|
-
active: "\u25C9",
|
|
11102
|
-
// ◉ in progress
|
|
11103
|
-
blocked: "\u2297",
|
|
11104
|
-
// ⊗ cannot advance
|
|
11105
|
-
done: "\u2713",
|
|
11106
|
-
// ✓ complete
|
|
11107
|
-
cancelled: "\u2717",
|
|
11108
|
-
// ✗ abandoned
|
|
11109
|
-
archived: "\u25A3",
|
|
11110
|
-
// ▣ stored, inactive
|
|
11111
|
-
proposed: "\u25C7"
|
|
11112
|
-
// ◇ tier-2 proposal queue (T946)
|
|
11113
|
-
};
|
|
11114
|
-
TASK_STATUS_SYMBOLS_ASCII = {
|
|
11115
|
-
pending: "-",
|
|
11116
|
-
active: "*",
|
|
11117
|
-
blocked: "x",
|
|
11118
|
-
done: "+",
|
|
11119
|
-
cancelled: "~",
|
|
11120
|
-
archived: "#",
|
|
11121
|
-
proposed: "?"
|
|
11122
|
-
};
|
|
11123
11218
|
}
|
|
11124
11219
|
});
|
|
11125
11220
|
|
|
@@ -11233,7 +11328,7 @@ var init_src2 = __esm({
|
|
|
11233
11328
|
init_peer();
|
|
11234
11329
|
init_evidence_atoms();
|
|
11235
11330
|
init_plan();
|
|
11236
|
-
|
|
11331
|
+
init_render2();
|
|
11237
11332
|
init_session2();
|
|
11238
11333
|
init_session_journal();
|
|
11239
11334
|
init_status_registry();
|
|
@@ -11431,1960 +11526,6 @@ var init_normalizer = __esm({
|
|
|
11431
11526
|
}
|
|
11432
11527
|
});
|
|
11433
11528
|
|
|
11434
|
-
// packages/cleo/src/cli/tree-context.ts
|
|
11435
|
-
function setTreeContext(ctx) {
|
|
11436
|
-
currentContext2 = {
|
|
11437
|
-
withDeps: ctx.withDeps ?? false,
|
|
11438
|
-
withBlockers: ctx.withBlockers ?? false
|
|
11439
|
-
};
|
|
11440
|
-
}
|
|
11441
|
-
function getTreeContext() {
|
|
11442
|
-
return currentContext2;
|
|
11443
|
-
}
|
|
11444
|
-
var currentContext2;
|
|
11445
|
-
var init_tree_context = __esm({
|
|
11446
|
-
"packages/cleo/src/cli/tree-context.ts"() {
|
|
11447
|
-
"use strict";
|
|
11448
|
-
currentContext2 = {
|
|
11449
|
-
withDeps: false,
|
|
11450
|
-
withBlockers: false
|
|
11451
|
-
};
|
|
11452
|
-
}
|
|
11453
|
-
});
|
|
11454
|
-
|
|
11455
|
-
// packages/cleo/src/cli/renderers/colors.ts
|
|
11456
|
-
function ansi(code) {
|
|
11457
|
-
return colorsEnabled ? code : "";
|
|
11458
|
-
}
|
|
11459
|
-
function statusSymbol(status) {
|
|
11460
|
-
const map2 = unicodeEnabled ? TASK_STATUS_SYMBOLS_UNICODE : TASK_STATUS_SYMBOLS_ASCII;
|
|
11461
|
-
return map2[status] ?? "?";
|
|
11462
|
-
}
|
|
11463
|
-
function statusColor(status) {
|
|
11464
|
-
switch (status) {
|
|
11465
|
-
case "pending":
|
|
11466
|
-
return CYAN;
|
|
11467
|
-
case "active":
|
|
11468
|
-
return GREEN;
|
|
11469
|
-
case "blocked":
|
|
11470
|
-
return RED;
|
|
11471
|
-
case "done":
|
|
11472
|
-
return DIM;
|
|
11473
|
-
case "cancelled":
|
|
11474
|
-
return DIM;
|
|
11475
|
-
case "archived":
|
|
11476
|
-
return DIM;
|
|
11477
|
-
default:
|
|
11478
|
-
return "";
|
|
11479
|
-
}
|
|
11480
|
-
}
|
|
11481
|
-
function prioritySymbol(priority) {
|
|
11482
|
-
if (unicodeEnabled) {
|
|
11483
|
-
switch (priority) {
|
|
11484
|
-
case "critical":
|
|
11485
|
-
return "\u{1F534}";
|
|
11486
|
-
// red circle emoji
|
|
11487
|
-
case "high":
|
|
11488
|
-
return "\u{1F7E1}";
|
|
11489
|
-
// yellow circle emoji
|
|
11490
|
-
case "medium":
|
|
11491
|
-
return "\u{1F535}";
|
|
11492
|
-
// blue circle emoji
|
|
11493
|
-
case "low":
|
|
11494
|
-
return "\u26AA";
|
|
11495
|
-
// white circle emoji
|
|
11496
|
-
default:
|
|
11497
|
-
return "";
|
|
11498
|
-
}
|
|
11499
|
-
}
|
|
11500
|
-
switch (priority) {
|
|
11501
|
-
case "critical":
|
|
11502
|
-
return "!";
|
|
11503
|
-
case "high":
|
|
11504
|
-
return "H";
|
|
11505
|
-
case "medium":
|
|
11506
|
-
return "M";
|
|
11507
|
-
case "low":
|
|
11508
|
-
return "L";
|
|
11509
|
-
default:
|
|
11510
|
-
return "";
|
|
11511
|
-
}
|
|
11512
|
-
}
|
|
11513
|
-
function priorityColor(priority) {
|
|
11514
|
-
switch (priority) {
|
|
11515
|
-
case "critical":
|
|
11516
|
-
return RED;
|
|
11517
|
-
case "high":
|
|
11518
|
-
return YELLOW;
|
|
11519
|
-
case "medium":
|
|
11520
|
-
return BLUE;
|
|
11521
|
-
case "low":
|
|
11522
|
-
return DIM;
|
|
11523
|
-
default:
|
|
11524
|
-
return "";
|
|
11525
|
-
}
|
|
11526
|
-
}
|
|
11527
|
-
function hRule(width = 65) {
|
|
11528
|
-
return BOX.h.repeat(width);
|
|
11529
|
-
}
|
|
11530
|
-
function shortDate(isoDate) {
|
|
11531
|
-
if (!isoDate) return "";
|
|
11532
|
-
return isoDate.split("T")[0] ?? isoDate;
|
|
11533
|
-
}
|
|
11534
|
-
var colorsEnabled, unicodeEnabled, BOLD, DIM, NC, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BOX;
|
|
11535
|
-
var init_colors = __esm({
|
|
11536
|
-
"packages/cleo/src/cli/renderers/colors.ts"() {
|
|
11537
|
-
"use strict";
|
|
11538
|
-
init_src2();
|
|
11539
|
-
colorsEnabled = (() => {
|
|
11540
|
-
if (process.env["NO_COLOR"] !== void 0) return false;
|
|
11541
|
-
if (process.env["FORCE_COLOR"] !== void 0) return true;
|
|
11542
|
-
return process.stdout.isTTY === true;
|
|
11543
|
-
})();
|
|
11544
|
-
unicodeEnabled = (() => {
|
|
11545
|
-
const lang = process.env["LANG"] ?? "";
|
|
11546
|
-
if (lang === "C" || lang === "POSIX") return false;
|
|
11547
|
-
return lang.includes("UTF") || process.platform === "darwin";
|
|
11548
|
-
})();
|
|
11549
|
-
BOLD = ansi("\x1B[1m");
|
|
11550
|
-
DIM = ansi("\x1B[2m");
|
|
11551
|
-
NC = ansi("\x1B[0m");
|
|
11552
|
-
RED = ansi("\x1B[0;31m");
|
|
11553
|
-
GREEN = ansi("\x1B[0;32m");
|
|
11554
|
-
YELLOW = ansi("\x1B[1;33m");
|
|
11555
|
-
BLUE = ansi("\x1B[0;34m");
|
|
11556
|
-
MAGENTA = ansi("\x1B[0;35m");
|
|
11557
|
-
CYAN = ansi("\x1B[0;36m");
|
|
11558
|
-
BOX = unicodeEnabled ? {
|
|
11559
|
-
tl: "\u256D",
|
|
11560
|
-
tr: "\u256E",
|
|
11561
|
-
bl: "\u2570",
|
|
11562
|
-
br: "\u256F",
|
|
11563
|
-
h: "\u2500",
|
|
11564
|
-
v: "\u2502",
|
|
11565
|
-
ml: "\u251C",
|
|
11566
|
-
mr: "\u2524"
|
|
11567
|
-
} : { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|", ml: "+", mr: "+" };
|
|
11568
|
-
}
|
|
11569
|
-
});
|
|
11570
|
-
|
|
11571
|
-
// packages/cleo/src/cli/renderers/system.ts
|
|
11572
|
-
import { formatTree, formatWaves } from "@cleocode/core/formatters";
|
|
11573
|
-
function cliColorize(text, style) {
|
|
11574
|
-
switch (style) {
|
|
11575
|
-
case "bold":
|
|
11576
|
-
return `${BOLD}${text}${NC}`;
|
|
11577
|
-
case "dim":
|
|
11578
|
-
return `${DIM}${text}${NC}`;
|
|
11579
|
-
case "red":
|
|
11580
|
-
return `${RED}${text}${NC}`;
|
|
11581
|
-
case "green":
|
|
11582
|
-
return `${GREEN}${text}${NC}`;
|
|
11583
|
-
case "yellow":
|
|
11584
|
-
return `${YELLOW}${text}${NC}`;
|
|
11585
|
-
case "blue":
|
|
11586
|
-
return `${BLUE}${text}${NC}`;
|
|
11587
|
-
case "magenta":
|
|
11588
|
-
return `${MAGENTA}${text}${NC}`;
|
|
11589
|
-
case "cyan":
|
|
11590
|
-
return `${CYAN}${text}${NC}`;
|
|
11591
|
-
case "reset":
|
|
11592
|
-
return `${NC}${text}`;
|
|
11593
|
-
default:
|
|
11594
|
-
return text;
|
|
11595
|
-
}
|
|
11596
|
-
}
|
|
11597
|
-
function renderDoctor(data, quiet) {
|
|
11598
|
-
const overall = data["overall"] ?? "unknown";
|
|
11599
|
-
const version = data["version"];
|
|
11600
|
-
const installation = data["installation"];
|
|
11601
|
-
const checks = data["checks"];
|
|
11602
|
-
if (quiet) {
|
|
11603
|
-
return overall;
|
|
11604
|
-
}
|
|
11605
|
-
const lines = [];
|
|
11606
|
-
const statusBadge = overall === "pass" ? `${GREEN}${BOLD}HEALTHY${NC}` : overall === "warning" ? `${YELLOW}${BOLD}DEGRADED${NC}` : overall === "fail" ? `${RED}${BOLD}UNHEALTHY${NC}` : `${DIM}${overall.toUpperCase()}${NC}`;
|
|
11607
|
-
lines.push(`System Status: ${statusBadge}`);
|
|
11608
|
-
if (version) lines.push(` ${DIM}Version:${NC} ${version}`);
|
|
11609
|
-
if (installation) lines.push(` ${DIM}Installation:${NC} ${installation}`);
|
|
11610
|
-
if (checks && checks.length > 0) {
|
|
11611
|
-
let passCount = 0;
|
|
11612
|
-
let warnCount = 0;
|
|
11613
|
-
let failCount = 0;
|
|
11614
|
-
for (const c of checks) {
|
|
11615
|
-
const s = c["status"];
|
|
11616
|
-
if (s === "pass") passCount++;
|
|
11617
|
-
else if (s === "warn" || s === "warning") warnCount++;
|
|
11618
|
-
else failCount++;
|
|
11619
|
-
}
|
|
11620
|
-
lines.push(
|
|
11621
|
-
` ${DIM}Checks:${NC} ${GREEN}${passCount} pass${NC} \xB7 ${YELLOW}${warnCount} warn${NC} \xB7 ${RED}${failCount} fail${NC}`
|
|
11622
|
-
);
|
|
11623
|
-
lines.push("");
|
|
11624
|
-
for (const check of checks) {
|
|
11625
|
-
const status = check["status"];
|
|
11626
|
-
const name = check["name"];
|
|
11627
|
-
const message = check["message"];
|
|
11628
|
-
const icon = status === "pass" ? `${GREEN}\u2713${NC}` : status === "warn" || status === "warning" ? `${YELLOW}\u26A0${NC}` : `${RED}\u2717${NC}`;
|
|
11629
|
-
const label = name ? `${BOLD}${name}${NC}` : "";
|
|
11630
|
-
lines.push(` ${icon} ${label}${label && message ? ` \u2014 ${message}` : message}`);
|
|
11631
|
-
}
|
|
11632
|
-
}
|
|
11633
|
-
return lines.join("\n");
|
|
11634
|
-
}
|
|
11635
|
-
function renderStats(data, quiet) {
|
|
11636
|
-
if (quiet) {
|
|
11637
|
-
const total = data["totalTasks"];
|
|
11638
|
-
return String(total ?? 0);
|
|
11639
|
-
}
|
|
11640
|
-
const lines = [];
|
|
11641
|
-
lines.push(`${BOLD}Project Statistics${NC}`);
|
|
11642
|
-
lines.push("");
|
|
11643
|
-
for (const [key, val] of Object.entries(data)) {
|
|
11644
|
-
if (typeof val === "object" && val !== null && !Array.isArray(val)) {
|
|
11645
|
-
lines.push(` ${BOLD}${formatLabel(key)}:${NC}`);
|
|
11646
|
-
for (const [subKey, subVal] of Object.entries(val)) {
|
|
11647
|
-
lines.push(` ${DIM}${formatLabel(subKey)}:${NC} ${String(subVal)}`);
|
|
11648
|
-
}
|
|
11649
|
-
} else {
|
|
11650
|
-
lines.push(` ${DIM}${formatLabel(key)}:${NC} ${String(val)}`);
|
|
11651
|
-
}
|
|
11652
|
-
}
|
|
11653
|
-
return lines.join("\n");
|
|
11654
|
-
}
|
|
11655
|
-
function renderNext(data, quiet) {
|
|
11656
|
-
const suggestion = data["suggestion"];
|
|
11657
|
-
const suggestions = data["suggestions"];
|
|
11658
|
-
const totalCandidates = data["totalCandidates"];
|
|
11659
|
-
if (suggestion !== void 0) {
|
|
11660
|
-
if (suggestion === null) {
|
|
11661
|
-
return quiet ? "" : "No pending tasks with satisfied dependencies.";
|
|
11662
|
-
}
|
|
11663
|
-
if (quiet) return String(suggestion["id"]);
|
|
11664
|
-
const pCol = priorityColor(String(suggestion["priority"] ?? ""));
|
|
11665
|
-
const lines = [
|
|
11666
|
-
`${BOLD}Next:${NC} ${BOLD}${suggestion["id"]}${NC} ${pCol}[${suggestion["priority"]}]${NC} ${suggestion["title"]}`
|
|
11667
|
-
];
|
|
11668
|
-
if (suggestion["phase"]) lines.push(` ${DIM}Phase:${NC} ${suggestion["phase"]}`);
|
|
11669
|
-
if (suggestion["reasons"]) {
|
|
11670
|
-
const reasons = suggestion["reasons"];
|
|
11671
|
-
for (const r of reasons) lines.push(` ${DIM}${r}${NC}`);
|
|
11672
|
-
}
|
|
11673
|
-
if (totalCandidates) lines.push(` ${DIM}(${totalCandidates} candidates)${NC}`);
|
|
11674
|
-
return lines.join("\n");
|
|
11675
|
-
}
|
|
11676
|
-
if (suggestions) {
|
|
11677
|
-
if (quiet) return suggestions.map((s) => String(s["id"])).join("\n");
|
|
11678
|
-
const lines = [];
|
|
11679
|
-
lines.push(`${BOLD}Top suggestions:${NC} ${DIM}(${totalCandidates} candidates)${NC}`);
|
|
11680
|
-
for (const s of suggestions) {
|
|
11681
|
-
const pCol = priorityColor(String(s["priority"] ?? ""));
|
|
11682
|
-
lines.push(
|
|
11683
|
-
` ${BOLD}${s["id"]}${NC} ${pCol}[${s["priority"]}]${NC} ${s["title"]} ${DIM}score: ${s["score"]}${NC}`
|
|
11684
|
-
);
|
|
11685
|
-
}
|
|
11686
|
-
return lines.join("\n");
|
|
11687
|
-
}
|
|
11688
|
-
return "No suggestions available.";
|
|
11689
|
-
}
|
|
11690
|
-
function renderBlockers(data, quiet) {
|
|
11691
|
-
const blockedTasks = data["blockedTasks"] ?? data["blockers"] ?? data["tasks"];
|
|
11692
|
-
const criticalBlockers = data["criticalBlockers"];
|
|
11693
|
-
const summary = data["summary"];
|
|
11694
|
-
const total = data["total"];
|
|
11695
|
-
const limit = data["limit"];
|
|
11696
|
-
if (!blockedTasks || blockedTasks.length === 0) {
|
|
11697
|
-
return quiet ? "" : summary ?? "No blocked tasks.";
|
|
11698
|
-
}
|
|
11699
|
-
if (quiet) {
|
|
11700
|
-
return blockedTasks.map((b) => String(b["id"])).join("\n");
|
|
11701
|
-
}
|
|
11702
|
-
const lines = [];
|
|
11703
|
-
const shown = blockedTasks.length;
|
|
11704
|
-
const totalLabel = typeof total === "number" && total !== shown ? ` of ${total}` : "";
|
|
11705
|
-
lines.push(`${RED}${BOLD}Blocked Tasks (${shown}${totalLabel})${NC}`);
|
|
11706
|
-
if (summary && summary !== `${shown} blocked task(s)`) {
|
|
11707
|
-
lines.push(`${DIM}${summary}${NC}`);
|
|
11708
|
-
}
|
|
11709
|
-
lines.push("");
|
|
11710
|
-
if (criticalBlockers && criticalBlockers.length > 0) {
|
|
11711
|
-
lines.push(`${RED}${BOLD}Critical Blockers (${criticalBlockers.length})${NC}`);
|
|
11712
|
-
for (const cb of criticalBlockers) {
|
|
11713
|
-
const id = String(cb["id"] ?? cb["taskId"] ?? "");
|
|
11714
|
-
const title = String(cb["title"] ?? "");
|
|
11715
|
-
const blocks = cb["blocks"];
|
|
11716
|
-
lines.push(` ${RED}\u2297${NC} ${BOLD}${id}${NC} ${title}`);
|
|
11717
|
-
if (blocks && blocks.length > 0) {
|
|
11718
|
-
lines.push(` ${DIM}Blocks: ${blocks.join(", ")}${NC}`);
|
|
11719
|
-
}
|
|
11720
|
-
}
|
|
11721
|
-
lines.push("");
|
|
11722
|
-
}
|
|
11723
|
-
for (const item of blockedTasks) {
|
|
11724
|
-
const id = String(item["id"]);
|
|
11725
|
-
const title = String(item["title"] ?? "");
|
|
11726
|
-
const priority = item["priority"];
|
|
11727
|
-
const blockedBy = item["blockedBy"];
|
|
11728
|
-
const blockedByStr = Array.isArray(blockedBy) ? blockedBy.join(", ") : blockedBy ?? "";
|
|
11729
|
-
const pBadge = priority ? `${priorityColor(priority)}[${priority}]${NC} ` : "";
|
|
11730
|
-
lines.push(` ${RED}\u2297${NC} ${BOLD}${id}${NC} ${pBadge}${title}`);
|
|
11731
|
-
if (blockedByStr) lines.push(` ${DIM}Blocked by: ${blockedByStr}${NC}`);
|
|
11732
|
-
}
|
|
11733
|
-
if (typeof limit === "number" && typeof total === "number" && total > shown) {
|
|
11734
|
-
lines.push("");
|
|
11735
|
-
lines.push(
|
|
11736
|
-
`${DIM}\u2500\u2500\u2500 ${shown} of ${total} (--limit ${limit}, --json for full set) \u2500\u2500\u2500${NC}`
|
|
11737
|
-
);
|
|
11738
|
-
}
|
|
11739
|
-
return lines.join("\n");
|
|
11740
|
-
}
|
|
11741
|
-
function renderWaves(data, opts) {
|
|
11742
|
-
return formatWaves(data, {
|
|
11743
|
-
mode: opts?.mode ?? "rich",
|
|
11744
|
-
colorize: cliColorize
|
|
11745
|
-
});
|
|
11746
|
-
}
|
|
11747
|
-
function renderTree(data, quiet) {
|
|
11748
|
-
const waves = data["waves"];
|
|
11749
|
-
const tree = data["tree"];
|
|
11750
|
-
const tasks = data["tasks"];
|
|
11751
|
-
const rendered = data["rendered"];
|
|
11752
|
-
const nodes = data["nodes"];
|
|
11753
|
-
if (waves) {
|
|
11754
|
-
const epicId = data["epicId"];
|
|
11755
|
-
const totalWaves = data["totalWaves"];
|
|
11756
|
-
const totalTasks = data["totalTasks"];
|
|
11757
|
-
if (quiet) {
|
|
11758
|
-
return renderWaves(data, { mode: "quiet" });
|
|
11759
|
-
}
|
|
11760
|
-
const header = epicId ? `${BOLD}Waves for ${epicId}${NC} ${DIM}(${totalWaves ?? waves.length} waves, ${totalTasks ?? "?"} tasks)${NC}` : `${BOLD}Execution Waves${NC}`;
|
|
11761
|
-
const body = renderWaves(data, { mode: "rich", epicId, totalWaves, totalTasks });
|
|
11762
|
-
return `${header}
|
|
11763
|
-
|
|
11764
|
-
${body}`;
|
|
11765
|
-
}
|
|
11766
|
-
if (tree) {
|
|
11767
|
-
const { withDeps, withBlockers } = getTreeContext();
|
|
11768
|
-
return formatTree(tree, {
|
|
11769
|
-
mode: quiet ? "quiet" : "rich",
|
|
11770
|
-
colorize: cliColorize,
|
|
11771
|
-
withDeps,
|
|
11772
|
-
withBlockers
|
|
11773
|
-
});
|
|
11774
|
-
}
|
|
11775
|
-
if (typeof rendered === "string" && rendered.length > 0) {
|
|
11776
|
-
if (quiet) {
|
|
11777
|
-
return nodes ? nodes.map((n) => String(n["id"])).join("\n") : "";
|
|
11778
|
-
}
|
|
11779
|
-
return rendered;
|
|
11780
|
-
}
|
|
11781
|
-
if (tasks) {
|
|
11782
|
-
if (quiet) return tasks.map((t) => t.id).join("\n");
|
|
11783
|
-
return tasks.map((t) => {
|
|
11784
|
-
const sSym = statusSymbol(t.status);
|
|
11785
|
-
return ` ${sSym} ${BOLD}${t.id}${NC} ${t.title}`;
|
|
11786
|
-
}).join("\n");
|
|
11787
|
-
}
|
|
11788
|
-
return quiet ? "" : "No tree data.";
|
|
11789
|
-
}
|
|
11790
|
-
function renderStart(data, quiet) {
|
|
11791
|
-
const task = data["task"];
|
|
11792
|
-
const taskId = data["taskId"];
|
|
11793
|
-
const id = task?.id ?? taskId ?? String(data["currentTask"] ?? "");
|
|
11794
|
-
const title = task?.title ?? String(data["title"] ?? "");
|
|
11795
|
-
if (quiet) return id;
|
|
11796
|
-
return `${GREEN}\u25B6 Started:${NC} ${BOLD}${id}${NC} ${title}`;
|
|
11797
|
-
}
|
|
11798
|
-
function renderStop(data, quiet) {
|
|
11799
|
-
const task = data["task"];
|
|
11800
|
-
const taskId = data["taskId"];
|
|
11801
|
-
const previousTask = data["previousTask"];
|
|
11802
|
-
const id = task?.id ?? taskId ?? previousTask ?? "";
|
|
11803
|
-
if (quiet) return id;
|
|
11804
|
-
if (!id) return "No task was active.";
|
|
11805
|
-
return `${YELLOW}\u25A0 Stopped:${NC} ${BOLD}${id}${NC}${task?.title ? ` ${task.title}` : ""}`;
|
|
11806
|
-
}
|
|
11807
|
-
function renderCurrent(data, quiet) {
|
|
11808
|
-
const task = data["task"];
|
|
11809
|
-
const currentTask = data["currentTask"];
|
|
11810
|
-
const id = task?.id ?? currentTask ?? "";
|
|
11811
|
-
if (!id) {
|
|
11812
|
-
return quiet ? "" : "No task currently active.";
|
|
11813
|
-
}
|
|
11814
|
-
if (quiet) return id;
|
|
11815
|
-
const sCol = statusColor(task?.status ?? "active");
|
|
11816
|
-
const sSym = statusSymbol(task?.status ?? "active");
|
|
11817
|
-
return `${BOLD}Current:${NC} ${sCol}${sSym}${NC} ${BOLD}${id}${NC}${task?.title ? ` ${task.title}` : ""}`;
|
|
11818
|
-
}
|
|
11819
|
-
function renderSession(data, quiet) {
|
|
11820
|
-
const sessionId = data["sessionId"];
|
|
11821
|
-
const status = data["status"];
|
|
11822
|
-
const sessions2 = data["sessions"];
|
|
11823
|
-
if (sessions2) {
|
|
11824
|
-
if (quiet) return sessions2.map((s) => String(s["id"])).join("\n");
|
|
11825
|
-
const lines2 = [];
|
|
11826
|
-
lines2.push(`${BOLD}Sessions (${sessions2.length})${NC}`);
|
|
11827
|
-
for (const s of sessions2) {
|
|
11828
|
-
const active = s["active"];
|
|
11829
|
-
const icon = active ? `${GREEN}\u25CF${NC}` : `${DIM}\u25CB${NC}`;
|
|
11830
|
-
lines2.push(` ${icon} ${BOLD}${s["id"]}${NC}${active ? " (active)" : ""}`);
|
|
11831
|
-
}
|
|
11832
|
-
return lines2.join("\n");
|
|
11833
|
-
}
|
|
11834
|
-
if (!sessionId) {
|
|
11835
|
-
return quiet ? "" : "No active session.";
|
|
11836
|
-
}
|
|
11837
|
-
if (quiet) return sessionId;
|
|
11838
|
-
const lines = [];
|
|
11839
|
-
lines.push(`${BOLD}Session:${NC} ${sessionId}`);
|
|
11840
|
-
if (status) lines.push(` ${DIM}Status:${NC} ${status}`);
|
|
11841
|
-
for (const [key, val] of Object.entries(data)) {
|
|
11842
|
-
if (key === "sessionId" || key === "status") continue;
|
|
11843
|
-
if (typeof val === "string" || typeof val === "number" || typeof val === "boolean") {
|
|
11844
|
-
lines.push(` ${DIM}${formatLabel(key)}:${NC} ${String(val)}`);
|
|
11845
|
-
}
|
|
11846
|
-
}
|
|
11847
|
-
return lines.join("\n");
|
|
11848
|
-
}
|
|
11849
|
-
function renderVersion(data, quiet) {
|
|
11850
|
-
const version = data["version"];
|
|
11851
|
-
if (quiet) return version ?? "";
|
|
11852
|
-
return `Cleo v${version}`;
|
|
11853
|
-
}
|
|
11854
|
-
function renderPlan(data, quiet) {
|
|
11855
|
-
if (quiet) {
|
|
11856
|
-
const readyCount = data["ready"]?.length ?? 0;
|
|
11857
|
-
return String(readyCount);
|
|
11858
|
-
}
|
|
11859
|
-
const lines = [];
|
|
11860
|
-
lines.push(`${BOLD}Planning View${NC}`);
|
|
11861
|
-
lines.push("");
|
|
11862
|
-
const inProgress = data["inProgress"];
|
|
11863
|
-
if (inProgress && inProgress.length > 0) {
|
|
11864
|
-
lines.push(`${BOLD}In-Progress Epics (${inProgress.length})${NC}`);
|
|
11865
|
-
for (const epic of inProgress) {
|
|
11866
|
-
const completion = epic["completionPercent"];
|
|
11867
|
-
const completionBar = renderCompletionBar(completion);
|
|
11868
|
-
lines.push(` ${BOLD}${epic["epicId"]}${NC} ${epic["epicTitle"]}`);
|
|
11869
|
-
lines.push(` ${completionBar} ${completion}% (${epic["activeTasks"]} active)`);
|
|
11870
|
-
}
|
|
11871
|
-
lines.push("");
|
|
11872
|
-
}
|
|
11873
|
-
const ready = data["ready"];
|
|
11874
|
-
if (ready && ready.length > 0) {
|
|
11875
|
-
lines.push(`${BOLD}Ready Tasks (${ready.length})${NC} ${DIM}ordered by leverage score${NC}`);
|
|
11876
|
-
for (const task of ready.slice(0, 10)) {
|
|
11877
|
-
const pCol = priorityColor(String(task["priority"] ?? "medium"));
|
|
11878
|
-
lines.push(` ${BOLD}${task["id"]}${NC} ${pCol}[${task["priority"]}]${NC} ${task["title"]}`);
|
|
11879
|
-
lines.push(
|
|
11880
|
-
` ${DIM}leverage:${NC} ${task["leverage"]} ${DIM}score:${NC} ${task["score"]}`
|
|
11881
|
-
);
|
|
11882
|
-
const reasons = task["reasons"];
|
|
11883
|
-
if (reasons && reasons.length > 0) {
|
|
11884
|
-
lines.push(` ${DIM}${reasons.join(", ")}${NC}`);
|
|
11885
|
-
}
|
|
11886
|
-
}
|
|
11887
|
-
if (ready.length > 10) {
|
|
11888
|
-
lines.push(` ${DIM}... and ${ready.length - 10} more${NC}`);
|
|
11889
|
-
}
|
|
11890
|
-
lines.push("");
|
|
11891
|
-
}
|
|
11892
|
-
const blocked = data["blocked"];
|
|
11893
|
-
if (blocked && blocked.length > 0) {
|
|
11894
|
-
lines.push(`${RED}${BOLD}Blocked Tasks (${blocked.length})${NC}`);
|
|
11895
|
-
for (const task of blocked.slice(0, 10)) {
|
|
11896
|
-
lines.push(` ${RED}\u2297${NC} ${BOLD}${task["id"]}${NC} ${task["title"]}`);
|
|
11897
|
-
const blockedBy = task["blockedBy"];
|
|
11898
|
-
if (blockedBy && blockedBy.length > 0) {
|
|
11899
|
-
lines.push(` ${DIM}Blocked by: ${blockedBy.join(", ")}${NC}`);
|
|
11900
|
-
}
|
|
11901
|
-
if (task["blocksCount"] > 0) {
|
|
11902
|
-
lines.push(` ${DIM}Blocks: ${task["blocksCount"]} task(s)${NC}`);
|
|
11903
|
-
}
|
|
11904
|
-
}
|
|
11905
|
-
if (blocked.length > 10) {
|
|
11906
|
-
lines.push(` ${DIM}... and ${blocked.length - 10} more${NC}`);
|
|
11907
|
-
}
|
|
11908
|
-
lines.push("");
|
|
11909
|
-
}
|
|
11910
|
-
const openBugs = data["openBugs"];
|
|
11911
|
-
if (openBugs && openBugs.length > 0) {
|
|
11912
|
-
lines.push(`${RED}${BOLD}Open Bugs (${openBugs.length})${NC}`);
|
|
11913
|
-
for (const bug of openBugs.slice(0, 10)) {
|
|
11914
|
-
const pCol = priorityColor(String(bug["priority"] ?? "medium"));
|
|
11915
|
-
lines.push(
|
|
11916
|
-
` ${RED}\u25CF${NC} ${BOLD}${bug["id"]}${NC} ${pCol}[${bug["priority"]}]${NC} ${bug["title"]}`
|
|
11917
|
-
);
|
|
11918
|
-
}
|
|
11919
|
-
if (openBugs.length > 10) {
|
|
11920
|
-
lines.push(` ${DIM}... and ${openBugs.length - 10} more${NC}`);
|
|
11921
|
-
}
|
|
11922
|
-
lines.push("");
|
|
11923
|
-
}
|
|
11924
|
-
const metrics = data["metrics"];
|
|
11925
|
-
if (metrics) {
|
|
11926
|
-
lines.push(`${BOLD}Metrics${NC}`);
|
|
11927
|
-
lines.push(
|
|
11928
|
-
` ${DIM}Total Epics:${NC} ${metrics["totalEpics"]} (${metrics["activeEpics"]} active)`
|
|
11929
|
-
);
|
|
11930
|
-
lines.push(` ${DIM}Total Tasks:${NC} ${metrics["totalTasks"]}`);
|
|
11931
|
-
lines.push(
|
|
11932
|
-
` ${DIM}Actionable:${NC} ${metrics["actionable"]} ${DIM}Blocked:${NC} ${metrics["blocked"]} ${DIM}Open Bugs:${NC} ${metrics["openBugs"]}`
|
|
11933
|
-
);
|
|
11934
|
-
lines.push(` ${DIM}Avg Leverage:${NC} ${metrics["avgLeverage"]}`);
|
|
11935
|
-
}
|
|
11936
|
-
return lines.join("\n");
|
|
11937
|
-
}
|
|
11938
|
-
function renderCompletionBar(percent) {
|
|
11939
|
-
const width = 20;
|
|
11940
|
-
const filled = Math.round(percent / 100 * width);
|
|
11941
|
-
const empty = width - filled;
|
|
11942
|
-
const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
11943
|
-
const color = percent >= 75 ? GREEN : percent >= 50 ? YELLOW : "";
|
|
11944
|
-
return `${color}[${bar}]${NC}`;
|
|
11945
|
-
}
|
|
11946
|
-
function renderBriefing(data, quiet) {
|
|
11947
|
-
if (quiet) {
|
|
11948
|
-
const next = data["nextTasks"] ?? [];
|
|
11949
|
-
return next.map((t) => String(t["id"] ?? "")).join("\n");
|
|
11950
|
-
}
|
|
11951
|
-
const lines = [];
|
|
11952
|
-
lines.push(`${BOLD}CLEO Session Briefing${NC} ${DIM}(source: tasks.db + brain.db)${NC}`);
|
|
11953
|
-
lines.push("");
|
|
11954
|
-
const lastSession = data["lastSession"];
|
|
11955
|
-
if (lastSession) {
|
|
11956
|
-
const handoff = lastSession["handoff"] ?? {};
|
|
11957
|
-
const endedAt = String(lastSession["endedAt"] ?? "");
|
|
11958
|
-
const duration = lastSession["duration"];
|
|
11959
|
-
lines.push(`${BOLD}Last Session${NC}`);
|
|
11960
|
-
if (endedAt) lines.push(` ${DIM}Ended:${NC} ${endedAt}`);
|
|
11961
|
-
if (typeof duration === "number") lines.push(` ${DIM}Duration:${NC} ${duration} min`);
|
|
11962
|
-
const completed = handoff["tasksCompleted"] ?? [];
|
|
11963
|
-
const created = handoff["tasksCreated"] ?? [];
|
|
11964
|
-
if (completed.length > 0) {
|
|
11965
|
-
lines.push(` ${DIM}Completed:${NC} ${completed.length} task(s) \u2014 ${completed.join(", ")}`);
|
|
11966
|
-
}
|
|
11967
|
-
if (created.length > 0) {
|
|
11968
|
-
lines.push(` ${DIM}Created:${NC} ${created.length} task(s) \u2014 ${created.join(", ")}`);
|
|
11969
|
-
}
|
|
11970
|
-
const decisions = handoff["decisionsRecorded"];
|
|
11971
|
-
if (typeof decisions === "number" && decisions > 0) {
|
|
11972
|
-
lines.push(` ${DIM}Decisions recorded:${NC} ${decisions}`);
|
|
11973
|
-
}
|
|
11974
|
-
if (handoff["note"]) {
|
|
11975
|
-
lines.push(` ${DIM}Note:${NC} ${String(handoff["note"])}`);
|
|
11976
|
-
}
|
|
11977
|
-
if (handoff["nextAction"]) {
|
|
11978
|
-
lines.push(` ${DIM}Next action:${NC} ${String(handoff["nextAction"])}`);
|
|
11979
|
-
}
|
|
11980
|
-
lines.push("");
|
|
11981
|
-
} else {
|
|
11982
|
-
lines.push(`${BOLD}Last Session${NC} ${DIM}(none \u2014 fresh session)${NC}`);
|
|
11983
|
-
lines.push("");
|
|
11984
|
-
}
|
|
11985
|
-
const currentTask = data["currentTask"];
|
|
11986
|
-
if (currentTask) {
|
|
11987
|
-
const sCol = statusColor(String(currentTask["status"] ?? ""));
|
|
11988
|
-
const sSym = statusSymbol(String(currentTask["status"] ?? ""));
|
|
11989
|
-
lines.push(
|
|
11990
|
-
`${BOLD}Current Task:${NC} ${sCol}${sSym}${NC} ${BOLD}${currentTask["id"]}${NC} ${currentTask["title"] ?? ""}`
|
|
11991
|
-
);
|
|
11992
|
-
const blockedBy = currentTask["blockedBy"];
|
|
11993
|
-
if (blockedBy && blockedBy.length > 0) {
|
|
11994
|
-
lines.push(` ${RED}Blocked by:${NC} ${blockedBy.join(", ")}`);
|
|
11995
|
-
}
|
|
11996
|
-
lines.push("");
|
|
11997
|
-
}
|
|
11998
|
-
const blockedTasks = data["blockedTasks"] ?? [];
|
|
11999
|
-
if (blockedTasks.length > 0) {
|
|
12000
|
-
lines.push(`${RED}${BOLD}Active Blockers (${blockedTasks.length})${NC}`);
|
|
12001
|
-
for (const t of blockedTasks.slice(0, 10)) {
|
|
12002
|
-
const bb = (t["blockedBy"] ?? []).join(", ");
|
|
12003
|
-
lines.push(` ${RED}\u2297${NC} ${BOLD}${t["id"]}${NC} ${t["title"] ?? ""}`);
|
|
12004
|
-
if (bb) lines.push(` ${DIM}Blocked by: ${bb}${NC}`);
|
|
12005
|
-
}
|
|
12006
|
-
if (blockedTasks.length > 10) {
|
|
12007
|
-
lines.push(` ${DIM}... and ${blockedTasks.length - 10} more${NC}`);
|
|
12008
|
-
}
|
|
12009
|
-
lines.push("");
|
|
12010
|
-
}
|
|
12011
|
-
const nextTasks = data["nextTasks"] ?? [];
|
|
12012
|
-
if (nextTasks.length > 0) {
|
|
12013
|
-
lines.push(`${BOLD}Next Suggested (${nextTasks.length})${NC} ${DIM}leverage-scored${NC}`);
|
|
12014
|
-
for (const t of nextTasks) {
|
|
12015
|
-
lines.push(
|
|
12016
|
-
` ${BOLD}${t["id"]}${NC} ${t["title"] ?? ""} ${DIM}leverage: ${t["leverage"] ?? 0}, score: ${t["score"] ?? 0}${NC}`
|
|
12017
|
-
);
|
|
12018
|
-
}
|
|
12019
|
-
lines.push("");
|
|
12020
|
-
}
|
|
12021
|
-
const activeEpics = data["activeEpics"] ?? [];
|
|
12022
|
-
if (activeEpics.length > 0) {
|
|
12023
|
-
lines.push(`${BOLD}Open Epics (${activeEpics.length})${NC}`);
|
|
12024
|
-
for (const e of activeEpics) {
|
|
12025
|
-
const pct = e["completionPercent"] ?? 0;
|
|
12026
|
-
lines.push(` ${BOLD}${e["id"]}${NC} ${e["title"] ?? ""} ${DIM}(${pct}% complete)${NC}`);
|
|
12027
|
-
}
|
|
12028
|
-
lines.push("");
|
|
12029
|
-
}
|
|
12030
|
-
const openBugs = data["openBugs"] ?? [];
|
|
12031
|
-
if (openBugs.length > 0) {
|
|
12032
|
-
lines.push(`${RED}${BOLD}Open Bugs (${openBugs.length})${NC}`);
|
|
12033
|
-
for (const b of openBugs.slice(0, 10)) {
|
|
12034
|
-
const pCol = priorityColor(String(b["priority"] ?? "medium"));
|
|
12035
|
-
lines.push(
|
|
12036
|
-
` ${RED}\u25CF${NC} ${BOLD}${b["id"]}${NC} ${pCol}[${b["priority"]}]${NC} ${b["title"] ?? ""}`
|
|
12037
|
-
);
|
|
12038
|
-
}
|
|
12039
|
-
lines.push("");
|
|
12040
|
-
}
|
|
12041
|
-
const memoryContext = data["memoryContext"];
|
|
12042
|
-
if (memoryContext) {
|
|
12043
|
-
const recentDecisions = memoryContext["recentDecisions"] ?? [];
|
|
12044
|
-
const recentObservations = memoryContext["recentObservations"] ?? [];
|
|
12045
|
-
if (recentDecisions.length > 0) {
|
|
12046
|
-
lines.push(`${BOLD}Recent Decisions (${recentDecisions.length})${NC} ${DIM}from BRAIN${NC}`);
|
|
12047
|
-
for (const d of recentDecisions.slice(0, 5)) {
|
|
12048
|
-
lines.push(` ${BOLD}${d["id"]}${NC} ${d["title"] ?? ""} ${DIM}(${d["date"] ?? ""})${NC}`);
|
|
12049
|
-
}
|
|
12050
|
-
lines.push("");
|
|
12051
|
-
}
|
|
12052
|
-
if (recentObservations.length > 0) {
|
|
12053
|
-
lines.push(
|
|
12054
|
-
`${BOLD}Recent Observations (${recentObservations.length})${NC} ${DIM}from BRAIN${NC}`
|
|
12055
|
-
);
|
|
12056
|
-
for (const o of recentObservations.slice(0, 5)) {
|
|
12057
|
-
lines.push(` ${BOLD}${o["id"]}${NC} ${o["title"] ?? ""} ${DIM}(${o["date"] ?? ""})${NC}`);
|
|
12058
|
-
}
|
|
12059
|
-
lines.push("");
|
|
12060
|
-
}
|
|
12061
|
-
}
|
|
12062
|
-
const warnings = data["warnings"];
|
|
12063
|
-
if (warnings && warnings.length > 0) {
|
|
12064
|
-
lines.push(`${YELLOW}${BOLD}Warnings${NC}`);
|
|
12065
|
-
for (const w of warnings) lines.push(` ${YELLOW}!${NC} ${w}`);
|
|
12066
|
-
lines.push("");
|
|
12067
|
-
}
|
|
12068
|
-
lines.push(
|
|
12069
|
-
`${DIM}Tip: pass --json for the full structured payload. All fields read from tasks.db + brain.db.${NC}`
|
|
12070
|
-
);
|
|
12071
|
-
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
12072
|
-
}
|
|
12073
|
-
function renderBrainMaintenance(data, quiet) {
|
|
12074
|
-
if (quiet) return String(data["duration"] ?? "");
|
|
12075
|
-
const lines = [];
|
|
12076
|
-
lines.push(`${GREEN}${BOLD}Maintenance complete.${NC}`);
|
|
12077
|
-
lines.push(` ${DIM}Duration:${NC} ${data["duration"]}ms`);
|
|
12078
|
-
const decay = data["decay"];
|
|
12079
|
-
if (decay) {
|
|
12080
|
-
lines.push(` ${DIM}Decay:${NC} ${decay["affected"]} learning(s) updated`);
|
|
12081
|
-
}
|
|
12082
|
-
const consolidation = data["consolidation"];
|
|
12083
|
-
if (consolidation) {
|
|
12084
|
-
lines.push(
|
|
12085
|
-
` ${DIM}Consolidation:${NC} ${consolidation["merged"]} merged, ${consolidation["removed"]} archived`
|
|
12086
|
-
);
|
|
12087
|
-
}
|
|
12088
|
-
const tierPromotion = data["tierPromotion"];
|
|
12089
|
-
if (tierPromotion) {
|
|
12090
|
-
lines.push(
|
|
12091
|
-
` ${DIM}Tier promotion:${NC} ${tierPromotion["promoted"]} promoted, ${tierPromotion["evicted"]} evicted`
|
|
12092
|
-
);
|
|
12093
|
-
}
|
|
12094
|
-
const reconciliation = data["reconciliation"];
|
|
12095
|
-
if (reconciliation) {
|
|
12096
|
-
lines.push(
|
|
12097
|
-
` ${DIM}Reconcile:${NC} ${reconciliation["decisionsFixed"]} decisions, ${reconciliation["observationsFixed"]} observations, ${reconciliation["linksRemoved"]} links`
|
|
12098
|
-
);
|
|
12099
|
-
}
|
|
12100
|
-
const embeddings = data["embeddings"];
|
|
12101
|
-
if (embeddings) {
|
|
12102
|
-
lines.push(
|
|
12103
|
-
` ${DIM}Embeddings:${NC} ${embeddings["processed"]} processed, ${embeddings["skipped"]} skipped, ${embeddings["errors"]} errors`
|
|
12104
|
-
);
|
|
12105
|
-
}
|
|
12106
|
-
return lines.join("\n");
|
|
12107
|
-
}
|
|
12108
|
-
function renderBrainBackfill(data, quiet) {
|
|
12109
|
-
if (quiet) return String(data["nodesInserted"] ?? "");
|
|
12110
|
-
const lines = [];
|
|
12111
|
-
const before = data["before"];
|
|
12112
|
-
const after = data["after"];
|
|
12113
|
-
const byType = data["byType"];
|
|
12114
|
-
lines.push(`${GREEN}${BOLD}Back-fill complete.${NC}`);
|
|
12115
|
-
if (before) {
|
|
12116
|
-
lines.push(` ${DIM}Before:${NC} ${before["nodes"]} nodes, ${before["edges"]} edges`);
|
|
12117
|
-
lines.push(
|
|
12118
|
-
` ${DIM}Source:${NC} ${before["decisions"]} decisions, ${before["patterns"]} patterns, ${before["learnings"]} learnings, ${before["observations"]} observations, ${before["stickyNotes"]} stickies`
|
|
12119
|
-
);
|
|
12120
|
-
}
|
|
12121
|
-
lines.push(
|
|
12122
|
-
` ${DIM}Nodes inserted:${NC} ${data["nodesInserted"]} (including ${data["stubsCreated"]} stub nodes)`
|
|
12123
|
-
);
|
|
12124
|
-
lines.push(` ${DIM}Edges inserted:${NC} ${data["edgesInserted"]}`);
|
|
12125
|
-
if (after) {
|
|
12126
|
-
lines.push(` ${DIM}After:${NC} ${after["nodes"]} nodes, ${after["edges"]} edges`);
|
|
12127
|
-
}
|
|
12128
|
-
if (byType && Object.keys(byType).length > 0) {
|
|
12129
|
-
lines.push("\n By type:");
|
|
12130
|
-
for (const [type2, count] of Object.entries(byType)) {
|
|
12131
|
-
lines.push(` ${DIM}${type2}:${NC} ${count}`);
|
|
12132
|
-
}
|
|
12133
|
-
}
|
|
12134
|
-
return lines.join("\n");
|
|
12135
|
-
}
|
|
12136
|
-
function renderBrainPurge(data, quiet) {
|
|
12137
|
-
if (quiet) {
|
|
12138
|
-
const total = (data["patternsDeleted"] ?? 0) + (data["learningsDeleted"] ?? 0) + (data["decisionsDeleted"] ?? 0) + (data["observationsDeleted"] ?? 0);
|
|
12139
|
-
return String(total);
|
|
12140
|
-
}
|
|
12141
|
-
const lines = [];
|
|
12142
|
-
const after = data["after"];
|
|
12143
|
-
lines.push(`${GREEN}${BOLD}Purge complete.${NC}`);
|
|
12144
|
-
lines.push(` ${DIM}Patterns deleted:${NC} ${data["patternsDeleted"]}`);
|
|
12145
|
-
lines.push(` ${DIM}Learnings deleted:${NC} ${data["learningsDeleted"]}`);
|
|
12146
|
-
lines.push(` ${DIM}Decisions deleted:${NC} ${data["decisionsDeleted"]}`);
|
|
12147
|
-
lines.push(` ${DIM}Observations deleted:${NC} ${data["observationsDeleted"]}`);
|
|
12148
|
-
if (after) {
|
|
12149
|
-
lines.push("");
|
|
12150
|
-
lines.push(`${BOLD}Post-purge counts:${NC}`);
|
|
12151
|
-
lines.push(` ${DIM}Patterns:${NC} ${after["patterns"]}`);
|
|
12152
|
-
lines.push(` ${DIM}Learnings:${NC} ${after["learnings"]}`);
|
|
12153
|
-
lines.push(` ${DIM}Decisions:${NC} ${after["decisions"]}`);
|
|
12154
|
-
lines.push(` ${DIM}Observations:${NC} ${after["observations"]}`);
|
|
12155
|
-
}
|
|
12156
|
-
lines.push(` ${DIM}FTS5 rebuilt:${NC} ${data["fts5Rebuilt"]}`);
|
|
12157
|
-
return lines.join("\n");
|
|
12158
|
-
}
|
|
12159
|
-
function renderBrainPlasticityStats(data, quiet) {
|
|
12160
|
-
if (quiet) return String(data["totalEvents"] ?? "");
|
|
12161
|
-
const lines = [];
|
|
12162
|
-
const recentEvents = data["recentEvents"];
|
|
12163
|
-
const limit = data["limit"];
|
|
12164
|
-
lines.push(`${BOLD}Brain Plasticity Stats (STDP)${NC}`);
|
|
12165
|
-
lines.push("\u2550".repeat(41));
|
|
12166
|
-
lines.push(` ${DIM}Total events:${NC} ${data["totalEvents"]}`);
|
|
12167
|
-
lines.push(` ${DIM}LTP (potentiation):${NC} ${data["ltpCount"]}`);
|
|
12168
|
-
lines.push(` ${DIM}LTD (depression):${NC} ${data["ltdCount"]}`);
|
|
12169
|
-
const netDeltaW = data["netDeltaW"] ?? 0;
|
|
12170
|
-
const sign = netDeltaW >= 0 ? "+" : "";
|
|
12171
|
-
lines.push(` ${DIM}Net \u0394w:${NC} ${sign}${netDeltaW.toFixed(4)}`);
|
|
12172
|
-
lines.push(` ${DIM}Last event:${NC} ${data["lastEventAt"] ?? "(none)"}`);
|
|
12173
|
-
if (recentEvents && recentEvents.length > 0) {
|
|
12174
|
-
lines.push(`
|
|
12175
|
-
${BOLD}Recent Events (newest first, limit=${limit ?? 20})${NC}`);
|
|
12176
|
-
for (const ev of recentEvents) {
|
|
12177
|
-
const evSign = ev["deltaW"] >= 0 ? "+" : "";
|
|
12178
|
-
const src = String(ev["sourceNode"] ?? "").slice(0, 30).padEnd(30);
|
|
12179
|
-
const tgt = String(ev["targetNode"] ?? "").slice(0, 30).padEnd(30);
|
|
12180
|
-
lines.push(
|
|
12181
|
-
` ${DIM}[${String(ev["kind"] ?? "").toUpperCase()}]${NC} ${src} \u2192 ${tgt} ${DIM}\u0394w=${evSign}${ev["deltaW"].toFixed(4)}${NC} ${ev["timestamp"]}`
|
|
12182
|
-
);
|
|
12183
|
-
}
|
|
12184
|
-
} else {
|
|
12185
|
-
lines.push("");
|
|
12186
|
-
lines.push(` ${DIM}No plasticity events recorded yet.${NC}`);
|
|
12187
|
-
lines.push(
|
|
12188
|
-
` ${DIM}Run \`cleo brain maintenance\` or \`cleo session end\` to trigger STDP.${NC}`
|
|
12189
|
-
);
|
|
12190
|
-
}
|
|
12191
|
-
return lines.join("\n");
|
|
12192
|
-
}
|
|
12193
|
-
function renderBrainQuality(data, quiet) {
|
|
12194
|
-
if (quiet) {
|
|
12195
|
-
const usageRate2 = data["usageRate"] ?? 0;
|
|
12196
|
-
return `${(usageRate2 * 100).toFixed(1)}%`;
|
|
12197
|
-
}
|
|
12198
|
-
const lines = [];
|
|
12199
|
-
const qualityDistribution = data["qualityDistribution"];
|
|
12200
|
-
const tierDistribution = data["tierDistribution"];
|
|
12201
|
-
const topRetrieved = data["topRetrieved"];
|
|
12202
|
-
const neverRetrieved = data["neverRetrieved"];
|
|
12203
|
-
const usageRate = data["usageRate"] ?? 0;
|
|
12204
|
-
const noiseRatio = data["noiseRatio"] ?? 0;
|
|
12205
|
-
lines.push(`${BOLD}Brain Memory Quality Report${NC}`);
|
|
12206
|
-
lines.push("\u2550".repeat(42));
|
|
12207
|
-
lines.push(` ${DIM}Total retrievals:${NC} ${data["totalRetrievals"]}`);
|
|
12208
|
-
lines.push(` ${DIM}Unique entries hit:${NC} ${data["uniqueEntriesRetrieved"]}`);
|
|
12209
|
-
lines.push(` ${DIM}Usage rate:${NC} ${(usageRate * 100).toFixed(1)}%`);
|
|
12210
|
-
lines.push(` ${DIM}Noise ratio:${NC} ${(noiseRatio * 100).toFixed(1)}%`);
|
|
12211
|
-
if (qualityDistribution) {
|
|
12212
|
-
lines.push("");
|
|
12213
|
-
lines.push(`${BOLD}Quality Distribution${NC}`);
|
|
12214
|
-
lines.push(` ${DIM}Low (<0.3):${NC} ${qualityDistribution["low"]}`);
|
|
12215
|
-
lines.push(` ${DIM}Med (0.3-0.6):${NC} ${qualityDistribution["medium"]}`);
|
|
12216
|
-
lines.push(` ${DIM}High (>0.6):${NC} ${qualityDistribution["high"]}`);
|
|
12217
|
-
}
|
|
12218
|
-
if (tierDistribution) {
|
|
12219
|
-
lines.push("");
|
|
12220
|
-
lines.push(`${BOLD}Tier Distribution${NC}`);
|
|
12221
|
-
lines.push(` ${DIM}Short:${NC} ${tierDistribution["short"]}`);
|
|
12222
|
-
lines.push(` ${DIM}Medium:${NC} ${tierDistribution["medium"]}`);
|
|
12223
|
-
lines.push(` ${DIM}Long:${NC} ${tierDistribution["long"]}`);
|
|
12224
|
-
if (tierDistribution["unknown"] > 0) {
|
|
12225
|
-
lines.push(` ${DIM}Unknown:${NC} ${tierDistribution["unknown"]}`);
|
|
12226
|
-
}
|
|
12227
|
-
}
|
|
12228
|
-
if (topRetrieved && topRetrieved.length > 0) {
|
|
12229
|
-
lines.push("");
|
|
12230
|
-
lines.push(`${BOLD}Top 10 Most Retrieved${NC}`);
|
|
12231
|
-
for (const e of topRetrieved) {
|
|
12232
|
-
lines.push(
|
|
12233
|
-
` ${CYAN}[${e["citationCount"]}x]${NC} ${DIM}${e["id"]}${NC} ${String(e["title"] ?? "").slice(0, 60)}`
|
|
12234
|
-
);
|
|
12235
|
-
}
|
|
12236
|
-
}
|
|
12237
|
-
if (neverRetrieved && neverRetrieved.length > 0) {
|
|
12238
|
-
lines.push("");
|
|
12239
|
-
lines.push(`${YELLOW}${BOLD}Never Retrieved (pruning candidates)${NC}`);
|
|
12240
|
-
for (const e of neverRetrieved) {
|
|
12241
|
-
lines.push(
|
|
12242
|
-
` ${DIM}q=${e["qualityScore"].toFixed(2)}${NC} ${DIM}${e["id"]}${NC} ${String(e["title"] ?? "").slice(0, 60)}`
|
|
12243
|
-
);
|
|
12244
|
-
}
|
|
12245
|
-
}
|
|
12246
|
-
return lines.join("\n");
|
|
12247
|
-
}
|
|
12248
|
-
function renderBrainExport(data, quiet) {
|
|
12249
|
-
if (quiet) return String(data["outputFile"] ?? "");
|
|
12250
|
-
return `${GREEN}Exported to ${data["outputFile"]}:${NC} ${data["nodeCount"]} nodes, ${data["edgeCount"]} edges (${String(data["format"] ?? "").toUpperCase()})`;
|
|
12251
|
-
}
|
|
12252
|
-
function renderAuditReconstruct(data, quiet) {
|
|
12253
|
-
if (quiet) return "";
|
|
12254
|
-
const taskId = data["taskId"];
|
|
12255
|
-
const directCommits = data["directCommits"] ?? [];
|
|
12256
|
-
const childIdRange = data["childIdRange"];
|
|
12257
|
-
const childCommits = data["childCommits"] ?? {};
|
|
12258
|
-
const releaseTags = data["releaseTags"] ?? [];
|
|
12259
|
-
const inferredChildren = data["inferredChildren"] ?? [];
|
|
12260
|
-
const firstSeenAt = data["firstSeenAt"];
|
|
12261
|
-
const lastSeenAt = data["lastSeenAt"];
|
|
12262
|
-
const lines = [
|
|
12263
|
-
`${BOLD}Lineage for ${taskId ?? "?"}${NC}`,
|
|
12264
|
-
"=".repeat(40),
|
|
12265
|
-
"",
|
|
12266
|
-
`${DIM}Direct commits:${NC} ${directCommits.length}`
|
|
12267
|
-
];
|
|
12268
|
-
for (const c of directCommits) {
|
|
12269
|
-
const sha = typeof c["sha"] === "string" ? c["sha"].slice(0, 10) : "?";
|
|
12270
|
-
const subject = typeof c["subject"] === "string" ? c["subject"] : "";
|
|
12271
|
-
lines.push(` ${CYAN}${sha}${NC} ${subject}`);
|
|
12272
|
-
}
|
|
12273
|
-
lines.push("");
|
|
12274
|
-
if (childIdRange) {
|
|
12275
|
-
lines.push(
|
|
12276
|
-
`${DIM}Inferred children:${NC} ${inferredChildren.join(", ")} (${childIdRange.min} \u2192 ${childIdRange.max})`
|
|
12277
|
-
);
|
|
12278
|
-
} else {
|
|
12279
|
-
lines.push(`${DIM}Inferred children:${NC} none`);
|
|
12280
|
-
}
|
|
12281
|
-
const childEntries = Object.entries(childCommits);
|
|
12282
|
-
if (childEntries.length > 0) {
|
|
12283
|
-
lines.push("");
|
|
12284
|
-
lines.push(`${BOLD}Child commits:${NC}`);
|
|
12285
|
-
for (const [childId, commits] of childEntries) {
|
|
12286
|
-
lines.push(` ${CYAN}${childId}${NC}: ${commits.length} commit(s)`);
|
|
12287
|
-
for (const c of commits) {
|
|
12288
|
-
const sha = typeof c["sha"] === "string" ? c["sha"].slice(0, 10) : "?";
|
|
12289
|
-
const subject = typeof c["subject"] === "string" ? c["subject"] : "";
|
|
12290
|
-
lines.push(` ${DIM}${sha}${NC} ${subject}`);
|
|
12291
|
-
}
|
|
12292
|
-
}
|
|
12293
|
-
}
|
|
12294
|
-
lines.push("");
|
|
12295
|
-
if (releaseTags.length > 0) {
|
|
12296
|
-
lines.push(`${BOLD}Release tags (${releaseTags.length}):${NC}`);
|
|
12297
|
-
for (const t of releaseTags) {
|
|
12298
|
-
const tag = typeof t["tag"] === "string" ? t["tag"] : "?";
|
|
12299
|
-
const sha = typeof t["commitSha"] === "string" ? t["commitSha"].slice(0, 10) : "?";
|
|
12300
|
-
const subject = typeof t["subject"] === "string" ? t["subject"] : "";
|
|
12301
|
-
lines.push(` ${GREEN}${tag}${NC} ${DIM}${sha}${NC} ${subject}`);
|
|
12302
|
-
}
|
|
12303
|
-
} else {
|
|
12304
|
-
lines.push(`${DIM}Release tags:${NC} none found`);
|
|
12305
|
-
}
|
|
12306
|
-
lines.push("");
|
|
12307
|
-
lines.push(`${DIM}First seen:${NC} ${firstSeenAt ?? "n/a"}`);
|
|
12308
|
-
lines.push(`${DIM}Last seen: ${NC} ${lastSeenAt ?? "n/a"}`);
|
|
12309
|
-
return lines.join("\n");
|
|
12310
|
-
}
|
|
12311
|
-
function renderSchemaCommand(data, quiet) {
|
|
12312
|
-
if (quiet) return "";
|
|
12313
|
-
const lines = [];
|
|
12314
|
-
lines.push(`Operation : ${String(data["operation"] ?? "")}`);
|
|
12315
|
-
lines.push(`Gateway : ${String(data["gateway"] ?? "")}`);
|
|
12316
|
-
lines.push(`Description: ${String(data["description"] ?? "")}`);
|
|
12317
|
-
lines.push("");
|
|
12318
|
-
const params = data["params"] ?? [];
|
|
12319
|
-
lines.push("Parameters:");
|
|
12320
|
-
if (params.length === 0) {
|
|
12321
|
-
lines.push(" (none declared)");
|
|
12322
|
-
} else {
|
|
12323
|
-
for (const p of params) {
|
|
12324
|
-
const req = p["required"] ? "[required]" : "[optional]";
|
|
12325
|
-
const enumVal = p["enum"];
|
|
12326
|
-
const enumStr = enumVal ? ` enum: ${enumVal.join(" | ")}` : "";
|
|
12327
|
-
const cli = p["cli"];
|
|
12328
|
-
let cliStr = "";
|
|
12329
|
-
if (cli) {
|
|
12330
|
-
const parts = [];
|
|
12331
|
-
if (cli["positional"]) parts.push("positional");
|
|
12332
|
-
if (cli["short"]) parts.push(`short: ${String(cli["short"])}`);
|
|
12333
|
-
if (cli["flag"]) parts.push(`flag: --${String(cli["flag"])}`);
|
|
12334
|
-
if (parts.length > 0) cliStr = ` cli: ${parts.join(", ")}`;
|
|
12335
|
-
}
|
|
12336
|
-
lines.push(` ${String(p["name"] ?? "")} (${String(p["type"] ?? "")}) ${req}`);
|
|
12337
|
-
lines.push(` ${String(p["description"] ?? "")}${enumStr}${cliStr}`);
|
|
12338
|
-
}
|
|
12339
|
-
}
|
|
12340
|
-
const gates = data["gates"];
|
|
12341
|
-
if (gates !== void 0) {
|
|
12342
|
-
lines.push("");
|
|
12343
|
-
lines.push("Gates:");
|
|
12344
|
-
if (gates.length === 0) {
|
|
12345
|
-
lines.push(" (none declared \u2014 see note on static gate table)");
|
|
12346
|
-
} else {
|
|
12347
|
-
for (const g of gates) {
|
|
12348
|
-
lines.push(` ${String(g["name"] ?? "")} \u2192 ${String(g["errorCode"] ?? "")}`);
|
|
12349
|
-
lines.push(` ${String(g["description"] ?? "")}`);
|
|
12350
|
-
const triggers = g["triggers"] ?? [];
|
|
12351
|
-
for (const t of triggers) {
|
|
12352
|
-
lines.push(` - ${t}`);
|
|
12353
|
-
}
|
|
12354
|
-
}
|
|
12355
|
-
}
|
|
12356
|
-
}
|
|
12357
|
-
const examples = data["examples"];
|
|
12358
|
-
if (examples !== void 0 && examples.length > 0) {
|
|
12359
|
-
lines.push("");
|
|
12360
|
-
lines.push("Examples:");
|
|
12361
|
-
for (const ex of examples) {
|
|
12362
|
-
lines.push(` ${String(ex["command"] ?? "")}`);
|
|
12363
|
-
lines.push(` ${String(ex["description"] ?? "")}`);
|
|
12364
|
-
}
|
|
12365
|
-
}
|
|
12366
|
-
return lines.join("\n");
|
|
12367
|
-
}
|
|
12368
|
-
function renderGeneric(data, quiet) {
|
|
12369
|
-
if (quiet) return "";
|
|
12370
|
-
const lines = [];
|
|
12371
|
-
for (const [key, val] of Object.entries(data)) {
|
|
12372
|
-
if (val === null || val === void 0) continue;
|
|
12373
|
-
if (Array.isArray(val)) {
|
|
12374
|
-
lines.push(`${BOLD}${formatLabel(key)}:${NC} (${val.length})`);
|
|
12375
|
-
for (const item of val.slice(0, 20)) {
|
|
12376
|
-
if (typeof item === "object" && item !== null) {
|
|
12377
|
-
const obj = item;
|
|
12378
|
-
const id = obj["id"] ?? "";
|
|
12379
|
-
const title = obj["title"] ?? obj["name"] ?? "";
|
|
12380
|
-
lines.push(` ${id}${title ? ` ${title}` : ""}`);
|
|
12381
|
-
} else {
|
|
12382
|
-
lines.push(` ${String(item)}`);
|
|
12383
|
-
}
|
|
12384
|
-
}
|
|
12385
|
-
if (val.length > 20) {
|
|
12386
|
-
lines.push(` ${DIM}... and ${val.length - 20} more${NC}`);
|
|
12387
|
-
}
|
|
12388
|
-
} else if (typeof val === "object") {
|
|
12389
|
-
lines.push(`${BOLD}${formatLabel(key)}:${NC}`);
|
|
12390
|
-
for (const [subKey, subVal] of Object.entries(val)) {
|
|
12391
|
-
lines.push(` ${DIM}${formatLabel(subKey)}:${NC} ${String(subVal)}`);
|
|
12392
|
-
}
|
|
12393
|
-
} else {
|
|
12394
|
-
lines.push(`${DIM}${formatLabel(key)}:${NC} ${String(val)}`);
|
|
12395
|
-
}
|
|
12396
|
-
}
|
|
12397
|
-
return lines.join("\n") || "OK";
|
|
12398
|
-
}
|
|
12399
|
-
function formatLabel(key) {
|
|
12400
|
-
return key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
12401
|
-
}
|
|
12402
|
-
var init_system2 = __esm({
|
|
12403
|
-
"packages/cleo/src/cli/renderers/system.ts"() {
|
|
12404
|
-
"use strict";
|
|
12405
|
-
init_tree_context();
|
|
12406
|
-
init_colors();
|
|
12407
|
-
}
|
|
12408
|
-
});
|
|
12409
|
-
|
|
12410
|
-
// packages/cleo/src/cli/renderers/nexus.ts
|
|
12411
|
-
function str(v, fallback = "\u2014") {
|
|
12412
|
-
if (v === null || v === void 0) return fallback;
|
|
12413
|
-
return String(v);
|
|
12414
|
-
}
|
|
12415
|
-
function num(v, width = 0, fallback = "\u2014") {
|
|
12416
|
-
if (v === null || v === void 0) return fallback;
|
|
12417
|
-
const s = String(Number(v));
|
|
12418
|
-
return width > 0 ? s.padStart(width) : s;
|
|
12419
|
-
}
|
|
12420
|
-
function renderNexusStatus(data, quiet) {
|
|
12421
|
-
if (quiet) return "";
|
|
12422
|
-
const repoPath = str(data["repoPath"]);
|
|
12423
|
-
const projectId = str(data["projectId"]);
|
|
12424
|
-
const indexed = data["indexed"];
|
|
12425
|
-
if (!indexed) {
|
|
12426
|
-
return `[nexus] Index status for: ${repoPath}
|
|
12427
|
-
Status: NOT INDEXED
|
|
12428
|
-
Run 'cleo nexus analyze' to build the index.`;
|
|
12429
|
-
}
|
|
12430
|
-
const staleFileCount = Number(data["staleFileCount"] ?? -1);
|
|
12431
|
-
const staleLabel = staleFileCount < 0 ? "unknown" : staleFileCount === 0 ? "up to date" : `${staleFileCount} stale`;
|
|
12432
|
-
return `[nexus] Index status for: ${repoPath}
|
|
12433
|
-
Project ID: ${projectId}
|
|
12434
|
-
Nodes: ${str(data["nodeCount"])}
|
|
12435
|
-
Relations: ${str(data["relationCount"])}
|
|
12436
|
-
Files: ${str(data["fileCount"])}
|
|
12437
|
-
Last indexed: ${str(data["lastIndexedAt"], "never")}
|
|
12438
|
-
Staleness: ${staleLabel}`;
|
|
12439
|
-
}
|
|
12440
|
-
function renderNexusSetup(data, quiet) {
|
|
12441
|
-
if (quiet) return "";
|
|
12442
|
-
const homeDir = str(data["homeDir"]);
|
|
12443
|
-
return `[nexus] Installed PreToolUse hook at ${homeDir}/.cleo/hooks/nexus-augment.sh
|
|
12444
|
-
[nexus] Hook will inject symbol context into Grep/Glob/Read tool calls`;
|
|
12445
|
-
}
|
|
12446
|
-
function renderNexusClusters(data, quiet) {
|
|
12447
|
-
if (quiet) return "";
|
|
12448
|
-
const projectId = str(data["projectId"]);
|
|
12449
|
-
const communities = data["communities"] ?? [];
|
|
12450
|
-
if (communities.length === 0) {
|
|
12451
|
-
return `[nexus] No communities found for project ${projectId}.
|
|
12452
|
-
Run 'cleo nexus analyze' first.`;
|
|
12453
|
-
}
|
|
12454
|
-
const lines = [
|
|
12455
|
-
`[nexus] Communities for project ${projectId} (${communities.length} total):`
|
|
12456
|
-
];
|
|
12457
|
-
for (const c of communities) {
|
|
12458
|
-
const cohesion = typeof c["cohesion"] === "number" ? c["cohesion"].toFixed(3) : "0.000";
|
|
12459
|
-
lines.push(
|
|
12460
|
-
` ${str(c["id"]).padEnd(16)} label=${str(c["label"] ?? "").padEnd(24)} symbols=${num(c["symbolCount"], 5)} cohesion=${cohesion}`
|
|
12461
|
-
);
|
|
12462
|
-
}
|
|
12463
|
-
return lines.join("\n");
|
|
12464
|
-
}
|
|
12465
|
-
function renderNexusFlows(data, quiet) {
|
|
12466
|
-
if (quiet) return "";
|
|
12467
|
-
const projectId = str(data["projectId"]);
|
|
12468
|
-
const flows = data["flows"] ?? [];
|
|
12469
|
-
if (flows.length === 0) {
|
|
12470
|
-
return `[nexus] No execution flows found for project ${projectId}.
|
|
12471
|
-
Run 'cleo nexus analyze' first.`;
|
|
12472
|
-
}
|
|
12473
|
-
const lines = [
|
|
12474
|
-
`[nexus] Execution flows for project ${projectId} (${flows.length} total):`
|
|
12475
|
-
];
|
|
12476
|
-
for (const p of flows) {
|
|
12477
|
-
const processType = str(p["processType"]).replace("_community", "");
|
|
12478
|
-
lines.push(
|
|
12479
|
-
` ${str(p["id"]).padEnd(30)} steps=${num(p["stepCount"], 3)} type=${processType.padEnd(12)} ${str(p["label"] ?? "")}`
|
|
12480
|
-
);
|
|
12481
|
-
}
|
|
12482
|
-
return lines.join("\n");
|
|
12483
|
-
}
|
|
12484
|
-
function renderNexusContext(data, quiet) {
|
|
12485
|
-
if (quiet) return "";
|
|
12486
|
-
const matchCount = Number(data["matchCount"] ?? 0);
|
|
12487
|
-
const symbolName = str(data["_symbolName"] ?? "(unknown)");
|
|
12488
|
-
if (matchCount === 0) {
|
|
12489
|
-
return `[nexus] No symbol found matching '${symbolName}'.
|
|
12490
|
-
Run 'cleo nexus analyze' first, or check the symbol name.`;
|
|
12491
|
-
}
|
|
12492
|
-
const results = data["results"] ?? [];
|
|
12493
|
-
const lines = [
|
|
12494
|
-
`[nexus] Context for symbol '${symbolName}' (${matchCount} match${matchCount !== 1 ? "es" : ""}):`
|
|
12495
|
-
];
|
|
12496
|
-
for (const r of results) {
|
|
12497
|
-
const callers = r["callers"] ?? [];
|
|
12498
|
-
const callees = r["callees"] ?? [];
|
|
12499
|
-
const processes = r["processes"] ?? [];
|
|
12500
|
-
const community = r["community"];
|
|
12501
|
-
const source = r["source"];
|
|
12502
|
-
lines.push("");
|
|
12503
|
-
let entry = ` Symbol: ${str(r["name"])} (${str(r["kind"])})
|
|
12504
|
-
File: ${str(r["filePath"], "n/a")}` + (r["startLine"] ? `:${str(r["startLine"])}` : "") + "\n";
|
|
12505
|
-
if (r["docSummary"]) entry += ` Doc: ${str(r["docSummary"])}
|
|
12506
|
-
`;
|
|
12507
|
-
if (community) entry += ` Community: ${str(community.label ?? community.id)}
|
|
12508
|
-
`;
|
|
12509
|
-
entry += ` Callers (${callers.length}): ${callers.length === 0 ? "none" : callers.map((c) => `${c.name}[${c.kind}]`).join(", ")}
|
|
12510
|
-
`;
|
|
12511
|
-
entry += ` Callees (${callees.length}): ${callees.length === 0 ? "none" : callees.map((c) => `${c.name}[${c.kind}]`).join(", ")}`;
|
|
12512
|
-
if (processes.length > 0) {
|
|
12513
|
-
entry += `
|
|
12514
|
-
Processes: ${processes.map((p) => `${str(p.label)}(${p.role})`).join(", ")}`;
|
|
12515
|
-
}
|
|
12516
|
-
lines.push(entry);
|
|
12517
|
-
if (source?.source) {
|
|
12518
|
-
const ext = str(r["filePath"]).split(".").pop() ?? "txt";
|
|
12519
|
-
lines.push(
|
|
12520
|
-
`
|
|
12521
|
-
Source (lines ${source.startLine}-${source.endLine}):
|
|
12522
|
-
\`\`\`${ext}
|
|
12523
|
-
${source.source.split("\n").map((line) => ` ${line}`).join("\n")}
|
|
12524
|
-
\`\`\``
|
|
12525
|
-
);
|
|
12526
|
-
} else if (source?.errors?.length) {
|
|
12527
|
-
lines.push(`
|
|
12528
|
-
[warning] Could not retrieve source: ${source.errors[0]}`);
|
|
12529
|
-
}
|
|
12530
|
-
}
|
|
12531
|
-
if (matchCount > 5) {
|
|
12532
|
-
lines.push(`
|
|
12533
|
-
(Showing 5 of ${matchCount} matches \u2014 use --json for full list)`);
|
|
12534
|
-
}
|
|
12535
|
-
return lines.join("\n");
|
|
12536
|
-
}
|
|
12537
|
-
function renderNexusImpact(data, quiet) {
|
|
12538
|
-
if (quiet) return "";
|
|
12539
|
-
const symbolName = str(data["_symbolName"] ?? data["targetName"] ?? "(unknown)");
|
|
12540
|
-
if (data["_notFound"]) {
|
|
12541
|
-
return `[nexus] No symbol found matching '${symbolName}'.
|
|
12542
|
-
Run 'cleo nexus analyze' first, or check the symbol name.`;
|
|
12543
|
-
}
|
|
12544
|
-
const lines = [
|
|
12545
|
-
`[nexus] Impact analysis for '${symbolName}'
|
|
12546
|
-
Target: ${str(data["targetName"])} (${str(data["targetKind"])})
|
|
12547
|
-
File: ${str(data["targetFilePath"], "n/a")}
|
|
12548
|
-
Risk: ${str(data["riskLevel"])} (${num(data["totalImpactedNodes"])} impacted node${Number(data["totalImpactedNodes"]) !== 1 ? "s" : ""})`
|
|
12549
|
-
];
|
|
12550
|
-
const impactByDepth = data["impactByDepth"] ?? [];
|
|
12551
|
-
if (Number(data["totalImpactedNodes"]) === 0) {
|
|
12552
|
-
lines.push(" No callers found \u2014 safe to modify.");
|
|
12553
|
-
} else {
|
|
12554
|
-
for (let i = 0; i < impactByDepth.length; i++) {
|
|
12555
|
-
const layer = impactByDepth[i];
|
|
12556
|
-
if (!layer || layer.nodes.length === 0) continue;
|
|
12557
|
-
const label = i === 0 ? "WILL BREAK" : i === 1 ? "LIKELY AFFECTED" : "MAY NEED TESTING";
|
|
12558
|
-
lines.push(`
|
|
12559
|
-
d=${i + 1} ${label} (${layer.nodes.length}):`);
|
|
12560
|
-
for (const node of layer.nodes.slice(0, 15)) {
|
|
12561
|
-
lines.push(
|
|
12562
|
-
` ${String(node.name).padEnd(36)} ${String(node.kind).padEnd(12)} ${node.filePath ?? ""}`
|
|
12563
|
-
);
|
|
12564
|
-
if (data["_why"] && node.reasons.length > 0) {
|
|
12565
|
-
for (const reason of node.reasons) {
|
|
12566
|
-
lines.push(` why: ${reason}`);
|
|
12567
|
-
}
|
|
12568
|
-
}
|
|
12569
|
-
}
|
|
12570
|
-
if (layer.nodes.length > 15) {
|
|
12571
|
-
lines.push(` ... and ${layer.nodes.length - 15} more`);
|
|
12572
|
-
}
|
|
12573
|
-
}
|
|
12574
|
-
}
|
|
12575
|
-
return lines.join("\n");
|
|
12576
|
-
}
|
|
12577
|
-
function renderNexusAnalyze(data, quiet) {
|
|
12578
|
-
if (quiet) return "";
|
|
12579
|
-
const isIncremental = !!data["incremental"];
|
|
12580
|
-
return `[nexus] Analysis complete${isIncremental ? " (incremental)" : ""}:
|
|
12581
|
-
Project ID: ${str(data["projectId"])}
|
|
12582
|
-
Files: ${str(data["fileCount"])}
|
|
12583
|
-
Nodes: ${str(data["nodeCount"])}
|
|
12584
|
-
Relations: ${str(data["relationCount"])}
|
|
12585
|
-
Duration: ${str(data["durationMs"])}ms`;
|
|
12586
|
-
}
|
|
12587
|
-
function renderNexusProjectsList(data, quiet) {
|
|
12588
|
-
if (quiet) return "";
|
|
12589
|
-
const list = data["projects"] ?? [];
|
|
12590
|
-
if (list.length === 0) {
|
|
12591
|
-
return "[nexus] No projects registered. Run: cleo nexus projects register";
|
|
12592
|
-
}
|
|
12593
|
-
const lines = [`[nexus] Registered projects (${list.length}):`, ""];
|
|
12594
|
-
for (const p of list) {
|
|
12595
|
-
const stats = p["stats"] ?? {};
|
|
12596
|
-
const nodes = Number(stats["nodeCount"] ?? 0);
|
|
12597
|
-
const rels = Number(stats["relationCount"] ?? 0);
|
|
12598
|
-
const indexed = p["lastIndexed"] ? str(p["lastIndexed"]).slice(0, 10) : "never";
|
|
12599
|
-
lines.push(
|
|
12600
|
-
` ${str(p["name"]).padEnd(28)} tasks=${num(p["taskCount"], 5)} nodes=${String(nodes).padStart(6)} relations=${String(rels).padStart(7)} indexed=${indexed}`
|
|
12601
|
-
);
|
|
12602
|
-
lines.push(` ${"".padEnd(28)} path=${str(p["path"])}`);
|
|
12603
|
-
}
|
|
12604
|
-
return lines.join("\n");
|
|
12605
|
-
}
|
|
12606
|
-
function renderNexusProjectsRegister(data, quiet) {
|
|
12607
|
-
if (quiet) return "";
|
|
12608
|
-
return `[nexus] Registered: ${str(data["path"])} (hash: ${str(data["hash"])})`;
|
|
12609
|
-
}
|
|
12610
|
-
function renderNexusProjectsRemove(data, quiet) {
|
|
12611
|
-
if (quiet) return "";
|
|
12612
|
-
return `[nexus] Removed: ${str(data["nameOrHash"] ?? data["removed"])}`;
|
|
12613
|
-
}
|
|
12614
|
-
function renderNexusProjectsScan(data, quiet) {
|
|
12615
|
-
if (quiet) return "";
|
|
12616
|
-
const roots = data["roots"] ?? [];
|
|
12617
|
-
const maxDepth = Number(data["_maxDepth"] ?? 4);
|
|
12618
|
-
const tally = data["tally"] ?? {};
|
|
12619
|
-
const unregistered = data["unregistered"] ?? [];
|
|
12620
|
-
const registered = data["registered"] ?? [];
|
|
12621
|
-
const autoRegistered = data["autoRegistered"] ?? [];
|
|
12622
|
-
const autoRegisterErrors = data["autoRegisterErrors"] ?? [];
|
|
12623
|
-
const autoRegister = !!data["_autoRegister"];
|
|
12624
|
-
const includeExisting = !!data["_includeExisting"];
|
|
12625
|
-
const lines = [
|
|
12626
|
-
`[nexus] Scanning ${roots.length} root(s) up to depth ${maxDepth}:`,
|
|
12627
|
-
...roots.map((r) => ` ${r}`),
|
|
12628
|
-
"",
|
|
12629
|
-
`[nexus] Scan complete \u2014 ${tally["total"] ?? 0} project(s) found (${tally["unregistered"] ?? 0} unregistered, ${tally["registered"] ?? 0} registered)`
|
|
12630
|
-
];
|
|
12631
|
-
if (unregistered.length > 0) {
|
|
12632
|
-
lines.push("\n Unregistered:");
|
|
12633
|
-
for (const p of unregistered) lines.push(` ${p}`);
|
|
12634
|
-
if (!autoRegister) {
|
|
12635
|
-
lines.push("\n Tip: run with --auto-register to register all of the above.");
|
|
12636
|
-
}
|
|
12637
|
-
}
|
|
12638
|
-
if (includeExisting && registered.length > 0) {
|
|
12639
|
-
lines.push("\n Already registered:");
|
|
12640
|
-
for (const p of registered) lines.push(` ${p}`);
|
|
12641
|
-
}
|
|
12642
|
-
if (autoRegister) {
|
|
12643
|
-
lines.push(
|
|
12644
|
-
`
|
|
12645
|
-
Auto-registered: ${autoRegistered.length} project(s)${autoRegisterErrors.length > 0 ? `, ${autoRegisterErrors.length} failed` : ""}`
|
|
12646
|
-
);
|
|
12647
|
-
for (const e of autoRegisterErrors) {
|
|
12648
|
-
lines.push(` FAILED ${e.path}: ${e.error}`);
|
|
12649
|
-
}
|
|
12650
|
-
}
|
|
12651
|
-
return lines.join("\n");
|
|
12652
|
-
}
|
|
12653
|
-
function renderNexusProjectsClean(data, quiet) {
|
|
12654
|
-
if (quiet) return "";
|
|
12655
|
-
const dryRun = !!data["dryRun"];
|
|
12656
|
-
const matched = Number(data["matched"] ?? 0);
|
|
12657
|
-
const purged = Number(data["purged"] ?? 0);
|
|
12658
|
-
const remaining = Number(data["remaining"] ?? 0);
|
|
12659
|
-
if (dryRun) {
|
|
12660
|
-
if (matched === 0) return "";
|
|
12661
|
-
return `[nexus] Dry-run \u2014 ${matched} project(s) would be purged. Rerun without --dry-run to delete.`;
|
|
12662
|
-
}
|
|
12663
|
-
const lines = [
|
|
12664
|
-
`[nexus] Purged ${purged} project(s). ${remaining} project(s) remaining in registry.`
|
|
12665
|
-
];
|
|
12666
|
-
const fsRemoved = data["fsRemoved"];
|
|
12667
|
-
const fsFailed = data["fsFailed"];
|
|
12668
|
-
if (typeof fsRemoved === "number") {
|
|
12669
|
-
lines.push(
|
|
12670
|
-
`[nexus] Filesystem cleanup: removed ${fsRemoved} dir(s)` + (typeof fsFailed === "number" && fsFailed > 0 ? `, ${fsFailed} skipped/failed.` : ".")
|
|
12671
|
-
);
|
|
12672
|
-
}
|
|
12673
|
-
const vacuumBytesFreed = data["vacuumBytesFreed"];
|
|
12674
|
-
if (typeof vacuumBytesFreed === "number") {
|
|
12675
|
-
const mb = (vacuumBytesFreed / (1024 * 1024)).toFixed(1);
|
|
12676
|
-
lines.push(`[nexus] VACUUM reclaimed ${mb} MB.`);
|
|
12677
|
-
}
|
|
12678
|
-
return lines.join("\n");
|
|
12679
|
-
}
|
|
12680
|
-
function renderNexusProjectsCleanPreview(data, _quiet) {
|
|
12681
|
-
const matched = Number(data["matched"] ?? 0);
|
|
12682
|
-
const totalCount = Number(data["totalCount"] ?? 0);
|
|
12683
|
-
const samplePaths = data["sample"] ?? [];
|
|
12684
|
-
const lines = [
|
|
12685
|
-
`[nexus] Clean preview \u2014 ${matched} project(s) of ${totalCount} total match criteria:`
|
|
12686
|
-
];
|
|
12687
|
-
if (matched === 0) {
|
|
12688
|
-
lines.push(" (no matches)");
|
|
12689
|
-
} else {
|
|
12690
|
-
for (const p of samplePaths) lines.push(` ${p}`);
|
|
12691
|
-
if (matched > 10) lines.push(` ... and ${matched - 10} more`);
|
|
12692
|
-
}
|
|
12693
|
-
return lines.join("\n");
|
|
12694
|
-
}
|
|
12695
|
-
function renderNexusRefreshBridge(data, quiet) {
|
|
12696
|
-
if (quiet) return "";
|
|
12697
|
-
if (data["written"]) {
|
|
12698
|
-
return `[nexus] nexus-bridge.md refreshed at ${str(data["path"])}`;
|
|
12699
|
-
}
|
|
12700
|
-
return `[nexus] nexus-bridge.md unchanged at ${str(data["path"])}`;
|
|
12701
|
-
}
|
|
12702
|
-
function renderNexusDiff(data, quiet) {
|
|
12703
|
-
if (quiet) return "";
|
|
12704
|
-
const changedFiles = data["changedFiles"] ?? [];
|
|
12705
|
-
const regressions = data["regressions"] ?? [];
|
|
12706
|
-
const lines = [
|
|
12707
|
-
`[nexus] Diff: ${str(data["beforeSha"])}..${str(data["afterSha"])}
|
|
12708
|
-
Changed files: ${changedFiles.length > 0 ? changedFiles.join(", ") : "n/a"}
|
|
12709
|
-
Nodes: before=${str(data["nodesBefore"])} after=${str(data["nodesAfter"])} new=+${str(data["newNodes"])} removed=-${str(data["removedNodes"])}
|
|
12710
|
-
Relations: before=${str(data["relationsBefore"])} after=${str(data["relationsAfter"])} new=+${str(data["newRelations"])} removed=-${str(data["removedRelations"])}
|
|
12711
|
-
Health: ${str(data["healthStatus"])}`
|
|
12712
|
-
];
|
|
12713
|
-
if (regressions.length > 0) {
|
|
12714
|
-
lines.push("\n REGRESSIONS:");
|
|
12715
|
-
for (const reg of regressions) lines.push(` - ${reg}`);
|
|
12716
|
-
} else {
|
|
12717
|
-
lines.push(" No regressions detected.");
|
|
12718
|
-
}
|
|
12719
|
-
return lines.join("\n");
|
|
12720
|
-
}
|
|
12721
|
-
function renderNexusRouteMap(data, quiet) {
|
|
12722
|
-
if (quiet) return "";
|
|
12723
|
-
const projectId = str(data["_projectId"] ?? "");
|
|
12724
|
-
const routes = data["routes"] ?? [];
|
|
12725
|
-
const distinctDeps = data["distinctDeps"] ?? [];
|
|
12726
|
-
if (routes.length === 0) {
|
|
12727
|
-
return `[nexus] No routes found for project ${projectId}.
|
|
12728
|
-
Run 'cleo nexus analyze' first.`;
|
|
12729
|
-
}
|
|
12730
|
-
const lines = [
|
|
12731
|
-
`[nexus] Route Map for project ${projectId} (${routes.length} total):`,
|
|
12732
|
-
"",
|
|
12733
|
-
"| Route ID | Handler | Method | Path | Deps | Callers |",
|
|
12734
|
-
"|----------|---------|--------|------|------|----------|"
|
|
12735
|
-
];
|
|
12736
|
-
for (const route of routes) {
|
|
12737
|
-
const routeMeta = route["routeMeta"] ?? {};
|
|
12738
|
-
const method = str(routeMeta["method"], "\u2014");
|
|
12739
|
-
const routePath = str(routeMeta["path"], "\u2014");
|
|
12740
|
-
const depCount = (route["fetchedDeps"] ?? []).length;
|
|
12741
|
-
lines.push(
|
|
12742
|
-
`| ${str(route["routeId"])} | ${str(route["handlerName"])} | ${method} | ${routePath} | ${depCount} | ${str(route["callerCount"])} |`
|
|
12743
|
-
);
|
|
12744
|
-
}
|
|
12745
|
-
lines.push("");
|
|
12746
|
-
if (distinctDeps.length > 0) {
|
|
12747
|
-
lines.push(`External dependencies: ${distinctDeps.join(", ")}`);
|
|
12748
|
-
}
|
|
12749
|
-
return lines.join("\n");
|
|
12750
|
-
}
|
|
12751
|
-
function renderNexusShapeCheck(data, quiet) {
|
|
12752
|
-
if (quiet) return "";
|
|
12753
|
-
const routeSymbol = str(data["_routeSymbol"] ?? data["handlerId"] ?? "");
|
|
12754
|
-
const callers = data["callers"] ?? [];
|
|
12755
|
-
const lines = [
|
|
12756
|
-
`[nexus] Shape Check for route ${routeSymbol}`,
|
|
12757
|
-
"",
|
|
12758
|
-
`Handler: ${str(data["handlerId"])}`,
|
|
12759
|
-
`Declared Shape: ${str(data["declaredShape"])}`,
|
|
12760
|
-
`Overall Status: ${str(data["overallStatus"])}`,
|
|
12761
|
-
`Recommendation: ${str(data["recommendation"])}`,
|
|
12762
|
-
""
|
|
12763
|
-
];
|
|
12764
|
-
if (callers.length === 0) {
|
|
12765
|
-
lines.push("No callers found.");
|
|
12766
|
-
} else {
|
|
12767
|
-
lines.push(
|
|
12768
|
-
`Callers (${callers.length} total):`,
|
|
12769
|
-
"| Caller | File | Expected Shape | Status |",
|
|
12770
|
-
"|--------|------|---------------|---------|"
|
|
12771
|
-
);
|
|
12772
|
-
for (const caller of callers) {
|
|
12773
|
-
lines.push(
|
|
12774
|
-
`| ${str(caller["callerName"])} | ${str(caller["callerFile"])} | ${str(caller["expectedShape"])} | ${str(caller["status"])} |`
|
|
12775
|
-
);
|
|
12776
|
-
}
|
|
12777
|
-
const incompatible = callers.filter((c) => c["status"] !== "compatible");
|
|
12778
|
-
if (incompatible.length > 0) {
|
|
12779
|
-
lines.push("\nIncompatibilities:");
|
|
12780
|
-
for (const caller of incompatible) {
|
|
12781
|
-
lines.push(` - ${str(caller["callerName"])}: ${str(caller["diagnosis"])}`);
|
|
12782
|
-
}
|
|
12783
|
-
}
|
|
12784
|
-
}
|
|
12785
|
-
return lines.join("\n");
|
|
12786
|
-
}
|
|
12787
|
-
function renderNexusFullContext(data, quiet) {
|
|
12788
|
-
if (quiet) return "";
|
|
12789
|
-
const nexus = data["nexus"];
|
|
12790
|
-
const brainMemories = data["brainMemories"] ?? [];
|
|
12791
|
-
const tasks = data["tasks"] ?? [];
|
|
12792
|
-
const sentientProposals = data["sentientProposals"] ?? [];
|
|
12793
|
-
const conduitThreads = data["conduitThreads"] ?? [];
|
|
12794
|
-
const plasticityWeight = data["plasticityWeight"] ?? { totalWeight: 0, edgeCount: 0 };
|
|
12795
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12796
|
-
const lines = [`
|
|
12797
|
-
## Living Brain: ${str(data["symbolId"])}`, "", "### NEXUS"];
|
|
12798
|
-
if (!nexus) {
|
|
12799
|
-
lines.push(` (no nexus data \u2014 run 'cleo nexus analyze' first)`);
|
|
12800
|
-
} else {
|
|
12801
|
-
const callers = nexus["callers"] ?? [];
|
|
12802
|
-
const callees = nexus["callees"] ?? [];
|
|
12803
|
-
lines.push(` Kind: ${str(nexus["kind"])} File: ${str(nexus["filePath"], "\u2014")}`);
|
|
12804
|
-
lines.push(
|
|
12805
|
-
` Callers (${callers.length}): ${callers.map((c) => c.name).slice(0, 10).join(", ") || "\u2014"}`
|
|
12806
|
-
);
|
|
12807
|
-
lines.push(
|
|
12808
|
-
` Callees (${callees.length}): ${callees.map((c) => c.name).slice(0, 10).join(", ") || "\u2014"}`
|
|
12809
|
-
);
|
|
12810
|
-
lines.push(
|
|
12811
|
-
` Plasticity: w=${plasticityWeight.totalWeight.toFixed(2)} edges=${plasticityWeight.edgeCount}`
|
|
12812
|
-
);
|
|
12813
|
-
}
|
|
12814
|
-
lines.push(`
|
|
12815
|
-
### BRAIN memories (${brainMemories.length})`);
|
|
12816
|
-
for (const m of brainMemories.slice(0, 10)) {
|
|
12817
|
-
lines.push(
|
|
12818
|
-
` [${str(m["nodeType"])}] ${str(m["label"]).slice(0, 80)} (edge=${str(m["edgeType"])} w=${Number(m["weight"] ?? 0).toFixed(2)})`
|
|
12819
|
-
);
|
|
12820
|
-
}
|
|
12821
|
-
if (brainMemories.length === 0) lines.push(` (none)`);
|
|
12822
|
-
lines.push(`
|
|
12823
|
-
### TASKS (${tasks.length})`);
|
|
12824
|
-
for (const t of tasks.slice(0, 10)) lines.push(` ${t.taskId} w=${t.weight.toFixed(2)}`);
|
|
12825
|
-
if (tasks.length === 0) lines.push(` (none)`);
|
|
12826
|
-
lines.push(`
|
|
12827
|
-
### SENTIENT proposals (${sentientProposals.length})`);
|
|
12828
|
-
for (const p of sentientProposals.slice(0, 5))
|
|
12829
|
-
lines.push(` ${p.title.slice(0, 80)} (w=${p.weight.toFixed(2)})`);
|
|
12830
|
-
if (sentientProposals.length === 0) lines.push(` (none)`);
|
|
12831
|
-
lines.push(`
|
|
12832
|
-
### CONDUIT threads (${conduitThreads.length})`);
|
|
12833
|
-
for (const c of conduitThreads.slice(0, 5)) lines.push(` ${c.nodeId} w=${c.weight.toFixed(2)}`);
|
|
12834
|
-
if (conduitThreads.length === 0) lines.push(` (none)`);
|
|
12835
|
-
lines.push(`
|
|
12836
|
-
(${durationMs}ms)`);
|
|
12837
|
-
return lines.join("\n");
|
|
12838
|
-
}
|
|
12839
|
-
function renderNexusTaskFootprint(data, quiet) {
|
|
12840
|
-
if (quiet) return "";
|
|
12841
|
-
const files = data["files"] ?? [];
|
|
12842
|
-
const symbols = data["symbols"] ?? [];
|
|
12843
|
-
const blastRadius = data["blastRadius"] ?? {};
|
|
12844
|
-
const brainObservations = data["brainObservations"] ?? [];
|
|
12845
|
-
const decisions = data["decisions"] ?? [];
|
|
12846
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12847
|
-
const lines = [
|
|
12848
|
-
`
|
|
12849
|
-
## Task Code Impact: ${str(data["taskId"])}`,
|
|
12850
|
-
"",
|
|
12851
|
-
`**Risk Score**: ${str(data["riskScore"])}`,
|
|
12852
|
-
`**Files** (${files.length}): ${files.slice(0, 10).join(", ") || "\u2014"}`,
|
|
12853
|
-
"",
|
|
12854
|
-
`### Symbols (${symbols.length})`
|
|
12855
|
-
];
|
|
12856
|
-
for (const s of symbols.slice(0, 20)) {
|
|
12857
|
-
lines.push(
|
|
12858
|
-
` [${str(s["riskLevel"])}] ${str(s["label"])} (${str(s["kind"])}) d1=${str(s["directCallers"])} total=${str(s["totalAffected"])}`
|
|
12859
|
-
);
|
|
12860
|
-
}
|
|
12861
|
-
if (symbols.length === 0)
|
|
12862
|
-
lines.push(` (none \u2014 run 'cleo nexus analyze' or link task to symbols first)`);
|
|
12863
|
-
lines.push("\n### Blast Radius");
|
|
12864
|
-
lines.push(
|
|
12865
|
-
` analyzed=${str(blastRadius["symbolsAnalyzed"])} total_affected=${str(blastRadius["totalAffected"])} max_risk=${str(blastRadius["maxRisk"])}`
|
|
12866
|
-
);
|
|
12867
|
-
lines.push(`
|
|
12868
|
-
### Brain Observations (${brainObservations.length})`);
|
|
12869
|
-
for (const o of brainObservations.slice(0, 5))
|
|
12870
|
-
lines.push(` [${str(o["nodeType"])}] ${str(o["label"]).slice(0, 80)}`);
|
|
12871
|
-
lines.push(`
|
|
12872
|
-
### Decisions (${decisions.length})`);
|
|
12873
|
-
for (const d of decisions.slice(0, 5))
|
|
12874
|
-
lines.push(` [${str(d["linkType"])}] ${str(d["decision"]).slice(0, 80)}`);
|
|
12875
|
-
lines.push(`
|
|
12876
|
-
(${durationMs}ms)`);
|
|
12877
|
-
return lines.join("\n");
|
|
12878
|
-
}
|
|
12879
|
-
function renderNexusBrainAnchors(data, quiet) {
|
|
12880
|
-
if (quiet) return "";
|
|
12881
|
-
const nexusNodes = data["nexusNodes"] ?? [];
|
|
12882
|
-
const tasksForNodes = data["tasksForNodes"] ?? [];
|
|
12883
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12884
|
-
const lines = [
|
|
12885
|
-
`
|
|
12886
|
-
## Brain Code Anchors: ${str(data["entryId"])}`,
|
|
12887
|
-
"",
|
|
12888
|
-
`**Plasticity Signal**: ${Number(data["plasticitySignal"] ?? 0).toFixed(2)}`,
|
|
12889
|
-
"",
|
|
12890
|
-
`### Nexus Nodes (${nexusNodes.length})`
|
|
12891
|
-
];
|
|
12892
|
-
for (const n of nexusNodes.slice(0, 20)) {
|
|
12893
|
-
lines.push(
|
|
12894
|
-
` [${str(n["kind"])}] ${str(n["label"])} file=${str(n["filePath"], "\u2014")} edge=${str(n["edgeType"])} w=${Number(n["weight"] ?? 0).toFixed(2)}`
|
|
12895
|
-
);
|
|
12896
|
-
}
|
|
12897
|
-
if (nexusNodes.length === 0) lines.push(` (none)`);
|
|
12898
|
-
lines.push(`
|
|
12899
|
-
### Tasks for Nodes (${tasksForNodes.length} nodes with task links)`);
|
|
12900
|
-
for (const entry of tasksForNodes.slice(0, 10)) {
|
|
12901
|
-
const tList = (entry["tasks"] ?? []).map((t) => t.taskId).join(", ");
|
|
12902
|
-
lines.push(` ${str(entry["nexusNodeId"])}: ${tList}`);
|
|
12903
|
-
}
|
|
12904
|
-
if (tasksForNodes.length === 0) lines.push(` (none)`);
|
|
12905
|
-
lines.push(`
|
|
12906
|
-
(${durationMs}ms)`);
|
|
12907
|
-
return lines.join("\n");
|
|
12908
|
-
}
|
|
12909
|
-
function renderNexusWhy(data, quiet) {
|
|
12910
|
-
if (quiet) return "";
|
|
12911
|
-
const chain = data["chain"] ?? [];
|
|
12912
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12913
|
-
const lines = [
|
|
12914
|
-
`
|
|
12915
|
-
## Code Reasoning: ${str(data["symbolId"])}`,
|
|
12916
|
-
"",
|
|
12917
|
-
`**Narrative**: ${str(data["narrative"])}`,
|
|
12918
|
-
"",
|
|
12919
|
-
`### Trace Chain (${chain.length} steps)`
|
|
12920
|
-
];
|
|
12921
|
-
if (chain.length === 0) {
|
|
12922
|
-
lines.push(` (no trace \u2014 run 'cleo nexus analyze' and 'cleo memory code-links' first)`);
|
|
12923
|
-
} else {
|
|
12924
|
-
for (const step of chain) {
|
|
12925
|
-
const refs = step["refs"] ?? [];
|
|
12926
|
-
const refsStr = refs.length > 0 ? ` refs=[${refs.join(", ")}]` : "";
|
|
12927
|
-
lines.push(
|
|
12928
|
-
` [${str(step["type"])}] ${str(step["id"])}: ${str(step["title"]).slice(0, 80)}${refsStr}`
|
|
12929
|
-
);
|
|
12930
|
-
}
|
|
12931
|
-
}
|
|
12932
|
-
lines.push(`
|
|
12933
|
-
(${durationMs}ms)`);
|
|
12934
|
-
return lines.join("\n");
|
|
12935
|
-
}
|
|
12936
|
-
function renderNexusImpactFull(data, quiet) {
|
|
12937
|
-
if (quiet) return "";
|
|
12938
|
-
const structural = data["structural"] ?? {};
|
|
12939
|
-
const openTasks = data["openTasks"] ?? [];
|
|
12940
|
-
const brainRiskNotes = data["brainRiskNotes"] ?? [];
|
|
12941
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12942
|
-
const lines = [
|
|
12943
|
-
`
|
|
12944
|
-
## Full Impact: ${str(data["symbolId"])}`,
|
|
12945
|
-
"",
|
|
12946
|
-
`**Merged Risk Score**: ${str(data["mergedRiskScore"])}`,
|
|
12947
|
-
`**Narrative**: ${str(data["narrative"])}`,
|
|
12948
|
-
"",
|
|
12949
|
-
"### Structural Blast Radius",
|
|
12950
|
-
` d=1 (will break)=${str(structural["directCallers"])} d=2 (likely affected)=${str(structural["likelyAffected"])} d=3 (may need testing)=${str(structural["mayNeedTesting"])} total=${str(structural["totalAffected"])} risk=${str(structural["riskLevel"])}`,
|
|
12951
|
-
"",
|
|
12952
|
-
`### Open Tasks (${openTasks.length})`
|
|
12953
|
-
];
|
|
12954
|
-
for (const t of openTasks.slice(0, 10)) {
|
|
12955
|
-
lines.push(
|
|
12956
|
-
` ${str(t["taskId"])} ${str(t["label"]).slice(0, 60)} w=${Number(t["weight"] ?? 0).toFixed(2)}`
|
|
12957
|
-
);
|
|
12958
|
-
}
|
|
12959
|
-
if (openTasks.length === 0) lines.push(` (none)`);
|
|
12960
|
-
lines.push(`
|
|
12961
|
-
### Brain Risk Notes (${brainRiskNotes.length})`);
|
|
12962
|
-
for (const n of brainRiskNotes.slice(0, 10)) {
|
|
12963
|
-
lines.push(
|
|
12964
|
-
` [${str(n["nodeType"])}] ${str(n["label"]).slice(0, 70)} edge=${str(n["edgeType"])} w=${Number(n["weight"] ?? 0).toFixed(2)}`
|
|
12965
|
-
);
|
|
12966
|
-
}
|
|
12967
|
-
if (brainRiskNotes.length === 0) lines.push(` (none)`);
|
|
12968
|
-
lines.push(`
|
|
12969
|
-
(${durationMs}ms)`);
|
|
12970
|
-
return lines.join("\n");
|
|
12971
|
-
}
|
|
12972
|
-
function renderNexusConduitScan(data, quiet) {
|
|
12973
|
-
if (quiet) return "";
|
|
12974
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12975
|
-
return `[nexus] conduit-scan complete: scanned=${str(data["scanned"])} linked=${str(data["linked"])} (${durationMs}ms)`;
|
|
12976
|
-
}
|
|
12977
|
-
function renderNexusTaskSymbols(data, quiet) {
|
|
12978
|
-
if (quiet) return "";
|
|
12979
|
-
const taskId = str(data["taskId"]);
|
|
12980
|
-
const symbols = data["symbols"] ?? [];
|
|
12981
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
12982
|
-
if (symbols.length === 0) {
|
|
12983
|
-
return `[nexus] No symbols found for task ${taskId}.
|
|
12984
|
-
Run 'cleo nexus analyze' and ensure git history is available.`;
|
|
12985
|
-
}
|
|
12986
|
-
const lines = [`[nexus] Symbols touched by ${taskId} (${symbols.length} total):`, ""];
|
|
12987
|
-
for (const s of symbols) {
|
|
12988
|
-
lines.push(
|
|
12989
|
-
` [${str(s["kind"]).padEnd(12)}] ${str(s["label"]).padEnd(50)} w=${Number(s["weight"] ?? 0).toFixed(2)} via=${str(s["matchStrategy"])}`
|
|
12990
|
-
);
|
|
12991
|
-
}
|
|
12992
|
-
lines.push("", `(${durationMs}ms)`);
|
|
12993
|
-
return lines.join("\n");
|
|
12994
|
-
}
|
|
12995
|
-
function renderNexusQuery(data, quiet) {
|
|
12996
|
-
if (quiet) return "";
|
|
12997
|
-
const markdown = str(data["_markdown"] ?? "");
|
|
12998
|
-
const rowCount = Number(data["row_count"] ?? 0);
|
|
12999
|
-
const executionTimeMs = Number(data["execution_time_ms"] ?? 0);
|
|
13000
|
-
return `${markdown}
|
|
13001
|
-
|
|
13002
|
-
[nexus] ${rowCount} rows in ${executionTimeMs.toFixed(2)}ms`;
|
|
13003
|
-
}
|
|
13004
|
-
function renderNexusContractsSync(data, quiet) {
|
|
13005
|
-
if (quiet) return "";
|
|
13006
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
13007
|
-
return `[nexus] Contracts extracted from ${str(data["projectId"])}:
|
|
13008
|
-
HTTP: ${str(data["http"])}
|
|
13009
|
-
gRPC: ${str(data["grpc"])}
|
|
13010
|
-
Topic: ${str(data["topic"])}
|
|
13011
|
-
Total: ${str(data["totalCount"])}
|
|
13012
|
-
(${durationMs}ms)`;
|
|
13013
|
-
}
|
|
13014
|
-
function renderNexusContractsShow(data, quiet) {
|
|
13015
|
-
if (quiet) return "";
|
|
13016
|
-
const projectA = str(data["_projectA"] ?? data["projectAId"]);
|
|
13017
|
-
const projectB = str(data["_projectB"] ?? data["projectBId"]);
|
|
13018
|
-
const matches = data["matches"] ?? [];
|
|
13019
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
13020
|
-
if (matches.length === 0) {
|
|
13021
|
-
return `[nexus] No contract matches found between ${projectA} and ${projectB}.
|
|
13022
|
-
Run 'cleo nexus contracts sync' on both projects first.`;
|
|
13023
|
-
}
|
|
13024
|
-
const lines = [
|
|
13025
|
-
`[nexus] Contract compatibility: ${projectA} \u2194 ${projectB}
|
|
13026
|
-
Compatible: ${str(data["compatibleCount"])} Incompatible: ${str(data["incompatibleCount"])} Partial: ${str(data["partialCount"])}
|
|
13027
|
-
Overall: ${str(data["overallCompatibility"])}%`,
|
|
13028
|
-
""
|
|
13029
|
-
];
|
|
13030
|
-
for (const m of matches.slice(0, 20)) {
|
|
13031
|
-
const contractA = m["contractA"] ?? { id: "\u2014" };
|
|
13032
|
-
const contractB = m["contractB"] ?? { id: "\u2014" };
|
|
13033
|
-
lines.push(
|
|
13034
|
-
` [${str(m["compatibility"]).toUpperCase().padEnd(12)}] ${contractA.id} \u2194 ${contractB.id} score=${Number(m["score"] ?? 0).toFixed(2)}`
|
|
13035
|
-
);
|
|
13036
|
-
}
|
|
13037
|
-
if (matches.length > 20) lines.push(` (showing 20 of ${matches.length} matches)`);
|
|
13038
|
-
lines.push("", `(${durationMs}ms)`);
|
|
13039
|
-
return lines.join("\n");
|
|
13040
|
-
}
|
|
13041
|
-
function renderNexusContractsLinkTasks(data, quiet) {
|
|
13042
|
-
if (quiet) return "";
|
|
13043
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
13044
|
-
return `[nexus] contracts link-tasks:
|
|
13045
|
-
Commits processed: ${str(data["commitsProcessed"])}
|
|
13046
|
-
Tasks found: ${str(data["tasksFound"])}
|
|
13047
|
-
Edges linked: ${str(data["linked"])}
|
|
13048
|
-
Last commit: ${str(data["lastCommitHash"], "\u2014")}
|
|
13049
|
-
(${durationMs}ms)`;
|
|
13050
|
-
}
|
|
13051
|
-
function renderNexusWiki(data, quiet) {
|
|
13052
|
-
if (quiet) return "";
|
|
13053
|
-
const outputDir = str(data["_outputDir"] ?? "");
|
|
13054
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
13055
|
-
const skippedCommunities = data["skippedCommunities"] ?? [];
|
|
13056
|
-
const skippedNote = skippedCommunities.length > 0 ? `
|
|
13057
|
-
Skipped: ${skippedCommunities.length} unchanged communities` : "";
|
|
13058
|
-
const loomNote = data["loomEnabled"] ? " (LOOM narratives enabled)" : " (scaffold mode)";
|
|
13059
|
-
return `[nexus] wiki generated${loomNote}:
|
|
13060
|
-
Communities: ${str(data["communityCount"])}
|
|
13061
|
-
Files: ${str(data["fileCount"])}
|
|
13062
|
-
Output: ${outputDir}` + skippedNote + `
|
|
13063
|
-
(${durationMs}ms)`;
|
|
13064
|
-
}
|
|
13065
|
-
function renderNexusHotPaths(data, quiet) {
|
|
13066
|
-
if (quiet) return "";
|
|
13067
|
-
const paths = data["paths"] ?? [];
|
|
13068
|
-
const count = Number(data["count"] ?? 0);
|
|
13069
|
-
const note = data["note"];
|
|
13070
|
-
const lines = [];
|
|
13071
|
-
if (note) lines.push(`[nexus] Note: ${note}`);
|
|
13072
|
-
if (paths.length === 0) {
|
|
13073
|
-
lines.push("[nexus] No hot paths found.");
|
|
13074
|
-
return lines.join("\n");
|
|
13075
|
-
}
|
|
13076
|
-
lines.push(
|
|
13077
|
-
"| Source | Target | Edge Type | Weight | Co-Access |\n| --- | --- | --- | --- | --- |"
|
|
13078
|
-
);
|
|
13079
|
-
for (const p of paths) {
|
|
13080
|
-
lines.push(
|
|
13081
|
-
`| ${str(p["sourceId"])} | ${str(p["targetId"])} | ${str(p["type"])} | ${Number(p["weight"] ?? 0).toFixed(4)} | ${str(p["coAccessedCount"])} |`
|
|
13082
|
-
);
|
|
13083
|
-
}
|
|
13084
|
-
lines.push(`
|
|
13085
|
-
${count} edge(s) shown.`);
|
|
13086
|
-
return lines.join("\n");
|
|
13087
|
-
}
|
|
13088
|
-
function renderNexusHotNodes(data, quiet) {
|
|
13089
|
-
if (quiet) return "";
|
|
13090
|
-
const nodes = data["nodes"] ?? [];
|
|
13091
|
-
const count = Number(data["count"] ?? 0);
|
|
13092
|
-
const note = data["note"];
|
|
13093
|
-
const lines = [];
|
|
13094
|
-
if (note) lines.push(`[nexus] Note: ${note}`);
|
|
13095
|
-
if (nodes.length === 0) {
|
|
13096
|
-
lines.push("[nexus] No hot nodes found.");
|
|
13097
|
-
return lines.join("\n");
|
|
13098
|
-
}
|
|
13099
|
-
lines.push("| Symbol | Total Weight | File | Kind |\n| --- | --- | --- | --- |");
|
|
13100
|
-
for (const n of nodes) {
|
|
13101
|
-
const file = str(n["filePath"], "(unknown)");
|
|
13102
|
-
lines.push(
|
|
13103
|
-
`| ${str(n["label"])} | ${Number(n["totalWeight"] ?? 0).toFixed(4)} | ${file} | ${str(n["kind"])} |`
|
|
13104
|
-
);
|
|
13105
|
-
}
|
|
13106
|
-
lines.push(`
|
|
13107
|
-
${count} node(s) shown.`);
|
|
13108
|
-
return lines.join("\n");
|
|
13109
|
-
}
|
|
13110
|
-
function renderNexusColdSymbols(data, quiet) {
|
|
13111
|
-
if (quiet) return "";
|
|
13112
|
-
const symbols = data["symbols"] ?? [];
|
|
13113
|
-
const count = Number(data["count"] ?? 0);
|
|
13114
|
-
const thresholdDays = Number(data["thresholdDays"] ?? 30);
|
|
13115
|
-
const note = data["note"];
|
|
13116
|
-
const lines = [];
|
|
13117
|
-
if (note) lines.push(`[nexus] Note: ${note}`);
|
|
13118
|
-
if (symbols.length === 0) {
|
|
13119
|
-
lines.push(`[nexus] No cold symbols found (threshold: ${thresholdDays} days, weight < 0.1).`);
|
|
13120
|
-
return lines.join("\n");
|
|
13121
|
-
}
|
|
13122
|
-
lines.push("| Symbol | Last Accessed | Weight | File |\n| --- | --- | --- | --- |");
|
|
13123
|
-
for (const s of symbols) {
|
|
13124
|
-
const lastAccessed = str(s["lastAccessed"], "(never)");
|
|
13125
|
-
const file = str(s["filePath"], "(unknown)");
|
|
13126
|
-
lines.push(
|
|
13127
|
-
`| ${str(s["label"])} | ${lastAccessed} | ${Number(s["maxWeight"] ?? 0).toFixed(4)} | ${file} |`
|
|
13128
|
-
);
|
|
13129
|
-
}
|
|
13130
|
-
lines.push(`
|
|
13131
|
-
${count} cold symbol(s) found (threshold: ${thresholdDays} days).`);
|
|
13132
|
-
return lines.join("\n");
|
|
13133
|
-
}
|
|
13134
|
-
function renderNexusSearchCode(data, quiet) {
|
|
13135
|
-
if (quiet) return "";
|
|
13136
|
-
const durationMs = Number(data["_durationMs"] ?? 0);
|
|
13137
|
-
return `(${durationMs}ms)`;
|
|
13138
|
-
}
|
|
13139
|
-
function renderNexusExport(data, quiet) {
|
|
13140
|
-
if (quiet) return "";
|
|
13141
|
-
if (data["outputFile"]) {
|
|
13142
|
-
return `[nexus] Exported to ${str(data["outputFile"])} (${str(data["nodeCount"])} nodes, ${str(data["edgeCount"])} edges)`;
|
|
13143
|
-
}
|
|
13144
|
-
return "";
|
|
13145
|
-
}
|
|
13146
|
-
var init_nexus2 = __esm({
|
|
13147
|
-
"packages/cleo/src/cli/renderers/nexus.ts"() {
|
|
13148
|
-
"use strict";
|
|
13149
|
-
}
|
|
13150
|
-
});
|
|
13151
|
-
|
|
13152
|
-
// packages/cleo/src/cli/renderers/tasks.ts
|
|
13153
|
-
function renderShow(data, quiet) {
|
|
13154
|
-
const task = data["task"];
|
|
13155
|
-
if (!task) return "No task found.";
|
|
13156
|
-
if (quiet) return renderShowQuiet(task);
|
|
13157
|
-
return renderShowFull(task);
|
|
13158
|
-
}
|
|
13159
|
-
function renderShowQuiet(task) {
|
|
13160
|
-
const sym = statusSymbol(task.status);
|
|
13161
|
-
const pLabel = `[${task.priority}]`;
|
|
13162
|
-
return `${task.id} ${sym} ${task.title} ${pLabel}
|
|
13163
|
-
Status: ${task.status}`;
|
|
13164
|
-
}
|
|
13165
|
-
function renderShowFull(task) {
|
|
13166
|
-
const lines = [];
|
|
13167
|
-
const w = 65;
|
|
13168
|
-
const hr = hRule(w);
|
|
13169
|
-
const pCol = priorityColor(task.priority);
|
|
13170
|
-
const sym = statusSymbol(task.status);
|
|
13171
|
-
lines.push("");
|
|
13172
|
-
lines.push(`${BOX.tl}${hr}${BOX.tr}`);
|
|
13173
|
-
lines.push(`${BOX.v} ${BOLD}${task.id}${NC} ${sym} ${pCol}[${task.priority}]${NC}`);
|
|
13174
|
-
lines.push(`${BOX.v} ${task.title}`);
|
|
13175
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13176
|
-
lines.push(`${BOX.v} ${DIM}Status:${NC} ${task.status}`);
|
|
13177
|
-
lines.push(`${BOX.v} ${DIM}Priority:${NC} ${task.priority}`);
|
|
13178
|
-
if (task.type) lines.push(`${BOX.v} ${DIM}Type:${NC} ${task.type}`);
|
|
13179
|
-
if (task.phase) lines.push(`${BOX.v} ${DIM}Phase:${NC} ${task.phase}`);
|
|
13180
|
-
if (task.size) lines.push(`${BOX.v} ${DIM}Size:${NC} ${task.size}`);
|
|
13181
|
-
if (task.labels?.length)
|
|
13182
|
-
lines.push(`${BOX.v} ${DIM}Labels:${NC} ${task.labels.join(", ")}`);
|
|
13183
|
-
if (task.parentId) lines.push(`${BOX.v} ${DIM}Parent:${NC} ${task.parentId}`);
|
|
13184
|
-
const created = shortDate(task.createdAt);
|
|
13185
|
-
if (created) lines.push(`${BOX.v} ${DIM}Created:${NC} ${created}`);
|
|
13186
|
-
const completed = shortDate(task.completedAt);
|
|
13187
|
-
if (completed) lines.push(`${BOX.v} ${DIM}Completed:${NC} ${completed}`);
|
|
13188
|
-
if (task.description) {
|
|
13189
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13190
|
-
lines.push(`${BOX.v} ${BOLD}Description${NC}`);
|
|
13191
|
-
for (const line of task.description.split("\n")) {
|
|
13192
|
-
lines.push(`${BOX.v} ${line}`);
|
|
13193
|
-
}
|
|
13194
|
-
}
|
|
13195
|
-
if (task.depends?.length) {
|
|
13196
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13197
|
-
lines.push(`${BOX.v} ${BOLD}Depends On${NC}`);
|
|
13198
|
-
lines.push(`${BOX.v} ${task.depends.join(", ")}`);
|
|
13199
|
-
}
|
|
13200
|
-
if (task.blockedBy) {
|
|
13201
|
-
lines.push(`${BOX.v} ${BOLD}Blocked By${NC}`);
|
|
13202
|
-
lines.push(`${BOX.v} ${RED}${task.blockedBy}${NC}`);
|
|
13203
|
-
}
|
|
13204
|
-
if (task.notes?.length) {
|
|
13205
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13206
|
-
lines.push(`${BOX.v} ${BOLD}Notes${NC} (${task.notes.length})`);
|
|
13207
|
-
const shown = task.notes.slice(-5);
|
|
13208
|
-
for (const note of shown) {
|
|
13209
|
-
const short = note.length > 58 ? note.slice(0, 55) + "..." : note;
|
|
13210
|
-
lines.push(`${BOX.v} \u2022 ${short}`);
|
|
13211
|
-
}
|
|
13212
|
-
if (task.notes.length > 5) {
|
|
13213
|
-
lines.push(`${BOX.v} ${DIM}... and ${task.notes.length - 5} more${NC}`);
|
|
13214
|
-
}
|
|
13215
|
-
}
|
|
13216
|
-
if (task.files?.length) {
|
|
13217
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13218
|
-
lines.push(`${BOX.v} ${BOLD}Files${NC}`);
|
|
13219
|
-
lines.push(`${BOX.v} ${task.files.join(", ")}`);
|
|
13220
|
-
}
|
|
13221
|
-
if (task.acceptance?.length) {
|
|
13222
|
-
lines.push(`${BOX.ml}${hr}${BOX.mr}`);
|
|
13223
|
-
lines.push(`${BOX.v} ${BOLD}Acceptance Criteria${NC}`);
|
|
13224
|
-
for (const criterion of task.acceptance) {
|
|
13225
|
-
lines.push(`${BOX.v} \u2610 ${criterion}`);
|
|
13226
|
-
}
|
|
13227
|
-
}
|
|
13228
|
-
lines.push(`${BOX.bl}${hr}${BOX.br}`);
|
|
13229
|
-
lines.push("");
|
|
13230
|
-
return lines.join("\n");
|
|
13231
|
-
}
|
|
13232
|
-
function renderList(data, quiet) {
|
|
13233
|
-
const tasks = data["tasks"] ?? [];
|
|
13234
|
-
const total = data["total"] ?? tasks.length;
|
|
13235
|
-
if (tasks.length === 0) {
|
|
13236
|
-
return quiet ? "" : "No tasks found.";
|
|
13237
|
-
}
|
|
13238
|
-
if (quiet) {
|
|
13239
|
-
return tasks.map((t) => `${t.id} ${statusSymbol(t.status)} ${t.title}`).join("\n");
|
|
13240
|
-
}
|
|
13241
|
-
const lines = [];
|
|
13242
|
-
const groups = { critical: [], high: [], medium: [], low: [] };
|
|
13243
|
-
for (const t of tasks) {
|
|
13244
|
-
const key = t.priority ?? "medium";
|
|
13245
|
-
if (!groups[key]) groups[key] = [];
|
|
13246
|
-
groups[key].push(t);
|
|
13247
|
-
}
|
|
13248
|
-
for (const prio of ["critical", "high", "medium", "low"]) {
|
|
13249
|
-
const group = groups[prio];
|
|
13250
|
-
if (!group || group.length === 0) continue;
|
|
13251
|
-
const pSym = prioritySymbol(prio);
|
|
13252
|
-
const pCol = priorityColor(prio);
|
|
13253
|
-
lines.push("");
|
|
13254
|
-
lines.push(`${pCol}${pSym} ${prio.toUpperCase()} (${group.length})${NC}`);
|
|
13255
|
-
for (const t of group) {
|
|
13256
|
-
const sCol = statusColor(t.status);
|
|
13257
|
-
const sSym = statusSymbol(t.status);
|
|
13258
|
-
lines.push(` ${BOLD}${t.id}${NC} ${sCol}${sSym} ${t.status}${NC}`);
|
|
13259
|
-
lines.push(` ${BOLD}${t.title}${NC}`);
|
|
13260
|
-
if (t.labels?.length) {
|
|
13261
|
-
lines.push(` ${DIM}# ${t.labels.join(", ")}${NC}`);
|
|
13262
|
-
}
|
|
13263
|
-
}
|
|
13264
|
-
}
|
|
13265
|
-
lines.push("");
|
|
13266
|
-
lines.push(`${DIM}${hRule(40)}${NC}`);
|
|
13267
|
-
lines.push(`Total: ${total} tasks`);
|
|
13268
|
-
return lines.join("\n");
|
|
13269
|
-
}
|
|
13270
|
-
function renderFind(data, quiet) {
|
|
13271
|
-
const results = data["results"] ?? [];
|
|
13272
|
-
const total = data["total"] ?? results.length;
|
|
13273
|
-
if (results.length === 0) {
|
|
13274
|
-
return quiet ? "" : "No matching tasks found.";
|
|
13275
|
-
}
|
|
13276
|
-
if (quiet) {
|
|
13277
|
-
return results.map((t) => `${t.id} ${t.title}`).join("\n");
|
|
13278
|
-
}
|
|
13279
|
-
const lines = [];
|
|
13280
|
-
lines.push(`${BOLD}Found ${total} result${total !== 1 ? "s" : ""}${NC}`);
|
|
13281
|
-
lines.push("");
|
|
13282
|
-
for (const t of results) {
|
|
13283
|
-
const sCol = statusColor(t.status);
|
|
13284
|
-
const sSym = statusSymbol(t.status);
|
|
13285
|
-
const pCol = priorityColor(t.priority);
|
|
13286
|
-
lines.push(` ${BOLD}${t.id}${NC} ${sCol}${sSym}${NC} ${pCol}[${t.priority}]${NC} ${t.title}`);
|
|
13287
|
-
if (t.description) {
|
|
13288
|
-
const short = t.description.length > 60 ? t.description.slice(0, 57) + "..." : t.description;
|
|
13289
|
-
lines.push(` ${DIM}${short}${NC}`);
|
|
13290
|
-
}
|
|
13291
|
-
}
|
|
13292
|
-
return lines.join("\n");
|
|
13293
|
-
}
|
|
13294
|
-
function renderAdd(data, quiet) {
|
|
13295
|
-
const task = data["task"];
|
|
13296
|
-
const duplicate = data["duplicate"];
|
|
13297
|
-
const dryRun = data["dryRun"];
|
|
13298
|
-
if (!task) return "No task created.";
|
|
13299
|
-
if (quiet) return task.id;
|
|
13300
|
-
const prefix = dryRun ? `${YELLOW}[DRY RUN]${NC} Would create:` : duplicate ? `${YELLOW}[DUPLICATE]${NC} Created:` : `${GREEN}Created:${NC}`;
|
|
13301
|
-
return `${prefix} ${BOLD}${task.id}${NC} ${task.title} [${task.priority}]`;
|
|
13302
|
-
}
|
|
13303
|
-
function renderUpdate(data, quiet) {
|
|
13304
|
-
const task = data["task"];
|
|
13305
|
-
const changes = data["changes"];
|
|
13306
|
-
if (!task) return "No task updated.";
|
|
13307
|
-
if (quiet) return task.id;
|
|
13308
|
-
const lines = [];
|
|
13309
|
-
lines.push(`${GREEN}Updated:${NC} ${BOLD}${task.id}${NC} ${task.title}`);
|
|
13310
|
-
if (Array.isArray(changes) && changes.length > 0) {
|
|
13311
|
-
lines.push(` ${DIM}Changed:${NC} ${changes.join(", ")}`);
|
|
13312
|
-
} else if (changes && typeof changes === "object" && Object.keys(changes).length > 0) {
|
|
13313
|
-
for (const [key, val] of Object.entries(changes)) {
|
|
13314
|
-
lines.push(` ${DIM}${key}:${NC} ${String(val)}`);
|
|
13315
|
-
}
|
|
13316
|
-
}
|
|
13317
|
-
return lines.join("\n");
|
|
13318
|
-
}
|
|
13319
|
-
function renderComplete(data, quiet) {
|
|
13320
|
-
const task = data["task"];
|
|
13321
|
-
const autoCompleted = data["autoCompleted"];
|
|
13322
|
-
if (!task) return "No task completed.";
|
|
13323
|
-
if (quiet) return task.id;
|
|
13324
|
-
const lines = [];
|
|
13325
|
-
lines.push(`${GREEN}\u2713 Completed:${NC} ${BOLD}${task.id}${NC} ${task.title}`);
|
|
13326
|
-
if (autoCompleted?.length) {
|
|
13327
|
-
lines.push(
|
|
13328
|
-
` ${DIM}Auto-completed ${autoCompleted.length} child task${autoCompleted.length > 1 ? "s" : ""}:${NC}`
|
|
13329
|
-
);
|
|
13330
|
-
for (const child of autoCompleted) {
|
|
13331
|
-
lines.push(` ${child.id} ${child.title}`);
|
|
13332
|
-
}
|
|
13333
|
-
}
|
|
13334
|
-
return lines.join("\n");
|
|
13335
|
-
}
|
|
13336
|
-
function renderDelete(data, quiet) {
|
|
13337
|
-
const deletedTask = data["deletedTask"];
|
|
13338
|
-
const cascadeDeleted = data["cascadeDeleted"];
|
|
13339
|
-
if (!deletedTask) return "No task deleted.";
|
|
13340
|
-
if (quiet) return deletedTask.id;
|
|
13341
|
-
const lines = [];
|
|
13342
|
-
lines.push(`${RED}\u2717 Deleted:${NC} ${BOLD}${deletedTask.id}${NC} ${deletedTask.title}`);
|
|
13343
|
-
if (cascadeDeleted?.length) {
|
|
13344
|
-
lines.push(
|
|
13345
|
-
` ${DIM}Cascade-deleted ${cascadeDeleted.length} child task${cascadeDeleted.length > 1 ? "s" : ""}:${NC}`
|
|
13346
|
-
);
|
|
13347
|
-
for (const child of cascadeDeleted) {
|
|
13348
|
-
lines.push(` ${child.id} ${child.title}`);
|
|
13349
|
-
}
|
|
13350
|
-
}
|
|
13351
|
-
return lines.join("\n");
|
|
13352
|
-
}
|
|
13353
|
-
function renderArchive(data, quiet) {
|
|
13354
|
-
const count = data["archivedCount"];
|
|
13355
|
-
const dryRun = data["dryRun"];
|
|
13356
|
-
const tasks = data["archivedTasks"];
|
|
13357
|
-
if (quiet) return String(count ?? 0);
|
|
13358
|
-
if (dryRun) {
|
|
13359
|
-
return `${YELLOW}[DRY RUN]${NC} Would archive ${count ?? 0} task${count !== 1 ? "s" : ""}`;
|
|
13360
|
-
}
|
|
13361
|
-
const lines = [];
|
|
13362
|
-
lines.push(`${GREEN}Archived ${count ?? 0} task${count !== 1 ? "s" : ""}${NC}`);
|
|
13363
|
-
if (tasks?.length) {
|
|
13364
|
-
for (const t of tasks.slice(0, 10)) {
|
|
13365
|
-
lines.push(` ${t.id} ${t.title}`);
|
|
13366
|
-
}
|
|
13367
|
-
if (tasks.length > 10) {
|
|
13368
|
-
lines.push(` ${DIM}... and ${tasks.length - 10} more${NC}`);
|
|
13369
|
-
}
|
|
13370
|
-
}
|
|
13371
|
-
return lines.join("\n");
|
|
13372
|
-
}
|
|
13373
|
-
function renderRestore(data, quiet) {
|
|
13374
|
-
const task = data["task"];
|
|
13375
|
-
const restoredTask = data["restoredTask"];
|
|
13376
|
-
const t = task ?? restoredTask;
|
|
13377
|
-
if (!t) return "No task restored.";
|
|
13378
|
-
if (quiet) return t.id;
|
|
13379
|
-
return `${GREEN}Restored:${NC} ${BOLD}${t.id}${NC} ${t.title}`;
|
|
13380
|
-
}
|
|
13381
|
-
var init_tasks2 = __esm({
|
|
13382
|
-
"packages/cleo/src/cli/renderers/tasks.ts"() {
|
|
13383
|
-
"use strict";
|
|
13384
|
-
init_colors();
|
|
13385
|
-
}
|
|
13386
|
-
});
|
|
13387
|
-
|
|
13388
11529
|
// packages/cleo/src/cli/renderers/index.ts
|
|
13389
11530
|
var renderers_exports = {};
|
|
13390
11531
|
__export(renderers_exports, {
|
|
@@ -13402,9 +11543,76 @@ import {
|
|
|
13402
11543
|
drainWarnings,
|
|
13403
11544
|
formatSuccess,
|
|
13404
11545
|
metaFooter,
|
|
13405
|
-
pagerFooter
|
|
11546
|
+
pagerFooter,
|
|
11547
|
+
renderAuditReconstruct,
|
|
11548
|
+
renderBlockers,
|
|
11549
|
+
renderBrainBackfill,
|
|
11550
|
+
renderBrainExport,
|
|
11551
|
+
renderBrainMaintenance,
|
|
11552
|
+
renderBrainPlasticityStats,
|
|
11553
|
+
renderBrainPurge,
|
|
11554
|
+
renderBrainQuality,
|
|
11555
|
+
renderBriefing,
|
|
11556
|
+
renderCurrent,
|
|
11557
|
+
renderDoctor,
|
|
11558
|
+
renderGeneric,
|
|
11559
|
+
renderNext,
|
|
11560
|
+
renderNexusAnalyze,
|
|
11561
|
+
renderNexusBrainAnchors,
|
|
11562
|
+
renderNexusClusters,
|
|
11563
|
+
renderNexusColdSymbols,
|
|
11564
|
+
renderNexusConduitScan,
|
|
11565
|
+
renderNexusContext as renderNexusContextResult,
|
|
11566
|
+
renderNexusContractsLinkTasks,
|
|
11567
|
+
renderNexusContractsShow,
|
|
11568
|
+
renderNexusContractsSync,
|
|
11569
|
+
renderNexusDiff,
|
|
11570
|
+
renderNexusExport,
|
|
11571
|
+
renderNexusFlows,
|
|
11572
|
+
renderNexusFullContext,
|
|
11573
|
+
renderNexusHotNodes,
|
|
11574
|
+
renderNexusHotPaths,
|
|
11575
|
+
renderNexusImpact,
|
|
11576
|
+
renderNexusImpactFull,
|
|
11577
|
+
renderNexusProjectsClean,
|
|
11578
|
+
renderNexusProjectsCleanPreview,
|
|
11579
|
+
renderNexusProjectsList,
|
|
11580
|
+
renderNexusProjectsRegister,
|
|
11581
|
+
renderNexusProjectsRemove,
|
|
11582
|
+
renderNexusProjectsScan,
|
|
11583
|
+
renderNexusQuery,
|
|
11584
|
+
renderNexusRefreshBridge,
|
|
11585
|
+
renderNexusRouteMap,
|
|
11586
|
+
renderNexusSearchCode,
|
|
11587
|
+
renderNexusSetup,
|
|
11588
|
+
renderNexusShapeCheck,
|
|
11589
|
+
renderNexusStatus,
|
|
11590
|
+
renderNexusTaskFootprint,
|
|
11591
|
+
renderNexusTaskSymbols,
|
|
11592
|
+
renderNexusWhy,
|
|
11593
|
+
renderNexusWiki,
|
|
11594
|
+
renderPlan,
|
|
11595
|
+
renderSchemaCommand,
|
|
11596
|
+
renderSession,
|
|
11597
|
+
renderStart,
|
|
11598
|
+
renderStats,
|
|
11599
|
+
renderStop,
|
|
11600
|
+
renderTree as renderTree2,
|
|
11601
|
+
renderVersion,
|
|
11602
|
+
renderWaves
|
|
13406
11603
|
} from "@cleocode/core";
|
|
13407
11604
|
import { applyFieldFilter, extractFieldFromResult } from "@cleocode/lafs";
|
|
11605
|
+
import {
|
|
11606
|
+
renderAdd,
|
|
11607
|
+
renderArchive,
|
|
11608
|
+
renderComplete,
|
|
11609
|
+
renderDelete,
|
|
11610
|
+
renderFind,
|
|
11611
|
+
renderList,
|
|
11612
|
+
renderRestore,
|
|
11613
|
+
renderShow,
|
|
11614
|
+
renderUpdate
|
|
11615
|
+
} from "@cleocode/core";
|
|
13408
11616
|
function generateRequestId() {
|
|
13409
11617
|
return randomUUID();
|
|
13410
11618
|
}
|
|
@@ -13611,9 +11819,6 @@ var init_renderers = __esm({
|
|
|
13611
11819
|
init_format_context();
|
|
13612
11820
|
init_lafs_validator();
|
|
13613
11821
|
init_normalizer();
|
|
13614
|
-
init_system2();
|
|
13615
|
-
init_nexus2();
|
|
13616
|
-
init_tasks2();
|
|
13617
11822
|
renderers = {
|
|
13618
11823
|
// Task CRUD
|
|
13619
11824
|
show: renderShow,
|
|
@@ -13639,12 +11844,12 @@ var init_renderers = __esm({
|
|
|
13639
11844
|
next: renderNext,
|
|
13640
11845
|
plan: renderPlan,
|
|
13641
11846
|
blockers: renderBlockers,
|
|
13642
|
-
tree:
|
|
13643
|
-
depends:
|
|
13644
|
-
deps:
|
|
11847
|
+
tree: renderTree2,
|
|
11848
|
+
depends: renderTree2,
|
|
11849
|
+
deps: renderTree2,
|
|
13645
11850
|
// Orchestration — `cleo orchestrate waves` emits { waves, epicId, ... }
|
|
13646
11851
|
// which renderTree handles via its data.waves branch (T1194/T1195).
|
|
13647
|
-
orchestrate:
|
|
11852
|
+
orchestrate: renderTree2,
|
|
13648
11853
|
session: renderSession,
|
|
13649
11854
|
version: renderVersion,
|
|
13650
11855
|
// T1593 — `cleo briefing` reads tasks.db + brain.db (NEVER markdown handoffs).
|
|
@@ -13665,7 +11870,7 @@ var init_renderers = __esm({
|
|
|
13665
11870
|
"nexus-setup": renderNexusSetup,
|
|
13666
11871
|
"nexus-clusters": renderNexusClusters,
|
|
13667
11872
|
"nexus-flows": renderNexusFlows,
|
|
13668
|
-
"nexus-context":
|
|
11873
|
+
"nexus-context": renderNexusContextResult,
|
|
13669
11874
|
"nexus-impact": renderNexusImpact,
|
|
13670
11875
|
"nexus-analyze": renderNexusAnalyze,
|
|
13671
11876
|
"nexus-projects-list": renderNexusProjectsList,
|
|
@@ -21508,7 +19713,7 @@ async function handleImpact(operation, params, startTime) {
|
|
|
21508
19713
|
}
|
|
21509
19714
|
}
|
|
21510
19715
|
var _nexusTypedHandler, QUERY_OPS6, MUTATE_OPS5, NexusHandler, IMPACT_REVERSE_TYPES;
|
|
21511
|
-
var
|
|
19716
|
+
var init_nexus2 = __esm({
|
|
21512
19717
|
"packages/cleo/src/dispatch/domains/nexus.ts"() {
|
|
21513
19718
|
"use strict";
|
|
21514
19719
|
init_typed();
|
|
@@ -24308,11 +22513,11 @@ function indentString(string, spaces) {
|
|
|
24308
22513
|
function generateNextLine(state, level) {
|
|
24309
22514
|
return "\n" + common.repeat(" ", state.indent * level);
|
|
24310
22515
|
}
|
|
24311
|
-
function testImplicitResolving(state,
|
|
22516
|
+
function testImplicitResolving(state, str2) {
|
|
24312
22517
|
var index, length, type2;
|
|
24313
22518
|
for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
|
|
24314
22519
|
type2 = state.implicitTypes[index];
|
|
24315
|
-
if (type2.resolve(
|
|
22520
|
+
if (type2.resolve(str2)) {
|
|
24316
22521
|
return true;
|
|
24317
22522
|
}
|
|
24318
22523
|
}
|
|
@@ -24785,7 +22990,7 @@ function renamed(from, to) {
|
|
|
24785
22990
|
throw new Error("Function yaml." + from + " is removed in js-yaml 4. Use yaml." + to + " instead, which is now safe by default.");
|
|
24786
22991
|
};
|
|
24787
22992
|
}
|
|
24788
|
-
var isNothing_1, isObject_1, toArray_1, repeat_1, isNegativeZero_1, extend_1, common, exception, snippet, TYPE_CONSTRUCTOR_OPTIONS, YAML_NODE_KINDS, type, schema,
|
|
22993
|
+
var isNothing_1, isObject_1, toArray_1, repeat_1, isNegativeZero_1, extend_1, common, exception, snippet, TYPE_CONSTRUCTOR_OPTIONS, YAML_NODE_KINDS, type, schema, str, seq, map, failsafe, _null, bool, int, YAML_FLOAT_PATTERN, SCIENTIFIC_WITHOUT_DOT, float, json, core, YAML_DATE_REGEXP, YAML_TIMESTAMP_REGEXP, timestamp, merge, BASE64_MAP, binary, _hasOwnProperty$3, _toString$2, omap, _toString$1, pairs, _hasOwnProperty$2, set, _default, _hasOwnProperty$1, CONTEXT_FLOW_IN, CONTEXT_FLOW_OUT, CONTEXT_BLOCK_IN, CONTEXT_BLOCK_OUT, CHOMPING_CLIP, CHOMPING_STRIP, CHOMPING_KEEP, PATTERN_NON_PRINTABLE, PATTERN_NON_ASCII_LINE_BREAKS, PATTERN_FLOW_INDICATORS, PATTERN_TAG_HANDLE, PATTERN_TAG_URI, simpleEscapeCheck, simpleEscapeMap, i, directiveHandlers, loadAll_1, load_1, loader, _toString, _hasOwnProperty, CHAR_BOM, CHAR_TAB, CHAR_LINE_FEED, CHAR_CARRIAGE_RETURN, CHAR_SPACE, CHAR_EXCLAMATION, CHAR_DOUBLE_QUOTE, CHAR_SHARP, CHAR_PERCENT, CHAR_AMPERSAND, CHAR_SINGLE_QUOTE, CHAR_ASTERISK, CHAR_COMMA, CHAR_MINUS, CHAR_COLON, CHAR_EQUALS, CHAR_GREATER_THAN, CHAR_QUESTION, CHAR_COMMERCIAL_AT, CHAR_LEFT_SQUARE_BRACKET, CHAR_RIGHT_SQUARE_BRACKET, CHAR_GRAVE_ACCENT, CHAR_LEFT_CURLY_BRACKET, CHAR_VERTICAL_LINE, CHAR_RIGHT_CURLY_BRACKET, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DEPRECATED_BASE60_SYNTAX, QUOTING_TYPE_SINGLE, QUOTING_TYPE_DOUBLE, STYLE_PLAIN, STYLE_SINGLE, STYLE_LITERAL, STYLE_FOLDED, STYLE_DOUBLE, dump_1, dumper, load, loadAll, dump, safeLoad, safeLoadAll, safeDump;
|
|
24789
22994
|
var init_js_yaml = __esm({
|
|
24790
22995
|
"node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs"() {
|
|
24791
22996
|
isNothing_1 = isNothing;
|
|
@@ -24865,7 +23070,7 @@ var init_js_yaml = __esm({
|
|
|
24865
23070
|
return result;
|
|
24866
23071
|
};
|
|
24867
23072
|
schema = Schema$1;
|
|
24868
|
-
|
|
23073
|
+
str = new type("tag:yaml.org,2002:str", {
|
|
24869
23074
|
kind: "scalar",
|
|
24870
23075
|
construct: function(data) {
|
|
24871
23076
|
return data !== null ? data : "";
|
|
@@ -24885,7 +23090,7 @@ var init_js_yaml = __esm({
|
|
|
24885
23090
|
});
|
|
24886
23091
|
failsafe = new schema({
|
|
24887
23092
|
explicit: [
|
|
24888
|
-
|
|
23093
|
+
str,
|
|
24889
23094
|
seq,
|
|
24890
23095
|
map
|
|
24891
23096
|
]
|
|
@@ -27715,11 +25920,11 @@ async function orchestrateAnalyzeParallelSafety(taskIds, projectRoot) {
|
|
|
27715
25920
|
};
|
|
27716
25921
|
}
|
|
27717
25922
|
}
|
|
27718
|
-
async function handleWorktreeComplete(taskId, projectRoot,
|
|
25923
|
+
async function handleWorktreeComplete(taskId, projectRoot, resolve7) {
|
|
27719
25924
|
try {
|
|
27720
25925
|
const { completeWorktreeForTask } = await import("@cleocode/core/internal");
|
|
27721
25926
|
const result = completeWorktreeForTask(taskId, projectRoot, {
|
|
27722
|
-
resolve:
|
|
25927
|
+
resolve: resolve7 ?? "auto"
|
|
27723
25928
|
});
|
|
27724
25929
|
if (result.outcome === "conflict") {
|
|
27725
25930
|
return {
|
|
@@ -28396,10 +26601,10 @@ var init_orchestrate2 = __esm({
|
|
|
28396
26601
|
startTime
|
|
28397
26602
|
);
|
|
28398
26603
|
const rawResolve = params.resolve;
|
|
28399
|
-
const
|
|
26604
|
+
const resolve7 = rawResolve === "manual" ? "manual" : rawResolve === "auto" ? "auto" : void 0;
|
|
28400
26605
|
const p = {
|
|
28401
26606
|
taskId: params.taskId,
|
|
28402
|
-
...
|
|
26607
|
+
...resolve7 !== void 0 ? { resolve: resolve7 } : {}
|
|
28403
26608
|
};
|
|
28404
26609
|
return wrapResult(
|
|
28405
26610
|
await coreOps2["worktree.complete"](p),
|
|
@@ -30768,7 +28973,7 @@ async function sagaReconcile(params) {
|
|
|
30768
28973
|
);
|
|
30769
28974
|
}
|
|
30770
28975
|
var _tasksTypedHandler, QUERY_OPS11, MUTATE_OPS10, TasksHandler;
|
|
30771
|
-
var
|
|
28976
|
+
var init_tasks2 = __esm({
|
|
30772
28977
|
"packages/cleo/src/dispatch/domains/tasks.ts"() {
|
|
30773
28978
|
"use strict";
|
|
30774
28979
|
init_typed();
|
|
@@ -32073,13 +30278,10 @@ var init_tools = __esm({
|
|
|
32073
30278
|
});
|
|
32074
30279
|
|
|
32075
30280
|
// packages/cleo/src/dispatch/domains/upgrade.ts
|
|
32076
|
-
import {
|
|
32077
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
32078
|
-
import { getLogger as getLogger17, getProjectRoot as getProjectRoot20 } from "@cleocode/core";
|
|
30281
|
+
import { getLogger as getLogger17, getProjectRoot as getProjectRoot20, getWorkflowTemplatesDir } from "@cleocode/core";
|
|
32079
30282
|
import { upgradeWorkflows } from "@cleocode/core/internal";
|
|
32080
30283
|
function resolveTemplatesDir() {
|
|
32081
|
-
|
|
32082
|
-
return resolve3(here, "..", "..", "..", "templates", "workflows");
|
|
30284
|
+
return getWorkflowTemplatesDir();
|
|
32083
30285
|
}
|
|
32084
30286
|
function toDispatchData(result) {
|
|
32085
30287
|
return {
|
|
@@ -32472,7 +30674,7 @@ var init_domains = __esm({
|
|
|
32472
30674
|
init_intelligence2();
|
|
32473
30675
|
init_llm2();
|
|
32474
30676
|
init_memory2();
|
|
32475
|
-
|
|
30677
|
+
init_nexus2();
|
|
32476
30678
|
init_orchestrate2();
|
|
32477
30679
|
init_pipeline3();
|
|
32478
30680
|
init_playbook2();
|
|
@@ -32481,7 +30683,7 @@ var init_domains = __esm({
|
|
|
32481
30683
|
init_sentient2();
|
|
32482
30684
|
init_session3();
|
|
32483
30685
|
init_sticky2();
|
|
32484
|
-
|
|
30686
|
+
init_tasks2();
|
|
32485
30687
|
init_tools();
|
|
32486
30688
|
init_upgrade();
|
|
32487
30689
|
init_worktree2();
|
|
@@ -32563,11 +30765,11 @@ function parseEnvValue(key, value) {
|
|
|
32563
30765
|
return value.toLowerCase() === "true" || value === "1";
|
|
32564
30766
|
}
|
|
32565
30767
|
if (schema2.type === "number") {
|
|
32566
|
-
const
|
|
32567
|
-
if (Number.isNaN(
|
|
30768
|
+
const num = parseInt(value, 10);
|
|
30769
|
+
if (Number.isNaN(num)) {
|
|
32568
30770
|
throw new ConfigValidationError(key, value, "must be a number");
|
|
32569
30771
|
}
|
|
32570
|
-
return
|
|
30772
|
+
return num;
|
|
32571
30773
|
}
|
|
32572
30774
|
return value;
|
|
32573
30775
|
}
|
|
@@ -33047,8 +31249,8 @@ __export(cli_exports, {
|
|
|
33047
31249
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
33048
31250
|
import { existsSync as existsSync5 } from "node:fs";
|
|
33049
31251
|
import { createRequire } from "node:module";
|
|
33050
|
-
import { dirname as
|
|
33051
|
-
import { fileURLToPath as
|
|
31252
|
+
import { dirname as dirname3, join as join8 } from "node:path";
|
|
31253
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
33052
31254
|
import { catalog, registerSkillLibraryFromPath } from "@cleocode/caamp";
|
|
33053
31255
|
import { autoRecordDispatchTokenUsage, getProjectRoot as getProjectRoot22, hooks } from "@cleocode/core/internal";
|
|
33054
31256
|
function ensureCaampLibrary() {
|
|
@@ -33058,15 +31260,15 @@ function ensureCaampLibrary() {
|
|
|
33058
31260
|
try {
|
|
33059
31261
|
const req = createRequire(import.meta.url);
|
|
33060
31262
|
const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
|
|
33061
|
-
const candidate =
|
|
31263
|
+
const candidate = dirname3(skillsPkgJson);
|
|
33062
31264
|
if (existsSync5(join8(candidate, "skills.json"))) {
|
|
33063
31265
|
skillsRoot = candidate;
|
|
33064
31266
|
}
|
|
33065
31267
|
} catch {
|
|
33066
31268
|
}
|
|
33067
31269
|
if (!skillsRoot) {
|
|
33068
|
-
const thisFile =
|
|
33069
|
-
const packageRoot = join8(
|
|
31270
|
+
const thisFile = fileURLToPath2(import.meta.url);
|
|
31271
|
+
const packageRoot = join8(dirname3(thisFile), "..", "..", "..", "..", "..");
|
|
33070
31272
|
const candidate = join8(packageRoot, "packages", "skills");
|
|
33071
31273
|
if (existsSync5(join8(candidate, "skills.json"))) {
|
|
33072
31274
|
skillsRoot = candidate;
|
|
@@ -36062,8 +34264,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
|
|
|
36062
34264
|
let tempDir = null;
|
|
36063
34265
|
try {
|
|
36064
34266
|
const { existsSync: existsSync17 } = await import("node:fs");
|
|
36065
|
-
const { basename, resolve:
|
|
36066
|
-
const resolvedPath =
|
|
34267
|
+
const { basename, resolve: resolve7 } = await import("node:path");
|
|
34268
|
+
const resolvedPath = resolve7(args.path);
|
|
36067
34269
|
if (!existsSync17(resolvedPath)) {
|
|
36068
34270
|
cliOutput(
|
|
36069
34271
|
{
|
|
@@ -36190,9 +34392,9 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
|
|
|
36190
34392
|
async run({ args }) {
|
|
36191
34393
|
try {
|
|
36192
34394
|
const { existsSync: existsSync17, statSync } = await import("node:fs");
|
|
36193
|
-
const { resolve:
|
|
34395
|
+
const { resolve: resolve7, basename, dirname: dirname10 } = await import("node:path");
|
|
36194
34396
|
const { execFileSync: execFileSync4 } = await import("node:child_process");
|
|
36195
|
-
const resolvedDir =
|
|
34397
|
+
const resolvedDir = resolve7(args.dir);
|
|
36196
34398
|
if (!existsSync17(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
|
|
36197
34399
|
cliOutput(
|
|
36198
34400
|
{
|
|
@@ -36225,8 +34427,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
|
|
|
36225
34427
|
}
|
|
36226
34428
|
const agentName = basename(resolvedDir);
|
|
36227
34429
|
const archiveName = `${agentName}.cantz`;
|
|
36228
|
-
const archivePath =
|
|
36229
|
-
const parentDir =
|
|
34430
|
+
const archivePath = resolve7(archiveName);
|
|
34431
|
+
const parentDir = dirname10(resolvedDir);
|
|
36230
34432
|
try {
|
|
36231
34433
|
execFileSync4("zip", ["-r", archivePath, agentName], {
|
|
36232
34434
|
cwd: parentDir,
|
|
@@ -36505,8 +34707,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
|
|
|
36505
34707
|
async run({ args }) {
|
|
36506
34708
|
try {
|
|
36507
34709
|
const { existsSync: existsSync17, readFileSync: readFileSync18, mkdirSync: mkdirSync5 } = await import("node:fs");
|
|
36508
|
-
const { resolve:
|
|
36509
|
-
const specPath =
|
|
34710
|
+
const { resolve: resolve7, join: join34 } = await import("node:path");
|
|
34711
|
+
const specPath = resolve7(args.spec);
|
|
36510
34712
|
if (!existsSync17(specPath)) {
|
|
36511
34713
|
cliError(`spec file not found: ${specPath}`, 4, { name: "E_NOT_FOUND" });
|
|
36512
34714
|
process.exitCode = 4;
|
|
@@ -36514,7 +34716,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
|
|
|
36514
34716
|
}
|
|
36515
34717
|
const specContent = readFileSync18(specPath, "utf-8");
|
|
36516
34718
|
const projectRoot = getProjectRoot24();
|
|
36517
|
-
const outputDir = args["output-dir"] ?
|
|
34719
|
+
const outputDir = args["output-dir"] ? resolve7(args["output-dir"]) : join34(projectRoot, ".cleo", "cant", "agents");
|
|
36518
34720
|
mkdirSync5(outputDir, { recursive: true });
|
|
36519
34721
|
if (args["dry-run"]) {
|
|
36520
34722
|
cliOutput(
|
|
@@ -37265,8 +35467,8 @@ function detectAuthType(provider, token) {
|
|
|
37265
35467
|
async function promptYesNo(question) {
|
|
37266
35468
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
37267
35469
|
try {
|
|
37268
|
-
const answer = await new Promise((
|
|
37269
|
-
rl.question(question, (a) =>
|
|
35470
|
+
const answer = await new Promise((resolve7) => {
|
|
35471
|
+
rl.question(question, (a) => resolve7(a));
|
|
37270
35472
|
});
|
|
37271
35473
|
const clean = answer.trim().toLowerCase();
|
|
37272
35474
|
return clean === "y" || clean === "yes";
|
|
@@ -37926,12 +36128,12 @@ async function promptPassphrase() {
|
|
|
37926
36128
|
"Cannot prompt for passphrase: stdin is not a TTY. Set the CLEO_BACKUP_PASSPHRASE environment variable for non-interactive use."
|
|
37927
36129
|
);
|
|
37928
36130
|
}
|
|
37929
|
-
return new Promise((
|
|
36131
|
+
return new Promise((resolve7) => {
|
|
37930
36132
|
process.stdout.write("Passphrase: ");
|
|
37931
36133
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
37932
36134
|
rl.question("", (answer) => {
|
|
37933
36135
|
rl.close();
|
|
37934
|
-
|
|
36136
|
+
resolve7(answer.trim());
|
|
37935
36137
|
});
|
|
37936
36138
|
});
|
|
37937
36139
|
}
|
|
@@ -39140,9 +37342,9 @@ __export(cant_exports, {
|
|
|
39140
37342
|
cantCommand: () => cantCommand
|
|
39141
37343
|
});
|
|
39142
37344
|
import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
|
|
39143
|
-
import { dirname as
|
|
37345
|
+
import { dirname as dirname4, isAbsolute, join as join13, resolve as resolve3 } from "node:path";
|
|
39144
37346
|
function resolveFilePath(file) {
|
|
39145
|
-
return isAbsolute(file) ? file :
|
|
37347
|
+
return isAbsolute(file) ? file : resolve3(process.cwd(), file);
|
|
39146
37348
|
}
|
|
39147
37349
|
function ensureExists(filePath, operation) {
|
|
39148
37350
|
if (existsSync10(filePath)) return true;
|
|
@@ -39306,7 +37508,7 @@ var init_cant = __esm({
|
|
|
39306
37508
|
let written = 0;
|
|
39307
37509
|
for (const outputFile of result.outputFiles) {
|
|
39308
37510
|
const outputPath = isAbsolute(outputFile.path) ? outputFile.path : join13(projectRoot, outputFile.path);
|
|
39309
|
-
mkdirSync2(
|
|
37511
|
+
mkdirSync2(dirname4(outputPath), { recursive: true });
|
|
39310
37512
|
writeFileSync3(outputPath, outputFile.content, "utf-8");
|
|
39311
37513
|
written++;
|
|
39312
37514
|
}
|
|
@@ -40073,10 +38275,10 @@ var init_check2 = __esm({
|
|
|
40073
38275
|
async run({ args }) {
|
|
40074
38276
|
const { spawnSync } = await import("node:child_process");
|
|
40075
38277
|
const { existsSync: existsSync17 } = await import("node:fs");
|
|
40076
|
-
const { join: join34, resolve:
|
|
38278
|
+
const { join: join34, resolve: resolve7 } = await import("node:path");
|
|
40077
38279
|
const strict = Boolean(args.strict);
|
|
40078
38280
|
const jsonOnly = Boolean(args.json);
|
|
40079
|
-
const repoRoot =
|
|
38281
|
+
const repoRoot = resolve7(process.cwd());
|
|
40080
38282
|
const gates = [
|
|
40081
38283
|
{
|
|
40082
38284
|
id: "gate-1",
|
|
@@ -41794,7 +39996,7 @@ __export(daemon_exports, {
|
|
|
41794
39996
|
});
|
|
41795
39997
|
import { existsSync as existsSync12 } from "node:fs";
|
|
41796
39998
|
import { join as join16 } from "node:path";
|
|
41797
|
-
import { fileURLToPath as
|
|
39999
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
41798
40000
|
import { getGCDaemonStatus, spawnGCDaemon, stopGCDaemon } from "@cleocode/core/gc/daemon.js";
|
|
41799
40001
|
import {
|
|
41800
40002
|
bootstrapDaemon as bootstrapSentientDaemon,
|
|
@@ -41858,7 +40060,7 @@ async function showDaemonStatus(cleoDir, projectRoot) {
|
|
|
41858
40060
|
}
|
|
41859
40061
|
}
|
|
41860
40062
|
function resolveDaemonInstallerScript() {
|
|
41861
|
-
const filePath =
|
|
40063
|
+
const filePath = fileURLToPath3(import.meta.url);
|
|
41862
40064
|
const candidate1 = join16(filePath, "..", "..", "..", "scripts", "install-daemon-service.mjs");
|
|
41863
40065
|
if (existsSync12(candidate1)) return candidate1;
|
|
41864
40066
|
const candidate2 = join16(
|
|
@@ -42313,13 +40515,131 @@ var init_delete = __esm({
|
|
|
42313
40515
|
}
|
|
42314
40516
|
});
|
|
42315
40517
|
|
|
40518
|
+
// packages/cleo/src/cli/renderers/colors.ts
|
|
40519
|
+
import {
|
|
40520
|
+
BLUE,
|
|
40521
|
+
BOLD,
|
|
40522
|
+
BOX,
|
|
40523
|
+
CYAN,
|
|
40524
|
+
DIM,
|
|
40525
|
+
GREEN,
|
|
40526
|
+
hRule,
|
|
40527
|
+
MAGENTA,
|
|
40528
|
+
NC,
|
|
40529
|
+
priorityColor,
|
|
40530
|
+
prioritySymbol,
|
|
40531
|
+
RED,
|
|
40532
|
+
shortDate,
|
|
40533
|
+
statusColor,
|
|
40534
|
+
statusSymbol,
|
|
40535
|
+
YELLOW
|
|
40536
|
+
} from "@cleocode/core";
|
|
40537
|
+
var init_colors = __esm({
|
|
40538
|
+
"packages/cleo/src/cli/renderers/colors.ts"() {
|
|
40539
|
+
"use strict";
|
|
40540
|
+
}
|
|
40541
|
+
});
|
|
40542
|
+
|
|
40543
|
+
// packages/cleo/src/cli/renderers/generic-tree.ts
|
|
40544
|
+
import { ascii as ascii2, KindIcon as KindIcon2, pickIcon, RelationIcon } from "@cleocode/contracts/render/icon.js";
|
|
40545
|
+
function renderGenericTree(result, opts) {
|
|
40546
|
+
const ctx = opts.ctx ?? resolveAnimateContext();
|
|
40547
|
+
if (!ctx.enabled) return "";
|
|
40548
|
+
if (opts.quiet) return renderQuiet(result);
|
|
40549
|
+
const useAscii = ctx.inputs.noColor;
|
|
40550
|
+
const lines = [];
|
|
40551
|
+
if (result.ancestors.length > 0) {
|
|
40552
|
+
lines.push(formatAncestorBanner(result.ancestors, useAscii));
|
|
40553
|
+
lines.push("");
|
|
40554
|
+
}
|
|
40555
|
+
const treeWithGlyphs = decorateGroupsEdges(result.tree, useAscii);
|
|
40556
|
+
const body = renderTree(treeWithGlyphs, { ctx });
|
|
40557
|
+
if (body) lines.push(body);
|
|
40558
|
+
if (opts.withDeps || opts.withBlockers) {
|
|
40559
|
+
const annotations = renderAnnotations(result.tree, opts);
|
|
40560
|
+
if (annotations) lines.push(annotations);
|
|
40561
|
+
}
|
|
40562
|
+
return lines.join("\n");
|
|
40563
|
+
}
|
|
40564
|
+
function decorateGroupsEdges(tree, useAscii) {
|
|
40565
|
+
const glyph = useAscii ? ascii2(RelationIcon.GROUPS) : RelationIcon.GROUPS;
|
|
40566
|
+
const prefix = `${glyph} `;
|
|
40567
|
+
const rows = tree.tree.map(
|
|
40568
|
+
(node) => node.metadata.edgeType === "groups" ? { ...node, title: `${prefix}${node.title}` } : node
|
|
40569
|
+
);
|
|
40570
|
+
return { ...tree, tree: rows };
|
|
40571
|
+
}
|
|
40572
|
+
function formatAncestorBanner(ancestors, useAscii) {
|
|
40573
|
+
const ordered = [...ancestors].reverse();
|
|
40574
|
+
const parts = ordered.map((node) => {
|
|
40575
|
+
const icon = pickIcon(kindIconOf(node.kind), { noColor: useAscii });
|
|
40576
|
+
return `${icon} ${node.id}`;
|
|
40577
|
+
});
|
|
40578
|
+
const arrow = useAscii ? " > " : " \u203A ";
|
|
40579
|
+
const upGlyph = useAscii ? "^" : "\u2191";
|
|
40580
|
+
const tip = arrow.trim();
|
|
40581
|
+
const chain = parts.join(arrow);
|
|
40582
|
+
return `${DIM}${upGlyph} ${chain}${tip}(here)${NC}`;
|
|
40583
|
+
}
|
|
40584
|
+
function renderQuiet(result) {
|
|
40585
|
+
return result.tree.tree.map((node) => node.id).join("\n");
|
|
40586
|
+
}
|
|
40587
|
+
function renderAnnotations(tree, opts) {
|
|
40588
|
+
const lines = [];
|
|
40589
|
+
for (const node of tree.tree) {
|
|
40590
|
+
if (opts.withDeps && node.metadata.depends.length > 0) {
|
|
40591
|
+
lines.push(`${DIM} ${node.id} depends-on: ${node.metadata.depends.join(", ")}${NC}`);
|
|
40592
|
+
}
|
|
40593
|
+
if (opts.withBlockers) {
|
|
40594
|
+
const chain = node.metadata.blockerChain ?? [];
|
|
40595
|
+
if (chain.length > 0) {
|
|
40596
|
+
lines.push(`${DIM} ${node.id} blocker-chain: ${chain.join(" \u2192 ")}${NC}`);
|
|
40597
|
+
}
|
|
40598
|
+
const leaves = node.metadata.leafBlockers ?? [];
|
|
40599
|
+
if (leaves.length > 0) {
|
|
40600
|
+
lines.push(`${DIM} ${node.id} leaf-blockers: ${leaves.join(", ")}${NC}`);
|
|
40601
|
+
}
|
|
40602
|
+
}
|
|
40603
|
+
}
|
|
40604
|
+
return lines.length > 0 ? `
|
|
40605
|
+
${lines.join("\n")}` : "";
|
|
40606
|
+
}
|
|
40607
|
+
function kindIconOf(kind) {
|
|
40608
|
+
switch (kind) {
|
|
40609
|
+
case "saga":
|
|
40610
|
+
return KindIcon2.SAGA;
|
|
40611
|
+
case "epic":
|
|
40612
|
+
return KindIcon2.EPIC;
|
|
40613
|
+
case "task":
|
|
40614
|
+
return KindIcon2.TASK;
|
|
40615
|
+
case "subtask":
|
|
40616
|
+
return KindIcon2.SUBTASK;
|
|
40617
|
+
}
|
|
40618
|
+
}
|
|
40619
|
+
function resolveAnimateContext() {
|
|
40620
|
+
return createAnimateContext({ flagResolution: getFormatContext() });
|
|
40621
|
+
}
|
|
40622
|
+
var init_generic_tree = __esm({
|
|
40623
|
+
"packages/cleo/src/cli/renderers/generic-tree.ts"() {
|
|
40624
|
+
"use strict";
|
|
40625
|
+
init_src();
|
|
40626
|
+
init_render();
|
|
40627
|
+
init_format_context();
|
|
40628
|
+
init_colors();
|
|
40629
|
+
}
|
|
40630
|
+
});
|
|
40631
|
+
|
|
42316
40632
|
// packages/cleo/src/cli/commands/deps.ts
|
|
42317
40633
|
var deps_exports = {};
|
|
42318
40634
|
__export(deps_exports, {
|
|
42319
40635
|
depsCommand: () => depsCommand,
|
|
42320
40636
|
treeCommand: () => treeCommand
|
|
42321
40637
|
});
|
|
42322
|
-
import {
|
|
40638
|
+
import {
|
|
40639
|
+
buildGenericTaskTree,
|
|
40640
|
+
depsCriticalPath,
|
|
40641
|
+
resolveProjectRoot as resolveProjectRoot2
|
|
40642
|
+
} from "@cleocode/core/internal";
|
|
42323
40643
|
var overviewCommand, showCommand4, wavesCommand, criticalPathCommand, impactCommand, cyclesCommand, validateCommand5, depsTreeCommand, depsCommand, treeCommand;
|
|
42324
40644
|
var init_deps = __esm({
|
|
42325
40645
|
"packages/cleo/src/cli/commands/deps.ts"() {
|
|
@@ -42327,8 +40647,9 @@ var init_deps = __esm({
|
|
|
42327
40647
|
init_src2();
|
|
42328
40648
|
init_dist();
|
|
42329
40649
|
init_cli();
|
|
40650
|
+
init_format_context();
|
|
40651
|
+
init_generic_tree();
|
|
42330
40652
|
init_renderers();
|
|
42331
|
-
init_tree_context();
|
|
42332
40653
|
overviewCommand = defineCommand({
|
|
42333
40654
|
meta: { name: "overview", description: "Overview of all dependencies" },
|
|
42334
40655
|
async run() {
|
|
@@ -42535,29 +40856,42 @@ var init_deps = __esm({
|
|
|
42535
40856
|
args: {
|
|
42536
40857
|
rootId: {
|
|
42537
40858
|
type: "positional",
|
|
42538
|
-
description: "Root task ID
|
|
42539
|
-
required:
|
|
40859
|
+
description: "Root task ID \u2014 walks parent + groups edges from here",
|
|
40860
|
+
required: true
|
|
42540
40861
|
},
|
|
42541
40862
|
withDeps: {
|
|
42542
40863
|
type: "boolean",
|
|
42543
|
-
description: "
|
|
40864
|
+
description: "Append direct depends chain below each task that has deps",
|
|
42544
40865
|
default: false
|
|
42545
40866
|
},
|
|
42546
40867
|
blockers: {
|
|
42547
40868
|
type: "boolean",
|
|
42548
|
-
description: "
|
|
40869
|
+
description: "Append transitive blocker chain and leaf blockers below each blocked task",
|
|
42549
40870
|
default: false
|
|
42550
40871
|
}
|
|
42551
40872
|
},
|
|
42552
40873
|
async run({ args }) {
|
|
42553
|
-
|
|
42554
|
-
|
|
42555
|
-
|
|
42556
|
-
|
|
42557
|
-
|
|
42558
|
-
|
|
42559
|
-
|
|
42560
|
-
|
|
40874
|
+
const cwd = resolveProjectRoot2();
|
|
40875
|
+
try {
|
|
40876
|
+
const result = await buildGenericTaskTree(cwd, args.rootId, {
|
|
40877
|
+
withBlockers: args.blockers
|
|
40878
|
+
});
|
|
40879
|
+
if (isJsonFormat()) {
|
|
40880
|
+
cliOutput(result, { command: "tree", operation: "tasks.graphTree" });
|
|
40881
|
+
return;
|
|
40882
|
+
}
|
|
40883
|
+
const text = renderGenericTree(result, {
|
|
40884
|
+
withDeps: args.withDeps,
|
|
40885
|
+
withBlockers: args.blockers,
|
|
40886
|
+
quiet: isQuiet()
|
|
40887
|
+
});
|
|
40888
|
+
if (text) process.stdout.write(`${text}
|
|
40889
|
+
`);
|
|
40890
|
+
} catch (err) {
|
|
40891
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
40892
|
+
cliError(`tree: ${msg}`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
|
|
40893
|
+
process.exit(4 /* NOT_FOUND */);
|
|
40894
|
+
}
|
|
42561
40895
|
}
|
|
42562
40896
|
});
|
|
42563
40897
|
}
|
|
@@ -42569,14 +40903,14 @@ __export(detect_drift_exports, {
|
|
|
42569
40903
|
detectDriftCommand: () => detectDriftCommand
|
|
42570
40904
|
});
|
|
42571
40905
|
import { existsSync as existsSync13, readdirSync, readFileSync as readFileSync13 } from "node:fs";
|
|
42572
|
-
import { dirname as
|
|
40906
|
+
import { dirname as dirname5, join as join17 } from "node:path";
|
|
42573
40907
|
function findProjectRoot() {
|
|
42574
40908
|
let currentDir = process.cwd();
|
|
42575
40909
|
while (currentDir !== "/") {
|
|
42576
40910
|
if (existsSync13(join17(currentDir, "package.json"))) {
|
|
42577
40911
|
return currentDir;
|
|
42578
40912
|
}
|
|
42579
|
-
const parent =
|
|
40913
|
+
const parent = dirname5(currentDir);
|
|
42580
40914
|
if (parent === currentDir) break;
|
|
42581
40915
|
currentDir = parent;
|
|
42582
40916
|
}
|
|
@@ -43090,14 +41424,14 @@ var init_diagnostics2 = __esm({
|
|
|
43090
41424
|
|
|
43091
41425
|
// packages/cleo/src/viewer/pidfile.ts
|
|
43092
41426
|
import { mkdir, readFile as readFile2, unlink, writeFile } from "node:fs/promises";
|
|
43093
|
-
import { dirname as
|
|
41427
|
+
import { dirname as dirname6, join as join18 } from "node:path";
|
|
43094
41428
|
import { getCleoHome as getCleoHome2 } from "@cleocode/core/internal";
|
|
43095
41429
|
function viewerPidFilePath() {
|
|
43096
41430
|
return join18(getCleoHome2(), "viewer.pid");
|
|
43097
41431
|
}
|
|
43098
41432
|
async function writeViewerPidFile(record) {
|
|
43099
41433
|
const path6 = viewerPidFilePath();
|
|
43100
|
-
await mkdir(
|
|
41434
|
+
await mkdir(dirname6(path6), { recursive: true });
|
|
43101
41435
|
await writeFile(path6, JSON.stringify(record, null, 2), "utf8");
|
|
43102
41436
|
return path6;
|
|
43103
41437
|
}
|
|
@@ -43193,16 +41527,16 @@ var init_port_allocator = __esm({
|
|
|
43193
41527
|
// packages/cleo/src/viewer/server.ts
|
|
43194
41528
|
import { createReadStream } from "node:fs";
|
|
43195
41529
|
import { stat } from "node:fs/promises";
|
|
43196
|
-
import { dirname as
|
|
43197
|
-
import { fileURLToPath as
|
|
41530
|
+
import { dirname as dirname7, join as join19, normalize, resolve as resolve4 } from "node:path";
|
|
41531
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
43198
41532
|
import {
|
|
43199
41533
|
createAttachmentStore as createAttachmentStore5,
|
|
43200
41534
|
getProjectRoot as getProjectRoot29,
|
|
43201
41535
|
searchAllProjectDocs
|
|
43202
41536
|
} from "@cleocode/core/internal";
|
|
43203
41537
|
function getViewerAssetsDir() {
|
|
43204
|
-
const thisFile =
|
|
43205
|
-
return
|
|
41538
|
+
const thisFile = fileURLToPath4(import.meta.url);
|
|
41539
|
+
return resolve4(dirname7(thisFile), "..", "..", "assets", "viewer");
|
|
43206
41540
|
}
|
|
43207
41541
|
function extOf(p) {
|
|
43208
41542
|
const i = p.lastIndexOf(".");
|
|
@@ -43233,9 +41567,9 @@ function inferTitle(markdown, fallback) {
|
|
|
43233
41567
|
async function serveStatic(res, assetsDir, relPath) {
|
|
43234
41568
|
const safeRel = normalize(relPath).replace(/^[\\/]+/, "");
|
|
43235
41569
|
const absPath = join19(assetsDir, safeRel);
|
|
43236
|
-
const resolvedAssets =
|
|
43237
|
-
const resolvedAbs =
|
|
43238
|
-
if (`${resolvedAbs}/`.indexOf(resolvedAssets) !== 0 && resolvedAbs !==
|
|
41570
|
+
const resolvedAssets = resolve4(assetsDir) + "/";
|
|
41571
|
+
const resolvedAbs = resolve4(absPath);
|
|
41572
|
+
if (`${resolvedAbs}/`.indexOf(resolvedAssets) !== 0 && resolvedAbs !== resolve4(assetsDir)) {
|
|
43239
41573
|
send(res, 404, "application/json", lafsErrorJson("E_NOT_FOUND", `not found: ${relPath}`));
|
|
43240
41574
|
return;
|
|
43241
41575
|
}
|
|
@@ -43434,10 +41768,10 @@ var init_server = __esm({
|
|
|
43434
41768
|
import { spawn } from "node:child_process";
|
|
43435
41769
|
import { open as fsOpen } from "node:fs/promises";
|
|
43436
41770
|
import { join as join20 } from "node:path";
|
|
43437
|
-
import { fileURLToPath as
|
|
41771
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
43438
41772
|
import { getCleoHome as getCleoHome3, getProjectRoot as getProjectRoot30 } from "@cleocode/core";
|
|
43439
41773
|
function getCleoBinPath() {
|
|
43440
|
-
const thisFile =
|
|
41774
|
+
const thisFile = fileURLToPath5(import.meta.url);
|
|
43441
41775
|
return join20(thisFile, "..", "..", "index.js");
|
|
43442
41776
|
}
|
|
43443
41777
|
async function waitForExit(pid, timeoutMs, intervalMs = 100) {
|
|
@@ -43914,7 +42248,7 @@ __export(docs_exports, {
|
|
|
43914
42248
|
docsCommand: () => docsCommand
|
|
43915
42249
|
});
|
|
43916
42250
|
import { appendFile, mkdir as mkdir2, readdir, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
43917
|
-
import { dirname as
|
|
42251
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
|
|
43918
42252
|
import {
|
|
43919
42253
|
buildDocsGraph,
|
|
43920
42254
|
CleoError as CleoError3,
|
|
@@ -44318,8 +42652,8 @@ var init_docs3 = __esm({
|
|
|
44318
42652
|
});
|
|
44319
42653
|
let writtenPath;
|
|
44320
42654
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
44321
|
-
const outPath = isAbsolute2(args.out) ? args.out :
|
|
44322
|
-
await mkdir2(
|
|
42655
|
+
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
42656
|
+
await mkdir2(dirname8(outPath), { recursive: true });
|
|
44323
42657
|
await writeFile2(outPath, result.markdown, "utf8");
|
|
44324
42658
|
writtenPath = outPath;
|
|
44325
42659
|
}
|
|
@@ -44439,8 +42773,8 @@ var init_docs3 = __esm({
|
|
|
44439
42773
|
base: args.base ?? void 0
|
|
44440
42774
|
});
|
|
44441
42775
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
44442
|
-
const outPath = isAbsolute2(args.out) ? args.out :
|
|
44443
|
-
await mkdir2(
|
|
42776
|
+
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
42777
|
+
await mkdir2(dirname8(outPath), { recursive: true });
|
|
44444
42778
|
await writeFile2(outPath, result.merged, "utf8");
|
|
44445
42779
|
humanInfo(`Wrote merged content to ${outPath}`);
|
|
44446
42780
|
}
|
|
@@ -44509,8 +42843,8 @@ var init_docs3 = __esm({
|
|
|
44509
42843
|
output2 = lines.join("\n");
|
|
44510
42844
|
}
|
|
44511
42845
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
44512
|
-
const outPath = isAbsolute2(args.out) ? args.out :
|
|
44513
|
-
await mkdir2(
|
|
42846
|
+
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
42847
|
+
await mkdir2(dirname8(outPath), { recursive: true });
|
|
44514
42848
|
await writeFile2(outPath, output2, "utf8");
|
|
44515
42849
|
humanInfo(`Wrote graph to ${outPath}`);
|
|
44516
42850
|
}
|
|
@@ -44907,10 +43241,10 @@ var init_docs3 = __esm({
|
|
|
44907
43241
|
async run({ args }) {
|
|
44908
43242
|
const projectRoot = getProjectRoot31();
|
|
44909
43243
|
const dirArg = String(args.dir);
|
|
44910
|
-
const scanRoot = isAbsolute2(dirArg) ? dirArg :
|
|
43244
|
+
const scanRoot = isAbsolute2(dirArg) ? dirArg : resolve5(projectRoot, dirArg);
|
|
44911
43245
|
const dryRun = args["dry-run"] === true;
|
|
44912
43246
|
const force = args.force === true;
|
|
44913
|
-
const manifestPath = args["audit-manifest"] ? isAbsolute2(String(args["audit-manifest"])) ? String(args["audit-manifest"]) :
|
|
43247
|
+
const manifestPath = args["audit-manifest"] ? isAbsolute2(String(args["audit-manifest"])) ? String(args["audit-manifest"]) : resolve5(projectRoot, String(args["audit-manifest"])) : void 0;
|
|
44914
43248
|
if (force) {
|
|
44915
43249
|
const auditLine = `${JSON.stringify({
|
|
44916
43250
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -45111,7 +43445,7 @@ __export(doctor_projects_exports, {
|
|
|
45111
43445
|
import {
|
|
45112
43446
|
checkAllRegisteredProjects
|
|
45113
43447
|
} from "@cleocode/core/internal";
|
|
45114
|
-
function
|
|
43448
|
+
function formatRow2(report, nameFallback) {
|
|
45115
43449
|
const hash = report.projectHash.padEnd(12).slice(0, 12);
|
|
45116
43450
|
const name = nameFallback.padEnd(24).slice(0, 24);
|
|
45117
43451
|
const path6 = report.projectPath.padEnd(40).slice(0, 40);
|
|
@@ -45162,7 +43496,7 @@ function printDoctorProjectsReport(report, opts, nameLookup) {
|
|
|
45162
43496
|
humanLine("-".repeat(header.length));
|
|
45163
43497
|
for (const project of report.projects) {
|
|
45164
43498
|
const name = nameLookup.get(project.projectHash) ?? "<unnamed>";
|
|
45165
|
-
humanLine(
|
|
43499
|
+
humanLine(formatRow2(project, name));
|
|
45166
43500
|
}
|
|
45167
43501
|
humanLine("");
|
|
45168
43502
|
humanLine(
|
|
@@ -48491,21 +46825,22 @@ var init_import = __esm({
|
|
|
48491
46825
|
var init_exports = {};
|
|
48492
46826
|
__export(init_exports, {
|
|
48493
46827
|
getGitignoreTemplate: () => getGitignoreTemplate,
|
|
48494
|
-
getWorkflowTemplatesDir: () =>
|
|
46828
|
+
getWorkflowTemplatesDir: () => getWorkflowTemplatesDir2,
|
|
48495
46829
|
initCommand: () => initCommand2
|
|
48496
46830
|
});
|
|
48497
46831
|
import { existsSync as existsSync15, readFileSync as readFileSync15 } from "node:fs";
|
|
48498
|
-
import {
|
|
48499
|
-
import { fileURLToPath as
|
|
46832
|
+
import { join as join26 } from "node:path";
|
|
46833
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
48500
46834
|
import {
|
|
48501
46835
|
CleoError as CleoError4,
|
|
48502
46836
|
formatError as formatError5,
|
|
46837
|
+
getWorkflowTemplatesDir as getCoreWorkflowTemplatesDir,
|
|
48503
46838
|
initProject as initProject2,
|
|
48504
46839
|
scaffoldWorkflows
|
|
48505
46840
|
} from "@cleocode/core";
|
|
48506
46841
|
function getGitignoreTemplate() {
|
|
48507
46842
|
try {
|
|
48508
|
-
const thisFile =
|
|
46843
|
+
const thisFile = fileURLToPath6(import.meta.url);
|
|
48509
46844
|
const packageRoot = join26(thisFile, "..", "..", "..", "..");
|
|
48510
46845
|
const localTemplatePath = join26(packageRoot, "templates", "cleo-gitignore");
|
|
48511
46846
|
const monorepoTemplatePath = join26(packageRoot, "..", "..", "templates", "cleo-gitignore");
|
|
@@ -48517,10 +46852,8 @@ function getGitignoreTemplate() {
|
|
|
48517
46852
|
}
|
|
48518
46853
|
return "# CLEO Project Data - Selective Git Tracking\nagent-outputs/\n";
|
|
48519
46854
|
}
|
|
48520
|
-
function
|
|
48521
|
-
|
|
48522
|
-
const packageRoot = resolve7(dirname10(thisFile), "..", "..", "..", "..");
|
|
48523
|
-
return join26(packageRoot, "templates", "workflows");
|
|
46855
|
+
function getWorkflowTemplatesDir2() {
|
|
46856
|
+
return getCoreWorkflowTemplatesDir();
|
|
48524
46857
|
}
|
|
48525
46858
|
var initCommand2;
|
|
48526
46859
|
var init_init = __esm({
|
|
@@ -48575,7 +46908,7 @@ var init_init = __esm({
|
|
|
48575
46908
|
try {
|
|
48576
46909
|
if (args.workflows) {
|
|
48577
46910
|
const projectRoot = process.cwd();
|
|
48578
|
-
const templatesDir =
|
|
46911
|
+
const templatesDir = getWorkflowTemplatesDir2();
|
|
48579
46912
|
const result2 = await scaffoldWorkflows({
|
|
48580
46913
|
projectRoot,
|
|
48581
46914
|
templatesDir,
|
|
@@ -49879,7 +48212,7 @@ async function _headlessPkceFlow(provider, authUrl) {
|
|
|
49879
48212
|
` After approving, paste the full redirect URL (http://localhost?code=\u2026&state=\u2026):
|
|
49880
48213
|
`
|
|
49881
48214
|
);
|
|
49882
|
-
return new Promise((
|
|
48215
|
+
return new Promise((resolve7, reject) => {
|
|
49883
48216
|
let buf = "";
|
|
49884
48217
|
process.stdin.setEncoding("utf8");
|
|
49885
48218
|
process.stdin.once("data", (chunk) => {
|
|
@@ -49891,7 +48224,7 @@ async function _headlessPkceFlow(provider, authUrl) {
|
|
|
49891
48224
|
reject(new Error('Redirect URL is missing the "code" parameter'));
|
|
49892
48225
|
return;
|
|
49893
48226
|
}
|
|
49894
|
-
|
|
48227
|
+
resolve7(code);
|
|
49895
48228
|
} catch {
|
|
49896
48229
|
reject(new Error(`Invalid redirect URL: ${buf}`));
|
|
49897
48230
|
}
|
|
@@ -49899,7 +48232,7 @@ async function _headlessPkceFlow(provider, authUrl) {
|
|
|
49899
48232
|
});
|
|
49900
48233
|
}
|
|
49901
48234
|
async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
|
|
49902
|
-
return new Promise((
|
|
48235
|
+
return new Promise((resolve7) => {
|
|
49903
48236
|
const server = createServer2((req, res) => {
|
|
49904
48237
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
49905
48238
|
const code = url.searchParams.get("code");
|
|
@@ -49909,7 +48242,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
|
|
|
49909
48242
|
if (error) {
|
|
49910
48243
|
res.end(`<h1>Authorization failed</h1><p>${error}</p><p>You may close this tab.</p>`);
|
|
49911
48244
|
server.close();
|
|
49912
|
-
|
|
48245
|
+
resolve7({
|
|
49913
48246
|
error: {
|
|
49914
48247
|
code: "E_PKCE_AUTH_DENIED",
|
|
49915
48248
|
codeName: "E_PKCE_AUTH_DENIED",
|
|
@@ -49921,7 +48254,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
|
|
|
49921
48254
|
if (!code || state !== expectedState) {
|
|
49922
48255
|
res.end("<h1>Invalid callback</h1><p>You may close this tab.</p>");
|
|
49923
48256
|
server.close();
|
|
49924
|
-
|
|
48257
|
+
resolve7({
|
|
49925
48258
|
error: {
|
|
49926
48259
|
code: "E_PKCE_INVALID_CALLBACK",
|
|
49927
48260
|
codeName: "E_PKCE_INVALID_CALLBACK",
|
|
@@ -49932,7 +48265,7 @@ async function _localCallbackPkceFlow(provider, authUrl, expectedState, port) {
|
|
|
49932
48265
|
}
|
|
49933
48266
|
res.end("<h1>Authorized</h1><p>You may close this tab and return to your terminal.</p>");
|
|
49934
48267
|
server.close();
|
|
49935
|
-
|
|
48268
|
+
resolve7({ code });
|
|
49936
48269
|
});
|
|
49937
48270
|
server.listen(port, "localhost", () => {
|
|
49938
48271
|
process.stderr.write("\n");
|
|
@@ -50065,7 +48398,7 @@ function _generateState() {
|
|
|
50065
48398
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
50066
48399
|
}
|
|
50067
48400
|
function _findFreePort() {
|
|
50068
|
-
return new Promise((
|
|
48401
|
+
return new Promise((resolve7, reject) => {
|
|
50069
48402
|
const srv = createServer2();
|
|
50070
48403
|
srv.listen(0, "localhost", () => {
|
|
50071
48404
|
const addr = srv.address();
|
|
@@ -50075,7 +48408,7 @@ function _findFreePort() {
|
|
|
50075
48408
|
return;
|
|
50076
48409
|
}
|
|
50077
48410
|
const port = addr.port;
|
|
50078
|
-
srv.close(() =>
|
|
48411
|
+
srv.close(() => resolve7(port));
|
|
50079
48412
|
});
|
|
50080
48413
|
srv.on("error", reject);
|
|
50081
48414
|
});
|
|
@@ -50697,14 +49030,14 @@ async function readStdin() {
|
|
|
50697
49030
|
if (process.stdin.isTTY) {
|
|
50698
49031
|
return "";
|
|
50699
49032
|
}
|
|
50700
|
-
return new Promise((
|
|
49033
|
+
return new Promise((resolve7, reject) => {
|
|
50701
49034
|
let data = "";
|
|
50702
49035
|
process.stdin.setEncoding("utf-8");
|
|
50703
49036
|
process.stdin.on("data", (chunk) => {
|
|
50704
49037
|
data += chunk;
|
|
50705
49038
|
});
|
|
50706
49039
|
process.stdin.on("end", () => {
|
|
50707
|
-
|
|
49040
|
+
resolve7(data.trim());
|
|
50708
49041
|
});
|
|
50709
49042
|
process.stdin.on("error", reject);
|
|
50710
49043
|
});
|
|
@@ -53083,7 +51416,7 @@ function applyJsonFlag2(jsonFlag) {
|
|
|
53083
51416
|
}
|
|
53084
51417
|
}
|
|
53085
51418
|
var initCommand3, registerCommand2, unregisterCommand, listCommand14, statusCommand10, showCommand8, resolveCommand2, discoverCommand2, augmentCommand2, setupCommand, searchCommand3, depsCommand3, criticalPathCommand2, blockingCommand, orphansCommand2, syncCommand5, reconcileCommand2, graphCommand3, shareStatusCommand, transferPreviewCommand, transferCommand, permissionSetCommand, permissionCommand, shareExportCommand, shareImportCommand, shareCommand, clustersCommand2, flowsCommand2, contextCommand4, impactCommand3, analyzeCommand3, projectsListCommand, projectsRegisterCommand, projectsRemoveCommand, projectsScanCommand, projectsCleanCommand, projectsCommand, refreshBridgeCommand, exportCommand6, diffCommand2, queryCommand2, routeMapCommand2, shapeCheckCommand2, fullContextCommand, taskFootprintCommand, brainAnchorsCommand, whyCommand, impactFullCommand2, conduitScanCommand, taskSymbolsCommand, searchCodeCommand2, contractsSyncCommand, contractsShowCommand, contractsLinkTasksCommand, contractsCommand, groupCommand, wikiCommand2, hotPathsCommand2, hotNodesCommand2, coldSymbolsCommand2, sigilSyncCommand, sigilListCommand, sigilCommand, topEntriesCommand, nexusCommand;
|
|
53086
|
-
var
|
|
51419
|
+
var init_nexus3 = __esm({
|
|
53087
51420
|
"packages/cleo/src/cli/commands/nexus.ts"() {
|
|
53088
51421
|
"use strict";
|
|
53089
51422
|
init_dist();
|
|
@@ -54273,13 +52606,13 @@ var init_nexus4 = __esm({
|
|
|
54273
52606
|
if (!skipPrompt) {
|
|
54274
52607
|
const { createInterface: createInterface4 } = await import("node:readline");
|
|
54275
52608
|
const rl = createInterface4({ input: process.stdin, output: process.stdout });
|
|
54276
|
-
const confirmed = await new Promise((
|
|
52609
|
+
const confirmed = await new Promise((resolve7) => {
|
|
54277
52610
|
rl.question(
|
|
54278
52611
|
`
|
|
54279
52612
|
[nexus] Delete ${matchCount} project(s) from the registry? [y/N] `,
|
|
54280
52613
|
(answer) => {
|
|
54281
52614
|
rl.close();
|
|
54282
|
-
|
|
52615
|
+
resolve7(answer.trim().toLowerCase() === "y");
|
|
54283
52616
|
}
|
|
54284
52617
|
);
|
|
54285
52618
|
});
|
|
@@ -60233,11 +58566,11 @@ async function runPostUpdateDiagnostics(opts) {
|
|
|
60233
58566
|
input: process.stdin,
|
|
60234
58567
|
output: process.stdout
|
|
60235
58568
|
});
|
|
60236
|
-
shouldMigrate = await new Promise((
|
|
58569
|
+
shouldMigrate = await new Promise((resolve7) => {
|
|
60237
58570
|
rl.question(" Do you want to run the upgrade now? [Y/n] ", (answer) => {
|
|
60238
58571
|
rl.close();
|
|
60239
58572
|
const clean = answer.trim().toLowerCase();
|
|
60240
|
-
|
|
58573
|
+
resolve7(clean === "" || clean === "y" || clean === "yes");
|
|
60241
58574
|
});
|
|
60242
58575
|
});
|
|
60243
58576
|
}
|
|
@@ -61681,7 +60014,7 @@ async function promptOwnerAuthPassword(sessionName) {
|
|
|
61681
60014
|
terminal: true
|
|
61682
60015
|
});
|
|
61683
60016
|
process.stderr.write(`[cleo] Enter owner-auth password for session "${sessionName}": `);
|
|
61684
|
-
const password = await new Promise((
|
|
60017
|
+
const password = await new Promise((resolve7) => {
|
|
61685
60018
|
if (process.stdin.setRawMode) {
|
|
61686
60019
|
process.stdin.setRawMode(
|
|
61687
60020
|
true
|
|
@@ -61699,10 +60032,10 @@ async function promptOwnerAuthPassword(sessionName) {
|
|
|
61699
60032
|
);
|
|
61700
60033
|
}
|
|
61701
60034
|
process.stderr.write("\n");
|
|
61702
|
-
|
|
60035
|
+
resolve7(pw);
|
|
61703
60036
|
} else if (ch === "") {
|
|
61704
60037
|
process.stderr.write("\n[cleo] Cancelled.\n");
|
|
61705
|
-
|
|
60038
|
+
resolve7("");
|
|
61706
60039
|
} else if (ch === "\x7F" || ch === "\b") {
|
|
61707
60040
|
pw = pw.slice(0, -1);
|
|
61708
60041
|
} else {
|
|
@@ -64508,7 +62841,7 @@ __export(tasks_exports, {
|
|
|
64508
62841
|
tasksCommand: () => tasksCommand
|
|
64509
62842
|
});
|
|
64510
62843
|
var showSub, findSub, nextSub, currentSub, planSub, analyzeSub, tasksCommand;
|
|
64511
|
-
var
|
|
62844
|
+
var init_tasks3 = __esm({
|
|
64512
62845
|
"packages/cleo/src/cli/commands/tasks.ts"() {
|
|
64513
62846
|
"use strict";
|
|
64514
62847
|
init_dist();
|
|
@@ -65784,7 +64117,7 @@ var upgrade_exports = {};
|
|
|
65784
64117
|
__export(upgrade_exports, {
|
|
65785
64118
|
upgradeCommand: () => upgradeCommand
|
|
65786
64119
|
});
|
|
65787
|
-
import { resolve as
|
|
64120
|
+
import { resolve as resolve6 } from "node:path";
|
|
65788
64121
|
import { CleoError as CleoError10, diagnoseUpgrade, runUpgrade as runUpgrade2, upgradeWorkflows as upgradeWorkflows2 } from "@cleocode/core/internal";
|
|
65789
64122
|
var workflowsSubcommand, upgradeCommand;
|
|
65790
64123
|
var init_upgrade2 = __esm({
|
|
@@ -65824,8 +64157,8 @@ var init_upgrade2 = __esm({
|
|
|
65824
64157
|
const dryRun = args["dry-run"] === true || args.check === true;
|
|
65825
64158
|
const force = args.force === true && !dryRun;
|
|
65826
64159
|
const result = await upgradeWorkflows2({
|
|
65827
|
-
projectRoot:
|
|
65828
|
-
templatesDir:
|
|
64160
|
+
projectRoot: resolve6(process.cwd()),
|
|
64161
|
+
templatesDir: getWorkflowTemplatesDir2(),
|
|
65829
64162
|
dryRun,
|
|
65830
64163
|
force
|
|
65831
64164
|
});
|
|
@@ -66190,7 +64523,7 @@ Logs: ${logFile}`
|
|
|
66190
64523
|
}
|
|
66191
64524
|
} catch {
|
|
66192
64525
|
}
|
|
66193
|
-
await new Promise((
|
|
64526
|
+
await new Promise((resolve7) => setTimeout(resolve7, 500));
|
|
66194
64527
|
}
|
|
66195
64528
|
if (!started) {
|
|
66196
64529
|
try {
|
|
@@ -66267,7 +64600,7 @@ var init_web = __esm({
|
|
|
66267
64600
|
}
|
|
66268
64601
|
for (let i = 0; i < 60; i++) {
|
|
66269
64602
|
if (!isProcessRunning(status.pid)) break;
|
|
66270
|
-
await new Promise((
|
|
64603
|
+
await new Promise((resolve7) => setTimeout(resolve7, 500));
|
|
66271
64604
|
}
|
|
66272
64605
|
if (isProcessRunning(status.pid)) {
|
|
66273
64606
|
try {
|
|
@@ -66319,7 +64652,7 @@ var init_web = __esm({
|
|
|
66319
64652
|
}
|
|
66320
64653
|
for (let i = 0; i < 60; i++) {
|
|
66321
64654
|
if (!isProcessRunning(status.pid)) break;
|
|
66322
|
-
await new Promise((
|
|
64655
|
+
await new Promise((resolve7) => setTimeout(resolve7, 500));
|
|
66323
64656
|
}
|
|
66324
64657
|
if (isProcessRunning(status.pid)) {
|
|
66325
64658
|
try {
|
|
@@ -66417,12 +64750,12 @@ __export(worktree_exports, {
|
|
|
66417
64750
|
import readline4 from "node:readline";
|
|
66418
64751
|
import { getProjectRoot as getProjectRoot43, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
|
|
66419
64752
|
async function promptYesNo2(question) {
|
|
66420
|
-
return new Promise((
|
|
64753
|
+
return new Promise((resolve7) => {
|
|
66421
64754
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
|
|
66422
64755
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
66423
64756
|
rl.close();
|
|
66424
64757
|
const trimmed = answer.trim().toLowerCase();
|
|
66425
|
-
|
|
64758
|
+
resolve7(trimmed === "y" || trimmed === "yes");
|
|
66426
64759
|
});
|
|
66427
64760
|
});
|
|
66428
64761
|
}
|
|
@@ -66756,8 +65089,8 @@ init_dist();
|
|
|
66756
65089
|
init_field_context();
|
|
66757
65090
|
init_format_context();
|
|
66758
65091
|
import { readFileSync as readFileSync17 } from "node:fs";
|
|
66759
|
-
import { dirname as
|
|
66760
|
-
import { fileURLToPath as
|
|
65092
|
+
import { dirname as dirname9, join as join33 } from "node:path";
|
|
65093
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
66761
65094
|
|
|
66762
65095
|
// packages/cleo/src/cli/generated/command-manifest.ts
|
|
66763
65096
|
var COMMAND_MANIFEST = [
|
|
@@ -67263,7 +65596,7 @@ var COMMAND_MANIFEST = [
|
|
|
67263
65596
|
exportName: "nexusCommand",
|
|
67264
65597
|
name: "nexus",
|
|
67265
65598
|
description: "Cross-project NEXUS operations",
|
|
67266
|
-
load: async () => (await Promise.resolve().then(() => (
|
|
65599
|
+
load: async () => (await Promise.resolve().then(() => (init_nexus3(), nexus_exports))).nexusCommand
|
|
67267
65600
|
},
|
|
67268
65601
|
{
|
|
67269
65602
|
exportName: "opsCommand",
|
|
@@ -67527,7 +65860,7 @@ var COMMAND_MANIFEST = [
|
|
|
67527
65860
|
exportName: "tasksCommand",
|
|
67528
65861
|
name: "tasks",
|
|
67529
65862
|
description: "Task query namespace: show, find, next, current, plan, analyze",
|
|
67530
|
-
load: async () => (await Promise.resolve().then(() => (
|
|
65863
|
+
load: async () => (await Promise.resolve().then(() => (init_tasks3(), tasks_exports))).tasksCommand
|
|
67531
65864
|
},
|
|
67532
65865
|
{
|
|
67533
65866
|
exportName: "telemetryCommand",
|
|
@@ -67592,11 +65925,11 @@ var noColor2 = (() => {
|
|
|
67592
65925
|
const env = globalThis.process?.env ?? {};
|
|
67593
65926
|
return env.NO_COLOR === "1" || env.TERM === "dumb" || env.TEST || env.CI;
|
|
67594
65927
|
})();
|
|
67595
|
-
var
|
|
67596
|
-
var bold2 =
|
|
67597
|
-
var cyan2 =
|
|
67598
|
-
var gray2 =
|
|
67599
|
-
var underline2 =
|
|
65928
|
+
var ansi = (code, reset = 39) => (t) => noColor2 ? t : `\x1B[${code}m${t}\x1B[${reset}m`;
|
|
65929
|
+
var bold2 = ansi(1, 22);
|
|
65930
|
+
var cyan2 = ansi(36);
|
|
65931
|
+
var gray2 = ansi(90);
|
|
65932
|
+
var underline2 = ansi(4, 24);
|
|
67600
65933
|
var IMPLICIT_ALIASES = {
|
|
67601
65934
|
tags: "labels"
|
|
67602
65935
|
};
|
|
@@ -67797,7 +66130,7 @@ async function detectFirstRun() {
|
|
|
67797
66130
|
return true;
|
|
67798
66131
|
}
|
|
67799
66132
|
function waitForEnterOrTimeout(timeoutMs) {
|
|
67800
|
-
return new Promise((
|
|
66133
|
+
return new Promise((resolve7) => {
|
|
67801
66134
|
let resolved = false;
|
|
67802
66135
|
const finish = () => {
|
|
67803
66136
|
if (resolved) return;
|
|
@@ -67809,7 +66142,7 @@ function waitForEnterOrTimeout(timeoutMs) {
|
|
|
67809
66142
|
process.stdin.pause();
|
|
67810
66143
|
} catch {
|
|
67811
66144
|
}
|
|
67812
|
-
|
|
66145
|
+
resolve7();
|
|
67813
66146
|
};
|
|
67814
66147
|
const onData = (chunk) => {
|
|
67815
66148
|
const s = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
@@ -67900,7 +66233,7 @@ Or via NodeSource: https://github.com/nodesource/distributions
|
|
|
67900
66233
|
}
|
|
67901
66234
|
}
|
|
67902
66235
|
function getPackageVersion() {
|
|
67903
|
-
const pkgPath = join33(
|
|
66236
|
+
const pkgPath = join33(dirname9(fileURLToPath7(import.meta.url)), "../../package.json");
|
|
67904
66237
|
const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
|
|
67905
66238
|
return pkg.version;
|
|
67906
66239
|
}
|