@devflow-tools/cli 0.15.0 → 0.16.0
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/commands/benchmark-cmd.d.ts +17 -4
- package/dist/commands/benchmark-cmd.d.ts.map +1 -1
- package/dist/commands/benchmark-cmd.js +71 -14
- package/dist/commands/benchmark-cmd.js.map +1 -1
- package/dist/commands/connect.d.ts +0 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +4 -10
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/context.d.ts +2 -2
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +5 -3
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/db.d.ts +25 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +258 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/docs.d.ts +20 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +37 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/doctor.d.ts +59 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +3912 -50
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/index-cmd.d.ts +1 -0
- package/dist/commands/index-cmd.d.ts.map +1 -1
- package/dist/commands/index-cmd.js +7 -0
- package/dist/commands/index-cmd.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/knowledge.d.ts +2 -1
- package/dist/commands/knowledge.d.ts.map +1 -1
- package/dist/commands/knowledge.js +11 -8
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/memory.d.ts +17 -1
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +22 -3
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/plugin-loader.d.ts +1 -1
- package/dist/commands/plugin-loader.d.ts.map +1 -1
- package/dist/commands/plugin-loader.js +1 -1
- package/dist/commands/plugin-loader.js.map +1 -1
- package/dist/commands/plugin-memory-hints.d.ts +23 -0
- package/dist/commands/plugin-memory-hints.d.ts.map +1 -0
- package/dist/commands/plugin-memory-hints.js +58 -0
- package/dist/commands/plugin-memory-hints.js.map +1 -0
- package/dist/commands/reset.d.ts +32 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +316 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +2 -1
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +33 -6
- package/dist/commands/status.js.map +1 -1
- package/dist/index.js +225 -96
- package/dist/index.js.map +1 -1
- package/dist/lib/plugin-setup.d.ts.map +1 -1
- package/dist/lib/plugin-setup.js +37 -2
- package/dist/lib/plugin-setup.js.map +1 -1
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +34 -36
- package/dist/plugin-files/dist/hooks/enforcer-summary.js +6 -0
- package/dist/plugin-files/dist/hooks/hook-client.js +6 -0
- package/dist/plugin-files/dist/hooks/hook-daemon.js +14 -0
- package/dist/plugin-files/dist/hooks/post-tool-use-failure.js +2 -0
- package/dist/plugin-files/dist/hooks/post-tool-use.js +3 -0
- package/dist/plugin-files/dist/hooks/pre-compact.js +3 -0
- package/dist/plugin-files/dist/hooks/pre-tool-use.js +2 -0
- package/dist/plugin-files/dist/hooks/server-bootstrap.js +109 -0
- package/dist/plugin-files/dist/hooks/session-end.js +2 -0
- package/dist/plugin-files/dist/hooks/stop.js +2 -0
- package/dist/plugin-files/dist/hooks/user-prompt-submit.js +2 -0
- package/dist/plugin-files/dist/skills/devflow:graphql/SKILL.md +2 -4
- package/dist/plugin-files/dist/skills/devflow:nest/SKILL.md +4 -4
- package/dist/plugin-files/dist/skills/devflow:nextjs/SKILL.md +4 -4
- package/dist/plugin-files/dist/skills/devflow:react/SKILL.md +6 -8
- package/dist/plugin-files/dist/skills/devflow:tailwind/SKILL.md +4 -2
- package/dist/plugin-files/dist/skills/devflow:vue/SKILL.md +2 -4
- package/dist/plugin-files/hooks/post-tool-use +2 -2
- package/dist/plugin-files/hooks/post-tool-use-failure +2 -2
- package/dist/plugin-files/hooks/pre-compact +2 -2
- package/dist/plugin-files/hooks/pre-tool-use +4 -4
- package/dist/plugin-files/hooks/session-end +2 -2
- package/dist/plugin-files/hooks/session-start +160 -77
- package/dist/plugin-files/hooks/stop +2 -8
- package/dist/plugin-files/hooks/user-prompt-submit +2 -2
- package/dist/plugin-files/package.json +13 -2
- package/package.json +27 -27
- package/dist/commands/dashboard.d.ts +0 -3
- package/dist/commands/dashboard.d.ts.map +0 -1
- package/dist/commands/dashboard.js +0 -10
- package/dist/commands/dashboard.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4,31 +4,6 @@ import chalk from "chalk";
|
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { detectMode } from "./mode.js";
|
|
7
|
-
import { initProject } from "./commands/init.js";
|
|
8
|
-
import { guidePluginInstallation, installPluginsFromList } from "./commands/plugin-guide.js";
|
|
9
|
-
import { connectAgent, getAvailableAgents } from "./commands/connect.js";
|
|
10
|
-
import { getIndexStatus } from "./commands/index-cmd.js";
|
|
11
|
-
import { getGraph } from "./commands/graph.js";
|
|
12
|
-
import { getContext, getTaskContext } from "./commands/context.js";
|
|
13
|
-
import { listWorkflows, runWorkflow, getWorkflowStatus, getWorkflowRuns, } from "./commands/workflow.js";
|
|
14
|
-
import { showMemory, setMemory, reviewCandidates } from "./commands/memory.js";
|
|
15
|
-
import { searchKnowledge } from "./commands/knowledge.js";
|
|
16
|
-
import { listSkills, searchSkills, installSkill, uninstallSkill } from "./commands/skill.js";
|
|
17
|
-
import { runDoctor, runDoctorAudit, runDoctorAuditFix, runDoctorViolations, runDoctorReceipts } from "./commands/doctor.js";
|
|
18
|
-
import { generateToken } from "./commands/session.js";
|
|
19
|
-
import { runBenchmark } from "./commands/benchmark-cmd.js";
|
|
20
|
-
import { runReview } from "./commands/review.js";
|
|
21
|
-
import { startServer, stopServer, serverStatus } from "./commands/server.js";
|
|
22
|
-
import { startAll } from "./commands/start.js";
|
|
23
|
-
import { stopAll } from "./commands/stop.js";
|
|
24
|
-
import { showStatus } from "./commands/status.js";
|
|
25
|
-
import { setupCommand } from "./commands/setup.js";
|
|
26
|
-
import { pluginListCommand } from "./commands/plugin/list.js";
|
|
27
|
-
import { pluginSearchCommand } from "./commands/plugin/search.js";
|
|
28
|
-
import { pluginInstallCommand } from "./commands/plugin/install.js";
|
|
29
|
-
import { pluginUninstallCommand } from "./commands/plugin/uninstall.js";
|
|
30
|
-
import { dashboardCommand } from "./commands/dashboard.js";
|
|
31
|
-
import { KnowledgeEngine } from "@devflow-tools/knowledge-engine";
|
|
32
7
|
import { createRequire } from "module";
|
|
33
8
|
const require = createRequire(import.meta.url);
|
|
34
9
|
// Read version from package.json at runtime
|
|
@@ -61,6 +36,7 @@ program
|
|
|
61
36
|
.option("--report", "Output onboarding markdown report to stdout")
|
|
62
37
|
.option("--json", "Output onboarding pack as JSON to stdout")
|
|
63
38
|
.option("--plugins <names>", "Comma-separated list of plugins to install (non-interactive)")
|
|
39
|
+
.option("--with-plugin <names>", "Interactively review optional memory hints from installed plugins")
|
|
64
40
|
.option("--no-plugins", "Skip plugin installation guide")
|
|
65
41
|
.action(async (opts) => {
|
|
66
42
|
const root = process.cwd();
|
|
@@ -78,12 +54,12 @@ program
|
|
|
78
54
|
}
|
|
79
55
|
const mode = detectMode(root);
|
|
80
56
|
console.error(chalk.blue(`DevFlow init — mode: ${mode}`));
|
|
57
|
+
const { initProject, renderInitReport } = await import("./commands/init.js");
|
|
81
58
|
const result = await initProject(root, { force: opts.force });
|
|
82
59
|
if (opts.json && result.onboardingPack) {
|
|
83
60
|
console.log(JSON.stringify(result.onboardingPack, null, 2));
|
|
84
61
|
}
|
|
85
62
|
else if (opts.report && result.onboardingPack) {
|
|
86
|
-
const { renderInitReport } = await import("./commands/init.js");
|
|
87
63
|
console.log(renderInitReport(result.onboardingPack));
|
|
88
64
|
}
|
|
89
65
|
else {
|
|
@@ -116,27 +92,66 @@ program
|
|
|
116
92
|
if (result.pluginDeployed && result.pluginEnabled && result.mcpConfigured) {
|
|
117
93
|
console.log(chalk.green("\nDevFlow is ready! Run `claude` to start."));
|
|
118
94
|
}
|
|
95
|
+
if (typeof opts.withPlugin === "string") {
|
|
96
|
+
const { reviewPluginMemoryHints } = await import("./commands/plugin-memory-hints.js");
|
|
97
|
+
const hints = await reviewPluginMemoryHints(root, opts.withPlugin);
|
|
98
|
+
console.log(chalk.dim(`Plugin memory hints: ${hints.selected}/${hints.available} selected`));
|
|
99
|
+
}
|
|
119
100
|
// ── Plugin installation guide ──
|
|
120
101
|
if (typeof opts.plugins === "string") {
|
|
121
102
|
// Non-interactive: --plugins <names>
|
|
103
|
+
const { installPluginsFromList } = await import("./commands/plugin-guide.js");
|
|
122
104
|
await installPluginsFromList(opts.plugins);
|
|
123
105
|
}
|
|
124
106
|
else if (opts.plugins !== false) {
|
|
125
107
|
// Interactive: no --plugins flag and not --no-plugins
|
|
108
|
+
const { guidePluginInstallation } = await import("./commands/plugin-guide.js");
|
|
126
109
|
await guidePluginInstallation(root);
|
|
127
110
|
}
|
|
128
111
|
}
|
|
129
112
|
});
|
|
113
|
+
// --- reset ---
|
|
114
|
+
program
|
|
115
|
+
.command("reset")
|
|
116
|
+
.description("Reset generated DevFlow project data")
|
|
117
|
+
.requiredOption("--scope <scope>", "memory | knowledge | codegraph | all")
|
|
118
|
+
.option("--backup-to <dir>", "Back up selected data before resetting")
|
|
119
|
+
.option("--force", "Reset without creating a backup")
|
|
120
|
+
.option("--project <path>", "Project directory", process.cwd())
|
|
121
|
+
.action(async (opts) => {
|
|
122
|
+
const { executeResetCommand } = await import("./commands/reset.js");
|
|
123
|
+
const succeeded = executeResetCommand(opts, {}, {
|
|
124
|
+
log: (message) => console.log(message),
|
|
125
|
+
error: (message) => console.error(chalk.red(message)),
|
|
126
|
+
});
|
|
127
|
+
if (!succeeded)
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
});
|
|
130
|
+
// --- db ---
|
|
131
|
+
const dbCmd = program
|
|
132
|
+
.command("db")
|
|
133
|
+
.description("Manage DevFlow databases");
|
|
134
|
+
dbCmd
|
|
135
|
+
.command("consolidate")
|
|
136
|
+
.description("Merge legacy project databases into the global database")
|
|
137
|
+
.option("--project <path>", "Project directory", process.cwd())
|
|
138
|
+
.option("--dry-run", "Report rows and conflicts without writing")
|
|
139
|
+
.action(async (opts) => {
|
|
140
|
+
const { consolidateDatabases, formatConsolidateResult } = await import("./commands/db.js");
|
|
141
|
+
const result = consolidateDatabases(opts);
|
|
142
|
+
for (const line of formatConsolidateResult(result))
|
|
143
|
+
console.log(line);
|
|
144
|
+
});
|
|
130
145
|
// --- connect ---
|
|
131
146
|
program
|
|
132
147
|
.command("connect [agent]")
|
|
133
|
-
.description("Configure
|
|
148
|
+
.description("Configure the Claude Code MCP connection")
|
|
134
149
|
.option("--command <cmd>", "MCP server command", "devflow-mcp")
|
|
135
|
-
.option("--sse <url>", "SSE server URL (instead of stdio)")
|
|
136
150
|
.action(async (agent, opts) => {
|
|
137
151
|
const root = process.cwd();
|
|
138
152
|
const mode = detectMode(root);
|
|
139
153
|
console.log(chalk.blue(`DevFlow connect — mode: ${mode}`));
|
|
154
|
+
const { connectAgent, getAvailableAgents } = await import("./commands/connect.js");
|
|
140
155
|
if (agent) {
|
|
141
156
|
const available = getAvailableAgents();
|
|
142
157
|
if (!available.includes(agent)) {
|
|
@@ -149,7 +164,6 @@ program
|
|
|
149
164
|
const results = await connectAgent({
|
|
150
165
|
agent: agent,
|
|
151
166
|
command: opts.command,
|
|
152
|
-
sseUrl: opts.sse,
|
|
153
167
|
});
|
|
154
168
|
for (const r of results) {
|
|
155
169
|
console.log(chalk.green(`✓ ${r}`));
|
|
@@ -164,9 +178,13 @@ program
|
|
|
164
178
|
program
|
|
165
179
|
.command("index")
|
|
166
180
|
.description("Show index status")
|
|
181
|
+
.option("--backfill-vectors", "Reconcile the index and wait for symbol vectors")
|
|
167
182
|
.option("--watch", "Start file watcher for hot updates (stub)")
|
|
168
183
|
.action(async (opts) => {
|
|
169
|
-
const
|
|
184
|
+
const { getIndexStatus, refreshIndex } = await import("./commands/index-cmd.js");
|
|
185
|
+
const status = opts.backfillVectors
|
|
186
|
+
? await refreshIndex(program.opts().local)
|
|
187
|
+
: await getIndexStatus(program.opts().local);
|
|
170
188
|
console.log(chalk.blue("Index Status"));
|
|
171
189
|
console.log(` Files: ${status.totalFiles}`);
|
|
172
190
|
console.log(` Symbols: ${status.totalSymbols}`);
|
|
@@ -181,6 +199,7 @@ program
|
|
|
181
199
|
.description("Show dependency graph")
|
|
182
200
|
.option("--depth <n>", "Expansion depth", "2")
|
|
183
201
|
.action(async (target, opts) => {
|
|
202
|
+
const { getGraph } = await import("./commands/graph.js");
|
|
184
203
|
const graph = await getGraph({ target, depth: parseInt(opts.depth, 10), skipServer: program.opts().local });
|
|
185
204
|
console.log(chalk.blue("Dependency Graph"));
|
|
186
205
|
console.log(` Nodes: ${graph.nodes.length}`);
|
|
@@ -196,6 +215,7 @@ program
|
|
|
196
215
|
.option("--why", "Show reasoning for file selection")
|
|
197
216
|
.action(async (query, opts) => {
|
|
198
217
|
if (opts.task) {
|
|
218
|
+
const { getTaskContext } = await import("./commands/context.js");
|
|
199
219
|
const result = await getTaskContext({
|
|
200
220
|
query,
|
|
201
221
|
mode: opts.mode,
|
|
@@ -211,6 +231,7 @@ program
|
|
|
211
231
|
}, null, 2));
|
|
212
232
|
}
|
|
213
233
|
else {
|
|
234
|
+
const { getContext } = await import("./commands/context.js");
|
|
214
235
|
const result = await getContext({
|
|
215
236
|
query,
|
|
216
237
|
mode: opts.mode,
|
|
@@ -231,6 +252,7 @@ workflowCmd
|
|
|
231
252
|
.command("list")
|
|
232
253
|
.description("List available workflows")
|
|
233
254
|
.action(async () => {
|
|
255
|
+
const { listWorkflows } = await import("./commands/workflow.js");
|
|
234
256
|
const workflows = await listWorkflows(program.opts().local);
|
|
235
257
|
if (workflows.length === 0) {
|
|
236
258
|
console.log(chalk.dim("No workflows registered."));
|
|
@@ -244,6 +266,7 @@ workflowCmd
|
|
|
244
266
|
.command("run <type> [input]")
|
|
245
267
|
.description("Run a workflow")
|
|
246
268
|
.action(async (type, input) => {
|
|
269
|
+
const { runWorkflow } = await import("./commands/workflow.js");
|
|
247
270
|
const result = await runWorkflow(type, { input: input ?? "" }, program.opts().local);
|
|
248
271
|
console.log(`Run: ${result.runId}`);
|
|
249
272
|
console.log(`Status: ${result.status}`);
|
|
@@ -253,6 +276,7 @@ workflowCmd
|
|
|
253
276
|
.command("status")
|
|
254
277
|
.description("Show running workflows")
|
|
255
278
|
.action(async () => {
|
|
279
|
+
const { getWorkflowStatus } = await import("./commands/workflow.js");
|
|
256
280
|
const runs = await getWorkflowStatus(program.opts().local);
|
|
257
281
|
console.log(`${runs.length} run(s)`);
|
|
258
282
|
for (const r of runs) {
|
|
@@ -263,6 +287,7 @@ workflowCmd
|
|
|
263
287
|
.command("runs")
|
|
264
288
|
.description("Show workflow history")
|
|
265
289
|
.action(async () => {
|
|
290
|
+
const { getWorkflowRuns } = await import("./commands/workflow.js");
|
|
266
291
|
const runs = await getWorkflowRuns(program.opts().local);
|
|
267
292
|
if (runs.length === 0) {
|
|
268
293
|
console.log(chalk.dim("No runs yet."));
|
|
@@ -280,14 +305,40 @@ const memoryCmd = program
|
|
|
280
305
|
memoryCmd
|
|
281
306
|
.command("show")
|
|
282
307
|
.description("Show current project memory")
|
|
283
|
-
.
|
|
284
|
-
|
|
308
|
+
.option("--source <source>", "Filter memories by source")
|
|
309
|
+
.action(async (options) => {
|
|
310
|
+
const { showMemory } = await import("./commands/memory.js");
|
|
311
|
+
const mem = await showMemory(program.opts().local, options.source);
|
|
285
312
|
console.log(JSON.stringify(mem, null, 2));
|
|
286
313
|
});
|
|
314
|
+
memoryCmd.command("list").description("List project memories")
|
|
315
|
+
.option("--source <source>", "Filter memories by source")
|
|
316
|
+
.action(async (options) => {
|
|
317
|
+
const { showMemory } = await import("./commands/memory.js");
|
|
318
|
+
console.log(JSON.stringify(await showMemory(program.opts().local, options.source), null, 2));
|
|
319
|
+
});
|
|
320
|
+
memoryCmd
|
|
321
|
+
.command("query [query]")
|
|
322
|
+
.description("Retrieve ranked project memory with a token budget")
|
|
323
|
+
.option("--purpose <purpose>", "Retrieval purpose", "task_context")
|
|
324
|
+
.option("--budget-tokens <count>", "Maximum response tokens", "2000")
|
|
325
|
+
.option("--scope <scope>", "Memory scope to include (repeatable)", (value, previous) => [...previous, value], [])
|
|
326
|
+
.action(async (query, options) => {
|
|
327
|
+
const { queryMemory } = await import("./commands/memory.js");
|
|
328
|
+
const result = await queryMemory({
|
|
329
|
+
query,
|
|
330
|
+
purpose: options.purpose,
|
|
331
|
+
budgetTokens: Number.parseInt(options.budgetTokens, 10),
|
|
332
|
+
scopes: options.scope.length > 0 ? options.scope : undefined,
|
|
333
|
+
skipServer: program.opts().local,
|
|
334
|
+
});
|
|
335
|
+
console.log(JSON.stringify(result, null, 2));
|
|
336
|
+
});
|
|
287
337
|
memoryCmd
|
|
288
338
|
.command("set <key> <value>")
|
|
289
339
|
.description("Set a memory key")
|
|
290
340
|
.action(async (key, value) => {
|
|
341
|
+
const { setMemory } = await import("./commands/memory.js");
|
|
291
342
|
await setMemory(key, value, program.opts().local);
|
|
292
343
|
console.log(chalk.green(`Memory set: ${key} = ${value}`));
|
|
293
344
|
});
|
|
@@ -295,28 +346,54 @@ memoryCmd
|
|
|
295
346
|
.command("review")
|
|
296
347
|
.description("Review memory candidates")
|
|
297
348
|
.action(async () => {
|
|
349
|
+
const { reviewCandidates } = await import("./commands/memory.js");
|
|
298
350
|
const candidates = await reviewCandidates(program.opts().local);
|
|
299
351
|
console.log(JSON.stringify(candidates, null, 2));
|
|
300
352
|
});
|
|
353
|
+
memoryCmd
|
|
354
|
+
.command("backfill-obs-vectors")
|
|
355
|
+
.description("Backfill missing observation vectors")
|
|
356
|
+
.option("--batch-size <count>", "Embedding batch size", "32")
|
|
357
|
+
.action(async (options) => {
|
|
358
|
+
const { backfillObservationVectors } = await import("./commands/memory.js");
|
|
359
|
+
const result = await backfillObservationVectors({
|
|
360
|
+
batchSize: Number.parseInt(options.batchSize, 10),
|
|
361
|
+
onProgress: ({ processed, remaining }) => {
|
|
362
|
+
console.log(` vectors: ${processed} processed, ${remaining} remaining`);
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
console.log(chalk.green(`Observation vectors ready: ${result.processed} added, ${result.remaining} remaining`));
|
|
366
|
+
});
|
|
301
367
|
// --- knowledge ---
|
|
302
368
|
const knowledgeCmd = program
|
|
303
369
|
.command("knowledge <query>")
|
|
304
370
|
.description("Search knowledge base")
|
|
305
371
|
.action(async (query) => {
|
|
306
|
-
const
|
|
372
|
+
const { queryKnowledge } = await import("./commands/knowledge.js");
|
|
373
|
+
const result = await queryKnowledge(query, undefined, undefined, program.opts().local);
|
|
374
|
+
const results = result.results;
|
|
307
375
|
console.log(chalk.blue(`Knowledge: "${query}"`));
|
|
308
376
|
console.log(` Results: ${results.length}`);
|
|
309
377
|
for (const r of results.slice(0, 5)) {
|
|
310
378
|
console.log(` — ${r.title}`);
|
|
311
379
|
}
|
|
312
380
|
});
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
.
|
|
381
|
+
const docsCmd = program
|
|
382
|
+
.command("docs")
|
|
383
|
+
.description("Documentation index management");
|
|
384
|
+
docsCmd
|
|
385
|
+
.command("sync [plugin-name]")
|
|
316
386
|
.description("Sync documentation for plugins")
|
|
317
387
|
.action(async (pluginName) => {
|
|
318
388
|
console.log(chalk.blue(`◉ Syncing docs${pluginName ? ` for ${pluginName} plugin` : ""}`));
|
|
319
|
-
const
|
|
389
|
+
const [{ KnowledgeEngine }, { EmbeddingProvider }] = await Promise.all([
|
|
390
|
+
import("@devflow-tools/knowledge-engine"),
|
|
391
|
+
import("@devflow-tools/memory-engine"),
|
|
392
|
+
]);
|
|
393
|
+
const engine = new KnowledgeEngine({
|
|
394
|
+
projectRoot: process.cwd(),
|
|
395
|
+
embedder: new EmbeddingProvider(),
|
|
396
|
+
});
|
|
320
397
|
if (pluginName) {
|
|
321
398
|
const results = await engine.syncDocs(pluginName);
|
|
322
399
|
for (const r of results) {
|
|
@@ -345,6 +422,43 @@ program
|
|
|
345
422
|
console.log(chalk.green("\n All docs synced."));
|
|
346
423
|
}
|
|
347
424
|
});
|
|
425
|
+
docsCmd
|
|
426
|
+
.command("backfill-vectors")
|
|
427
|
+
.description("Backfill missing knowledge chunk vectors")
|
|
428
|
+
.option("--source <name>", "Only backfill one knowledge source")
|
|
429
|
+
.option("--batch-size <count>", "Embedding batch size", "32")
|
|
430
|
+
.action(async (options) => {
|
|
431
|
+
const { backfillKnowledgeVectors } = await import("./commands/docs.js");
|
|
432
|
+
const result = await backfillKnowledgeVectors({
|
|
433
|
+
source: options.source,
|
|
434
|
+
batchSize: Number.parseInt(options.batchSize, 10),
|
|
435
|
+
onProgress: ({ processed, remaining }) => {
|
|
436
|
+
console.log(` vectors: ${processed} processed, ${remaining} remaining`);
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
console.log(chalk.green(`Knowledge vectors ready: ${result.processed} added, ${result.remaining} remaining`));
|
|
440
|
+
});
|
|
441
|
+
docsCmd
|
|
442
|
+
.command("resync [plugin-name]")
|
|
443
|
+
.description("Rebuild documentation chunks before vector backfill")
|
|
444
|
+
.requiredOption("--with-headings", "Use heading-aware 500-3000 character chunks")
|
|
445
|
+
.action(async (pluginName, options) => {
|
|
446
|
+
const { resyncKnowledgeDocs } = await import("./commands/docs.js");
|
|
447
|
+
console.log(chalk.blue(`Resyncing docs${pluginName ? ` for ${pluginName}` : ""} with headings`));
|
|
448
|
+
const results = await resyncKnowledgeDocs({
|
|
449
|
+
source: pluginName,
|
|
450
|
+
withHeadings: options.withHeadings,
|
|
451
|
+
});
|
|
452
|
+
for (const result of results) {
|
|
453
|
+
if (result.added > 0) {
|
|
454
|
+
console.log(` ${chalk.green("✓")} ${result.source} → ${result.added} chunks`);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
console.log(` ${chalk.red("✗")} ${result.source} — ${result.errors.join(", ") || "no content"}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
console.log(chalk.green("Docs resynced. Run `devflow docs backfill-vectors` to rebuild vectors."));
|
|
461
|
+
});
|
|
348
462
|
// --- skill ---
|
|
349
463
|
const skillCmd = program
|
|
350
464
|
.command("skill")
|
|
@@ -353,6 +467,7 @@ skillCmd
|
|
|
353
467
|
.command("list")
|
|
354
468
|
.description("List installed skills")
|
|
355
469
|
.action(async () => {
|
|
470
|
+
const { listSkills } = await import("./commands/skill.js");
|
|
356
471
|
const skills = await listSkills(program.opts().local);
|
|
357
472
|
if (skills.length === 0) {
|
|
358
473
|
console.log(chalk.dim("No skills installed. Use 'devflow skill search' to find plugins."));
|
|
@@ -366,6 +481,7 @@ skillCmd
|
|
|
366
481
|
.command("search <query>")
|
|
367
482
|
.description("Search available plugins")
|
|
368
483
|
.action(async (query) => {
|
|
484
|
+
const { searchSkills } = await import("./commands/skill.js");
|
|
369
485
|
const results = await searchSkills(query, program.opts().local);
|
|
370
486
|
console.log(chalk.blue(`Search: "${query}"`));
|
|
371
487
|
if (results.length === 0) {
|
|
@@ -381,6 +497,7 @@ skillCmd
|
|
|
381
497
|
.description("Install a plugin/skill")
|
|
382
498
|
.action(async (name) => {
|
|
383
499
|
try {
|
|
500
|
+
const { installSkill } = await import("./commands/skill.js");
|
|
384
501
|
const result = await installSkill(name, process.cwd(), program.opts().local);
|
|
385
502
|
console.log(chalk.green(`✓ Installed @devflow-tools/plugin-${result.name}@${result.version}`));
|
|
386
503
|
if (result.templates.length > 0) {
|
|
@@ -397,6 +514,7 @@ skillCmd
|
|
|
397
514
|
.description("Uninstall a plugin/skill")
|
|
398
515
|
.action(async (name) => {
|
|
399
516
|
try {
|
|
517
|
+
const { uninstallSkill } = await import("./commands/skill.js");
|
|
400
518
|
await uninstallSkill(name, process.cwd(), program.opts().local);
|
|
401
519
|
console.log(chalk.green(`✓ Uninstalled ${name}`));
|
|
402
520
|
}
|
|
@@ -410,12 +528,15 @@ program
|
|
|
410
528
|
.command("doctor")
|
|
411
529
|
.description("Run project health check")
|
|
412
530
|
.option("--json", "Output as JSON")
|
|
531
|
+
.option("--strict", "Exit with status 1 when any health section has warnings or errors")
|
|
532
|
+
.option("--project <path>", "Project directory", process.cwd())
|
|
413
533
|
.option("--audit", "Verify audit chain integrity")
|
|
414
534
|
.option("--audit-fix", "Rebuild audit chain signatures")
|
|
415
535
|
.option("--violations", "Show violation records")
|
|
416
536
|
.option("--last <period>", "Filter violations by time (e.g. 7d, 24h)")
|
|
417
537
|
.option("--receipts", "Show current session receipt status")
|
|
418
538
|
.action(async (opts) => {
|
|
539
|
+
const { runDoctorCommand, runDoctorAudit, runDoctorAuditFix, runDoctorViolations, runDoctorReceipts, } = await import("./commands/doctor.js");
|
|
419
540
|
if (opts.audit) {
|
|
420
541
|
const report = await runDoctorAudit();
|
|
421
542
|
console.log(opts.json ? JSON.stringify(report) : `Audit chain: ${report.valid ? "VALID" : `BROKEN at seq ${report.brokenAt}`} (${report.entryCount} entries)`);
|
|
@@ -444,49 +565,12 @@ program
|
|
|
444
565
|
}
|
|
445
566
|
return;
|
|
446
567
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
console.log(chalk.blue(`DevFlow Doctor v${pkgVersion}\n`));
|
|
454
|
-
console.log(chalk.bold("◉ Index Status"));
|
|
455
|
-
console.log(` Files ${report.index.totalFiles.toLocaleString()}`);
|
|
456
|
-
console.log(` Symbols ${report.index.totalSymbols.toLocaleString()}`);
|
|
457
|
-
console.log(` Graph (${report.graph.edges.toLocaleString()} edges)`);
|
|
458
|
-
console.log(` Status ${report.index.indexing ? "indexing" : "idle"}`);
|
|
459
|
-
console.log();
|
|
460
|
-
console.log(chalk.bold("◉ Memory"));
|
|
461
|
-
console.log(` Project ${report.memory.projectReady ? "ready" : "not set"}`);
|
|
462
|
-
console.log(` Preferences ${report.memory.userPrefs} set`);
|
|
463
|
-
console.log();
|
|
464
|
-
console.log(chalk.bold("◉ Knowledge"));
|
|
465
|
-
console.log(` Sources ${report.knowledge.sources}`);
|
|
466
|
-
console.log();
|
|
467
|
-
console.log(chalk.bold("◉ Server"));
|
|
468
|
-
if (report.server.running) {
|
|
469
|
-
console.log(` ${chalk.green("✔")} Running on http://localhost:13337`);
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
console.log(` ${chalk.yellow("○")} Not running — run \`devflow server start\` for telemetry`);
|
|
473
|
-
}
|
|
474
|
-
console.log();
|
|
475
|
-
console.log(chalk.bold("◉ Plugins"));
|
|
476
|
-
if (report.plugins.installed === 0) {
|
|
477
|
-
console.log(` ${chalk.dim("No plugins installed")}`);
|
|
478
|
-
}
|
|
479
|
-
else {
|
|
480
|
-
for (const name of report.plugins.names) {
|
|
481
|
-
console.log(` ${name}`);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
console.log();
|
|
485
|
-
console.log(chalk.bold("◉ Workflows"));
|
|
486
|
-
console.log(` Registered ${report.workflows.registered}`);
|
|
487
|
-
console.log();
|
|
488
|
-
const scoreColor = report.readyScore >= 70 ? chalk.green : report.readyScore >= 40 ? chalk.yellow : chalk.red;
|
|
489
|
-
console.log(`AI Ready: ${scoreColor(report.readyScore + "%")}`);
|
|
568
|
+
const exitCode = await runDoctorCommand({
|
|
569
|
+
project: opts.project,
|
|
570
|
+
json: opts.json,
|
|
571
|
+
strict: opts.strict,
|
|
572
|
+
});
|
|
573
|
+
process.exitCode = exitCode;
|
|
490
574
|
});
|
|
491
575
|
// --- session ---
|
|
492
576
|
program
|
|
@@ -494,21 +578,43 @@ program
|
|
|
494
578
|
.description("Generate a session token for MCP Gateway authentication")
|
|
495
579
|
.option("--expires <seconds>", "Token TTL in seconds", "3600")
|
|
496
580
|
.action(async (opts) => {
|
|
581
|
+
const { generateToken } = await import("./commands/session.js");
|
|
497
582
|
const result = await generateToken(process.cwd(), parseInt(opts.expires, 10));
|
|
498
583
|
console.log(JSON.stringify(result, null, 2));
|
|
499
584
|
});
|
|
500
585
|
// --- benchmark ---
|
|
501
|
-
program
|
|
502
|
-
.command("benchmark
|
|
503
|
-
.description("Run
|
|
504
|
-
|
|
505
|
-
.
|
|
506
|
-
.
|
|
507
|
-
|
|
508
|
-
|
|
586
|
+
const benchmarkCmd = program
|
|
587
|
+
.command("benchmark")
|
|
588
|
+
.description("Run and inspect reproducible A/B benchmarks");
|
|
589
|
+
benchmarkCmd
|
|
590
|
+
.command("run")
|
|
591
|
+
.description("Run a benchmark suite and persist the report")
|
|
592
|
+
.option("--suite <id>", "Benchmark suite", "default")
|
|
593
|
+
.option("--project <root>", "Initialized project root", process.cwd())
|
|
594
|
+
.option("--rounds <n>", "Rounds per task", "1")
|
|
595
|
+
.option("--output <format>", "text | json", "text")
|
|
596
|
+
.action(async (opts) => {
|
|
597
|
+
const { runBenchmarkCommand } = await import("./commands/benchmark-cmd.js");
|
|
598
|
+
console.log(await runBenchmarkCommand({
|
|
599
|
+
projectRoot: opts.project,
|
|
600
|
+
suite: opts.suite,
|
|
601
|
+
rounds: parseInt(opts.rounds, 10),
|
|
509
602
|
output: opts.output,
|
|
510
|
-
});
|
|
511
|
-
|
|
603
|
+
}));
|
|
604
|
+
});
|
|
605
|
+
benchmarkCmd
|
|
606
|
+
.command("report")
|
|
607
|
+
.description("Render a persisted benchmark report")
|
|
608
|
+
.option("--run-id <id>", "Specific report; defaults to latest")
|
|
609
|
+
.option("--baseline <id>", "Prior report used for regression comparison")
|
|
610
|
+
.option("--output <format>", "text | json | markdown", "text")
|
|
611
|
+
.action(async (opts) => {
|
|
612
|
+
const { reportBenchmarkCommand } = await import("./commands/benchmark-cmd.js");
|
|
613
|
+
console.log(await reportBenchmarkCommand({
|
|
614
|
+
runId: opts.runId,
|
|
615
|
+
baselineRunId: opts.baseline,
|
|
616
|
+
output: opts.output,
|
|
617
|
+
}));
|
|
512
618
|
});
|
|
513
619
|
// --- review ---
|
|
514
620
|
program
|
|
@@ -516,6 +622,7 @@ program
|
|
|
516
622
|
.description("Review a PR or current branch diff")
|
|
517
623
|
.option("--agent <agent>", "AI agent to use", "claude")
|
|
518
624
|
.action(async (prUrl, opts) => {
|
|
625
|
+
const { runReview } = await import("./commands/review.js");
|
|
519
626
|
const output = await runReview({ prUrl, agent: opts.agent });
|
|
520
627
|
console.log(output);
|
|
521
628
|
});
|
|
@@ -529,6 +636,7 @@ serverCmd
|
|
|
529
636
|
.option("--port <n>", "Port number", "13337")
|
|
530
637
|
.action(async (opts) => {
|
|
531
638
|
console.log(chalk.blue("Starting DevFlow server..."));
|
|
639
|
+
const { startServer } = await import("./commands/server.js");
|
|
532
640
|
const result = await startServer({ port: parseInt(opts.port, 10) });
|
|
533
641
|
console.log(chalk.green(`Server started (pid: ${result.pid}) on port ${opts.port}`));
|
|
534
642
|
});
|
|
@@ -536,6 +644,7 @@ serverCmd
|
|
|
536
644
|
.command("stop")
|
|
537
645
|
.description("Stop the DevFlow REST server")
|
|
538
646
|
.action(async () => {
|
|
647
|
+
const { stopServer } = await import("./commands/server.js");
|
|
539
648
|
const ok = await stopServer();
|
|
540
649
|
if (ok)
|
|
541
650
|
console.log(chalk.green("Server stopped"));
|
|
@@ -546,6 +655,7 @@ serverCmd
|
|
|
546
655
|
.command("status")
|
|
547
656
|
.description("Show server status")
|
|
548
657
|
.action(async () => {
|
|
658
|
+
const { serverStatus } = await import("./commands/server.js");
|
|
549
659
|
const status = await serverStatus();
|
|
550
660
|
if (status.running)
|
|
551
661
|
console.log(chalk.green(`Running (pid: ${status.pid})`));
|
|
@@ -553,7 +663,14 @@ serverCmd
|
|
|
553
663
|
console.log(chalk.yellow("Not running"));
|
|
554
664
|
});
|
|
555
665
|
// --- dashboard ---
|
|
556
|
-
program
|
|
666
|
+
program
|
|
667
|
+
.command("dashboard")
|
|
668
|
+
.description("Open DevFlow Dashboard")
|
|
669
|
+
.action(() => {
|
|
670
|
+
console.log(chalk.blue("The Dashboard is served by the DevFlow server."));
|
|
671
|
+
console.log(chalk.dim("Run: devflow start"));
|
|
672
|
+
console.log(chalk.dim("Then open: http://localhost:13337"));
|
|
673
|
+
});
|
|
557
674
|
// --- start ---
|
|
558
675
|
program
|
|
559
676
|
.command("start")
|
|
@@ -561,6 +678,7 @@ program
|
|
|
561
678
|
.option("--port <n>", "Server port", "13337")
|
|
562
679
|
.option("-d, --background", "Run in background (detached)")
|
|
563
680
|
.action(async (opts) => {
|
|
681
|
+
const { startAll } = await import("./commands/start.js");
|
|
564
682
|
await startAll({
|
|
565
683
|
port: parseInt(opts.port, 10),
|
|
566
684
|
background: !!opts.background,
|
|
@@ -571,6 +689,7 @@ program
|
|
|
571
689
|
.command("stop")
|
|
572
690
|
.description("Stop DevFlow server")
|
|
573
691
|
.action(async () => {
|
|
692
|
+
const { stopAll } = await import("./commands/stop.js");
|
|
574
693
|
await stopAll();
|
|
575
694
|
});
|
|
576
695
|
// --- status ---
|
|
@@ -578,6 +697,7 @@ program
|
|
|
578
697
|
.command("status")
|
|
579
698
|
.description("Show DevFlow services status")
|
|
580
699
|
.action(async () => {
|
|
700
|
+
const { showStatus } = await import("./commands/status.js");
|
|
581
701
|
await showStatus();
|
|
582
702
|
});
|
|
583
703
|
// --- setup ---
|
|
@@ -588,6 +708,7 @@ program
|
|
|
588
708
|
.option("--skip-mcp", "Skip MCP configuration")
|
|
589
709
|
.option("--skip-plugin", "Skip plugin registration")
|
|
590
710
|
.action(async (opts) => {
|
|
711
|
+
const { setupCommand } = await import("./commands/setup.js");
|
|
591
712
|
await setupCommand({
|
|
592
713
|
agent: opts.agent,
|
|
593
714
|
skipMcp: !!opts.skipMcp,
|
|
@@ -598,9 +719,17 @@ program
|
|
|
598
719
|
const pluginCmd = program
|
|
599
720
|
.command("plugin")
|
|
600
721
|
.description("Manage DevFlow plugins");
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
722
|
+
if (process.argv.includes("plugin")) {
|
|
723
|
+
const [{ pluginListCommand }, { pluginSearchCommand }, { pluginInstallCommand }, { pluginUninstallCommand },] = await Promise.all([
|
|
724
|
+
import("./commands/plugin/list.js"),
|
|
725
|
+
import("./commands/plugin/search.js"),
|
|
726
|
+
import("./commands/plugin/install.js"),
|
|
727
|
+
import("./commands/plugin/uninstall.js"),
|
|
728
|
+
]);
|
|
729
|
+
pluginCmd.addCommand(pluginListCommand);
|
|
730
|
+
pluginCmd.addCommand(pluginSearchCommand);
|
|
731
|
+
pluginCmd.addCommand(pluginInstallCommand);
|
|
732
|
+
pluginCmd.addCommand(pluginUninstallCommand);
|
|
733
|
+
}
|
|
734
|
+
await program.parseAsync();
|
|
606
735
|
//# sourceMappingURL=index.js.map
|