clawvault 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/register-workgraph-commands.js +1 -918
- package/dist/{chunk-P62WHA27.js → chunk-42MXU7A6.js} +47 -58
- package/dist/{chunk-23YDQ3QU.js → chunk-4ITRXIVT.js} +3 -3
- package/dist/{chunk-7YZWHM36.js → chunk-4VQTUVH7.js} +26 -52
- package/dist/{chunk-EK6S23ZB.js → chunk-5PJ4STIC.js} +5 -9
- package/dist/{chunk-4PY655YM.js → chunk-AZYOKJYC.js} +1 -13
- package/dist/{chunk-PBACDKKP.js → chunk-ECRZL5XR.js} +6 -22
- package/dist/{chunk-VSL7KY3M.js → chunk-ERNE2FZ5.js} +3 -3
- package/dist/{chunk-QSHD36LH.js → chunk-FAKNOB7Y.js} +1 -1
- package/dist/{chunk-QVEERJSP.js → chunk-HR4KN6S2.js} +3 -3
- package/dist/{chunk-QSRRMEYM.js → chunk-IIOU45CK.js} +1 -1
- package/dist/{chunk-33VSQP4J.js → chunk-IJBFGPCS.js} +5 -9
- package/dist/{chunk-4BQTQMJP.js → chunk-K7PNYS45.js} +1 -1
- package/dist/{chunk-ESVS6K2B.js → chunk-MNPUYCHQ.js} +1 -1
- package/dist/{chunk-MM6QGW3P.js → chunk-NTOPJI7W.js} +1 -1
- package/dist/{chunk-MW5C6ZQA.js → chunk-P5EPF6MB.js} +13 -110
- package/dist/{chunk-U4O6C46S.js → chunk-PG56HX5T.js} +1 -1
- package/dist/{chunk-ESFLMDRB.js → chunk-PI4WMLMG.js} +3 -3
- package/dist/{chunk-BUEW6IIK.js → chunk-QMHPQYUV.js} +2 -3
- package/dist/{chunk-GAOWA7GR.js → chunk-QPDDIHXE.js} +10 -10
- package/dist/{chunk-SLXOR3CC.js → chunk-S5OJEGFG.js} +1 -1
- package/dist/{chunk-2ZDO52B4.js → chunk-U67V476Y.js} +1 -18
- package/dist/{chunk-STCQGCEQ.js → chunk-UCQAOZHW.js} +2 -2
- package/dist/chunk-WIOLLGAD.js +190 -0
- package/dist/{chunk-ZN54U2OZ.js → chunk-WJVWINEM.js} +4 -53
- package/dist/{chunk-77Q5CSPJ.js → chunk-Y3TIJEBP.js} +3 -92
- package/dist/{chunk-CLJTREDS.js → chunk-YDWHS4LJ.js} +9 -29
- package/dist/{chunk-W4SPAEE7.js → chunk-YNIPYN4F.js} +2 -2
- package/dist/{chunk-NCKFNBHJ.js → chunk-YXQCA6B7.js} +2 -33
- package/dist/{chunk-33DOSHTA.js → chunk-ZZA73MFY.js} +36 -176
- package/dist/cli/index.js +17 -23
- package/dist/commands/archive.js +1 -1
- package/dist/commands/backlog.js +1 -1
- package/dist/commands/blocked.js +1 -1
- package/dist/commands/canvas.js +2 -2
- package/dist/commands/checkpoint.js +1 -1
- package/dist/commands/compat.js +1 -1
- package/dist/commands/context.js +6 -6
- package/dist/commands/doctor.js +12 -12
- package/dist/commands/embed.js +4 -4
- package/dist/commands/entities.js +1 -1
- package/dist/commands/graph.js +3 -3
- package/dist/commands/inject.js +4 -4
- package/dist/commands/kanban.js +1 -1
- package/dist/commands/link.js +4 -4
- package/dist/commands/migrate-observations.js +1 -1
- package/dist/commands/observe.js +7 -7
- package/dist/commands/project.js +2 -2
- package/dist/commands/rebuild-embeddings.js +2 -2
- package/dist/commands/rebuild.js +5 -5
- package/dist/commands/recover.js +1 -1
- package/dist/commands/reflect.js +4 -4
- package/dist/commands/repair-session.js +1 -1
- package/dist/commands/replay.js +6 -6
- package/dist/commands/session-recap.js +1 -1
- package/dist/commands/setup.js +3 -3
- package/dist/commands/shell-init.js +1 -1
- package/dist/commands/sleep.js +10 -10
- package/dist/commands/status.js +13 -25
- package/dist/commands/sync-bd.js +1 -1
- package/dist/commands/tailscale.js +1 -1
- package/dist/commands/task.js +1 -1
- package/dist/commands/template.js +1 -1
- package/dist/commands/wake.js +5 -5
- package/dist/index.d.ts +0 -7
- package/dist/index.js +32 -38
- package/dist/lib/auto-linker.js +2 -2
- package/dist/lib/canvas-layout.js +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/entity-index.js +1 -1
- package/dist/lib/project-utils.js +2 -2
- package/dist/lib/session-repair.js +1 -1
- package/dist/lib/session-utils.js +1 -1
- package/dist/lib/tailscale.js +1 -1
- package/dist/lib/task-utils.js +1 -1
- package/dist/lib/template-engine.js +1 -1
- package/dist/lib/webdav.js +1 -1
- package/dist/plugin/index.d.ts +352 -0
- package/dist/plugin/index.js +4264 -0
- package/dist/workgraph/index.js +5 -5
- package/dist/workgraph/ledger.js +2 -2
- package/dist/workgraph/registry.js +2 -2
- package/dist/workgraph/store.js +4 -4
- package/dist/workgraph/thread.js +5 -5
- package/dist/workgraph/types.js +1 -1
- package/hooks/clawvault/HOOK.md +3 -3
- package/hooks/clawvault/handler.js +0 -2
- package/openclaw.plugin.json +201 -23
- package/package.json +7 -10
- package/dist/chunk-6FH3IULF.js +0 -352
- package/dist/chunk-GGA32J2R.js +0 -784
- package/dist/commands/workgraph.d.ts +0 -124
- package/dist/commands/workgraph.js +0 -38
- package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
- package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
- package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
- package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
- package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
- package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
- package/dist/openclaw-plugin.d.ts +0 -8
- package/dist/openclaw-plugin.js +0 -14
- package/dist/transformers.node-A2ZRORSQ.js +0 -46775
package/dist/chunk-GGA32J2R.js
DELETED
|
@@ -1,784 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
block,
|
|
3
|
-
claim,
|
|
4
|
-
createThread,
|
|
5
|
-
decompose,
|
|
6
|
-
done,
|
|
7
|
-
release
|
|
8
|
-
} from "./chunk-VSL7KY3M.js";
|
|
9
|
-
import {
|
|
10
|
-
create,
|
|
11
|
-
list,
|
|
12
|
-
read
|
|
13
|
-
} from "./chunk-QVEERJSP.js";
|
|
14
|
-
import {
|
|
15
|
-
allClaims,
|
|
16
|
-
readAll,
|
|
17
|
-
recent
|
|
18
|
-
} from "./chunk-4BQTQMJP.js";
|
|
19
|
-
import {
|
|
20
|
-
defineType,
|
|
21
|
-
listTypes
|
|
22
|
-
} from "./chunk-MM6QGW3P.js";
|
|
23
|
-
|
|
24
|
-
// src/commands/workgraph.ts
|
|
25
|
-
import os from "os";
|
|
26
|
-
import path from "path";
|
|
27
|
-
import chalk from "chalk";
|
|
28
|
-
var BOX = {
|
|
29
|
-
topLeft: "\u256D",
|
|
30
|
-
topRight: "\u256E",
|
|
31
|
-
bottomLeft: "\u2570",
|
|
32
|
-
bottomRight: "\u256F",
|
|
33
|
-
horizontal: "\u2500",
|
|
34
|
-
vertical: "\u2502",
|
|
35
|
-
teeRight: "\u251C",
|
|
36
|
-
teeLeft: "\u2524",
|
|
37
|
-
teeDown: "\u252C",
|
|
38
|
-
teeUp: "\u2534",
|
|
39
|
-
cross: "\u253C"
|
|
40
|
-
};
|
|
41
|
-
var PRIORITY_CONFIG = {
|
|
42
|
-
urgent: { color: chalk.red, symbol: "\u{1F534}", label: "URGENT" },
|
|
43
|
-
high: { color: chalk.yellow, symbol: "\u{1F7E0}", label: "HIGH" },
|
|
44
|
-
medium: { color: chalk.blue, symbol: "\u{1F535}", label: "MEDIUM" },
|
|
45
|
-
low: { color: chalk.gray, symbol: "\u26AA", label: "LOW" }
|
|
46
|
-
};
|
|
47
|
-
var STATUS_CONFIG = {
|
|
48
|
-
open: { color: chalk.cyan, symbol: "\u25CB", label: "Open" },
|
|
49
|
-
active: { color: chalk.green, symbol: "\u25CF", label: "Active" },
|
|
50
|
-
blocked: { color: chalk.red, symbol: "\u2298", label: "Blocked" },
|
|
51
|
-
done: { color: chalk.gray, symbol: "\u2713", label: "Done" },
|
|
52
|
-
cancelled: { color: chalk.dim, symbol: "\u2717", label: "Cancelled" }
|
|
53
|
-
};
|
|
54
|
-
var OP_COLORS = {
|
|
55
|
-
create: chalk.green,
|
|
56
|
-
update: chalk.blue,
|
|
57
|
-
delete: chalk.red,
|
|
58
|
-
claim: chalk.yellow,
|
|
59
|
-
release: chalk.cyan,
|
|
60
|
-
block: chalk.red,
|
|
61
|
-
unblock: chalk.green,
|
|
62
|
-
done: chalk.greenBright,
|
|
63
|
-
cancel: chalk.gray,
|
|
64
|
-
define: chalk.magenta,
|
|
65
|
-
decompose: chalk.cyan
|
|
66
|
-
};
|
|
67
|
-
function getAgentName() {
|
|
68
|
-
return process.env.CLAWVAULT_AGENT ?? os.hostname();
|
|
69
|
-
}
|
|
70
|
-
function resolveVaultPath(optionPath) {
|
|
71
|
-
return path.resolve(optionPath ?? process.env.CLAWVAULT_PATH ?? process.cwd());
|
|
72
|
-
}
|
|
73
|
-
function formatRelativeTime(isoTimestamp) {
|
|
74
|
-
const now = Date.now();
|
|
75
|
-
const then = new Date(isoTimestamp).getTime();
|
|
76
|
-
const diffMs = now - then;
|
|
77
|
-
if (diffMs < 0) return "just now";
|
|
78
|
-
const seconds = Math.floor(diffMs / 1e3);
|
|
79
|
-
const minutes = Math.floor(seconds / 60);
|
|
80
|
-
const hours = Math.floor(minutes / 60);
|
|
81
|
-
const days = Math.floor(hours / 24);
|
|
82
|
-
const weeks = Math.floor(days / 7);
|
|
83
|
-
if (weeks > 0) return `${weeks}w ago`;
|
|
84
|
-
if (days > 0) return `${days}d ago`;
|
|
85
|
-
if (hours > 0) return `${hours}h ago`;
|
|
86
|
-
if (minutes > 0) return `${minutes}m ago`;
|
|
87
|
-
if (seconds > 0) return `${seconds}s ago`;
|
|
88
|
-
return "just now";
|
|
89
|
-
}
|
|
90
|
-
function drawLine(width, title) {
|
|
91
|
-
if (!title) {
|
|
92
|
-
return BOX.horizontal.repeat(width);
|
|
93
|
-
}
|
|
94
|
-
const titlePadded = ` ${title} `;
|
|
95
|
-
const remaining = width - titlePadded.length - 2;
|
|
96
|
-
const left = Math.floor(remaining / 2);
|
|
97
|
-
const right = remaining - left;
|
|
98
|
-
return BOX.horizontal.repeat(left) + chalk.bold(titlePadded) + BOX.horizontal.repeat(right);
|
|
99
|
-
}
|
|
100
|
-
function drawBox(title, lines, width = 60) {
|
|
101
|
-
const innerWidth = width - 2;
|
|
102
|
-
const output = [];
|
|
103
|
-
output.push(BOX.topLeft + drawLine(innerWidth, title) + BOX.topRight);
|
|
104
|
-
for (const line of lines) {
|
|
105
|
-
const stripped = stripAnsi(line);
|
|
106
|
-
const padding = innerWidth - stripped.length;
|
|
107
|
-
output.push(BOX.vertical + line + " ".repeat(Math.max(0, padding)) + BOX.vertical);
|
|
108
|
-
}
|
|
109
|
-
output.push(BOX.bottomLeft + BOX.horizontal.repeat(innerWidth) + BOX.bottomRight);
|
|
110
|
-
return output.join("\n");
|
|
111
|
-
}
|
|
112
|
-
function stripAnsi(str) {
|
|
113
|
-
return str.replace(/\x1B\[[0-9;]*m/g, "");
|
|
114
|
-
}
|
|
115
|
-
function truncate(str, maxLen) {
|
|
116
|
-
if (str.length <= maxLen) return str;
|
|
117
|
-
return str.slice(0, maxLen - 1) + "\u2026";
|
|
118
|
-
}
|
|
119
|
-
function formatThreadLine(inst, showOwner = true) {
|
|
120
|
-
const status = inst.fields.status;
|
|
121
|
-
const priority = inst.fields.priority ?? "medium";
|
|
122
|
-
const title = truncate(String(inst.fields.title ?? inst.path), 40);
|
|
123
|
-
const owner = inst.fields.owner;
|
|
124
|
-
const statusCfg = STATUS_CONFIG[status] ?? STATUS_CONFIG.open;
|
|
125
|
-
const priorityCfg = PRIORITY_CONFIG[priority] ?? PRIORITY_CONFIG.medium;
|
|
126
|
-
let line = `${statusCfg.color(statusCfg.symbol)} ${priorityCfg.symbol} ${chalk.white(title)}`;
|
|
127
|
-
if (showOwner && owner) {
|
|
128
|
-
line += chalk.dim(` @${owner}`);
|
|
129
|
-
}
|
|
130
|
-
return line;
|
|
131
|
-
}
|
|
132
|
-
function parseList(value) {
|
|
133
|
-
if (!value) return [];
|
|
134
|
-
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
135
|
-
}
|
|
136
|
-
function formatError(what, why, fix) {
|
|
137
|
-
return [
|
|
138
|
-
"",
|
|
139
|
-
chalk.red.bold("\u2717 Error: ") + chalk.red(what),
|
|
140
|
-
"",
|
|
141
|
-
chalk.dim("Why: ") + why,
|
|
142
|
-
chalk.dim("Fix: ") + chalk.cyan(fix),
|
|
143
|
-
""
|
|
144
|
-
].join("\n");
|
|
145
|
-
}
|
|
146
|
-
async function statusCommand(vaultPath) {
|
|
147
|
-
const agentName = getAgentName();
|
|
148
|
-
const now = /* @__PURE__ */ new Date();
|
|
149
|
-
const greeting = getGreeting(now.getHours());
|
|
150
|
-
console.log("");
|
|
151
|
-
console.log(chalk.bold.cyan(`${greeting}, ${agentName}!`));
|
|
152
|
-
console.log(chalk.dim(`${now.toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" })}`));
|
|
153
|
-
console.log("");
|
|
154
|
-
const allThreads = list(vaultPath, "thread");
|
|
155
|
-
const activeThreads = allThreads.filter((t) => t.fields.status === "active");
|
|
156
|
-
const openThreads = allThreads.filter((t) => t.fields.status === "open");
|
|
157
|
-
const blockedThreads = allThreads.filter((t) => t.fields.status === "blocked");
|
|
158
|
-
const myActiveThreads = activeThreads.filter((t) => t.fields.owner === agentName);
|
|
159
|
-
if (myActiveThreads.length > 0) {
|
|
160
|
-
const activeLines = myActiveThreads.map((t) => formatThreadLine(t, false));
|
|
161
|
-
console.log(drawBox("\u{1F525} Your Active Work", activeLines, 65));
|
|
162
|
-
console.log("");
|
|
163
|
-
}
|
|
164
|
-
if (openThreads.length > 0) {
|
|
165
|
-
const sorted = sortByPriority(openThreads);
|
|
166
|
-
const availableLines = sorted.slice(0, 5).map((t) => formatThreadLine(t, false));
|
|
167
|
-
if (sorted.length > 5) {
|
|
168
|
-
availableLines.push(chalk.dim(` ... and ${sorted.length - 5} more`));
|
|
169
|
-
}
|
|
170
|
-
console.log(drawBox("\u{1F4CB} Available Work", availableLines, 65));
|
|
171
|
-
console.log("");
|
|
172
|
-
}
|
|
173
|
-
if (blockedThreads.length > 0) {
|
|
174
|
-
const blockedLines = blockedThreads.slice(0, 3).map((t) => {
|
|
175
|
-
const title = truncate(String(t.fields.title ?? t.path), 35);
|
|
176
|
-
const deps = t.fields.deps ?? [];
|
|
177
|
-
const depStr = deps.length > 0 ? chalk.dim(` \u2192 ${deps[0]}`) : "";
|
|
178
|
-
return `${STATUS_CONFIG.blocked.color(STATUS_CONFIG.blocked.symbol)} ${title}${depStr}`;
|
|
179
|
-
});
|
|
180
|
-
console.log(drawBox("\u26D4 Blocked", blockedLines, 65));
|
|
181
|
-
console.log("");
|
|
182
|
-
}
|
|
183
|
-
const recentEntries = recent(vaultPath, 8);
|
|
184
|
-
if (recentEntries.length > 0) {
|
|
185
|
-
const activityLines = recentEntries.reverse().map((e) => {
|
|
186
|
-
const opColor = OP_COLORS[e.op] ?? chalk.white;
|
|
187
|
-
const target = truncate(path.basename(e.target, ".md"), 25);
|
|
188
|
-
const time = formatRelativeTime(e.ts);
|
|
189
|
-
return `${opColor(e.op.padEnd(8))} ${chalk.white(target)} ${chalk.dim(time)}`;
|
|
190
|
-
});
|
|
191
|
-
console.log(drawBox("\u{1F4DC} Recent Activity", activityLines, 65));
|
|
192
|
-
console.log("");
|
|
193
|
-
}
|
|
194
|
-
const claims = allClaims(vaultPath);
|
|
195
|
-
const teamMembers = /* @__PURE__ */ new Map();
|
|
196
|
-
for (const [target, owner] of claims) {
|
|
197
|
-
const current = teamMembers.get(owner) ?? [];
|
|
198
|
-
current.push(target);
|
|
199
|
-
teamMembers.set(owner, current);
|
|
200
|
-
}
|
|
201
|
-
if (teamMembers.size > 0) {
|
|
202
|
-
const teamLines = [];
|
|
203
|
-
for (const [member, threads] of teamMembers) {
|
|
204
|
-
const isYou = member === agentName;
|
|
205
|
-
const name = isYou ? chalk.green(`${member} (you)`) : chalk.white(member);
|
|
206
|
-
teamLines.push(`${chalk.cyan("\u25CF")} ${name}: ${chalk.dim(`${threads.length} active`)}`);
|
|
207
|
-
}
|
|
208
|
-
console.log(drawBox("\u{1F465} Team Status", teamLines, 65));
|
|
209
|
-
console.log("");
|
|
210
|
-
}
|
|
211
|
-
const summaryParts = [
|
|
212
|
-
chalk.green(`${activeThreads.length} active`),
|
|
213
|
-
chalk.cyan(`${openThreads.length} open`),
|
|
214
|
-
chalk.red(`${blockedThreads.length} blocked`)
|
|
215
|
-
];
|
|
216
|
-
console.log(chalk.dim("Summary: ") + summaryParts.join(chalk.dim(" \xB7 ")));
|
|
217
|
-
console.log("");
|
|
218
|
-
}
|
|
219
|
-
function getGreeting(hour) {
|
|
220
|
-
if (hour < 12) return "\u2600\uFE0F Good morning";
|
|
221
|
-
if (hour < 17) return "\u{1F324}\uFE0F Good afternoon";
|
|
222
|
-
return "\u{1F319} Good evening";
|
|
223
|
-
}
|
|
224
|
-
function sortByPriority(threads) {
|
|
225
|
-
const priorityOrder = { urgent: 0, high: 1, medium: 2, low: 3 };
|
|
226
|
-
return [...threads].sort((a, b) => {
|
|
227
|
-
const priorityA = String(a.fields.priority ?? "medium");
|
|
228
|
-
const priorityB = String(b.fields.priority ?? "medium");
|
|
229
|
-
const pa = priorityOrder[priorityA] ?? 2;
|
|
230
|
-
const pb = priorityOrder[priorityB] ?? 2;
|
|
231
|
-
return pa - pb;
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
async function threadCreateCommand(vaultPath, title, options) {
|
|
235
|
-
const agentName = getAgentName();
|
|
236
|
-
const goal = options.goal ?? `Complete: ${title}`;
|
|
237
|
-
const priority = options.priority ?? "medium";
|
|
238
|
-
const deps = parseList(options.deps);
|
|
239
|
-
const tags = parseList(options.tags);
|
|
240
|
-
try {
|
|
241
|
-
const inst = createThread(vaultPath, title, goal, agentName, {
|
|
242
|
-
priority,
|
|
243
|
-
deps,
|
|
244
|
-
tags
|
|
245
|
-
});
|
|
246
|
-
console.log("");
|
|
247
|
-
console.log(chalk.green.bold("\u2713 Thread created"));
|
|
248
|
-
console.log("");
|
|
249
|
-
console.log(chalk.dim(" Path: ") + chalk.white(inst.path));
|
|
250
|
-
console.log(chalk.dim(" Title: ") + chalk.white(inst.fields.title));
|
|
251
|
-
console.log(chalk.dim(" Goal: ") + chalk.white(inst.fields.goal));
|
|
252
|
-
console.log(chalk.dim(" Priority: ") + formatPriority(priority));
|
|
253
|
-
if (deps.length > 0) {
|
|
254
|
-
console.log(chalk.dim(" Deps: ") + chalk.cyan(deps.join(", ")));
|
|
255
|
-
}
|
|
256
|
-
if (tags.length > 0) {
|
|
257
|
-
console.log(chalk.dim(" Tags: ") + chalk.magenta(tags.join(", ")));
|
|
258
|
-
}
|
|
259
|
-
console.log("");
|
|
260
|
-
console.log(chalk.dim(`Claim it: ${chalk.cyan(`clawvault wg thread claim ${inst.path}`)}`));
|
|
261
|
-
console.log("");
|
|
262
|
-
} catch (err) {
|
|
263
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
264
|
-
console.error(formatError(
|
|
265
|
-
"Failed to create thread",
|
|
266
|
-
message,
|
|
267
|
-
"Check the title is unique and vault path is correct"
|
|
268
|
-
));
|
|
269
|
-
process.exitCode = 1;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
function formatPriority(priority) {
|
|
273
|
-
const cfg = PRIORITY_CONFIG[priority] ?? PRIORITY_CONFIG.medium;
|
|
274
|
-
return cfg.color(`${cfg.symbol} ${cfg.label}`);
|
|
275
|
-
}
|
|
276
|
-
async function threadListCommand(vaultPath, options) {
|
|
277
|
-
let threads = list(vaultPath, "thread");
|
|
278
|
-
if (options.status) {
|
|
279
|
-
threads = threads.filter((t) => t.fields.status === options.status);
|
|
280
|
-
}
|
|
281
|
-
if (options.owner) {
|
|
282
|
-
const ownerFilter = options.owner === "me" ? getAgentName() : options.owner;
|
|
283
|
-
threads = threads.filter((t) => t.fields.owner === ownerFilter);
|
|
284
|
-
}
|
|
285
|
-
if (options.json) {
|
|
286
|
-
console.log(JSON.stringify(threads, null, 2));
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
if (threads.length === 0) {
|
|
290
|
-
console.log("");
|
|
291
|
-
console.log(chalk.dim("No threads found matching filters."));
|
|
292
|
-
console.log("");
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
console.log("");
|
|
296
|
-
console.log(chalk.bold(`Threads (${threads.length})`));
|
|
297
|
-
console.log(chalk.dim("\u2500".repeat(70)));
|
|
298
|
-
const sorted = sortByPriority(threads);
|
|
299
|
-
for (const t of sorted) {
|
|
300
|
-
const status = t.fields.status;
|
|
301
|
-
const priority = t.fields.priority ?? "medium";
|
|
302
|
-
const title = truncate(String(t.fields.title ?? t.path), 35);
|
|
303
|
-
const owner = t.fields.owner;
|
|
304
|
-
const updated = formatRelativeTime(String(t.fields.updated));
|
|
305
|
-
const statusCfg = STATUS_CONFIG[status] ?? STATUS_CONFIG.open;
|
|
306
|
-
const priorityCfg = PRIORITY_CONFIG[priority] ?? PRIORITY_CONFIG.medium;
|
|
307
|
-
let line = `${statusCfg.color(statusCfg.symbol.padEnd(2))}`;
|
|
308
|
-
line += `${priorityCfg.symbol} `;
|
|
309
|
-
line += chalk.white(title.padEnd(37));
|
|
310
|
-
line += owner ? chalk.cyan(`@${owner}`.padEnd(15)) : " ".repeat(15);
|
|
311
|
-
line += chalk.dim(updated);
|
|
312
|
-
console.log(line);
|
|
313
|
-
}
|
|
314
|
-
console.log(chalk.dim("\u2500".repeat(70)));
|
|
315
|
-
console.log("");
|
|
316
|
-
}
|
|
317
|
-
async function threadClaimCommand(vaultPath, threadPath) {
|
|
318
|
-
const agentName = getAgentName();
|
|
319
|
-
const normalizedPath = normalizeThreadPath(threadPath);
|
|
320
|
-
try {
|
|
321
|
-
const inst = claim(vaultPath, normalizedPath, agentName);
|
|
322
|
-
console.log("");
|
|
323
|
-
console.log(chalk.green.bold("\u2713 Thread claimed"));
|
|
324
|
-
console.log("");
|
|
325
|
-
const briefLines = [
|
|
326
|
-
chalk.dim("Title: ") + chalk.white.bold(inst.fields.title),
|
|
327
|
-
chalk.dim("Goal: ") + chalk.white(inst.fields.goal),
|
|
328
|
-
chalk.dim("Priority: ") + formatPriority(String(inst.fields.priority ?? "medium"))
|
|
329
|
-
];
|
|
330
|
-
const deps = inst.fields.deps ?? [];
|
|
331
|
-
if (deps.length > 0) {
|
|
332
|
-
briefLines.push(chalk.dim("Deps: ") + chalk.cyan(deps.join(", ")));
|
|
333
|
-
}
|
|
334
|
-
const contextRefs = inst.fields.context_refs ?? [];
|
|
335
|
-
if (contextRefs.length > 0) {
|
|
336
|
-
briefLines.push(chalk.dim("Context: ") + chalk.magenta(contextRefs.join(", ")));
|
|
337
|
-
}
|
|
338
|
-
console.log(drawBox("\u{1F4CB} Work Brief", briefLines, 65));
|
|
339
|
-
console.log("");
|
|
340
|
-
if (inst.body && inst.body.trim()) {
|
|
341
|
-
console.log(chalk.dim("\u2500".repeat(65)));
|
|
342
|
-
console.log(chalk.dim("Notes:"));
|
|
343
|
-
console.log(inst.body.trim().split("\n").slice(0, 10).join("\n"));
|
|
344
|
-
console.log(chalk.dim("\u2500".repeat(65)));
|
|
345
|
-
console.log("");
|
|
346
|
-
}
|
|
347
|
-
console.log(chalk.dim(`When done: ${chalk.cyan(`clawvault wg thread done ${normalizedPath}`)}`));
|
|
348
|
-
console.log("");
|
|
349
|
-
} catch (err) {
|
|
350
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
351
|
-
console.error(formatError(
|
|
352
|
-
"Failed to claim thread",
|
|
353
|
-
message,
|
|
354
|
-
'Ensure the thread exists and is in "open" status'
|
|
355
|
-
));
|
|
356
|
-
process.exitCode = 1;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
function normalizeThreadPath(input) {
|
|
360
|
-
if (input.startsWith("threads/")) return input;
|
|
361
|
-
if (input.endsWith(".md")) return `threads/${input}`;
|
|
362
|
-
return `threads/${input}.md`;
|
|
363
|
-
}
|
|
364
|
-
async function threadDoneCommand(vaultPath, threadPath, options) {
|
|
365
|
-
const agentName = getAgentName();
|
|
366
|
-
const normalizedPath = normalizeThreadPath(threadPath);
|
|
367
|
-
try {
|
|
368
|
-
const inst = done(vaultPath, normalizedPath, agentName, options.output);
|
|
369
|
-
console.log("");
|
|
370
|
-
console.log(chalk.green.bold("\u2713 Thread completed!"));
|
|
371
|
-
console.log("");
|
|
372
|
-
console.log(chalk.dim(" Title: ") + chalk.white(inst.fields.title));
|
|
373
|
-
console.log(chalk.dim(" Status: ") + chalk.green("done"));
|
|
374
|
-
if (options.output) {
|
|
375
|
-
console.log(chalk.dim(" Output: ") + chalk.white(truncate(options.output, 50)));
|
|
376
|
-
}
|
|
377
|
-
console.log("");
|
|
378
|
-
console.log(chalk.dim("Great work! \u{1F389}"));
|
|
379
|
-
console.log("");
|
|
380
|
-
} catch (err) {
|
|
381
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
382
|
-
console.error(formatError(
|
|
383
|
-
"Failed to complete thread",
|
|
384
|
-
message,
|
|
385
|
-
'Ensure you own the thread and it is in "active" status'
|
|
386
|
-
));
|
|
387
|
-
process.exitCode = 1;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
async function threadBlockCommand(vaultPath, threadPath, options) {
|
|
391
|
-
const agentName = getAgentName();
|
|
392
|
-
const normalizedPath = normalizeThreadPath(threadPath);
|
|
393
|
-
if (!options.by) {
|
|
394
|
-
console.error(formatError(
|
|
395
|
-
"Missing --by option",
|
|
396
|
-
"You must specify what is blocking this thread",
|
|
397
|
-
'clawvault wg thread block <path> --by "reason or dependency"'
|
|
398
|
-
));
|
|
399
|
-
process.exitCode = 1;
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
try {
|
|
403
|
-
const inst = block(vaultPath, normalizedPath, agentName, options.by, options.reason);
|
|
404
|
-
console.log("");
|
|
405
|
-
console.log(chalk.yellow.bold("\u2298 Thread blocked"));
|
|
406
|
-
console.log("");
|
|
407
|
-
console.log(chalk.dim(" Title: ") + chalk.white(inst.fields.title));
|
|
408
|
-
console.log(chalk.dim(" Blocked by: ") + chalk.red(options.by));
|
|
409
|
-
if (options.reason) {
|
|
410
|
-
console.log(chalk.dim(" Reason: ") + chalk.white(options.reason));
|
|
411
|
-
}
|
|
412
|
-
console.log("");
|
|
413
|
-
} catch (err) {
|
|
414
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
415
|
-
console.error(formatError(
|
|
416
|
-
"Failed to block thread",
|
|
417
|
-
message,
|
|
418
|
-
'Ensure the thread exists and is in "active" status'
|
|
419
|
-
));
|
|
420
|
-
process.exitCode = 1;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
async function threadReleaseCommand(vaultPath, threadPath, options) {
|
|
424
|
-
const agentName = getAgentName();
|
|
425
|
-
const normalizedPath = normalizeThreadPath(threadPath);
|
|
426
|
-
try {
|
|
427
|
-
const inst = release(vaultPath, normalizedPath, agentName, options.reason);
|
|
428
|
-
console.log("");
|
|
429
|
-
console.log(chalk.cyan.bold("\u21A9 Thread released"));
|
|
430
|
-
console.log("");
|
|
431
|
-
console.log(chalk.dim(" Title: ") + chalk.white(inst.fields.title));
|
|
432
|
-
console.log(chalk.dim(" Status: ") + chalk.cyan("open"));
|
|
433
|
-
if (options.reason) {
|
|
434
|
-
console.log(chalk.dim(" Reason: ") + chalk.white(options.reason));
|
|
435
|
-
}
|
|
436
|
-
console.log("");
|
|
437
|
-
console.log(chalk.dim("Thread is now available for others to claim."));
|
|
438
|
-
console.log("");
|
|
439
|
-
} catch (err) {
|
|
440
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
441
|
-
console.error(formatError(
|
|
442
|
-
"Failed to release thread",
|
|
443
|
-
message,
|
|
444
|
-
"Ensure you own the thread"
|
|
445
|
-
));
|
|
446
|
-
process.exitCode = 1;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
async function threadDecomposeCommand(vaultPath, threadPath, options) {
|
|
450
|
-
const agentName = getAgentName();
|
|
451
|
-
const normalizedPath = normalizeThreadPath(threadPath);
|
|
452
|
-
if (!options.into || options.into.length === 0) {
|
|
453
|
-
console.error(formatError(
|
|
454
|
-
"Missing --into option",
|
|
455
|
-
"You must specify sub-thread titles",
|
|
456
|
-
'clawvault wg thread decompose <path> --into "sub1" --into "sub2"'
|
|
457
|
-
));
|
|
458
|
-
process.exitCode = 1;
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
try {
|
|
462
|
-
const parent = read(vaultPath, normalizedPath);
|
|
463
|
-
if (!parent) {
|
|
464
|
-
throw new Error(`Thread not found: ${normalizedPath}`);
|
|
465
|
-
}
|
|
466
|
-
const subthreads = options.into.map((title) => ({
|
|
467
|
-
title,
|
|
468
|
-
goal: `Sub-task of: ${parent.fields.title}`
|
|
469
|
-
}));
|
|
470
|
-
const created = decompose(vaultPath, normalizedPath, subthreads, agentName);
|
|
471
|
-
console.log("");
|
|
472
|
-
console.log(chalk.green.bold("\u2713 Thread decomposed"));
|
|
473
|
-
console.log("");
|
|
474
|
-
console.log(chalk.dim(" Parent: ") + chalk.white(parent.fields.title));
|
|
475
|
-
console.log(chalk.dim(" Created sub-threads:"));
|
|
476
|
-
for (const sub of created) {
|
|
477
|
-
console.log(chalk.cyan(` \u2192 ${sub.fields.title}`));
|
|
478
|
-
}
|
|
479
|
-
console.log("");
|
|
480
|
-
} catch (err) {
|
|
481
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
482
|
-
console.error(formatError(
|
|
483
|
-
"Failed to decompose thread",
|
|
484
|
-
message,
|
|
485
|
-
"Ensure the thread exists"
|
|
486
|
-
));
|
|
487
|
-
process.exitCode = 1;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
async function ledgerCommand(vaultPath, options) {
|
|
491
|
-
let entries = readAll(vaultPath);
|
|
492
|
-
if (options.actor) {
|
|
493
|
-
const actorFilter = options.actor === "me" ? getAgentName() : options.actor;
|
|
494
|
-
entries = entries.filter((e) => e.actor === actorFilter);
|
|
495
|
-
}
|
|
496
|
-
if (options.target) {
|
|
497
|
-
entries = entries.filter((e) => e.target.includes(options.target));
|
|
498
|
-
}
|
|
499
|
-
const limit = options.last ?? 20;
|
|
500
|
-
entries = entries.slice(-limit);
|
|
501
|
-
if (options.json) {
|
|
502
|
-
console.log(JSON.stringify(entries, null, 2));
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
if (entries.length === 0) {
|
|
506
|
-
console.log("");
|
|
507
|
-
console.log(chalk.dim("No ledger entries found."));
|
|
508
|
-
console.log("");
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
console.log("");
|
|
512
|
-
console.log(chalk.bold(`Ledger (last ${entries.length} entries)`));
|
|
513
|
-
console.log(chalk.dim("\u2500".repeat(80)));
|
|
514
|
-
for (const entry of entries.reverse()) {
|
|
515
|
-
const opColor = OP_COLORS[entry.op] ?? chalk.white;
|
|
516
|
-
const time = formatRelativeTime(entry.ts);
|
|
517
|
-
const target = truncate(entry.target, 30);
|
|
518
|
-
const actor = entry.actor;
|
|
519
|
-
let line = chalk.dim(time.padEnd(10));
|
|
520
|
-
line += opColor(entry.op.toUpperCase().padEnd(10));
|
|
521
|
-
line += chalk.white(target.padEnd(32));
|
|
522
|
-
line += chalk.cyan(`@${actor}`);
|
|
523
|
-
console.log(line);
|
|
524
|
-
if (entry.data && Object.keys(entry.data).length > 0) {
|
|
525
|
-
const dataStr = JSON.stringify(entry.data);
|
|
526
|
-
console.log(chalk.dim(` ${truncate(dataStr, 68)}`));
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
console.log(chalk.dim("\u2500".repeat(80)));
|
|
530
|
-
console.log("");
|
|
531
|
-
}
|
|
532
|
-
async function defineCommand(vaultPath, typeName, options) {
|
|
533
|
-
const agentName = getAgentName();
|
|
534
|
-
const description = options.description ?? `Custom type: ${typeName}`;
|
|
535
|
-
const fields = {};
|
|
536
|
-
if (options.fields) {
|
|
537
|
-
const fieldPairs = options.fields.split(",");
|
|
538
|
-
for (const pair of fieldPairs) {
|
|
539
|
-
const [name, type] = pair.split(":").map((s) => s.trim());
|
|
540
|
-
if (name && type) {
|
|
541
|
-
fields[name] = { type };
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
try {
|
|
546
|
-
const typeDef = defineType(
|
|
547
|
-
vaultPath,
|
|
548
|
-
typeName,
|
|
549
|
-
description,
|
|
550
|
-
fields,
|
|
551
|
-
agentName,
|
|
552
|
-
options.dir
|
|
553
|
-
);
|
|
554
|
-
console.log("");
|
|
555
|
-
console.log(chalk.green.bold("\u2713 Type defined"));
|
|
556
|
-
console.log("");
|
|
557
|
-
console.log(chalk.dim(" Name: ") + chalk.magenta(typeDef.name));
|
|
558
|
-
console.log(chalk.dim(" Directory: ") + chalk.white(typeDef.directory));
|
|
559
|
-
console.log(chalk.dim(" Fields:"));
|
|
560
|
-
for (const [fieldName, fieldDef] of Object.entries(typeDef.fields)) {
|
|
561
|
-
const required = fieldDef.required ? chalk.red("*") : " ";
|
|
562
|
-
console.log(chalk.dim(` ${required} ${fieldName}: ${fieldDef.type}`));
|
|
563
|
-
}
|
|
564
|
-
console.log("");
|
|
565
|
-
console.log(chalk.dim(`Create instances: ${chalk.cyan(`clawvault wg create ${typeDef.name} "title"`)}`));
|
|
566
|
-
console.log("");
|
|
567
|
-
} catch (err) {
|
|
568
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
569
|
-
console.error(formatError(
|
|
570
|
-
"Failed to define type",
|
|
571
|
-
message,
|
|
572
|
-
"Ensure the type name is unique and not a built-in type"
|
|
573
|
-
));
|
|
574
|
-
process.exitCode = 1;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
async function typesCommand(vaultPath, options) {
|
|
578
|
-
const types = listTypes(vaultPath);
|
|
579
|
-
if (options.json) {
|
|
580
|
-
console.log(JSON.stringify(types, null, 2));
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
console.log("");
|
|
584
|
-
console.log(chalk.bold(`Primitive Types (${types.length})`));
|
|
585
|
-
console.log(chalk.dim("\u2500".repeat(70)));
|
|
586
|
-
for (const typeDef of types) {
|
|
587
|
-
const builtInBadge = typeDef.builtIn ? chalk.cyan(" [built-in]") : chalk.magenta(" [custom]");
|
|
588
|
-
console.log("");
|
|
589
|
-
console.log(chalk.white.bold(typeDef.name) + builtInBadge);
|
|
590
|
-
console.log(chalk.dim(` ${typeDef.description}`));
|
|
591
|
-
console.log(chalk.dim(` Directory: ${typeDef.directory}/`));
|
|
592
|
-
console.log(chalk.dim(" Fields:"));
|
|
593
|
-
const fieldEntries = Object.entries(typeDef.fields);
|
|
594
|
-
for (const [fieldName, fieldDef] of fieldEntries) {
|
|
595
|
-
const required = fieldDef.required ? chalk.red("*") : " ";
|
|
596
|
-
const defaultVal = fieldDef.default !== void 0 ? chalk.dim(` = ${JSON.stringify(fieldDef.default)}`) : "";
|
|
597
|
-
const desc = fieldDef.description ? chalk.dim(` \u2014 ${fieldDef.description}`) : "";
|
|
598
|
-
console.log(` ${required} ${chalk.cyan(fieldName)}: ${fieldDef.type}${defaultVal}${desc}`);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
console.log("");
|
|
602
|
-
console.log(chalk.dim("\u2500".repeat(70)));
|
|
603
|
-
console.log("");
|
|
604
|
-
}
|
|
605
|
-
async function createCommand(vaultPath, typeName, title, options) {
|
|
606
|
-
const agentName = getAgentName();
|
|
607
|
-
const body = options.body ?? "";
|
|
608
|
-
const fields = { title };
|
|
609
|
-
const knownOptions = /* @__PURE__ */ new Set(["body", "vault"]);
|
|
610
|
-
for (const [key, value] of Object.entries(options)) {
|
|
611
|
-
if (!knownOptions.has(key) && value !== void 0) {
|
|
612
|
-
fields[key] = value;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
try {
|
|
616
|
-
const inst = create(vaultPath, typeName, fields, body, agentName);
|
|
617
|
-
console.log("");
|
|
618
|
-
console.log(chalk.green.bold(`\u2713 ${typeName} created`));
|
|
619
|
-
console.log("");
|
|
620
|
-
console.log(chalk.dim(" Path: ") + chalk.white(inst.path));
|
|
621
|
-
console.log(chalk.dim(" Title: ") + chalk.white(inst.fields.title));
|
|
622
|
-
console.log("");
|
|
623
|
-
} catch (err) {
|
|
624
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
625
|
-
console.error(formatError(
|
|
626
|
-
`Failed to create ${typeName}`,
|
|
627
|
-
message,
|
|
628
|
-
`Ensure the type "${typeName}" exists. Run: clawvault wg types`
|
|
629
|
-
));
|
|
630
|
-
process.exitCode = 1;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
async function boardCommand(vaultPath, options) {
|
|
634
|
-
const threads = list(vaultPath, "thread");
|
|
635
|
-
const termWidth = options.width ?? process.stdout.columns ?? 120;
|
|
636
|
-
const columns = {
|
|
637
|
-
open: [],
|
|
638
|
-
active: [],
|
|
639
|
-
blocked: [],
|
|
640
|
-
done: [],
|
|
641
|
-
cancelled: []
|
|
642
|
-
};
|
|
643
|
-
for (const t of threads) {
|
|
644
|
-
const status = t.fields.status;
|
|
645
|
-
if (columns[status]) {
|
|
646
|
-
columns[status].push(t);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
for (const status of Object.keys(columns)) {
|
|
650
|
-
columns[status] = sortByPriority(columns[status]);
|
|
651
|
-
}
|
|
652
|
-
const visibleStatuses = ["open", "active", "blocked", "done"];
|
|
653
|
-
const colWidth = Math.floor((termWidth - visibleStatuses.length - 1) / visibleStatuses.length);
|
|
654
|
-
const cardWidth = colWidth - 4;
|
|
655
|
-
console.log("");
|
|
656
|
-
console.log(chalk.bold.cyan("\u2554" + "\u2550".repeat(termWidth - 2) + "\u2557"));
|
|
657
|
-
console.log(chalk.bold.cyan("\u2551") + chalk.bold(" WORKGRAPH BOARD").padEnd(termWidth - 2) + chalk.bold.cyan("\u2551"));
|
|
658
|
-
console.log(chalk.bold.cyan("\u255A" + "\u2550".repeat(termWidth - 2) + "\u255D"));
|
|
659
|
-
console.log("");
|
|
660
|
-
let headerLine = "";
|
|
661
|
-
for (const status of visibleStatuses) {
|
|
662
|
-
const cfg = STATUS_CONFIG[status];
|
|
663
|
-
const header = `${cfg.symbol} ${cfg.label} (${columns[status].length})`;
|
|
664
|
-
const padded = header.padEnd(colWidth);
|
|
665
|
-
headerLine += cfg.color(padded);
|
|
666
|
-
}
|
|
667
|
-
console.log(headerLine);
|
|
668
|
-
console.log(chalk.dim("\u2500".repeat(termWidth)));
|
|
669
|
-
const maxRows = Math.max(...visibleStatuses.map((s) => columns[s].length), 1);
|
|
670
|
-
for (let row = 0; row < Math.min(maxRows, 15); row++) {
|
|
671
|
-
let line = "";
|
|
672
|
-
for (const status of visibleStatuses) {
|
|
673
|
-
const t = columns[status][row];
|
|
674
|
-
if (t) {
|
|
675
|
-
const card = formatBoardCard(t, cardWidth);
|
|
676
|
-
line += card.padEnd(colWidth);
|
|
677
|
-
} else {
|
|
678
|
-
line += " ".repeat(colWidth);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
console.log(line);
|
|
682
|
-
}
|
|
683
|
-
if (maxRows > 15) {
|
|
684
|
-
console.log(chalk.dim(`... and ${maxRows - 15} more rows`));
|
|
685
|
-
}
|
|
686
|
-
console.log("");
|
|
687
|
-
console.log(chalk.dim("\u2500".repeat(termWidth)));
|
|
688
|
-
const legendParts = Object.entries(PRIORITY_CONFIG).map(
|
|
689
|
-
([, cfg]) => `${cfg.symbol} ${cfg.label}`
|
|
690
|
-
);
|
|
691
|
-
console.log(chalk.dim("Priority: ") + legendParts.join(chalk.dim(" \xB7 ")));
|
|
692
|
-
console.log("");
|
|
693
|
-
}
|
|
694
|
-
function formatBoardCard(t, width) {
|
|
695
|
-
const priority = t.fields.priority ?? "medium";
|
|
696
|
-
const title = truncate(String(t.fields.title ?? t.path), width - 4);
|
|
697
|
-
const owner = t.fields.owner;
|
|
698
|
-
const priorityCfg = PRIORITY_CONFIG[priority] ?? PRIORITY_CONFIG.medium;
|
|
699
|
-
let card = `${priorityCfg.symbol} ${title}`;
|
|
700
|
-
if (owner) {
|
|
701
|
-
card += chalk.dim(` @${truncate(owner, 8)}`);
|
|
702
|
-
}
|
|
703
|
-
return card;
|
|
704
|
-
}
|
|
705
|
-
function registerWorkgraphCommands(program) {
|
|
706
|
-
const wg = program.command("wg").description("Workgraph \u2014 multi-agent coordination primitives");
|
|
707
|
-
wg.command("status").description("Agent morning briefing with active work, available tasks, and team status").option("-v, --vault <path>", "Vault path").action(async (options) => {
|
|
708
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
709
|
-
await statusCommand(vaultPath);
|
|
710
|
-
});
|
|
711
|
-
const threadCmd = wg.command("thread").description("Thread lifecycle operations");
|
|
712
|
-
threadCmd.command("create <title>").description("Create a new thread").option("--goal <goal>", "What success looks like").option("--priority <priority>", "urgent | high | medium | low", "medium").option("--deps <deps>", "Comma-separated dependency paths").option("--tags <tags>", "Comma-separated tags").option("-v, --vault <path>", "Vault path").action(async (title, options) => {
|
|
713
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
714
|
-
await threadCreateCommand(vaultPath, title, options);
|
|
715
|
-
});
|
|
716
|
-
threadCmd.command("list").description("List threads with optional filters").option("--status <status>", "Filter by status: open | active | blocked | done | cancelled").option("--owner <owner>", 'Filter by owner (use "me" for current agent)').option("--json", "Output as JSON").option("-v, --vault <path>", "Vault path").action(async (options) => {
|
|
717
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
718
|
-
await threadListCommand(vaultPath, options);
|
|
719
|
-
});
|
|
720
|
-
threadCmd.command("claim <path>").description("Claim a thread and show work brief").option("-v, --vault <path>", "Vault path").action(async (threadPath, options) => {
|
|
721
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
722
|
-
await threadClaimCommand(vaultPath, threadPath);
|
|
723
|
-
});
|
|
724
|
-
threadCmd.command("done <path>").description("Mark thread as complete").option("--output <output>", "Completion summary or output").option("-v, --vault <path>", "Vault path").action(async (threadPath, options) => {
|
|
725
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
726
|
-
await threadDoneCommand(vaultPath, threadPath, options);
|
|
727
|
-
});
|
|
728
|
-
threadCmd.command("block <path>").description("Block thread on a dependency").requiredOption("--by <blocker>", "What is blocking this thread").option("--reason <reason>", "Additional context").option("-v, --vault <path>", "Vault path").action(async (threadPath, options) => {
|
|
729
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
730
|
-
await threadBlockCommand(vaultPath, threadPath, options);
|
|
731
|
-
});
|
|
732
|
-
threadCmd.command("release <path>").description("Release thread back to the pool").option("--reason <reason>", "Why releasing").option("-v, --vault <path>", "Vault path").action(async (threadPath, options) => {
|
|
733
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
734
|
-
await threadReleaseCommand(vaultPath, threadPath, options);
|
|
735
|
-
});
|
|
736
|
-
threadCmd.command("decompose <path>").description("Break thread into sub-threads").option("--into <titles...>", "Sub-thread titles").option("-v, --vault <path>", "Vault path").action(async (threadPath, options) => {
|
|
737
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
738
|
-
await threadDecomposeCommand(vaultPath, threadPath, { into: options.into ?? [] });
|
|
739
|
-
});
|
|
740
|
-
wg.command("ledger").description("View coordination history").option("--last <n>", "Number of entries to show", "20").option("--actor <actor>", 'Filter by actor (use "me" for current agent)').option("--target <target>", "Filter by target path substring").option("--json", "Output as JSON").option("-v, --vault <path>", "Vault path").action(async (options) => {
|
|
741
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
742
|
-
await ledgerCommand(vaultPath, {
|
|
743
|
-
last: options.last ? parseInt(options.last, 10) : 20,
|
|
744
|
-
actor: options.actor,
|
|
745
|
-
target: options.target,
|
|
746
|
-
json: options.json
|
|
747
|
-
});
|
|
748
|
-
});
|
|
749
|
-
wg.command("define <type>").description("Define a new primitive type").option("--fields <fields>", "Comma-separated field definitions (name:type)").option("--dir <directory>", "Custom directory for instances").option("--description <desc>", "Type description").option("-v, --vault <path>", "Vault path").action(async (typeName, options) => {
|
|
750
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
751
|
-
await defineCommand(vaultPath, typeName, options);
|
|
752
|
-
});
|
|
753
|
-
wg.command("types").description("List all primitive types with their fields").option("--json", "Output as JSON").option("-v, --vault <path>", "Vault path").action(async (options) => {
|
|
754
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
755
|
-
await typesCommand(vaultPath, options);
|
|
756
|
-
});
|
|
757
|
-
wg.command("create <type> <title>").description("Create any primitive instance").option("--body <body>", "Markdown body content").option("-v, --vault <path>", "Vault path").allowUnknownOption(true).action(async (typeName, title, options) => {
|
|
758
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
759
|
-
await createCommand(vaultPath, typeName, title, options);
|
|
760
|
-
});
|
|
761
|
-
wg.command("board").description("Terminal kanban board view").option("--width <width>", "Terminal width override").option("-v, --vault <path>", "Vault path").action(async (options) => {
|
|
762
|
-
const vaultPath = resolveVaultPath(options.vault);
|
|
763
|
-
await boardCommand(vaultPath, {
|
|
764
|
-
width: options.width ? parseInt(options.width, 10) : void 0
|
|
765
|
-
});
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
export {
|
|
770
|
-
statusCommand,
|
|
771
|
-
threadCreateCommand,
|
|
772
|
-
threadListCommand,
|
|
773
|
-
threadClaimCommand,
|
|
774
|
-
threadDoneCommand,
|
|
775
|
-
threadBlockCommand,
|
|
776
|
-
threadReleaseCommand,
|
|
777
|
-
threadDecomposeCommand,
|
|
778
|
-
ledgerCommand,
|
|
779
|
-
defineCommand,
|
|
780
|
-
typesCommand,
|
|
781
|
-
createCommand,
|
|
782
|
-
boardCommand,
|
|
783
|
-
registerWorkgraphCommands
|
|
784
|
-
};
|