ai-spector 0.8.40 → 0.8.42
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.js +415 -7
- package/dist/cli.js.map +1 -1
- package/dist/core/graph/InMemoryGraph.d.ts.map +1 -1
- package/dist/core/graph/detail-sections.d.ts.map +1 -1
- package/dist/core/graph/doc-extract.d.ts.map +1 -1
- package/dist/core/graph/expand-path-nodes.d.ts.map +1 -1
- package/dist/core/graph/health.d.ts.map +1 -1
- package/dist/core/graph/impact.d.ts.map +1 -1
- package/dist/core/graph/index.d.ts.map +1 -1
- package/dist/core/graph/knowledge.d.ts.map +1 -1
- package/dist/core/graph/load.d.ts.map +1 -1
- package/dist/core/graph/merge.d.ts.map +1 -1
- package/dist/core/graph/patch.d.ts.map +1 -1
- package/dist/core/graph/path-target-edges.d.ts.map +1 -1
- package/dist/core/graph/project.d.ts.map +1 -1
- package/dist/core/graph/query.d.ts.map +1 -1
- package/dist/core/graph/resolve.d.ts.map +1 -1
- package/dist/core/graph/session.d.ts.map +1 -1
- package/dist/core/graph/stats.d.ts.map +1 -1
- package/dist/core/graph/translation.d.ts +5 -3
- package/dist/core/graph/translation.d.ts.map +1 -1
- package/dist/core/graph/translation.js +35 -9
- package/dist/core/graph/translation.js.map +1 -1
- package/dist/core/index/docs-build.d.ts.map +1 -1
- package/dist/core/operations/bootstrap.d.ts.map +1 -1
- package/dist/core/operations/check.d.ts +30 -0
- package/dist/core/operations/check.d.ts.map +1 -0
- package/dist/core/operations/check.js +279 -0
- package/dist/core/operations/check.js.map +1 -0
- package/dist/core/operations/context.d.ts +84 -0
- package/dist/core/operations/context.d.ts.map +1 -0
- package/dist/core/operations/context.js +164 -0
- package/dist/core/operations/context.js.map +1 -0
- package/dist/core/operations/extracted.d.ts +80 -0
- package/dist/core/operations/extracted.d.ts.map +1 -0
- package/dist/core/operations/extracted.js +135 -0
- package/dist/core/operations/extracted.js.map +1 -0
- package/dist/core/operations/graph-merge.d.ts.map +1 -1
- package/dist/core/operations/graph-query.d.ts +1 -0
- package/dist/core/operations/graph-query.d.ts.map +1 -1
- package/dist/core/operations/graph-query.js +17 -1
- package/dist/core/operations/graph-query.js.map +1 -1
- package/dist/core/operations/hooks.d.ts.map +1 -1
- package/dist/core/operations/hooks.js +13 -0
- package/dist/core/operations/hooks.js.map +1 -1
- package/dist/core/operations/index.d.ts.map +1 -1
- package/dist/core/operations/index.js +39 -2
- package/dist/core/operations/index.js.map +1 -1
- package/dist/core/operations/lang.d.ts.map +1 -1
- package/dist/core/operations/lang.js +5 -5
- package/dist/core/operations/lang.js.map +1 -1
- package/dist/core/operations/resolve-task.d.ts +9 -0
- package/dist/core/operations/resolve-task.d.ts.map +1 -1
- package/dist/core/operations/resolve-task.js +10 -1
- package/dist/core/operations/resolve-task.js.map +1 -1
- package/dist/core/operations/task-templates.d.ts +17 -0
- package/dist/core/operations/task-templates.d.ts.map +1 -0
- package/dist/core/operations/task-templates.js +45 -0
- package/dist/core/operations/task-templates.js.map +1 -0
- package/dist/core/operations/task.d.ts +262 -0
- package/dist/core/operations/task.d.ts.map +1 -0
- package/dist/core/operations/task.js +639 -0
- package/dist/core/operations/task.js.map +1 -0
- package/dist/core/operations/template.d.ts.map +1 -1
- package/dist/core/operations/template.js +5 -0
- package/dist/core/operations/template.js.map +1 -1
- package/dist/core/operations/validate.d.ts.map +1 -1
- package/dist/core/paths/localized-output.d.ts +15 -0
- package/dist/core/paths/localized-output.d.ts.map +1 -0
- package/dist/core/paths/localized-output.js +65 -0
- package/dist/core/paths/localized-output.js.map +1 -0
- package/dist/core/registry/build.d.ts.map +1 -1
- package/dist/core/registry/structure-patch.d.ts.map +1 -1
- package/dist/core/util/fs.d.ts +2 -0
- package/dist/core/util/fs.d.ts.map +1 -1
- package/dist/core/util/fs.js +8 -1
- package/dist/core/util/fs.js.map +1 -1
- package/dist/core/visualize/html.d.ts.map +1 -1
- package/dist/core/visualize/stats.d.ts.map +1 -1
- package/dist/interfaces/cli/format/check.d.ts +3 -0
- package/dist/interfaces/cli/format/check.d.ts.map +1 -0
- package/dist/interfaces/cli/format/check.js +29 -0
- package/dist/interfaces/cli/format/check.js.map +1 -0
- package/dist/interfaces/cli/format/cocoindex.d.ts.map +1 -1
- package/dist/interfaces/cli/format/comments.d.ts.map +1 -1
- package/dist/interfaces/cli/format/comments.js.map +1 -1
- package/dist/interfaces/cli/format/context.d.ts +5 -0
- package/dist/interfaces/cli/format/context.d.ts.map +1 -0
- package/dist/interfaces/cli/format/context.js +46 -0
- package/dist/interfaces/cli/format/context.js.map +1 -0
- package/dist/interfaces/cli/format/extracted.d.ts +6 -0
- package/dist/interfaces/cli/format/extracted.d.ts.map +1 -0
- package/dist/interfaces/cli/format/extracted.js +59 -0
- package/dist/interfaces/cli/format/extracted.js.map +1 -0
- package/dist/interfaces/cli/format/graph.d.ts.map +1 -1
- package/dist/interfaces/cli/format/graph.js.map +1 -1
- package/dist/interfaces/cli/format/index-cmd.d.ts.map +1 -1
- package/dist/interfaces/cli/format/misc.d.ts.map +1 -1
- package/dist/interfaces/cli/format/misc.js.map +1 -1
- package/dist/interfaces/cli/format/reviews.d.ts.map +1 -1
- package/dist/interfaces/cli/format/task.d.ts +9 -0
- package/dist/interfaces/cli/format/task.d.ts.map +1 -0
- package/dist/interfaces/cli/format/task.js +66 -0
- package/dist/interfaces/cli/format/task.js.map +1 -0
- package/dist/interfaces/mcp/schemas.d.ts +732 -16
- package/dist/interfaces/mcp/schemas.d.ts.map +1 -1
- package/dist/interfaces/mcp/schemas.js +225 -3
- package/dist/interfaces/mcp/schemas.js.map +1 -1
- package/dist/interfaces/mcp/server.js +136 -1
- package/dist/interfaces/mcp/server.js.map +1 -1
- package/dist/interfaces/mcp/tools/analyze.js.map +1 -1
- package/dist/interfaces/mcp/tools/check.d.ts +4 -0
- package/dist/interfaces/mcp/tools/check.d.ts.map +1 -0
- package/dist/interfaces/mcp/tools/check.js +5 -0
- package/dist/interfaces/mcp/tools/check.js.map +1 -0
- package/dist/interfaces/mcp/tools/cocoindex.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/cocoindex.js.map +1 -1
- package/dist/interfaces/mcp/tools/comments.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/comments.js.map +1 -1
- package/dist/interfaces/mcp/tools/context.d.ts +6 -0
- package/dist/interfaces/mcp/tools/context.d.ts.map +1 -0
- package/dist/interfaces/mcp/tools/context.js +26 -0
- package/dist/interfaces/mcp/tools/context.js.map +1 -0
- package/dist/interfaces/mcp/tools/extracted.d.ts +7 -0
- package/dist/interfaces/mcp/tools/extracted.d.ts.map +1 -0
- package/dist/interfaces/mcp/tools/extracted.js +35 -0
- package/dist/interfaces/mcp/tools/extracted.js.map +1 -0
- package/dist/interfaces/mcp/tools/graph.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/graph.js +13 -1
- package/dist/interfaces/mcp/tools/graph.js.map +1 -1
- package/dist/interfaces/mcp/tools/index.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/index.js.map +1 -1
- package/dist/interfaces/mcp/tools/lang.js.map +1 -1
- package/dist/interfaces/mcp/tools/resolve-task.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/resolve-task.js +43 -12
- package/dist/interfaces/mcp/tools/resolve-task.js.map +1 -1
- package/dist/interfaces/mcp/tools/reviews.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/reviews.js.map +1 -1
- package/dist/interfaces/mcp/tools/task.d.ts +13 -0
- package/dist/interfaces/mcp/tools/task.d.ts.map +1 -0
- package/dist/interfaces/mcp/tools/task.js +68 -0
- package/dist/interfaces/mcp/tools/task.js.map +1 -0
- package/dist/interfaces/mcp/tools/template.d.ts.map +1 -1
- package/dist/interfaces/mcp/tools/template.js.map +1 -1
- package/dist/interfaces/sdk/index.d.ts +8 -0
- package/dist/interfaces/sdk/index.d.ts.map +1 -1
- package/dist/interfaces/sdk/index.js +8 -0
- package/dist/interfaces/sdk/index.js.map +1 -1
- package/dist/interfaces/types/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/scaffold/.ai-spector/.docflow/config/workspace.rules.json +15 -0
- package/scaffold/.ai-spector/.docflow/tasks/index.json +5 -0
- package/scaffold/claude/.claude/skills/ai-spector-generate-basic-design/skill.md +19 -5
- package/scaffold/claude/.claude/skills/ai-spector-generate-srs/skill.md +27 -5
- package/scaffold/claude/.claude/skills/ai-spector-resolve-task/skill.md +4 -4
- package/scaffold/claude/.claude/skills/ai-spector-task/skill.md +28 -0
- package/scaffold/claude/CLAUDE.md +29 -3
- package/scaffold/cursor/WORKFLOW.md +18 -5
- package/scaffold/cursor/commands/_workflow.md +2 -1
- package/scaffold/cursor/skills/README.md +6 -1
- package/scaffold/cursor/skills/_skill-router.md +14 -2
- package/scaffold/cursor/skills/ai-spector/references/clarify.md +50 -0
- package/scaffold/cursor/skills/ai-spector/references/context-store.md +45 -0
- package/scaffold/cursor/skills/ai-spector/references/extract-specs.md +39 -0
- package/scaffold/cursor/skills/ai-spector/references/generate-graph.md +1 -1
- package/scaffold/cursor/skills/ai-spector/references/generate-workflow.md +54 -9
- package/scaffold/cursor/skills/ai-spector/references/plan-and-briefing.md +49 -0
- package/scaffold/cursor/skills/ai-spector/references/workspace-check.md +50 -0
- package/scaffold/cursor/skills/ai-spector-check/SKILL.md +30 -0
- package/scaffold/cursor/skills/ai-spector-generate-basic-design/SKILL.md +7 -2
- package/scaffold/cursor/skills/ai-spector-generate-srs/SKILL.md +7 -2
- package/scaffold/cursor/skills/ai-spector-resolve-task/SKILL.md +4 -4
- package/scaffold/cursor/skills/ai-spector-resolve-task/references/runbook.md +23 -9
- package/scaffold/cursor/skills/ai-spector-task/SKILL.md +36 -0
- package/scaffold/cursor/skills/ai-spector-task/references/runbook.md +76 -0
- package/schemas/context-store.schema.json +32 -0
- package/schemas/task-state.schema.json +67 -0
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,8 @@ import { writeJson, readJson } from "./core/util/fs.js";
|
|
|
6
6
|
import { resolveProjectPaths } from "./core/util/paths.js";
|
|
7
7
|
import { buildSectionRegistry } from "./core/registry/build.js";
|
|
8
8
|
import { bootstrapFromRegistry } from "./core/operations/bootstrap.js";
|
|
9
|
+
import { applyPrimaryLanguageOutputs } from "./core/graph/translation.js";
|
|
10
|
+
import { loadDocflowConfig } from "./core/config/load.js";
|
|
9
11
|
import { validateGraph, formatIssues } from "./core/operations/validate.js";
|
|
10
12
|
import { runInit } from "./core/operations/init.js";
|
|
11
13
|
import { runLangAdd, runLangSetClient } from "./core/operations/lang.js";
|
|
@@ -13,6 +15,14 @@ import { runLangQueueFailed, runLangQueueFail, runLangQueuePending, runLangQueue
|
|
|
13
15
|
import { formatPendingTable, formatResolvedTable, formatFailedTable } from "./core/lang/queue.js";
|
|
14
16
|
import { runHooksInstall, runHooksPreCommit, formatPreCommitReport } from "./core/operations/hooks.js";
|
|
15
17
|
import { runSetup, runSetupCheck } from "./core/operations/setup.js";
|
|
18
|
+
import { runCheck } from "./core/operations/check.js";
|
|
19
|
+
import { formatCheck } from "./interfaces/cli/format/check.js";
|
|
20
|
+
import { runContextList, runContextRecord, runContextResolve, } from "./core/operations/context.js";
|
|
21
|
+
import { formatContextList, formatContextRecord, formatContextResolve, } from "./interfaces/cli/format/context.js";
|
|
22
|
+
import { runSpecList, runSpecApprove, runSpecReject, } from "./core/operations/extracted.js";
|
|
23
|
+
import { formatSpecList, formatSpecApprove, formatSpecReject, } from "./interfaces/cli/format/extracted.js";
|
|
24
|
+
import { runTaskAbandon, runTaskApprovePlan, runTaskComplete, runTaskCreate, runTaskGet, runTaskList, runTaskPause, runTaskResume, runTaskUpdate, recordGenerateWaveProgress, } from "./core/operations/task.js";
|
|
25
|
+
import { formatTaskCreate, formatTaskGet, formatTaskList, formatTaskSimple, formatTaskUpdate, } from "./interfaces/cli/format/task.js";
|
|
16
26
|
import { runSyncCursor } from "./core/operations/sync-cursor.js";
|
|
17
27
|
import { runGraphQuery } from "./core/operations/graph-query.js";
|
|
18
28
|
import { runGraphImpact } from "./core/operations/graph-impact.js";
|
|
@@ -113,6 +123,361 @@ program
|
|
|
113
123
|
console.log(formatSetupAudit(audit, true));
|
|
114
124
|
}
|
|
115
125
|
});
|
|
126
|
+
program
|
|
127
|
+
.command("check")
|
|
128
|
+
.description("Validate workspace structure & config (warns on drift; non-zero exit on errors)")
|
|
129
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
130
|
+
.option("--fix", "Auto-create missing directories where possible")
|
|
131
|
+
.option("-p, --path <paths...>", "Validate specific doc output path(s) after writing (repeatable)")
|
|
132
|
+
.option("--json", "JSON output")
|
|
133
|
+
.action(async (opts) => {
|
|
134
|
+
const root = resolve(opts.cwd ?? process.cwd());
|
|
135
|
+
const paths = opts.path;
|
|
136
|
+
const result = await runCheck({ root, fix: opts.fix, paths });
|
|
137
|
+
if (opts.json)
|
|
138
|
+
console.log(JSON.stringify(result, null, 2));
|
|
139
|
+
else
|
|
140
|
+
console.log(formatCheck(result));
|
|
141
|
+
if (!result.ok)
|
|
142
|
+
process.exitCode = 1;
|
|
143
|
+
});
|
|
144
|
+
const context = program
|
|
145
|
+
.command("context")
|
|
146
|
+
.description("Clarification context store (questions answered before generation)");
|
|
147
|
+
context
|
|
148
|
+
.command("list")
|
|
149
|
+
.description("List context entries, optionally filtered by doc type / status")
|
|
150
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
151
|
+
.option("-t, --doc-type <type>", "Doc type store (e.g. srs)")
|
|
152
|
+
.option("-s, --status <status>", "Filter: open | answered | stale")
|
|
153
|
+
.option("--json", "JSON output")
|
|
154
|
+
.action(async (opts) => {
|
|
155
|
+
const result = await runContextList({
|
|
156
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
157
|
+
docType: opts.docType,
|
|
158
|
+
status: opts.status,
|
|
159
|
+
});
|
|
160
|
+
if (opts.json)
|
|
161
|
+
console.log(JSON.stringify(result, null, 2));
|
|
162
|
+
else
|
|
163
|
+
console.log(formatContextList(result));
|
|
164
|
+
});
|
|
165
|
+
context
|
|
166
|
+
.command("record <docType> <question>")
|
|
167
|
+
.description("Record a clarifying question (pass --answer to record it answered)")
|
|
168
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
169
|
+
.option("-a, --answer <answer>", "Answer (records entry as answered)")
|
|
170
|
+
.option("--scope <scope>", "DAG node / section this informs (e.g. srs.use-cases)")
|
|
171
|
+
.option("--source <source>", "user | inferred | data-source", "user")
|
|
172
|
+
.option("--refs <paths>", "Comma-separated source files that make this stale on change")
|
|
173
|
+
.option("--by <name>", "Who answered")
|
|
174
|
+
.option("--json", "JSON output")
|
|
175
|
+
.action(async (docType, question, opts) => {
|
|
176
|
+
const result = await runContextRecord({
|
|
177
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
178
|
+
docType,
|
|
179
|
+
question,
|
|
180
|
+
answer: opts.answer,
|
|
181
|
+
scope: opts.scope,
|
|
182
|
+
source: opts.source,
|
|
183
|
+
sourceRefs: opts.refs
|
|
184
|
+
? opts.refs.split(",").map((s) => s.trim()).filter(Boolean)
|
|
185
|
+
: undefined,
|
|
186
|
+
answeredBy: opts.by,
|
|
187
|
+
});
|
|
188
|
+
if (opts.json)
|
|
189
|
+
console.log(JSON.stringify(result, null, 2));
|
|
190
|
+
else
|
|
191
|
+
console.log(formatContextRecord(result));
|
|
192
|
+
});
|
|
193
|
+
context
|
|
194
|
+
.command("resolve <docType> <id> <answer>")
|
|
195
|
+
.description("Answer an open/stale entry by id (e.g. Q-001)")
|
|
196
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
197
|
+
.option("--by <name>", "Who answered")
|
|
198
|
+
.option("--json", "JSON output")
|
|
199
|
+
.action(async (docType, id, answer, opts) => {
|
|
200
|
+
const result = await runContextResolve({
|
|
201
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
202
|
+
docType,
|
|
203
|
+
id,
|
|
204
|
+
answer,
|
|
205
|
+
answeredBy: opts.by,
|
|
206
|
+
});
|
|
207
|
+
if (opts.json)
|
|
208
|
+
console.log(JSON.stringify(result, null, 2));
|
|
209
|
+
else
|
|
210
|
+
console.log(formatContextResolve(result));
|
|
211
|
+
});
|
|
212
|
+
const spec = program
|
|
213
|
+
.command("spec")
|
|
214
|
+
.description("Extracted-spec review queue (specs pulled from generated docs, approved before graph merge)");
|
|
215
|
+
spec
|
|
216
|
+
.command("list")
|
|
217
|
+
.description("List extracted specs, optionally filtered by doc type / status")
|
|
218
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
219
|
+
.option("-t, --doc-type <type>", "Doc type queue (e.g. srs)")
|
|
220
|
+
.option("-s, --status <status>", "Filter: pending | approved | rejected")
|
|
221
|
+
.option("--json", "JSON output")
|
|
222
|
+
.action(async (opts) => {
|
|
223
|
+
const result = await runSpecList({
|
|
224
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
225
|
+
docType: opts.docType,
|
|
226
|
+
status: opts.status,
|
|
227
|
+
});
|
|
228
|
+
if (opts.json)
|
|
229
|
+
console.log(JSON.stringify(result, null, 2));
|
|
230
|
+
else
|
|
231
|
+
console.log(formatSpecList(result));
|
|
232
|
+
});
|
|
233
|
+
spec
|
|
234
|
+
.command("approve <docType> <id>")
|
|
235
|
+
.description("Approve a pending spec; merges its graph patch (if any) into the graph")
|
|
236
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
237
|
+
.option("--by <name>", "Reviewer name")
|
|
238
|
+
.option("--note <note>", "Review note")
|
|
239
|
+
.option("--skip-merge", "Approve without merging the graph patch")
|
|
240
|
+
.option("--json", "JSON output")
|
|
241
|
+
.action(async (docType, id, opts) => {
|
|
242
|
+
const result = await runSpecApprove({
|
|
243
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
244
|
+
docType,
|
|
245
|
+
id,
|
|
246
|
+
by: opts.by,
|
|
247
|
+
note: opts.note,
|
|
248
|
+
skipMerge: opts.skipMerge,
|
|
249
|
+
});
|
|
250
|
+
if (opts.json)
|
|
251
|
+
console.log(JSON.stringify(result, null, 2));
|
|
252
|
+
else
|
|
253
|
+
console.log(formatSpecApprove(result));
|
|
254
|
+
});
|
|
255
|
+
spec
|
|
256
|
+
.command("reject <docType> <id>")
|
|
257
|
+
.description("Reject a pending spec (kept for audit, never merged)")
|
|
258
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
259
|
+
.option("--by <name>", "Reviewer name")
|
|
260
|
+
.option("--note <note>", "Why the spec was rejected")
|
|
261
|
+
.option("--json", "JSON output")
|
|
262
|
+
.action(async (docType, id, opts) => {
|
|
263
|
+
const result = await runSpecReject({
|
|
264
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
265
|
+
docType,
|
|
266
|
+
id,
|
|
267
|
+
by: opts.by,
|
|
268
|
+
note: opts.note,
|
|
269
|
+
});
|
|
270
|
+
if (opts.json)
|
|
271
|
+
console.log(JSON.stringify(result, null, 2));
|
|
272
|
+
else
|
|
273
|
+
console.log(formatSpecReject(result));
|
|
274
|
+
});
|
|
275
|
+
const task = program
|
|
276
|
+
.command("task")
|
|
277
|
+
.description("Workflow task state (persist plan/progress across sessions)");
|
|
278
|
+
task
|
|
279
|
+
.command("create")
|
|
280
|
+
.description("Create a new workflow task")
|
|
281
|
+
.requiredOption("-k, --kind <kind>", "generate | resolve")
|
|
282
|
+
.requiredOption("-w, --workflow <workflow>", "generate-srs | generate-basic-design | resolve")
|
|
283
|
+
.requiredOption("-t, --trigger <text>", "User intent that started this task")
|
|
284
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
285
|
+
.option("--doc-type <type>", "Doc type for generate workflows (e.g. srs)")
|
|
286
|
+
.option("--force", "Replace existing active task in the same slot")
|
|
287
|
+
.option("--json", "JSON output")
|
|
288
|
+
.action(async (opts) => {
|
|
289
|
+
const result = await runTaskCreate({
|
|
290
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
291
|
+
kind: opts.kind,
|
|
292
|
+
workflow: opts.workflow,
|
|
293
|
+
trigger: opts.trigger,
|
|
294
|
+
docType: opts.docType,
|
|
295
|
+
force: opts.force,
|
|
296
|
+
});
|
|
297
|
+
if (opts.json)
|
|
298
|
+
console.log(JSON.stringify(result, null, 2));
|
|
299
|
+
else
|
|
300
|
+
console.log(formatTaskCreate(result));
|
|
301
|
+
});
|
|
302
|
+
task
|
|
303
|
+
.command("list")
|
|
304
|
+
.description("List tasks")
|
|
305
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
306
|
+
.option("-s, --status <status>", "Filter by status (comma-separated)")
|
|
307
|
+
.option("-k, --kind <kind>", "generate | resolve")
|
|
308
|
+
.option("-w, --workflow <workflow>", "Workflow id filter")
|
|
309
|
+
.option("--recent", "Only tasks in index.recent")
|
|
310
|
+
.option("--json", "JSON output")
|
|
311
|
+
.action(async (opts) => {
|
|
312
|
+
const status = opts.status
|
|
313
|
+
? opts.status.split(",").map((s) => s.trim())
|
|
314
|
+
: undefined;
|
|
315
|
+
const result = await runTaskList({
|
|
316
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
317
|
+
status: status?.length === 1 ? status[0] : status,
|
|
318
|
+
kind: opts.kind,
|
|
319
|
+
workflow: opts.workflow,
|
|
320
|
+
recentOnly: opts.recent,
|
|
321
|
+
});
|
|
322
|
+
if (opts.json)
|
|
323
|
+
console.log(JSON.stringify(result, null, 2));
|
|
324
|
+
else
|
|
325
|
+
console.log(formatTaskList(result));
|
|
326
|
+
});
|
|
327
|
+
task
|
|
328
|
+
.command("get <taskId>")
|
|
329
|
+
.description("Get full task state")
|
|
330
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
331
|
+
.option("--json", "JSON output")
|
|
332
|
+
.action(async (taskId, opts) => {
|
|
333
|
+
const result = await runTaskGet({
|
|
334
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
335
|
+
taskId,
|
|
336
|
+
});
|
|
337
|
+
if (opts.json)
|
|
338
|
+
console.log(JSON.stringify(result, null, 2));
|
|
339
|
+
else
|
|
340
|
+
console.log(formatTaskGet(result));
|
|
341
|
+
});
|
|
342
|
+
task
|
|
343
|
+
.command("update <taskId>")
|
|
344
|
+
.description("Patch task state (pass --patch as JSON)")
|
|
345
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
346
|
+
.option("--patch <json>", "JSON patch object (TaskUpdatePatch)")
|
|
347
|
+
.option("--json", "JSON output")
|
|
348
|
+
.action(async (taskId, opts) => {
|
|
349
|
+
if (!opts.patch) {
|
|
350
|
+
throw new Error("--patch is required (JSON object)");
|
|
351
|
+
}
|
|
352
|
+
const patch = JSON.parse(opts.patch);
|
|
353
|
+
const result = await runTaskUpdate({
|
|
354
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
355
|
+
taskId,
|
|
356
|
+
patch,
|
|
357
|
+
});
|
|
358
|
+
if (opts.json)
|
|
359
|
+
console.log(JSON.stringify(result, null, 2));
|
|
360
|
+
else
|
|
361
|
+
console.log(formatTaskUpdate(result));
|
|
362
|
+
});
|
|
363
|
+
task
|
|
364
|
+
.command("approve <taskId>")
|
|
365
|
+
.description("Approve the task plan and advance to the next step")
|
|
366
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
367
|
+
.option("--plan <json>", "Plan JSON (StoredPlan) if not already set on task")
|
|
368
|
+
.option("--json", "JSON output")
|
|
369
|
+
.action(async (taskId, opts) => {
|
|
370
|
+
const result = await runTaskApprovePlan({
|
|
371
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
372
|
+
taskId,
|
|
373
|
+
plan: opts.plan ? JSON.parse(opts.plan) : undefined,
|
|
374
|
+
});
|
|
375
|
+
if (opts.json)
|
|
376
|
+
console.log(JSON.stringify(result, null, 2));
|
|
377
|
+
else
|
|
378
|
+
console.log(formatTaskSimple("Approved plan for", result));
|
|
379
|
+
});
|
|
380
|
+
task
|
|
381
|
+
.command("pause <taskId>")
|
|
382
|
+
.description("Pause a task")
|
|
383
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
384
|
+
.option("--json", "JSON output")
|
|
385
|
+
.action(async (taskId, opts) => {
|
|
386
|
+
const result = await runTaskPause({
|
|
387
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
388
|
+
taskId,
|
|
389
|
+
});
|
|
390
|
+
if (opts.json)
|
|
391
|
+
console.log(JSON.stringify(result, null, 2));
|
|
392
|
+
else
|
|
393
|
+
console.log(formatTaskSimple("Paused", result));
|
|
394
|
+
});
|
|
395
|
+
task
|
|
396
|
+
.command("resume <taskId>")
|
|
397
|
+
.description("Resume a paused task (validates workspace and drift)")
|
|
398
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
399
|
+
.option("--json", "JSON output")
|
|
400
|
+
.action(async (taskId, opts) => {
|
|
401
|
+
const result = await runTaskResume({
|
|
402
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
403
|
+
taskId,
|
|
404
|
+
});
|
|
405
|
+
if (opts.json)
|
|
406
|
+
console.log(JSON.stringify(result, null, 2));
|
|
407
|
+
else {
|
|
408
|
+
const lines = [
|
|
409
|
+
`Resume ${result.task.id} — canContinue: ${result.canContinue}`,
|
|
410
|
+
` workspace: ${result.workspaceOk ? "ok" : "errors"}`,
|
|
411
|
+
` drift: ${result.drift.length} file(s)`,
|
|
412
|
+
` stale: ${result.staleContextIds.join(", ") || "none"}`,
|
|
413
|
+
` next: ${result.suggestedNext}`,
|
|
414
|
+
];
|
|
415
|
+
if (result.drift.length > 0) {
|
|
416
|
+
for (const d of result.drift) {
|
|
417
|
+
lines.push(` ${d.kind}: ${d.path}`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
console.log(lines.join("\n"));
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
task
|
|
424
|
+
.command("complete <taskId>")
|
|
425
|
+
.description("Mark a task complete")
|
|
426
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
427
|
+
.option("--summary <text>", "Completion summary")
|
|
428
|
+
.option("--json", "JSON output")
|
|
429
|
+
.action(async (taskId, opts) => {
|
|
430
|
+
const result = await runTaskComplete({
|
|
431
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
432
|
+
taskId,
|
|
433
|
+
summary: opts.summary,
|
|
434
|
+
});
|
|
435
|
+
if (opts.json)
|
|
436
|
+
console.log(JSON.stringify(result, null, 2));
|
|
437
|
+
else
|
|
438
|
+
console.log(formatTaskSimple("Completed", result));
|
|
439
|
+
});
|
|
440
|
+
task
|
|
441
|
+
.command("record-wave <taskId> <waveId>")
|
|
442
|
+
.description("Record generate wave progress (e.g. wave-1 done with artifacts)")
|
|
443
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
444
|
+
.option("-s, --status <status>", "done | in-progress | blocked", "done")
|
|
445
|
+
.option("--artifacts <paths>", "Comma-separated doc paths written this wave")
|
|
446
|
+
.option("--blocker <text>", "Blocker message when status is blocked")
|
|
447
|
+
.option("--json", "JSON output")
|
|
448
|
+
.action(async (taskId, waveId, opts) => {
|
|
449
|
+
const result = await recordGenerateWaveProgress({
|
|
450
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
451
|
+
taskId,
|
|
452
|
+
waveId,
|
|
453
|
+
status: opts.status,
|
|
454
|
+
artifacts: opts.artifacts
|
|
455
|
+
? opts.artifacts.split(",").map((p) => p.trim()).filter(Boolean)
|
|
456
|
+
: undefined,
|
|
457
|
+
blocker: opts.blocker ?? null,
|
|
458
|
+
});
|
|
459
|
+
if (opts.json)
|
|
460
|
+
console.log(JSON.stringify(result, null, 2));
|
|
461
|
+
else
|
|
462
|
+
console.log(formatTaskUpdate(result));
|
|
463
|
+
});
|
|
464
|
+
task
|
|
465
|
+
.command("abandon <taskId>")
|
|
466
|
+
.description("Abandon a task")
|
|
467
|
+
.option("-C, --cwd <path>", "Project root", process.cwd())
|
|
468
|
+
.option("--reason <text>", "Why the task was abandoned")
|
|
469
|
+
.option("--json", "JSON output")
|
|
470
|
+
.action(async (taskId, opts) => {
|
|
471
|
+
const result = await runTaskAbandon({
|
|
472
|
+
root: resolve(opts.cwd ?? process.cwd()),
|
|
473
|
+
taskId,
|
|
474
|
+
reason: opts.reason,
|
|
475
|
+
});
|
|
476
|
+
if (opts.json)
|
|
477
|
+
console.log(JSON.stringify(result, null, 2));
|
|
478
|
+
else
|
|
479
|
+
console.log(formatTaskSimple("Abandoned", result));
|
|
480
|
+
});
|
|
116
481
|
const lang = program.command("lang").description("Manage project languages");
|
|
117
482
|
lang
|
|
118
483
|
.command("add <code>")
|
|
@@ -287,6 +652,16 @@ graph
|
|
|
287
652
|
const graphPath = opts.output ?? paths.graph;
|
|
288
653
|
const registry = await readJson(registryPath);
|
|
289
654
|
const graph = bootstrapFromRegistry(registry);
|
|
655
|
+
try {
|
|
656
|
+
const { config } = await loadDocflowConfig(paths.root);
|
|
657
|
+
const primary = config.languages[0];
|
|
658
|
+
if (primary) {
|
|
659
|
+
applyPrimaryLanguageOutputs(graph, primary.code, config.languages.map((l) => l.code));
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
// uninitialized project — keep manifest paths as-is
|
|
664
|
+
}
|
|
290
665
|
await writeJson(graphPath, graph.toTraceabilityGraph());
|
|
291
666
|
console.log(`Wrote ${graphPath} (${graph.nodesById.size} nodes, ${graph.toTraceabilityGraph().edges.length} edges)`);
|
|
292
667
|
});
|
|
@@ -301,6 +676,7 @@ graph
|
|
|
301
676
|
const paths = await getPaths(cmd);
|
|
302
677
|
const result = await runGraphQuery({
|
|
303
678
|
graphPath: paths.graph,
|
|
679
|
+
projectRoot: paths.root,
|
|
304
680
|
seedId: id,
|
|
305
681
|
direction: opts.direction,
|
|
306
682
|
depth: Number(opts.depth),
|
|
@@ -876,9 +1252,10 @@ cocoindex
|
|
|
876
1252
|
});
|
|
877
1253
|
// ── resolve-task ──────────────────────────────────────────────────────────────
|
|
878
1254
|
program
|
|
879
|
-
.command("resolve-task
|
|
880
|
-
.description("Execute a resolve-task plan from a JSON file
|
|
1255
|
+
.command("resolve-task [planJson]")
|
|
1256
|
+
.description("Execute a resolve-task plan from a JSON file or --task-id (approved task in .ai-spector/.docflow/tasks/).")
|
|
881
1257
|
.option("--root <path>", "Project root (default: cwd)")
|
|
1258
|
+
.option("--task-id <id>", "Load approved plan from task file")
|
|
882
1259
|
.option("--dry-run", "Validate plan without writing any changes")
|
|
883
1260
|
.option("--json", "JSON output")
|
|
884
1261
|
.action(async (planJson, opts) => {
|
|
@@ -889,8 +1266,28 @@ program
|
|
|
889
1266
|
const { runGraphReport } = await import("./core/operations/graph-report.js");
|
|
890
1267
|
const { runGraphImpact } = await import("./core/operations/graph-impact.js");
|
|
891
1268
|
const { resolveProjectPaths } = await import("./core/util/paths.js");
|
|
892
|
-
const
|
|
1269
|
+
const { loadResolveExecutionContext, recordResolveStepProgress, } = await import("./core/operations/task.js");
|
|
893
1270
|
const paths = await resolveProjectPaths(opts.root);
|
|
1271
|
+
let intent;
|
|
1272
|
+
let goalSpec;
|
|
1273
|
+
let plan;
|
|
1274
|
+
const taskId = opts.taskId;
|
|
1275
|
+
if (taskId) {
|
|
1276
|
+
const ctx = await loadResolveExecutionContext({ root: paths.root, taskId });
|
|
1277
|
+
intent = ctx.intent;
|
|
1278
|
+
goalSpec = ctx.goalSpec;
|
|
1279
|
+
plan = ctx.plan;
|
|
1280
|
+
}
|
|
1281
|
+
else {
|
|
1282
|
+
if (!planJson) {
|
|
1283
|
+
throw new Error("Provide planJson path or --task-id");
|
|
1284
|
+
}
|
|
1285
|
+
const raw = await readJson(resolve(planJson));
|
|
1286
|
+
goalSpec = createGoalSpec(raw.goalSpec.trigger, raw.goalSpec.domain, raw.goalSpec.scope, raw.goalSpec.criteria, raw.goalSpec.notes);
|
|
1287
|
+
plan = createPlan(goalSpec, raw.plan.steps, goalSpec.scope.map((nodeId) => ({ nodeId, directCallers: 0, riskLevel: "low" })));
|
|
1288
|
+
plan.approvedAt = new Date().toISOString();
|
|
1289
|
+
intent = raw.intent;
|
|
1290
|
+
}
|
|
894
1291
|
const executors = {
|
|
895
1292
|
index: async (_args, root) => {
|
|
896
1293
|
await runIndex({ root, graphOnly: false, docsOnly: false });
|
|
@@ -916,11 +1313,21 @@ program
|
|
|
916
1313
|
return { artifacts: [] };
|
|
917
1314
|
},
|
|
918
1315
|
};
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
1316
|
+
const onStepComplete = taskId
|
|
1317
|
+
? async (event) => {
|
|
1318
|
+
await recordResolveStepProgress({
|
|
1319
|
+
root: paths.root,
|
|
1320
|
+
taskId,
|
|
1321
|
+
plan: event.plan,
|
|
1322
|
+
stepId: event.stepId,
|
|
1323
|
+
stepStatus: event.status,
|
|
1324
|
+
artifacts: event.artifacts,
|
|
1325
|
+
blocker: event.issue ?? null,
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
: undefined;
|
|
922
1329
|
const result = await runResolveTask({
|
|
923
|
-
intent
|
|
1330
|
+
intent,
|
|
924
1331
|
goalSpec,
|
|
925
1332
|
plan,
|
|
926
1333
|
projectRoot: paths.root,
|
|
@@ -928,6 +1335,7 @@ program
|
|
|
928
1335
|
rulesPath: paths.rulesImpact,
|
|
929
1336
|
executors,
|
|
930
1337
|
dryRun: opts.dryRun,
|
|
1338
|
+
onStepComplete,
|
|
931
1339
|
});
|
|
932
1340
|
if (opts.json)
|
|
933
1341
|
console.log(JSON.stringify(result, null, 2));
|