@delete101020/aidlc 4.0.0 → 4.0.2
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 +62 -39
- package/dist/bundle.js +268 -101
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,36 +3,32 @@
|
|
|
3
3
|
[](https://github.com/delete101020/ai-native-sdlc/blob/main/LICENSE)
|
|
4
4
|
[](https://www.npmjs.com/package/@delete101020/aidlc)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
The terminal side of **AIDLC Native**: drive Claude through the six stages of the
|
|
7
|
+
[AI-Native SDLC Playbook](https://claude.com/blog/the-ai-native-sdlc-playbook) —
|
|
8
|
+
**Plan → Design → Build → Test → Deploy → Maintain** — from any shell, a CI job or
|
|
9
|
+
a cron script. Every stage is an agent that writes one artifact (`intent.md`,
|
|
10
|
+
`spec.md`, `plan.md`, `verify.md`, `review.md`, `incident.md`), and the
|
|
11
|
+
pipeline waits at the review gates you keep.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
The CLI shares `.aidlc/workspace.yaml` and the run files with the
|
|
14
|
+
[VS Code extension](https://marketplace.visualstudio.com/items?itemName=delete101020.aidlc-native)
|
|
15
|
+
(no daemon, no IPC), so an epic started in one can be finished in the other.
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
**Claude only.** The CLI shells out to `claude --print --append-system-prompt
|
|
18
|
+
<skill>`. No Anthropic SDK calls.
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
per-epic **memory** tool, and the `/annotate-artifact` + `/epic-context` skills. Review epic
|
|
20
|
-
artifacts in a browser and apply feedback back to the Markdown — from a plain terminal +
|
|
21
|
-
Claude Code, no VS Code required. Optional `aidlc globals memory-hook enable` auto-loads an
|
|
22
|
-
epic's memory whenever a prompt mentions it. See the [`globals`](#globals--built-in-workflow-agents--skills-under-claude) command.
|
|
20
|
+
> **A fork** of [`aidlc-io/aidlc`](https://github.com/aidlc-io/aidlc) by hueanmy, not
|
|
21
|
+
> affiliated with the upstream author. The package is scoped because the upstream
|
|
22
|
+
> owns `aidlc` on npm; the command it installs is still `aidlc`.
|
|
23
23
|
|
|
24
24
|
## Install
|
|
25
25
|
|
|
26
|
-
The CLI of **AIDLC Native**, a fork of [`aidlc-io/aidlc`](https://github.com/aidlc-io/aidlc)
|
|
27
|
-
(not affiliated with the upstream author). The package is scoped because the
|
|
28
|
-
upstream owns `aidlc` on npm; the command it installs is still `aidlc`:
|
|
29
|
-
|
|
30
26
|
```sh
|
|
31
27
|
npm install -g @delete101020/aidlc
|
|
32
28
|
aidlc --version
|
|
33
29
|
```
|
|
34
30
|
|
|
35
|
-
If the upstream `aidlc` package is installed globally, `npm uninstall -g aidlc`
|
|
31
|
+
If the upstream `aidlc` package is installed globally, run `npm uninstall -g aidlc`
|
|
36
32
|
first — both provide the `aidlc` command.
|
|
37
33
|
|
|
38
34
|
To run unreleased changes, build it from the repo:
|
|
@@ -41,7 +37,6 @@ To run unreleased changes, build it from the repo:
|
|
|
41
37
|
pnpm install # at repo root
|
|
42
38
|
pnpm -r compile
|
|
43
39
|
cd packages/cli && pnpm bundle && npm link # makes `aidlc` available globally
|
|
44
|
-
aidlc --version # 3.5.1
|
|
45
40
|
```
|
|
46
41
|
|
|
47
42
|
`npm link` points at the working tree, so a later `pnpm bundle` is enough to
|
|
@@ -60,20 +55,36 @@ Run `aidlc doctor` to verify all of the above.
|
|
|
60
55
|
## Five-minute walkthrough
|
|
61
56
|
|
|
62
57
|
```sh
|
|
63
|
-
# 1.
|
|
64
|
-
|
|
58
|
+
# 1. A workspace with the AI-Native SDLC workflow
|
|
59
|
+
cd my-project
|
|
65
60
|
aidlc init
|
|
61
|
+
aidlc preset apply ai-native # 6 agents, 7 skills, the ai-native-full pipeline
|
|
66
62
|
aidlc doctor # confirm claude is wired up
|
|
67
63
|
|
|
68
|
-
# 2.
|
|
69
|
-
aidlc
|
|
70
|
-
aidlc list # see the agents, skills, pipeline you got
|
|
64
|
+
# 2. Start an epic — the brief picks a recipe (here: native-fix)
|
|
65
|
+
aidlc epic start EPIC-1 --brief "fix the login redirect loop"
|
|
71
66
|
|
|
72
|
-
# 3.
|
|
73
|
-
aidlc run
|
|
74
|
-
aidlc run
|
|
67
|
+
# 3. Let Claude work it, stopping at each review gate
|
|
68
|
+
aidlc run exec EPIC-1 # exit 2 = waiting for your review
|
|
69
|
+
aidlc run approve EPIC-1 # or: aidlc run reject EPIC-1 --reason "…"
|
|
70
|
+
aidlc run exec EPIC-1 # carries on to the next gate
|
|
75
71
|
```
|
|
76
72
|
|
|
73
|
+
Recipes right-size the pipeline to the task:
|
|
74
|
+
|
|
75
|
+
| Recipe | Steps | For |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `native-full` | intent → spec → build-plan → implement → verify → review | New behaviour |
|
|
78
|
+
| `native-fix` | intent → build-plan → implement → verify → review | Bugs, refactors, tech debt |
|
|
79
|
+
| `native-lite` | intent → build-plan → implement → review | Small changes with a precedent in the code |
|
|
80
|
+
| `native-quick` | intent → build-plan → implement → verify | Small, well-understood changes |
|
|
81
|
+
| `native-align` | intent → spec | Agreeing on scope before any code |
|
|
82
|
+
| `native-hotfix` | build-plan → implement → review | Production is down and the cause is known |
|
|
83
|
+
|
|
84
|
+
Pick one yourself with `aidlc epic start <id> --recipe native-full`, or list them
|
|
85
|
+
with `aidlc pipeline recipes`. Stage 6 has its own entry point — see
|
|
86
|
+
[`maintain`](#maintain--stage-6-the-ai-native-return-path).
|
|
87
|
+
|
|
77
88
|
## Command reference
|
|
78
89
|
|
|
79
90
|
Global flags available on every subcommand:
|
|
@@ -125,15 +136,16 @@ run-state JSON files are parseable. Exit 1 on any failure (including skill /
|
|
|
125
136
|
runner / runtime checks). `--json` emits every section as
|
|
126
137
|
`{ ok, failures, sections }` — a parseable CI preflight.
|
|
127
138
|
|
|
128
|
-
### `mcp` — give another CLI the
|
|
139
|
+
### `mcp` — give another CLI the code-graph server
|
|
129
140
|
|
|
130
141
|
```
|
|
131
142
|
aidlc mcp status
|
|
132
143
|
aidlc mcp register [--runner codex] [--dry-run]
|
|
133
144
|
```
|
|
134
145
|
|
|
135
|
-
The VS Code extension registers
|
|
136
|
-
automatically, project-scoped
|
|
146
|
+
The VS Code extension registers a code-graph MCP server with Claude
|
|
147
|
+
automatically, project-scoped — `ast-graph` by default, or `codegraph` when
|
|
148
|
+
`aidlcNative.astGraph.engine` is set to it. Codex keeps MCP servers in `~/.codex/config.toml`,
|
|
137
149
|
which is per-user: registering there points every Codex session on the machine
|
|
138
150
|
at this workspace's graph, so it stays an explicit command. `register` copies
|
|
139
151
|
the binary and db path out of the registration Claude already has — run
|
|
@@ -255,8 +267,9 @@ aidlc preset apply <name> # merges into current workspace (no ov
|
|
|
255
267
|
aidlc preset save <name> # snapshot current workspace to .aidlc/presets/<name>.json
|
|
256
268
|
```
|
|
257
269
|
|
|
258
|
-
Built-in presets: `
|
|
259
|
-
pipeline
|
|
270
|
+
Built-in presets: `ai-native` (the six-stage AI-Native SDLC workflow),
|
|
271
|
+
`sdlc` (the classic AIDLC pipeline: Plan → (Design ∥ Test Plan) →
|
|
272
|
+
Implement ∥ Generate Test Cases → Execute Test), `code-review` and `release-notes` (single-agent pipelines).
|
|
260
273
|
|
|
261
274
|
### Epics
|
|
262
275
|
|
|
@@ -265,14 +278,24 @@ under whatever `state.root` your `workspace.yaml` declares (default
|
|
|
265
278
|
`docs/epics/`).
|
|
266
279
|
|
|
267
280
|
```
|
|
268
|
-
aidlc epic list [--status pending|in_progress|done|failed] [--json]
|
|
281
|
+
aidlc epic list [--status pending|in_progress|done|failed] [--tag <tag>…] [--json]
|
|
269
282
|
aidlc epic status <id> [--json] # phase-by-phase view
|
|
270
283
|
aidlc epic show <id> # alias for status
|
|
271
284
|
aidlc epic start <id> --brief "…" [--llm] # classify the brief → recipe → assembled pipeline
|
|
272
285
|
aidlc epic start <id> --recipe <recipeId> # or pick the recipe yourself
|
|
273
286
|
aidlc epic start <id> --pipeline <pipelineId> # or use an existing pipeline as-is
|
|
287
|
+
aidlc epic start <id> … --tag payment --tag "thanh toán" # tag it at creation
|
|
288
|
+
aidlc epic tag <id> # print this epic's tags
|
|
289
|
+
aidlc epic tag <id> payment "release q3" # add tags (also --add/--remove/--set/--clear)
|
|
274
290
|
```
|
|
275
291
|
|
|
292
|
+
**Tags** are free text in and one canonical form on disk: uppercase, ASCII,
|
|
293
|
+
dash-separated — `"thanh toán VNPay"` is stored as `THANH-TOAN-VNPAY`, and the
|
|
294
|
+
accents and case are folded on the way *in* to a filter too, so `--tag "thanh
|
|
295
|
+
toán"` finds it. Repeating `--tag` narrows: an epic must carry every tag given.
|
|
296
|
+
They live under `tags` in the epic's `state.json` and are shown, and editable,
|
|
297
|
+
on each card in the VS Code panel.
|
|
298
|
+
|
|
276
299
|
`epic start` mirrors the extension's smart **Start Epic**: `--brief` classifies
|
|
277
300
|
the requirement into a task-type recipe (heuristic by default, `--llm` for
|
|
278
301
|
model-backed classification) and assembles a right-sized pipeline.
|
|
@@ -581,12 +604,12 @@ still needed by other globally-installed workflows.
|
|
|
581
604
|
|
|
582
605
|
## Recipes
|
|
583
606
|
|
|
584
|
-
### Drive
|
|
607
|
+
### Drive an AI-Native epic end-to-end, unattended
|
|
585
608
|
|
|
586
609
|
```sh
|
|
587
|
-
aidlc preset apply
|
|
588
|
-
aidlc
|
|
589
|
-
aidlc run exec
|
|
610
|
+
aidlc preset apply ai-native
|
|
611
|
+
aidlc epic start EPIC-7 --recipe native-full
|
|
612
|
+
aidlc run exec EPIC-7 --auto-approve # clears human gates without pausing
|
|
590
613
|
```
|
|
591
614
|
|
|
592
615
|
### Manually mark a phase done that you completed outside AIDLC
|
|
@@ -622,7 +645,7 @@ aidlc epic list --json | jq '.[] | select(.status=="in_progress") | .id'
|
|
|
622
645
|
|
|
623
646
|
```sh
|
|
624
647
|
# Terminal 1 — kick off the run, then walk away
|
|
625
|
-
aidlc
|
|
648
|
+
aidlc epic start ABC-123 --brief "…"
|
|
626
649
|
aidlc run exec ABC-123 --auto-approve
|
|
627
650
|
|
|
628
651
|
# Terminal 2 — live table
|
package/dist/bundle.js
CHANGED
|
@@ -24601,6 +24601,64 @@ var require_EpicPipelineStore = __commonJS({
|
|
|
24601
24601
|
}
|
|
24602
24602
|
});
|
|
24603
24603
|
|
|
24604
|
+
// ../core/dist/loader/epicTags.js
|
|
24605
|
+
var require_epicTags = __commonJS({
|
|
24606
|
+
"../core/dist/loader/epicTags.js"(exports2) {
|
|
24607
|
+
"use strict";
|
|
24608
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
24609
|
+
exports2.MAX_TAG_LENGTH = exports2.EPIC_TAGS_KEY = void 0;
|
|
24610
|
+
exports2.normalizeTag = normalizeTag;
|
|
24611
|
+
exports2.normalizeTags = normalizeTags2;
|
|
24612
|
+
exports2.readEpicTags = readEpicTags3;
|
|
24613
|
+
exports2.epicMatchesTags = epicMatchesTags2;
|
|
24614
|
+
exports2.applyTagEdit = applyTagEdit2;
|
|
24615
|
+
exports2.EPIC_TAGS_KEY = "tags";
|
|
24616
|
+
exports2.MAX_TAG_LENGTH = 48;
|
|
24617
|
+
function normalizeTag(raw) {
|
|
24618
|
+
if (typeof raw !== "string") {
|
|
24619
|
+
return "";
|
|
24620
|
+
}
|
|
24621
|
+
return raw.normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/[đĐ]/g, "d").toUpperCase().replace(/[^A-Z0-9_]+/g, "-").replace(/-+/g, "-").replace(/^[-_]+|[-_]+$/g, "").slice(0, exports2.MAX_TAG_LENGTH).replace(/[-_]+$/g, "");
|
|
24622
|
+
}
|
|
24623
|
+
function normalizeTags2(raw) {
|
|
24624
|
+
const parts = Array.isArray(raw) ? raw : typeof raw === "string" ? raw.split(/[,\n]/) : [];
|
|
24625
|
+
const out2 = /* @__PURE__ */ new Set();
|
|
24626
|
+
for (const part of parts) {
|
|
24627
|
+
const tag = normalizeTag(part);
|
|
24628
|
+
if (tag) {
|
|
24629
|
+
out2.add(tag);
|
|
24630
|
+
}
|
|
24631
|
+
}
|
|
24632
|
+
return [...out2].sort();
|
|
24633
|
+
}
|
|
24634
|
+
function readEpicTags3(parsed) {
|
|
24635
|
+
if (!parsed || typeof parsed !== "object") {
|
|
24636
|
+
return [];
|
|
24637
|
+
}
|
|
24638
|
+
return normalizeTags2(parsed[exports2.EPIC_TAGS_KEY]);
|
|
24639
|
+
}
|
|
24640
|
+
function epicMatchesTags2(epicTags, filter) {
|
|
24641
|
+
const wanted = normalizeTags2(filter);
|
|
24642
|
+
if (wanted.length === 0) {
|
|
24643
|
+
return true;
|
|
24644
|
+
}
|
|
24645
|
+
const have = new Set(normalizeTags2(epicTags));
|
|
24646
|
+
return wanted.every((t) => have.has(t));
|
|
24647
|
+
}
|
|
24648
|
+
function applyTagEdit2(current, edit) {
|
|
24649
|
+
const base = edit.set !== void 0 ? normalizeTags2(edit.set) : normalizeTags2(current);
|
|
24650
|
+
const next = new Set(base);
|
|
24651
|
+
for (const t of normalizeTags2(edit.add)) {
|
|
24652
|
+
next.add(t);
|
|
24653
|
+
}
|
|
24654
|
+
for (const t of normalizeTags2(edit.remove)) {
|
|
24655
|
+
next.delete(t);
|
|
24656
|
+
}
|
|
24657
|
+
return [...next].sort();
|
|
24658
|
+
}
|
|
24659
|
+
}
|
|
24660
|
+
});
|
|
24661
|
+
|
|
24604
24662
|
// ../core/dist/epics/ContextCollector.js
|
|
24605
24663
|
var require_ContextCollector = __commonJS({
|
|
24606
24664
|
"../core/dist/epics/ContextCollector.js"(exports2) {
|
|
@@ -24997,6 +25055,7 @@ var require_EpicScaffold = __commonJS({
|
|
|
24997
25055
|
var PipelineRunner_1 = require_PipelineRunner();
|
|
24998
25056
|
var RunStateStore_1 = require_RunStateStore();
|
|
24999
25057
|
var EpicPipelineStore_1 = require_EpicPipelineStore();
|
|
25058
|
+
var epicTags_1 = require_epicTags();
|
|
25000
25059
|
var ContextCollector_1 = require_ContextCollector();
|
|
25001
25060
|
var PlanGenerator_1 = require_PlanGenerator();
|
|
25002
25061
|
var EpicScaffoldError3 = class extends Error {
|
|
@@ -25071,7 +25130,7 @@ var require_EpicScaffold = __commonJS({
|
|
|
25071
25130
|
fs14.writeFileSync(stateFile, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
25072
25131
|
}
|
|
25073
25132
|
function scaffoldEpic2(args) {
|
|
25074
|
-
const { workspaceRoot, doc, epicId, title, description, target, agents, inputs, extraProjects, pipeline, seedArtifacts, enableAutopilot = false, strictMode = true } = args;
|
|
25133
|
+
const { workspaceRoot, doc, epicId, title, description, target, agents, inputs, extraProjects, pipeline, seedArtifacts, enableAutopilot = false, strictMode = true, tags } = args;
|
|
25075
25134
|
if (!epicId.trim()) {
|
|
25076
25135
|
throw new EpicScaffoldError3("Epic id is required.");
|
|
25077
25136
|
}
|
|
@@ -25107,6 +25166,9 @@ var require_EpicScaffold = __commonJS({
|
|
|
25107
25166
|
// because the point of a per-epic knob is that it can be found and flipped
|
|
25108
25167
|
// by hand on an epic that turns out bigger or smaller than it looked.
|
|
25109
25168
|
strict_mode: strictMode,
|
|
25169
|
+
// Written even when empty, for the same reason as `strict_mode`: a key that
|
|
25170
|
+
// is there is a key someone can find and fill in by hand.
|
|
25171
|
+
[epicTags_1.EPIC_TAGS_KEY]: (0, epicTags_1.normalizeTags)(tags),
|
|
25110
25172
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25111
25173
|
stepStates: agents.map((a) => ({
|
|
25112
25174
|
agent: a,
|
|
@@ -31818,7 +31880,7 @@ AIDLC is an AI-driven SDLC + agent workflow runner. It drives Claude through a
|
|
|
31818
31880
|
pipeline you declare in \`.aidlc/workspace.yaml\`, tracking every run, step, and
|
|
31819
31881
|
token. It has two surfaces that share the same files on disk (no daemon):
|
|
31820
31882
|
|
|
31821
|
-
- **VS Code extension** \u2014 **AIDLC Native** (\`delete101020.aidlc\`, on the VS Code
|
|
31883
|
+
- **VS Code extension** \u2014 **AIDLC Native** (\`delete101020.aidlc-native\`, on the VS Code
|
|
31822
31884
|
Marketplace and Open VSX; commands and settings under \`aidlcNative.*\`) \u2014 a
|
|
31823
31885
|
visual Builder for workspace.yaml,
|
|
31824
31886
|
a sidebar launcher, epic/run tracking, and the **AIDLC Monitor** (token usage,
|
|
@@ -31866,7 +31928,7 @@ the other within ~200ms.
|
|
|
31866
31928
|
- Bootstrap: \`aidlc init\`, \`aidlc validate\`, \`aidlc doctor\`, \`aidlc list [--json]\`.
|
|
31867
31929
|
- Config (mirrors the Builder): \`aidlc skill|agent|pipeline add|list|show|remove\`.
|
|
31868
31930
|
- Presets: \`aidlc preset apply|save|list\` (built-ins code-review, release-notes, sdlc).
|
|
31869
|
-
- Epics: \`aidlc epic list|status <id>|start <id> --brief "\u2026" [--llm]\`.
|
|
31931
|
+
- Epics: \`aidlc epic list [--tag <tag>]|status <id>|start <id> --brief "\u2026" [--llm]|tag <id> [tags\u2026]\`.
|
|
31870
31932
|
- Recipes: \`aidlc recipe init\`, \`aidlc pipeline recipes|classify "<brief>"|generate\`.
|
|
31871
31933
|
- Runs: \`aidlc run start <pipeline> --context k=v\`, \`aidlc run exec <runId> [--auto-approve]\`.
|
|
31872
31934
|
- Watch: \`aidlc watch\`, \`aidlc tail\`, \`aidlc dashboard\`, \`aidlc monitor [--start|--open]\`.
|
|
@@ -31876,7 +31938,7 @@ the other within ~200ms.
|
|
|
31876
31938
|
|
|
31877
31939
|
## VS Code extension setup & UI
|
|
31878
31940
|
1. Install **AIDLC Native** from the Extensions view (Marketplace in VS Code, Open VSX
|
|
31879
|
-
in Antigravity / Cursor / VSCodium), or \`code --install-extension delete101020.aidlc\`.
|
|
31941
|
+
in Antigravity / Cursor / VSCodium), or \`code --install-extension delete101020.aidlc-native\`.
|
|
31880
31942
|
CLI: \`npm install -g @delete101020/aidlc\` (the command is \`aidlc\`).
|
|
31881
31943
|
2. Ensure \`claude\` is on PATH and authenticated (the sidebar surfaces MCP/claude state).
|
|
31882
31944
|
3. Open a project folder. The **AIDLC** sidebar (activity bar) shows:
|
|
@@ -31949,7 +32011,8 @@ VS Code extension over the filesystem.
|
|
|
31949
32011
|
|
|
31950
32012
|
\u2500\u2500 Step 4: Work by epic (task-type \u2192 pipeline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
31951
32013
|
aidlc epic start <id> --brief "\u2026" [--llm]
|
|
31952
|
-
aidlc epic list [--status \u2026] aidlc epic status <id>
|
|
32014
|
+
aidlc epic list [--status \u2026] [--tag \u2026] aidlc epic status <id>
|
|
32015
|
+
aidlc epic tag <id> [tags\u2026] tag an epic (stored uppercase)
|
|
31953
32016
|
|
|
31954
32017
|
\u2500\u2500 Step 5: Watch what's happening \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
31955
32018
|
aidlc watch live table of all runs
|
|
@@ -31973,10 +32036,10 @@ var require_dist = __commonJS({
|
|
|
31973
32036
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
31974
32037
|
exports2.parseFollowUps = exports2.FollowUpsParseError = exports2.FollowUpManifestSchema = exports2.FollowUpItemSchema = exports2.SIGNAL_FILE = exports2.FOLLOW_UP_ARTIFACT = exports2.readEpicSignal = exports2.existingEpicIds = exports2.followUpIdFor = exports2.followUpEpicId = exports2.renderIntentMarkdown = exports2.openFollowUpEpic = exports2.openIncidentEpic = exports2.SignalParseError = exports2.isSignal = exports2.parseSignal = exports2.SignalSchema = exports2.EpicStepEditError = exports2.resolveStepRef = exports2.describeGateEffect = exports2.commitEpicStepEdit = exports2.planSetEpicStepGates = exports2.planRemoveEpicStep = exports2.planAddEpicStep = exports2.EpicScaffoldError = exports2.epicsRoot = exports2.mapStepStatusToEpic = exports2.mirrorRunStateToEpic = exports2.scaffoldEpic = exports2.resolveArtifactCommitConfig = exports2.commitApprovedArtifacts = exports2.PipelineAdaptError = exports2.applyAdaptation = exports2.parseAdaptationVerdict = exports2.buildAdaptationPrompt = exports2.buildPhaseCatalog = exports2.slugEpicId = exports2.parseClassificationVerdict = exports2.buildClassificationPrompt = exports2.heuristicClassify = exports2.PipelineAssembleError = exports2.recipePipelineId = exports2.assemblePipeline = exports2.collectWorkspaceRefIssues = exports2.stepDagId = exports2.stepAgentId = exports2.normalizeStep = exports2.WorkspaceValidationError = exports2.validateWorkspace = exports2.WorkspaceSchema = void 0;
|
|
31975
32038
|
exports2.composeAgentPrompt = exports2.PROJECT_INSTRUCTION_FILES = exports2.findProjectInstructions = exports2.stripPersonaMetadata = exports2.PersonaLoader = exports2.SkillNotFoundError = exports2.SkillLoader = exports2.EnvVarMissingError = exports2.EnvResolver = exports2.epicPipelineReport = exports2.planEpicPipelineExtraction = exports2.epicOwningPipeline = exports2.unstageEpicPipeline = exports2.stageEpicPipeline = exports2.writeEpicPipelines = exports2.splitEpicPipelines = exports2.mergeEpicPipelines = exports2.epicPipelinePath = exports2.EPIC_PIPELINE_FILENAME = exports2.WORKSPACE_DIR = exports2.WORKSPACE_FILENAME = exports2.WorkspaceParseError = exports2.WorkspaceNotFoundError = exports2.WorkspaceLoader = exports2.renderPlanMarkdown = exports2.generatePlan = exports2.collectContext = exports2.followUpHookFailures = exports2.pendingFollowUpDone = exports2.applyFollowUpHookRun = exports2.trackFollowUpChildren = exports2.writeFollowUpHookLedger = exports2.readFollowUpHookLedger = exports2.followUpHookLedgerPath = exports2.runFollowUpHook = exports2.fillFollowUpHookCommand = exports2.resolveFollowUpHooks = exports2.epicPipelineId = exports2.FOLLOW_UP_HOOK_TIMEOUT_MS = exports2.FOLLOW_UP_HOOKS_LEDGER = exports2.stepProducesFollowUps = exports2.collectFollowUpHookIssues = exports2.FOLLOW_UP_HOOK_PLACEHOLDERS = exports2.FOLLOW_UP_HOOK_KEYS = exports2.FOLLOW_UP_INTENT = exports2.FOLLOW_UPS_FILE = exports2.openManifestFollowUp = exports2.followUpChildId = exports2.followUpsOf = exports2.readEpicFollowUps = void 0;
|
|
31976
|
-
exports2.
|
|
31977
|
-
exports2.
|
|
31978
|
-
exports2.
|
|
31979
|
-
exports2.AIDLC_CORE_VERSION = exports2.AIDLC_CLI_GUIDE_TEXT = exports2.AIDLC_KNOWLEDGE = exports2.clearResolveCommandCache = exports2.resolveCommand = exports2.remapClaudePath = exports2.claudeConfigEnv = exports2.claudeJsonPath = exports2.isDefaultClaudeConfigDir = exports2.claudeConfigDir = exports2.resolveClaudeConfigDir = exports2.defaultClaudeConfigDir = exports2.getClaudeConfigDirOverride = exports2.setClaudeConfigDir = exports2.resolveDeclaredPath = exports2.expandHome = exports2.ProfileLoadError = exports2.UnknownStandardError = exports2.builtinProfiles = void 0;
|
|
32039
|
+
exports2.buildClaudeSpawnEnv = exports2.hasClaudeLogin = exports2.isInsideClaudeCodeSession = exports2.createJsonSink = exports2.createLineSink = exports2.isCodexMcpConfigured = exports2.codexConfigPath = exports2.readProjectMcpServer = exports2.mcpRegistrarFor = exports2.codexMcpRegistrar = exports2.claudeMcpRegistrar = exports2.CodexRunner = exports2.DefaultRunner = exports2.RunnerRegistry = exports2.targetPath = exports2.scopePaths = exports2.discoverAssets = exports2.commandBodyIsStale = exports2.readEpicTags = exports2.normalizeTags = exports2.normalizeTag = exports2.epicMatchesTags = exports2.applyTagEdit = exports2.MAX_TAG_LENGTH = exports2.EPIC_TAGS_KEY = exports2.strictModeSection = exports2.resolveEpicStrictMode = exports2.epicStrictMode = exports2.commandBodyPredatesStrictMode = exports2.STRICT_MODE_KEY = exports2.STRICT_MODE_HEADING = exports2.writeUserEpicIdPrefix = exports2.userConfigPath = exports2.readUserConfig = exports2.readGitUserName = exports2.ensureUserConfigIgnored = exports2.USER_CONFIG_RELPATH = exports2.USER_CONFIG_IGNORE_LINE = exports2.suggestEpicId = exports2.resolveEpicIdPrefixChain = exports2.resolveEpicIdPrefix = exports2.epicIdDateStamp = exports2.deriveEpicIdPrefix = exports2.EPIC_ID_PREFIX_PATTERN = exports2.EPIC_ID_PREFIX_KEY = exports2.resolveArtifactLanguage = exports2.commandBodyPredatesArtifactLanguage = exports2.artifactLanguageSection = exports2.ARTIFACT_LANGUAGE_HEADING = exports2.stripPersonaDirectives = void 0;
|
|
32040
|
+
exports2.getBuiltinRecipeSummaries = exports2.getAllBuiltinPipelineSummaries = exports2.getSdlcBuiltinPipelineSummary = exports2.getBuiltinPipelineSummary = exports2.getBuiltinWorkflowByPipelineId = exports2.getBuiltinWorkflow = exports2.workflowSlug = exports2.builtinTemplatesRoot = exports2.pipelineCommandId = exports2.PHASES = exports2.BUILTIN_WORKFLOWS = exports2.withBackfilledStepNames = exports2.describeDrift = exports2.reconcileRunSteps = exports2.RUN_STATE_SCHEMA_VERSION = exports2.migrateRunState = exports2.stepIdentity = exports2.resolvePath = exports2.AutoReviewerError = exports2.runAutoReview = exports2.renderRunReport = exports2.verifyRun = exports2.runExecLoop = exports2.estimateCostUsd = exports2.providerAliases = exports2.ratesFromConfig = exports2.mergeRates = exports2.BUILTIN_RATES = exports2.checkBudget = exports2.PipelineRunError = exports2.submitAutoReviewVerdict = exports2.requestStepUpdate = exports2.rerunStep = exports2.rejectStep = exports2.approveStep = exports2.markStepDone = exports2.canStartStep = exports2.startRun = exports2.activateBackendFromWorkspace = exports2.activateRunStateBackend = exports2.resolveRunStateBackend = exports2.GitRunStateStore = exports2.RUN_ID_PATTERN = exports2.FileRunStateStore = exports2.RunStateStore = exports2.harnessCapabilities = exports2.NO_HARNESS_CAPABILITIES = exports2.RunnerValidationError = exports2.validateRunnerExport = exports2.CustomRunnerLoader = void 0;
|
|
32041
|
+
exports2.TRACE_RULES = exports2.PROFILES_DIR = exports2.DEFAULT_PROFILE_ID = exports2.BUILTIN_PROFILE_IDS = exports2.setEpicMemoryHook = exports2.isEpicMemoryHookEnabled = exports2.installAnnotationTools = exports2.relativeEpicRoot = exports2.provisionDeclaredWorkflows = exports2.provisionWorkflowFiles = exports2.writeWorkflowArtifactTemplates = exports2.writeWorkflowCommands = exports2.provisionShortcutDocs = exports2.writeTwoLayerCommands = exports2.shortcutCommandDoc = exports2.backboneCommandDoc = exports2.unprovisionedPhases = exports2.nextEligiblePhase = exports2.resolveComposition = exports2.shortcutCommandId = exports2.getCanonicalPhase = exports2.isCanonicalPhase = exports2.BACKBONE_COMMAND_ID = exports2.CANONICAL_PHASE_IDS = exports2.CANONICAL_PHASES = exports2.renderTemplate = exports2.DEFAULT_GLOBAL_WORKFLOW_IDS = exports2.detectGlobalBuiltinSource = exports2.uninstallWorkflowGlobalsByIds = exports2.isWorkflowGloballyInstalled = exports2.installWorkflowGlobalsByIds = exports2.installGlobalDefaults = exports2.resolveProviderModel = exports2.isClaudeTierAlias = exports2.CLAUDE_TIER_ALIASES = exports2.FAST_MODEL = exports2.CODING_MODEL = exports2.PLANNING_MODEL = exports2.isBuiltinPreset = exports2.BUILTIN_PRESET_IDS = exports2.writeBuiltinAutoReviewValidators = exports2.resolvePrimaryStack = exports2.getSdlcArtifactTemplates = exports2.getBuiltinArtifactTemplates = exports2.phaseArtifactFileName = exports2.sdlcClaudeCommand = exports2.builtinClaudeCommand = exports2.loadAllBuiltinPresets = exports2.loadBuiltinPreset = exports2.planRecipeMigration = void 0;
|
|
32042
|
+
exports2.AIDLC_CORE_VERSION = exports2.AIDLC_CLI_GUIDE_TEXT = exports2.AIDLC_KNOWLEDGE = exports2.clearResolveCommandCache = exports2.resolveCommand = exports2.remapClaudePath = exports2.claudeConfigEnv = exports2.claudeJsonPath = exports2.isDefaultClaudeConfigDir = exports2.claudeConfigDir = exports2.resolveClaudeConfigDir = exports2.defaultClaudeConfigDir = exports2.getClaudeConfigDirOverride = exports2.setClaudeConfigDir = exports2.resolveDeclaredPath = exports2.expandHome = exports2.ProfileLoadError = exports2.UnknownStandardError = exports2.builtinProfiles = exports2.loadActiveProfile = exports2.loadProfile = exports2.listProfileManifests = exports2.resolveStandard = exports2.workspaceStandard = exports2.isBuiltinProfileId = exports2.ProfileSchema = void 0;
|
|
31980
32043
|
var WorkspaceSchema_1 = require_WorkspaceSchema();
|
|
31981
32044
|
Object.defineProperty(exports2, "WorkspaceSchema", { enumerable: true, get: function() {
|
|
31982
32045
|
return WorkspaceSchema_1.WorkspaceSchema;
|
|
@@ -32377,6 +32440,28 @@ var require_dist = __commonJS({
|
|
|
32377
32440
|
Object.defineProperty(exports2, "strictModeSection", { enumerable: true, get: function() {
|
|
32378
32441
|
return strictMode_1.strictModeSection;
|
|
32379
32442
|
} });
|
|
32443
|
+
var epicTags_1 = require_epicTags();
|
|
32444
|
+
Object.defineProperty(exports2, "EPIC_TAGS_KEY", { enumerable: true, get: function() {
|
|
32445
|
+
return epicTags_1.EPIC_TAGS_KEY;
|
|
32446
|
+
} });
|
|
32447
|
+
Object.defineProperty(exports2, "MAX_TAG_LENGTH", { enumerable: true, get: function() {
|
|
32448
|
+
return epicTags_1.MAX_TAG_LENGTH;
|
|
32449
|
+
} });
|
|
32450
|
+
Object.defineProperty(exports2, "applyTagEdit", { enumerable: true, get: function() {
|
|
32451
|
+
return epicTags_1.applyTagEdit;
|
|
32452
|
+
} });
|
|
32453
|
+
Object.defineProperty(exports2, "epicMatchesTags", { enumerable: true, get: function() {
|
|
32454
|
+
return epicTags_1.epicMatchesTags;
|
|
32455
|
+
} });
|
|
32456
|
+
Object.defineProperty(exports2, "normalizeTag", { enumerable: true, get: function() {
|
|
32457
|
+
return epicTags_1.normalizeTag;
|
|
32458
|
+
} });
|
|
32459
|
+
Object.defineProperty(exports2, "normalizeTags", { enumerable: true, get: function() {
|
|
32460
|
+
return epicTags_1.normalizeTags;
|
|
32461
|
+
} });
|
|
32462
|
+
Object.defineProperty(exports2, "readEpicTags", { enumerable: true, get: function() {
|
|
32463
|
+
return epicTags_1.readEpicTags;
|
|
32464
|
+
} });
|
|
32380
32465
|
var commandBodyFreshness_1 = require_commandBodyFreshness();
|
|
32381
32466
|
Object.defineProperty(exports2, "commandBodyIsStale", { enumerable: true, get: function() {
|
|
32382
32467
|
return commandBodyFreshness_1.commandBodyIsStale;
|
|
@@ -41510,7 +41595,7 @@ var require_package = __commonJS({
|
|
|
41510
41595
|
"package.json"(exports2, module2) {
|
|
41511
41596
|
module2.exports = {
|
|
41512
41597
|
name: "@delete101020/aidlc",
|
|
41513
|
-
version: "4.0.
|
|
41598
|
+
version: "4.0.2",
|
|
41514
41599
|
description: "AIDLC Native CLI, a fork of AIDLC \u2014 drive Claude through the six-stage AI-Native SDLC Playbook: Plan \u2192 Design \u2192 Build \u2192 Test \u2192 Deploy \u2192 Maintain, with artifact gates, requirements traceability, an incident loop back to Plan, and Spec Kit support.",
|
|
41515
41600
|
license: "MIT",
|
|
41516
41601
|
repository: {
|
|
@@ -44179,7 +44264,7 @@ var safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
|
44179
44264
|
var safeDump = renamed("safeDump", "dump");
|
|
44180
44265
|
|
|
44181
44266
|
// src/index.ts
|
|
44182
|
-
var
|
|
44267
|
+
var import_core26 = __toESM(require_dist());
|
|
44183
44268
|
|
|
44184
44269
|
// src/commands/validate.ts
|
|
44185
44270
|
var import_chalk = __toESM(require_source());
|
|
@@ -47130,11 +47215,12 @@ var http = __toESM(require("http"));
|
|
|
47130
47215
|
var path11 = __toESM(require("path"));
|
|
47131
47216
|
var import_chalk14 = __toESM(require_source());
|
|
47132
47217
|
var import_chokidar3 = __toESM(require_chokidar());
|
|
47133
|
-
var
|
|
47218
|
+
var import_core18 = __toESM(require_dist());
|
|
47134
47219
|
|
|
47135
47220
|
// src/epicsList.ts
|
|
47136
47221
|
var fs9 = __toESM(require("fs"));
|
|
47137
47222
|
var path10 = __toESM(require("path"));
|
|
47223
|
+
var import_core17 = __toESM(require_dist());
|
|
47138
47224
|
var STATUS_VALUES = ["pending", "in_progress", "done", "failed"];
|
|
47139
47225
|
function asStatus(v) {
|
|
47140
47226
|
return STATUS_VALUES.includes(v) ? v : "pending";
|
|
@@ -47178,6 +47264,7 @@ function listEpics(workspaceRoot, doc) {
|
|
|
47178
47264
|
description: typeof parsed.description === "string" ? parsed.description : "",
|
|
47179
47265
|
status: asStatus(parsed.status),
|
|
47180
47266
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : "",
|
|
47267
|
+
tags: (0, import_core17.readEpicTags)(parsed),
|
|
47181
47268
|
pipeline: typeof parsed.pipeline === "string" ? parsed.pipeline : null,
|
|
47182
47269
|
agents: Array.isArray(parsed.agents) ? parsed.agents.map(String) : [],
|
|
47183
47270
|
currentStep: typeof parsed.currentStep === "number" ? parsed.currentStep : 0,
|
|
@@ -47234,12 +47321,12 @@ function registerDashboard(program3) {
|
|
|
47234
47321
|
}
|
|
47235
47322
|
if (url.pathname === "/api/runs") {
|
|
47236
47323
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
47237
|
-
res.end(JSON.stringify(
|
|
47324
|
+
res.end(JSON.stringify(import_core18.RunStateStore.list(root)));
|
|
47238
47325
|
return;
|
|
47239
47326
|
}
|
|
47240
47327
|
if (url.pathname.startsWith("/api/runs/")) {
|
|
47241
47328
|
const runId = url.pathname.slice("/api/runs/".length);
|
|
47242
|
-
const state =
|
|
47329
|
+
const state = import_core18.RunStateStore.load(root, runId);
|
|
47243
47330
|
if (!state) {
|
|
47244
47331
|
res.writeHead(404);
|
|
47245
47332
|
res.end("not found");
|
|
@@ -47381,7 +47468,7 @@ function handleAction(req, res, root) {
|
|
|
47381
47468
|
res.end(JSON.stringify({ error: "invalid JSON" }));
|
|
47382
47469
|
return;
|
|
47383
47470
|
}
|
|
47384
|
-
const state =
|
|
47471
|
+
const state = import_core18.RunStateStore.load(root, payload.runId);
|
|
47385
47472
|
if (!state) {
|
|
47386
47473
|
res.writeHead(404);
|
|
47387
47474
|
res.end(JSON.stringify({ error: `run not found: ${payload.runId}` }));
|
|
@@ -47391,31 +47478,31 @@ function handleAction(req, res, root) {
|
|
|
47391
47478
|
try {
|
|
47392
47479
|
switch (payload.type) {
|
|
47393
47480
|
case "mark-done": {
|
|
47394
|
-
const ws =
|
|
47481
|
+
const ws = import_core18.WorkspaceLoader.load(root);
|
|
47395
47482
|
const pipeline = ws.config.pipelines.find((p) => p.id === state.pipelineId);
|
|
47396
47483
|
if (!pipeline) {
|
|
47397
47484
|
throw new Error(`pipeline ${state.pipelineId} not found`);
|
|
47398
47485
|
}
|
|
47399
|
-
next = (0,
|
|
47486
|
+
next = (0, import_core18.markStepDone)({ state, pipeline, workspaceRoot: root });
|
|
47400
47487
|
break;
|
|
47401
47488
|
}
|
|
47402
47489
|
case "approve": {
|
|
47403
|
-
const ws =
|
|
47490
|
+
const ws = import_core18.WorkspaceLoader.load(root);
|
|
47404
47491
|
const pipeline = ws.config.pipelines.find((p) => p.id === state.pipelineId);
|
|
47405
47492
|
if (!pipeline) {
|
|
47406
47493
|
throw new Error(`pipeline ${state.pipelineId} not found`);
|
|
47407
47494
|
}
|
|
47408
|
-
next = (0,
|
|
47495
|
+
next = (0, import_core18.approveStep)({ state, pipeline });
|
|
47409
47496
|
if (payload.comment) {
|
|
47410
47497
|
next.steps[state.currentStepIdx].feedback = payload.comment;
|
|
47411
47498
|
}
|
|
47412
47499
|
break;
|
|
47413
47500
|
}
|
|
47414
47501
|
case "reject":
|
|
47415
|
-
next = (0,
|
|
47502
|
+
next = (0, import_core18.rejectStep)({ state, reason: payload.reason ?? "" });
|
|
47416
47503
|
break;
|
|
47417
47504
|
case "rerun":
|
|
47418
|
-
next = (0,
|
|
47505
|
+
next = (0, import_core18.rerunStep)({ state, feedback: payload.feedback });
|
|
47419
47506
|
break;
|
|
47420
47507
|
default:
|
|
47421
47508
|
res.writeHead(400);
|
|
@@ -47424,7 +47511,7 @@ function handleAction(req, res, root) {
|
|
|
47424
47511
|
}
|
|
47425
47512
|
} catch (err) {
|
|
47426
47513
|
const msg2 = err instanceof Error ? err.message : String(err);
|
|
47427
|
-
const missing = err instanceof
|
|
47514
|
+
const missing = err instanceof import_core18.PipelineRunError ? err.missing : void 0;
|
|
47428
47515
|
res.writeHead(400);
|
|
47429
47516
|
res.end(JSON.stringify({ error: msg2, missing }));
|
|
47430
47517
|
return;
|
|
@@ -47963,27 +48050,39 @@ var import_chalk15 = __toESM(require_source());
|
|
|
47963
48050
|
var import_cli_table32 = __toESM(require_cli_table3());
|
|
47964
48051
|
var fs10 = __toESM(require("fs"));
|
|
47965
48052
|
var path12 = __toESM(require("path"));
|
|
47966
|
-
var
|
|
48053
|
+
var import_core19 = __toESM(require_dist());
|
|
47967
48054
|
function registerEpic(program3) {
|
|
47968
48055
|
const cmd = program3.command("epic").description("List + inspect epics from <state.root>/<id>/state.json (mirrors the extension)");
|
|
47969
|
-
cmd.command("list").description("List all epics found under workspace state.root (default: docs/epics/)").option("--json", "Output raw JSON").option("--status <status>", "Filter by status (pending | in_progress | done | failed)").
|
|
48056
|
+
cmd.command("list").description("List all epics found under workspace state.root (default: docs/epics/)").option("--json", "Output raw JSON").option("--status <status>", "Filter by status (pending | in_progress | done | failed)").option(
|
|
48057
|
+
"--tag <tag>",
|
|
48058
|
+
'Filter by tag \u2014 repeatable, and an epic must carry all of them. Case and accents are folded, so --tag "thanh to\xE1n" finds THANH-TOAN',
|
|
48059
|
+
collectKv,
|
|
48060
|
+
[]
|
|
48061
|
+
).action((opts, actionCmd) => {
|
|
47970
48062
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
47971
48063
|
const doc = readYaml(root);
|
|
47972
48064
|
let epics = listEpics(root, doc);
|
|
47973
48065
|
if (opts.status) {
|
|
47974
48066
|
epics = epics.filter((e) => e.status === opts.status);
|
|
47975
48067
|
}
|
|
48068
|
+
const wantedTags = (0, import_core19.normalizeTags)(opts.tag);
|
|
48069
|
+
if (wantedTags.length > 0) {
|
|
48070
|
+
epics = epics.filter((e) => (0, import_core19.epicMatchesTags)(e.tags, wantedTags));
|
|
48071
|
+
}
|
|
47976
48072
|
if (opts.json) {
|
|
47977
48073
|
console.log(JSON.stringify(epics, null, 2));
|
|
47978
48074
|
return;
|
|
47979
48075
|
}
|
|
47980
48076
|
if (epics.length === 0) {
|
|
47981
48077
|
console.log(import_chalk15.default.dim("No epics found."));
|
|
48078
|
+
if (wantedTags.length > 0) {
|
|
48079
|
+
console.log(import_chalk15.default.dim(` tags = ${wantedTags.join(" + ")}`));
|
|
48080
|
+
}
|
|
47982
48081
|
console.log(import_chalk15.default.dim(` state.root = ${doc?.state ? doc.state.root ?? "docs/epics" : "docs/epics"}`));
|
|
47983
48082
|
return;
|
|
47984
48083
|
}
|
|
47985
48084
|
const table = new import_cli_table32.default({
|
|
47986
|
-
head: [import_chalk15.default.bold("Epic"), import_chalk15.default.bold("Title"), import_chalk15.default.bold("Progress"), import_chalk15.default.bold("Status"), import_chalk15.default.bold("Pipeline")],
|
|
48085
|
+
head: [import_chalk15.default.bold("Epic"), import_chalk15.default.bold("Title"), import_chalk15.default.bold("Tags"), import_chalk15.default.bold("Progress"), import_chalk15.default.bold("Status"), import_chalk15.default.bold("Pipeline")],
|
|
47987
48086
|
style: { head: [], border: [] }
|
|
47988
48087
|
});
|
|
47989
48088
|
for (const epic of epics) {
|
|
@@ -47994,6 +48093,7 @@ function registerEpic(program3) {
|
|
|
47994
48093
|
table.push([
|
|
47995
48094
|
import_chalk15.default.bold(epic.id),
|
|
47996
48095
|
truncate(epic.title || import_chalk15.default.dim("(untitled)"), 40),
|
|
48096
|
+
epic.tags.length > 0 ? import_chalk15.default.cyan(truncate(epic.tags.join(" "), 28)) : import_chalk15.default.dim("\u2014"),
|
|
47997
48097
|
stepLabel2,
|
|
47998
48098
|
colorEpicStatus(epic.status),
|
|
47999
48099
|
import_chalk15.default.dim(epic.pipeline ?? "\u2014")
|
|
@@ -48021,7 +48121,7 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48021
48121
|
}
|
|
48022
48122
|
printEpicDetail(epic);
|
|
48023
48123
|
});
|
|
48024
|
-
cmd.command("start <epicId>").description(`Scaffold a new epic on disk (folder + artifacts + run state) \u2014 mirrors the extension's "Start epic"`).option("--recipe <id>", "assemble a right-sized pipeline from this recipe").option("--pipeline <id>", "use an existing pipeline as-is").option("--brief <text...>", "classify this requirement brief into a recipe, then assemble").option("--llm", "use the `claude` CLI to classify --brief (falls back to heuristic)").option("--from <pipelineId>", "override the recipe's source pipeline").option("--title <title>", "epic title").option("--desc <description>", "epic description / requirement snapshot").option("--input <kv>", "capability input as key=value (repeatable)", collectKv, []).option("--no-strict", "work to the size of this epic \u2014 no invented NFR / risk / alternatives sections").action((epicId, opts, actionCmd) => {
|
|
48124
|
+
cmd.command("start <epicId>").description(`Scaffold a new epic on disk (folder + artifacts + run state) \u2014 mirrors the extension's "Start epic"`).option("--recipe <id>", "assemble a right-sized pipeline from this recipe").option("--pipeline <id>", "use an existing pipeline as-is").option("--brief <text...>", "classify this requirement brief into a recipe, then assemble").option("--llm", "use the `claude` CLI to classify --brief (falls back to heuristic)").option("--from <pipelineId>", "override the recipe's source pipeline").option("--title <title>", "epic title").option("--desc <description>", "epic description / requirement snapshot").option("--input <kv>", "capability input as key=value (repeatable)", collectKv, []).option("--tag <tag>", 'tag for this epic (repeatable) \u2014 stored uppercase, e.g. "thanh to\xE1n" \u2192 THANH-TOAN', collectKv, []).option("--no-strict", "work to the size of this epic \u2014 no invented NFR / risk / alternatives sections").action((epicId, opts, actionCmd) => {
|
|
48025
48125
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48026
48126
|
const doc = requireYaml(root);
|
|
48027
48127
|
const modes = [opts.recipe, opts.pipeline, opts.brief?.length ? "brief" : void 0].filter(Boolean).length;
|
|
@@ -48031,7 +48131,7 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48031
48131
|
}
|
|
48032
48132
|
let config;
|
|
48033
48133
|
try {
|
|
48034
|
-
config = (0,
|
|
48134
|
+
config = (0, import_core19.validateWorkspace)(doc, ".aidlc/workspace.yaml");
|
|
48035
48135
|
} catch (err) {
|
|
48036
48136
|
console.error(import_chalk15.default.red("workspace.yaml is invalid \u2014 fix it before starting an epic:"));
|
|
48037
48137
|
console.error(import_chalk15.default.dim(err instanceof Error ? err.message : String(err)));
|
|
@@ -48055,7 +48155,7 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48055
48155
|
let recipeId = opts.recipe;
|
|
48056
48156
|
if (!recipeId) {
|
|
48057
48157
|
const brief = (opts.brief ?? []).join(" ").trim();
|
|
48058
|
-
const heur = (0,
|
|
48158
|
+
const heur = (0, import_core19.heuristicClassify)(brief, config.recipes);
|
|
48059
48159
|
let verdict = heur;
|
|
48060
48160
|
if (opts.llm) {
|
|
48061
48161
|
console.log(import_chalk15.default.dim(`Provisional \u2192 ${heur.recipeId} (${heur.confidence}, heuristic) \u2014 refining with claude\u2026`));
|
|
@@ -48070,20 +48170,20 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48070
48170
|
recipe.from = opts.from;
|
|
48071
48171
|
}
|
|
48072
48172
|
}
|
|
48073
|
-
const pipelineId = (0,
|
|
48173
|
+
const pipelineId = (0, import_core19.recipePipelineId)({ recipeId, epicId, taken: existingIds(doc.pipelines) });
|
|
48074
48174
|
try {
|
|
48075
|
-
pipelineCfg = (0,
|
|
48175
|
+
pipelineCfg = (0, import_core19.assemblePipeline)(config, { recipeId, pipelineId });
|
|
48076
48176
|
} catch (err) {
|
|
48077
|
-
if (err instanceof
|
|
48177
|
+
if (err instanceof import_core19.PipelineAssembleError) {
|
|
48078
48178
|
console.error(import_chalk15.default.red("Could not assemble pipeline: ") + import_chalk15.default.dim(err.message));
|
|
48079
48179
|
process.exit(1);
|
|
48080
48180
|
}
|
|
48081
48181
|
throw err;
|
|
48082
48182
|
}
|
|
48083
48183
|
doc.pipelines.push(pipelineCfg);
|
|
48084
|
-
(0,
|
|
48184
|
+
(0, import_core19.stageEpicPipeline)(doc, pipelineCfg.id, epicId);
|
|
48085
48185
|
try {
|
|
48086
|
-
(0,
|
|
48186
|
+
(0, import_core19.validateWorkspace)(doc, ".aidlc/workspace.yaml");
|
|
48087
48187
|
} catch (err) {
|
|
48088
48188
|
console.error(import_chalk15.default.red("Assembled pipeline failed validation \u2014 not written:"));
|
|
48089
48189
|
console.error(import_chalk15.default.dim(err instanceof Error ? err.message : String(err)));
|
|
@@ -48092,7 +48192,7 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48092
48192
|
writeYaml(root, doc);
|
|
48093
48193
|
console.log(import_chalk15.default.dim(`Assembled pipeline ${import_chalk15.default.bold(pipelineCfg.id)} from recipe ${import_chalk15.default.bold(recipeId)}`));
|
|
48094
48194
|
}
|
|
48095
|
-
const agents = Array.isArray(pipelineCfg.steps) ? pipelineCfg.steps.map(
|
|
48195
|
+
const agents = Array.isArray(pipelineCfg.steps) ? pipelineCfg.steps.map(import_core19.stepAgentId) : [];
|
|
48096
48196
|
const inputs = {};
|
|
48097
48197
|
for (const kv of opts.input) {
|
|
48098
48198
|
const eq = kv.indexOf("=");
|
|
@@ -48101,7 +48201,7 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48101
48201
|
}
|
|
48102
48202
|
}
|
|
48103
48203
|
try {
|
|
48104
|
-
const { epicDir } = (0,
|
|
48204
|
+
const { epicDir } = (0, import_core19.scaffoldEpic)({
|
|
48105
48205
|
workspaceRoot: root,
|
|
48106
48206
|
doc,
|
|
48107
48207
|
epicId,
|
|
@@ -48111,13 +48211,18 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48111
48211
|
agents,
|
|
48112
48212
|
inputs,
|
|
48113
48213
|
pipeline: pipelineCfg,
|
|
48114
|
-
strictMode: opts.strict
|
|
48214
|
+
strictMode: opts.strict,
|
|
48215
|
+
tags: opts.tag
|
|
48115
48216
|
});
|
|
48217
|
+
const tags = (0, import_core19.normalizeTags)(opts.tag);
|
|
48116
48218
|
const steps = agents.join(" \u2192 ");
|
|
48117
48219
|
console.log(import_chalk15.default.green("\u2714") + ` Started epic ${import_chalk15.default.bold(epicId)}`);
|
|
48118
48220
|
console.log(import_chalk15.default.dim(` Pipeline: ${pipelineCfg.id}`));
|
|
48119
48221
|
console.log(import_chalk15.default.dim(` Steps: ${steps}`));
|
|
48120
48222
|
console.log(import_chalk15.default.dim(` Dir: ${epicDir}`));
|
|
48223
|
+
if (tags.length > 0) {
|
|
48224
|
+
console.log(import_chalk15.default.dim(" Tags: ") + import_chalk15.default.cyan(tags.join(" ")));
|
|
48225
|
+
}
|
|
48121
48226
|
if (!opts.strict) {
|
|
48122
48227
|
console.log(import_chalk15.default.dim(" Depth: strict_mode: false \u2014 phases stay proportional to the work"));
|
|
48123
48228
|
}
|
|
@@ -48131,20 +48236,79 @@ ${epics.length} epic${epics.length !== 1 ? "s" : ""}`));
|
|
|
48131
48236
|
console.log(`
|
|
48132
48237
|
Run ${import_chalk15.default.cyan(`${runCmd} ${epicId}`)} in Claude to begin.`);
|
|
48133
48238
|
} catch (err) {
|
|
48134
|
-
if (err instanceof
|
|
48239
|
+
if (err instanceof import_core19.EpicScaffoldError) {
|
|
48135
48240
|
console.error(import_chalk15.default.red(err.message));
|
|
48136
48241
|
process.exit(1);
|
|
48137
48242
|
}
|
|
48138
48243
|
throw err;
|
|
48139
48244
|
}
|
|
48140
48245
|
});
|
|
48246
|
+
cmd.command("tag <id> [tags...]").description("Show or edit an epic's tags. Bare `tag <id>` prints them; extra words are added.").option("--add <tag>", "add a tag (repeatable) \u2014 same as passing it positionally", collectKv, []).option("--remove <tag>", "remove a tag (repeatable)", collectKv, []).option("--set <tag>", "replace every tag with these (repeatable)", collectKv, []).option("--clear", "remove every tag").option("--json", "Output the resulting tags as JSON").action((id, positional, opts, actionCmd) => {
|
|
48247
|
+
const root = resolveWorkspaceRoot(actionCmd);
|
|
48248
|
+
const doc = readYaml(root);
|
|
48249
|
+
const file = path12.join((0, import_core19.epicsRoot)(root, doc), id, "state.json");
|
|
48250
|
+
if (!fs10.existsSync(file)) {
|
|
48251
|
+
const all = listEpics(root, doc).map((e) => e.id);
|
|
48252
|
+
console.error(import_chalk15.default.red(`Epic "${id}" not found.`));
|
|
48253
|
+
if (all.length > 0) {
|
|
48254
|
+
console.error(import_chalk15.default.dim(`Available: ${all.join(", ")}`));
|
|
48255
|
+
}
|
|
48256
|
+
process.exit(1);
|
|
48257
|
+
}
|
|
48258
|
+
let state;
|
|
48259
|
+
try {
|
|
48260
|
+
state = JSON.parse(fs10.readFileSync(file, "utf8"));
|
|
48261
|
+
} catch (err) {
|
|
48262
|
+
console.error(import_chalk15.default.red(`Could not read ${file}: ${err instanceof Error ? err.message : String(err)}`));
|
|
48263
|
+
process.exit(1);
|
|
48264
|
+
return;
|
|
48265
|
+
}
|
|
48266
|
+
const before = (0, import_core19.readEpicTags)(state);
|
|
48267
|
+
const add = [...positional, ...opts.add];
|
|
48268
|
+
const clear = opts.clear === true;
|
|
48269
|
+
const hasEdit = clear || add.length > 0 || opts.remove.length > 0 || opts.set.length > 0;
|
|
48270
|
+
if (!hasEdit) {
|
|
48271
|
+
if (opts.json) {
|
|
48272
|
+
console.log(JSON.stringify(before, null, 2));
|
|
48273
|
+
return;
|
|
48274
|
+
}
|
|
48275
|
+
console.log(before.length > 0 ? import_chalk15.default.cyan(before.join(" ")) : import_chalk15.default.dim("(no tags)"));
|
|
48276
|
+
return;
|
|
48277
|
+
}
|
|
48278
|
+
const after = (0, import_core19.applyTagEdit)(before, {
|
|
48279
|
+
// `--clear` is `--set` with nothing in it; spelling it separately keeps
|
|
48280
|
+
// "remove everything" from needing an empty-string argument.
|
|
48281
|
+
set: clear ? [] : opts.set.length > 0 ? opts.set : void 0,
|
|
48282
|
+
add,
|
|
48283
|
+
remove: opts.remove
|
|
48284
|
+
});
|
|
48285
|
+
if (after.join("\0") === before.join("\0")) {
|
|
48286
|
+
console.log(import_chalk15.default.dim(`No change \u2014 ${id} already has ${before.length > 0 ? import_chalk15.default.cyan(before.join(" ")) : "no tags"}.`));
|
|
48287
|
+
return;
|
|
48288
|
+
}
|
|
48289
|
+
state[import_core19.EPIC_TAGS_KEY] = after;
|
|
48290
|
+
try {
|
|
48291
|
+
fs10.writeFileSync(file, JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
48292
|
+
} catch (err) {
|
|
48293
|
+
console.error(import_chalk15.default.red(`Could not write ${file}: ${err instanceof Error ? err.message : String(err)}`));
|
|
48294
|
+
process.exit(1);
|
|
48295
|
+
}
|
|
48296
|
+
if (opts.json) {
|
|
48297
|
+
console.log(JSON.stringify(after, null, 2));
|
|
48298
|
+
return;
|
|
48299
|
+
}
|
|
48300
|
+
console.log(import_chalk15.default.green("\u2714") + ` ${import_chalk15.default.bold(id)} tags: ` + (after.length > 0 ? import_chalk15.default.cyan(after.join(" ")) : import_chalk15.default.dim("(none)")));
|
|
48301
|
+
if (before.length > 0) {
|
|
48302
|
+
console.log(import_chalk15.default.dim(` was: ${before.join(" ")}`));
|
|
48303
|
+
}
|
|
48304
|
+
});
|
|
48141
48305
|
const pipelineCmd = cmd.command("pipeline").description("Move epic-owned pipelines out of the shared workspace.yaml");
|
|
48142
48306
|
pipelineCmd.command("extract").description(
|
|
48143
48307
|
"Move each epic's pipeline out of .aidlc/workspace.yaml into\n <state.root>/<epic>/pipeline.yaml. Only pipelines an epic names in its\n own state.json move; shared and hand-authored ones stay put."
|
|
48144
48308
|
).option("--dry-run", "List what would move, write nothing").action((opts, actionCmd) => {
|
|
48145
48309
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48146
48310
|
const doc = requireYaml(root);
|
|
48147
|
-
const plan = (0,
|
|
48311
|
+
const plan = (0, import_core19.planEpicPipelineExtraction)(root, doc);
|
|
48148
48312
|
if (plan.length === 0) {
|
|
48149
48313
|
console.log(import_chalk15.default.dim("No inline epic pipelines left to move."));
|
|
48150
48314
|
return;
|
|
@@ -48160,7 +48324,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48160
48324
|
return;
|
|
48161
48325
|
}
|
|
48162
48326
|
for (const item of plan) {
|
|
48163
|
-
(0,
|
|
48327
|
+
(0, import_core19.stageEpicPipeline)(doc, item.pipelineId, item.epicId);
|
|
48164
48328
|
}
|
|
48165
48329
|
writeYaml(root, doc);
|
|
48166
48330
|
console.log(import_chalk15.default.green("\u2714") + ` Moved ${plan.length} pipeline(s) out of .aidlc/workspace.yaml.`);
|
|
@@ -48169,19 +48333,19 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48169
48333
|
cmd.command("next-id").description("Print the id to give the next epic \u2014 honours epic_id_prefix in .aidlc/user.yaml").action((_opts, actionCmd) => {
|
|
48170
48334
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48171
48335
|
const doc = requireYaml(root);
|
|
48172
|
-
const dir = (0,
|
|
48336
|
+
const dir = (0, import_core19.epicsRoot)(root, doc);
|
|
48173
48337
|
const existing = fs10.existsSync(dir) ? fs10.readdirSync(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
|
|
48174
|
-
const { prefix } = (0,
|
|
48175
|
-
user: (0,
|
|
48338
|
+
const { prefix } = (0, import_core19.resolveEpicIdPrefixChain)({
|
|
48339
|
+
user: (0, import_core19.readUserConfig)(root),
|
|
48176
48340
|
workspace: doc,
|
|
48177
|
-
gitUserName: (0,
|
|
48341
|
+
gitUserName: (0, import_core19.readGitUserName)(root)
|
|
48178
48342
|
});
|
|
48179
|
-
console.log((0,
|
|
48343
|
+
console.log((0, import_core19.suggestEpicId)(existing, prefix));
|
|
48180
48344
|
});
|
|
48181
48345
|
cmd.command("strict <epicId> [value]").description("Show or set an epic's depth of work (strict_mode in its state.json)").action((epicId, value, _opts, actionCmd) => {
|
|
48182
48346
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48183
48347
|
const doc = requireYaml(root);
|
|
48184
|
-
const file = path12.join((0,
|
|
48348
|
+
const file = path12.join((0, import_core19.epicsRoot)(root, doc), epicId, "state.json");
|
|
48185
48349
|
if (!fs10.existsSync(file)) {
|
|
48186
48350
|
console.error(import_chalk15.default.red(`No epic "${epicId}" \u2014 expected ${file}`));
|
|
48187
48351
|
process.exit(1);
|
|
@@ -48195,7 +48359,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48195
48359
|
return;
|
|
48196
48360
|
}
|
|
48197
48361
|
if (value === void 0) {
|
|
48198
|
-
const on = (0,
|
|
48362
|
+
const on = (0, import_core19.epicStrictMode)(state);
|
|
48199
48363
|
console.log(`${epicId}: strict_mode ${on ? import_chalk15.default.bold("true") : import_chalk15.default.bold("false")}`);
|
|
48200
48364
|
console.log(import_chalk15.default.dim(on ? " Phases work at full depth. Set false for an epic the size of one task." : " Phases stay proportional to the work \u2014 no invented NFR / risk sections."));
|
|
48201
48365
|
return;
|
|
@@ -48207,7 +48371,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48207
48371
|
console.error(import_chalk15.default.red(`Expected on|off, got "${value}".`));
|
|
48208
48372
|
process.exit(1);
|
|
48209
48373
|
}
|
|
48210
|
-
state[
|
|
48374
|
+
state[import_core19.STRICT_MODE_KEY] = truthy.includes(v);
|
|
48211
48375
|
fs10.writeFileSync(file, JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
48212
48376
|
console.log(import_chalk15.default.green("\u2714") + ` ${epicId}: strict_mode ${truthy.includes(v)}`);
|
|
48213
48377
|
console.log(import_chalk15.default.dim(" Takes effect on the next phase run \u2014 nothing already written changes."));
|
|
@@ -48222,7 +48386,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48222
48386
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48223
48387
|
const doc = requireYaml(root);
|
|
48224
48388
|
const { runState, pipelineCfg } = requireEditableEpic(root, doc, epicId);
|
|
48225
|
-
const plan = runEdit(() => (0,
|
|
48389
|
+
const plan = runEdit(() => (0, import_core19.planAddEpicStep)({
|
|
48226
48390
|
runState,
|
|
48227
48391
|
pipeline: pipelineCfg,
|
|
48228
48392
|
step: {
|
|
@@ -48247,7 +48411,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48247
48411
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48248
48412
|
const doc = requireYaml(root);
|
|
48249
48413
|
const { runState, pipelineCfg } = requireEditableEpic(root, doc, epicId);
|
|
48250
|
-
const plan = runEdit(() => (0,
|
|
48414
|
+
const plan = runEdit(() => (0, import_core19.planRemoveEpicStep)({ runState, pipeline: pipelineCfg, step }));
|
|
48251
48415
|
writeEdit(root, doc, plan);
|
|
48252
48416
|
console.log(import_chalk15.default.green("\u2714") + ` Removed step ${import_chalk15.default.bold(plan.stepId)} from ${import_chalk15.default.bold(pipelineCfg.id)}`);
|
|
48253
48417
|
printSteps(plan);
|
|
@@ -48256,7 +48420,7 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48256
48420
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
48257
48421
|
const doc = requireYaml(root);
|
|
48258
48422
|
const { runState, pipelineCfg } = requireEditableEpic(root, doc, epicId);
|
|
48259
|
-
const plan = runEdit(() => (0,
|
|
48423
|
+
const plan = runEdit(() => (0, import_core19.planSetEpicStepGates)({
|
|
48260
48424
|
runState,
|
|
48261
48425
|
pipeline: pipelineCfg,
|
|
48262
48426
|
step,
|
|
@@ -48276,14 +48440,14 @@ ${plan.length} pipeline(s) would move. Re-run without --dry-run.`));
|
|
|
48276
48440
|
const arrow = c.to ? import_chalk15.default.yellow("on") : import_chalk15.default.dim("off");
|
|
48277
48441
|
console.log(` ${import_chalk15.default.dim(c.gate)} ${import_chalk15.default.dim(String(c.from))} \u2192 ${arrow}`);
|
|
48278
48442
|
}
|
|
48279
|
-
const note = (0,
|
|
48443
|
+
const note = (0, import_core19.describeGateEffect)(plan.stepStatus, plan.changes);
|
|
48280
48444
|
if (note) {
|
|
48281
48445
|
console.log(import_chalk15.default.yellow(` The step is ${plan.stepStatus}. `) + import_chalk15.default.dim(note));
|
|
48282
48446
|
}
|
|
48283
48447
|
});
|
|
48284
48448
|
}
|
|
48285
48449
|
function requireEditableEpic(root, doc, epicId) {
|
|
48286
|
-
const runState =
|
|
48450
|
+
const runState = import_core19.RunStateStore.load(root, epicId);
|
|
48287
48451
|
if (!runState) {
|
|
48288
48452
|
console.error(import_chalk15.default.red(`Epic "${epicId}" has no run state at .aidlc/runs/${epicId}.json.`));
|
|
48289
48453
|
console.error(import_chalk15.default.dim(" Only a pipeline-backed epic has a step list to edit."));
|
|
@@ -48307,7 +48471,7 @@ function runEdit(plan) {
|
|
|
48307
48471
|
try {
|
|
48308
48472
|
return plan();
|
|
48309
48473
|
} catch (err) {
|
|
48310
|
-
if (err instanceof
|
|
48474
|
+
if (err instanceof import_core19.EpicStepEditError) {
|
|
48311
48475
|
console.error(import_chalk15.default.red(err.message));
|
|
48312
48476
|
process.exit(1);
|
|
48313
48477
|
}
|
|
@@ -48316,7 +48480,7 @@ function runEdit(plan) {
|
|
|
48316
48480
|
}
|
|
48317
48481
|
function writeEdit(root, doc, plan) {
|
|
48318
48482
|
const before = JSON.parse(JSON.stringify(doc.pipelines));
|
|
48319
|
-
(0,
|
|
48483
|
+
(0, import_core19.commitEpicStepEdit)({
|
|
48320
48484
|
workspaceRoot: root,
|
|
48321
48485
|
doc,
|
|
48322
48486
|
plan,
|
|
@@ -48335,13 +48499,13 @@ function writePipeline(root, doc, pipeline) {
|
|
|
48335
48499
|
);
|
|
48336
48500
|
let config;
|
|
48337
48501
|
try {
|
|
48338
|
-
config = (0,
|
|
48502
|
+
config = (0, import_core19.validateWorkspace)(doc, ".aidlc/workspace.yaml");
|
|
48339
48503
|
} catch (err) {
|
|
48340
48504
|
console.error(import_chalk15.default.red("The edited pipeline fails workspace validation \u2014 nothing was written:"));
|
|
48341
48505
|
console.error(import_chalk15.default.dim(err instanceof Error ? err.message : String(err)));
|
|
48342
48506
|
process.exit(1);
|
|
48343
48507
|
}
|
|
48344
|
-
const issues = (0,
|
|
48508
|
+
const issues = (0, import_core19.collectWorkspaceRefIssues)(config).filter((i) => i.path.startsWith(`pipelines.${pipeline.id}.`));
|
|
48345
48509
|
if (issues.length > 0) {
|
|
48346
48510
|
console.error(import_chalk15.default.red("The edited step references something the workspace does not define \u2014 nothing was written:"));
|
|
48347
48511
|
for (const issue of issues) {
|
|
@@ -48355,7 +48519,7 @@ function printSteps(plan) {
|
|
|
48355
48519
|
const { runState } = plan;
|
|
48356
48520
|
runState.steps.forEach((s, i) => {
|
|
48357
48521
|
const marker = i === runState.currentStepIdx ? import_chalk15.default.yellow("\u25B6") : " ";
|
|
48358
|
-
const label = i === plan.index ? import_chalk15.default.bold((0,
|
|
48522
|
+
const label = i === plan.index ? import_chalk15.default.bold((0, import_core19.stepIdentity)(s)) : import_chalk15.default.dim((0, import_core19.stepIdentity)(s));
|
|
48359
48523
|
console.log(` ${marker} ${import_chalk15.default.dim(String(i))} ${label} ${import_chalk15.default.dim("(" + s.status + ")")}`);
|
|
48360
48524
|
});
|
|
48361
48525
|
if (plan.previousCurrentStepIdx !== runState.currentStepIdx) {
|
|
@@ -48375,6 +48539,9 @@ function printEpicDetail(epic) {
|
|
|
48375
48539
|
if (epic.description) {
|
|
48376
48540
|
console.log(import_chalk15.default.dim(" desc: ") + epic.description);
|
|
48377
48541
|
}
|
|
48542
|
+
if (epic.tags.length) {
|
|
48543
|
+
console.log(import_chalk15.default.dim(" tags: ") + import_chalk15.default.cyan(epic.tags.join(" ")));
|
|
48544
|
+
}
|
|
48378
48545
|
if (epic.pipeline) {
|
|
48379
48546
|
console.log(import_chalk15.default.dim(" pipeline: ") + epic.pipeline);
|
|
48380
48547
|
}
|
|
@@ -48424,7 +48591,7 @@ function truncate(s, max) {
|
|
|
48424
48591
|
|
|
48425
48592
|
// src/commands/recipe.ts
|
|
48426
48593
|
var import_chalk16 = __toESM(require_source());
|
|
48427
|
-
var
|
|
48594
|
+
var import_core20 = __toESM(require_dist());
|
|
48428
48595
|
function registerRecipe(program3) {
|
|
48429
48596
|
const cmd = program3.command("recipe").description("Manage task-type recipes in workspace.yaml");
|
|
48430
48597
|
cmd.command("init").description("Back-fill task-type recipes from the existing pipeline (enables --brief suggestion)").option("--dry-run", "print what would be added without writing").action((opts, actionCmd) => {
|
|
@@ -48434,7 +48601,7 @@ function registerRecipe(program3) {
|
|
|
48434
48601
|
console.log(import_chalk16.default.dim(`Workspace already has ${doc.recipes.length} recipe(s) \u2014 nothing to do.`));
|
|
48435
48602
|
return;
|
|
48436
48603
|
}
|
|
48437
|
-
const recipes = (0,
|
|
48604
|
+
const recipes = (0, import_core20.planRecipeMigration)(doc);
|
|
48438
48605
|
if (!recipes) {
|
|
48439
48606
|
console.error(import_chalk16.default.yellow(
|
|
48440
48607
|
"No recipes could be derived. A pipeline whose steps overlap the built-in\nSDLC phases (plan, design, implement, execute-test, \u2026) is required.\nApply the SDLC preset first: aidlc preset apply sdlc"
|
|
@@ -48465,7 +48632,7 @@ var path13 = __toESM(require("path"));
|
|
|
48465
48632
|
var import_child_process4 = require("child_process");
|
|
48466
48633
|
var readline = __toESM(require("readline"));
|
|
48467
48634
|
var import_chalk17 = __toESM(require_source());
|
|
48468
|
-
var
|
|
48635
|
+
var import_core21 = __toESM(require_dist());
|
|
48469
48636
|
var OBSERVE_PORT = 4981;
|
|
48470
48637
|
var OBSERVE_HOST = "127.0.0.1";
|
|
48471
48638
|
var OBSERVE_BASE = `http://${OBSERVE_HOST}:${OBSERVE_PORT}`;
|
|
@@ -48477,10 +48644,10 @@ function aidlcDataDir() {
|
|
|
48477
48644
|
return path13.join(os2.homedir(), ".aidlc", "observe-data");
|
|
48478
48645
|
}
|
|
48479
48646
|
function settingsPath() {
|
|
48480
|
-
return path13.join((0,
|
|
48647
|
+
return path13.join((0, import_core21.claudeConfigDir)(), "settings.json");
|
|
48481
48648
|
}
|
|
48482
48649
|
function pluginsRoot() {
|
|
48483
|
-
return path13.join((0,
|
|
48650
|
+
return path13.join((0, import_core21.claudeConfigDir)(), "plugins");
|
|
48484
48651
|
}
|
|
48485
48652
|
function parsePluginList(out2) {
|
|
48486
48653
|
if (!/agents-observe/i.test(out2)) return null;
|
|
@@ -48838,14 +49005,14 @@ opening ${DASHBOARD_URL} \u2026`));
|
|
|
48838
49005
|
// src/commands/ask.ts
|
|
48839
49006
|
var import_child_process5 = require("child_process");
|
|
48840
49007
|
var import_chalk18 = __toESM(require_source());
|
|
48841
|
-
var
|
|
49008
|
+
var import_core22 = __toESM(require_dist());
|
|
48842
49009
|
var ASK_SYSTEM_PROMPT = `You are the AIDLC assistant, embedded in the \`aidlc\` CLI.
|
|
48843
49010
|
Answer the user's question about AIDLC concisely and practically \u2014 prefer the
|
|
48844
49011
|
exact command, flag, or button name over abstract description. When the user is
|
|
48845
49012
|
getting started, give them the concrete next command to run. Use the reference
|
|
48846
49013
|
below as ground truth and never invent commands or settings not listed in it.
|
|
48847
49014
|
|
|
48848
|
-
${
|
|
49015
|
+
${import_core22.AIDLC_KNOWLEDGE}`;
|
|
48849
49016
|
function registerAsk(program3) {
|
|
48850
49017
|
program3.command("ask <prompt...>").description("ask Claude about AIDLC \u2014 setup, concepts, and CLI commands").action(async (promptParts, _opts, cmd) => {
|
|
48851
49018
|
const userPrompt = promptParts.join(" ").trim();
|
|
@@ -48861,7 +49028,7 @@ function registerAsk(program3) {
|
|
|
48861
49028
|
process.exit(1);
|
|
48862
49029
|
}
|
|
48863
49030
|
const root = resolveWorkspaceRoot(cmd);
|
|
48864
|
-
const runner = new
|
|
49031
|
+
const runner = new import_core22.DefaultRunner();
|
|
48865
49032
|
process.stderr.write("\n");
|
|
48866
49033
|
const result = await runner.run({
|
|
48867
49034
|
skill: ASK_SYSTEM_PROMPT,
|
|
@@ -48881,31 +49048,31 @@ function registerAsk(program3) {
|
|
|
48881
49048
|
}
|
|
48882
49049
|
|
|
48883
49050
|
// src/commands/guide.ts
|
|
48884
|
-
var
|
|
49051
|
+
var import_core23 = __toESM(require_dist());
|
|
48885
49052
|
function registerGuide(program3) {
|
|
48886
49053
|
program3.command("guide").description("step-by-step getting-started reference (no LLM, no cost)").action(() => {
|
|
48887
|
-
console.log(
|
|
49054
|
+
console.log(import_core23.AIDLC_CLI_GUIDE_TEXT);
|
|
48888
49055
|
});
|
|
48889
49056
|
}
|
|
48890
49057
|
|
|
48891
49058
|
// src/commands/globals.ts
|
|
48892
49059
|
var import_chalk19 = __toESM(require_source());
|
|
48893
|
-
var
|
|
49060
|
+
var import_core24 = __toESM(require_dist());
|
|
48894
49061
|
function registerGlobals(program3) {
|
|
48895
49062
|
const cmd = program3.command("globals").description("Install / uninstall built-in workflow agents + skills under ~/.claude/");
|
|
48896
49063
|
cmd.command("status").description("Show which built-in workflows are installed globally").option("--json", "Output raw JSON").action((opts) => {
|
|
48897
49064
|
const root = cliTemplatesRoot();
|
|
48898
|
-
const rows =
|
|
49065
|
+
const rows = import_core24.BUILTIN_WORKFLOWS.map((w) => ({
|
|
48899
49066
|
id: w.id,
|
|
48900
49067
|
name: w.name,
|
|
48901
|
-
installed: (0,
|
|
49068
|
+
installed: (0, import_core24.isWorkflowGloballyInstalled)(root, w.id)
|
|
48902
49069
|
}));
|
|
48903
49070
|
if (opts.json) {
|
|
48904
49071
|
console.log(JSON.stringify(rows, null, 2));
|
|
48905
49072
|
return;
|
|
48906
49073
|
}
|
|
48907
49074
|
console.log(import_chalk19.default.bold(`
|
|
48908
|
-
Built-in workflow globals (${(0,
|
|
49075
|
+
Built-in workflow globals (${(0, import_core24.claudeConfigDir)()})`));
|
|
48909
49076
|
for (const r of rows) {
|
|
48910
49077
|
const mark = r.installed ? import_chalk19.default.green("\u2714 installed") : import_chalk19.default.dim("\xB7 not installed");
|
|
48911
49078
|
console.log(` ${import_chalk19.default.cyan(r.id.padEnd(24))} ${mark}`);
|
|
@@ -48914,22 +49081,22 @@ Built-in workflow globals (${(0, import_core23.claudeConfigDir)()})`));
|
|
|
48914
49081
|
});
|
|
48915
49082
|
cmd.command("install [ids...]").description("Install built-in workflow globals (default: the standard workflows)").action((ids) => {
|
|
48916
49083
|
const root = cliTemplatesRoot();
|
|
48917
|
-
const targetIds = ids.length > 0 ? ids : [...
|
|
48918
|
-
const known = new Set(
|
|
49084
|
+
const targetIds = ids.length > 0 ? ids : [...import_core24.DEFAULT_GLOBAL_WORKFLOW_IDS];
|
|
49085
|
+
const known = new Set(import_core24.BUILTIN_WORKFLOWS.map((w) => w.id));
|
|
48919
49086
|
const unknown = targetIds.filter((id) => !known.has(id));
|
|
48920
49087
|
if (unknown.length > 0) {
|
|
48921
49088
|
console.error(import_chalk19.default.red(`Unknown workflow id(s): ${unknown.join(", ")}`));
|
|
48922
49089
|
console.error(import_chalk19.default.dim(`Known: ${[...known].join(", ")}`));
|
|
48923
49090
|
process.exit(1);
|
|
48924
49091
|
}
|
|
48925
|
-
const reports = (0,
|
|
49092
|
+
const reports = (0, import_core24.installWorkflowGlobalsByIds)(root, targetIds);
|
|
48926
49093
|
for (const r of reports) {
|
|
48927
49094
|
console.log(
|
|
48928
49095
|
import_chalk19.default.green("\u2714") + ` ${import_chalk19.default.bold(r.workflow)} \u2014 wrote ${r.written.length}, skipped ${r.skipped.length}`
|
|
48929
49096
|
);
|
|
48930
49097
|
}
|
|
48931
|
-
console.log(import_chalk19.default.dim(` Files live under ${(0,
|
|
48932
|
-
const ann = (0,
|
|
49098
|
+
console.log(import_chalk19.default.dim(` Files live under ${(0, import_core24.claudeConfigDir)()}/{agents,skills}`));
|
|
49099
|
+
const ann = (0, import_core24.installAnnotationTools)(root);
|
|
48933
49100
|
if (ann.installed) {
|
|
48934
49101
|
console.log(
|
|
48935
49102
|
import_chalk19.default.green("\u2714") + " annotation tooling \u2014 renderer + annotron + epic-memory + /annotate-artifact, /epic-context"
|
|
@@ -48940,8 +49107,8 @@ Built-in workflow globals (${(0, import_core23.claudeConfigDir)()})`));
|
|
|
48940
49107
|
});
|
|
48941
49108
|
cmd.command("uninstall [ids...]").description("Remove AIDLC-installed workflow globals (preserves files shared by other installed workflows)").action((ids) => {
|
|
48942
49109
|
const root = cliTemplatesRoot();
|
|
48943
|
-
const targetIds = ids.length > 0 ? ids : [...
|
|
48944
|
-
const reports = (0,
|
|
49110
|
+
const targetIds = ids.length > 0 ? ids : [...import_core24.DEFAULT_GLOBAL_WORKFLOW_IDS];
|
|
49111
|
+
const reports = (0, import_core24.uninstallWorkflowGlobalsByIds)(targetIds, void 0, root);
|
|
48945
49112
|
let removed = 0;
|
|
48946
49113
|
for (const r of reports) {
|
|
48947
49114
|
removed += r.removed.length;
|
|
@@ -48955,19 +49122,19 @@ Built-in workflow globals (${(0, import_core23.claudeConfigDir)()})`));
|
|
|
48955
49122
|
});
|
|
48956
49123
|
const hook = cmd.command("memory-hook <action>").description("Toggle the epic-memory auto-load hook (action: enable | disable | status)").action((action) => {
|
|
48957
49124
|
if (action === "status") {
|
|
48958
|
-
const on = (0,
|
|
49125
|
+
const on = (0, import_core24.isEpicMemoryHookEnabled)();
|
|
48959
49126
|
console.log(`Epic-memory hook: ${on ? import_chalk19.default.green("enabled") : import_chalk19.default.dim("disabled")}`);
|
|
48960
49127
|
return;
|
|
48961
49128
|
}
|
|
48962
49129
|
if (action === "enable") {
|
|
48963
|
-
(0,
|
|
48964
|
-
const r = (0,
|
|
49130
|
+
(0, import_core24.installAnnotationTools)(cliTemplatesRoot());
|
|
49131
|
+
const r = (0, import_core24.setEpicMemoryHook)(true);
|
|
48965
49132
|
console.log(import_chalk19.default.green("\u2714") + ` Epic-memory hook enabled${r.changed ? "" : " (already on)"}.`);
|
|
48966
49133
|
console.log(import_chalk19.default.dim(" A prompt that mentions an epic now auto-loads its epic-memory.json."));
|
|
48967
49134
|
return;
|
|
48968
49135
|
}
|
|
48969
49136
|
if (action === "disable") {
|
|
48970
|
-
const r = (0,
|
|
49137
|
+
const r = (0, import_core24.setEpicMemoryHook)(false);
|
|
48971
49138
|
console.log(import_chalk19.default.yellow("\u2193") + ` Epic-memory hook disabled${r.changed ? "" : " (already off)"}.`);
|
|
48972
49139
|
return;
|
|
48973
49140
|
}
|
|
@@ -49149,14 +49316,14 @@ function tryInstallSkill(root) {
|
|
|
49149
49316
|
var fs13 = __toESM(require("fs"));
|
|
49150
49317
|
var path15 = __toESM(require("path"));
|
|
49151
49318
|
var import_chalk21 = __toESM(require_source());
|
|
49152
|
-
var
|
|
49319
|
+
var import_core25 = __toESM(require_dist());
|
|
49153
49320
|
var INCIDENT_RECIPE = "native-incident";
|
|
49154
49321
|
var FOLLOW_UP_RECIPE = "native-full";
|
|
49155
49322
|
function registerMaintain(program3) {
|
|
49156
49323
|
const cmd = program3.command("maintain").description("Stage 6 \u2014 turn a production signal into an incident epic (AI-Native SDLC)").option("-s, --signal <file>", 'signal JSON file ("-" reads stdin)').option("--recipe <id>", `recipe to assemble the incident pipeline from (default: ${INCIDENT_RECIPE})`).option("--pipeline <id>", "use an existing pipeline as-is instead of a recipe").option("--from <pipelineId>", "override the recipe's source pipeline").option("--epic <id>", "epic id (default: derived from the symptom, e.g. INC-CHECKOUT-RETURNS-500)").option("--prefix <prefix>", "id prefix when deriving (default: INC)").option("--json", "output the result as JSON").action((opts, actionCmd) => {
|
|
49157
49324
|
runMaintain(opts, actionCmd);
|
|
49158
49325
|
});
|
|
49159
|
-
cmd.command("follow-up <incidentEpic>").description("Open the epic this incident calls for, with its intent.md already written").option("-s, --signal <file>", `signal JSON (default: the incident epic's ${
|
|
49326
|
+
cmd.command("follow-up <incidentEpic>").description("Open the epic this incident calls for, with its intent.md already written").option("-s, --signal <file>", `signal JSON (default: the incident epic's ${import_core25.SIGNAL_FILE})`).option("--recipe <id>", `recipe for the new epic (default: ${FOLLOW_UP_RECIPE})`).option("--pipeline <id>", "use an existing pipeline as-is instead of a recipe").option("--from <pipelineId>", "override the recipe's source pipeline").option("--epic <id>", "id for the new epic (default: <incidentEpic>-FIX)").option("--intent <file>", "use this markdown as intent.md verbatim, instead of rendering one").option("--problem <text>", "the problem in the user's terms \u2014 no solution language").option("--who-hurts <text>", "the specific role doing the specific task").option("--cost <text>", "what it costs them (default: the signal's scope)").option("--done <text>", "the observable condition that says this cannot recur").option("--question <text>", "an open question for the human gate (repeatable)", collect, []).option("--json", "output the result as JSON").action((incidentEpic, opts, actionCmd) => {
|
|
49160
49327
|
runFollowUp(incidentEpic, opts, actionCmd);
|
|
49161
49328
|
});
|
|
49162
49329
|
}
|
|
@@ -49170,14 +49337,14 @@ function runMaintain(opts, actionCmd) {
|
|
|
49170
49337
|
const root = resolveWorkspaceRoot(actionCmd);
|
|
49171
49338
|
const doc = requireYaml(root);
|
|
49172
49339
|
const signal = loadSignal(opts.signal);
|
|
49173
|
-
const epicId = opts.epic?.trim() || (0,
|
|
49340
|
+
const epicId = opts.epic?.trim() || (0, import_core25.followUpEpicId)(signal, { prefix: opts.prefix, taken: (0, import_core25.existingEpicIds)(root, doc) });
|
|
49174
49341
|
const pipelineCfg = resolvePipeline(root, doc, {
|
|
49175
49342
|
pipeline: opts.pipeline,
|
|
49176
49343
|
recipe: opts.recipe ?? INCIDENT_RECIPE,
|
|
49177
49344
|
from: opts.from
|
|
49178
49345
|
}, epicId);
|
|
49179
49346
|
try {
|
|
49180
|
-
const result = (0,
|
|
49347
|
+
const result = (0, import_core25.openIncidentEpic)({
|
|
49181
49348
|
workspaceRoot: root,
|
|
49182
49349
|
doc,
|
|
49183
49350
|
signal,
|
|
@@ -49212,16 +49379,16 @@ function runFollowUp(incidentEpic, opts, actionCmd) {
|
|
|
49212
49379
|
if (opts.signal) {
|
|
49213
49380
|
signal = loadSignal(opts.signal);
|
|
49214
49381
|
} else {
|
|
49215
|
-
const raw = (0,
|
|
49382
|
+
const raw = (0, import_core25.readEpicSignal)(root, doc, incidentEpic);
|
|
49216
49383
|
if (raw === null) {
|
|
49217
49384
|
fail2(
|
|
49218
|
-
`Epic "${incidentEpic}" has no ${
|
|
49385
|
+
`Epic "${incidentEpic}" has no ${import_core25.SIGNAL_FILE} to open a follow-up from.`,
|
|
49219
49386
|
`Pass one with --signal <file>, or register the incident first: aidlc maintain --signal <file>`
|
|
49220
49387
|
);
|
|
49221
49388
|
}
|
|
49222
|
-
signal = parseOrFail(raw, path15.join(incidentEpic,
|
|
49389
|
+
signal = parseOrFail(raw, path15.join(incidentEpic, import_core25.SIGNAL_FILE));
|
|
49223
49390
|
}
|
|
49224
|
-
const epicId = opts.epic?.trim() || (0,
|
|
49391
|
+
const epicId = opts.epic?.trim() || (0, import_core25.followUpIdFor)(incidentEpic, (0, import_core25.existingEpicIds)(root, doc));
|
|
49225
49392
|
const pipelineCfg = resolvePipeline(root, doc, {
|
|
49226
49393
|
pipeline: opts.pipeline,
|
|
49227
49394
|
recipe: opts.recipe ?? FOLLOW_UP_RECIPE,
|
|
@@ -49243,7 +49410,7 @@ function runFollowUp(incidentEpic, opts, actionCmd) {
|
|
|
49243
49410
|
intentMarkdown = fs13.readFileSync(opts.intent, "utf8");
|
|
49244
49411
|
}
|
|
49245
49412
|
try {
|
|
49246
|
-
const result = (0,
|
|
49413
|
+
const result = (0, import_core25.openFollowUpEpic)({
|
|
49247
49414
|
workspaceRoot: root,
|
|
49248
49415
|
doc,
|
|
49249
49416
|
signal,
|
|
@@ -49282,7 +49449,7 @@ function resolvePipeline(root, doc, opts, epicId) {
|
|
|
49282
49449
|
}
|
|
49283
49450
|
let config;
|
|
49284
49451
|
try {
|
|
49285
|
-
config = (0,
|
|
49452
|
+
config = (0, import_core25.validateWorkspace)(doc, ".aidlc/workspace.yaml");
|
|
49286
49453
|
} catch (err) {
|
|
49287
49454
|
fail2(
|
|
49288
49455
|
"workspace.yaml is invalid \u2014 fix it before running stage 6:",
|
|
@@ -49301,26 +49468,26 @@ function resolvePipeline(root, doc, opts, epicId) {
|
|
|
49301
49468
|
recipe.from = opts.from;
|
|
49302
49469
|
}
|
|
49303
49470
|
}
|
|
49304
|
-
const pipelineId = (0,
|
|
49471
|
+
const pipelineId = (0, import_core25.recipePipelineId)({
|
|
49305
49472
|
recipeId: opts.recipe,
|
|
49306
49473
|
epicId,
|
|
49307
49474
|
taken: existingIds(doc.pipelines)
|
|
49308
49475
|
});
|
|
49309
49476
|
let pipelineCfg;
|
|
49310
49477
|
try {
|
|
49311
|
-
pipelineCfg = (0,
|
|
49478
|
+
pipelineCfg = (0, import_core25.assemblePipeline)(config, { recipeId: opts.recipe, pipelineId });
|
|
49312
49479
|
} catch (err) {
|
|
49313
|
-
if (err instanceof
|
|
49480
|
+
if (err instanceof import_core25.PipelineAssembleError) {
|
|
49314
49481
|
fail2("Could not assemble pipeline: " + err.message);
|
|
49315
49482
|
}
|
|
49316
49483
|
throw err;
|
|
49317
49484
|
}
|
|
49318
49485
|
doc.pipelines.push(pipelineCfg);
|
|
49319
49486
|
if (epicId) {
|
|
49320
|
-
(0,
|
|
49487
|
+
(0, import_core25.stageEpicPipeline)(doc, pipelineCfg.id, epicId);
|
|
49321
49488
|
}
|
|
49322
49489
|
try {
|
|
49323
|
-
(0,
|
|
49490
|
+
(0, import_core25.validateWorkspace)(doc, ".aidlc/workspace.yaml");
|
|
49324
49491
|
} catch (err) {
|
|
49325
49492
|
fail2(
|
|
49326
49493
|
"Assembled pipeline failed validation \u2014 not written:",
|
|
@@ -49342,9 +49509,9 @@ function loadSignal(file) {
|
|
|
49342
49509
|
}
|
|
49343
49510
|
function parseOrFail(raw, where) {
|
|
49344
49511
|
try {
|
|
49345
|
-
return (0,
|
|
49512
|
+
return (0, import_core25.parseSignal)(raw);
|
|
49346
49513
|
} catch (err) {
|
|
49347
|
-
if (err instanceof
|
|
49514
|
+
if (err instanceof import_core25.SignalParseError) {
|
|
49348
49515
|
fail2(`${where}: ${err.message}`, EXAMPLE_SIGNAL);
|
|
49349
49516
|
}
|
|
49350
49517
|
throw err;
|
|
@@ -49372,7 +49539,7 @@ function fail2(message, detail) {
|
|
|
49372
49539
|
process.exit(1);
|
|
49373
49540
|
}
|
|
49374
49541
|
function rethrow(err) {
|
|
49375
|
-
if (err instanceof
|
|
49542
|
+
if (err instanceof import_core25.EpicScaffoldError) {
|
|
49376
49543
|
fail2(err.message);
|
|
49377
49544
|
}
|
|
49378
49545
|
throw err;
|
|
@@ -49386,7 +49553,7 @@ program2.name("aidlc").description("AIDLC terminal CLI \u2014 drive workspace.ya
|
|
|
49386
49553
|
setQuiet(true);
|
|
49387
49554
|
}
|
|
49388
49555
|
const raw = thisCommand.opts().workspace ?? process.env.AIDLC_WORKSPACE ?? process.cwd();
|
|
49389
|
-
(0,
|
|
49556
|
+
(0, import_core26.activateBackendFromWorkspace)(path16.resolve(raw), (text) => load(text));
|
|
49390
49557
|
});
|
|
49391
49558
|
registerInit(program2);
|
|
49392
49559
|
registerValidate(program2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delete101020/aidlc",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "AIDLC Native CLI, a fork of AIDLC — drive Claude through the six-stage AI-Native SDLC Playbook: Plan → Design → Build → Test → Deploy → Maintain, with artifact gates, requirements traceability, an incident loop back to Plan, and Spec Kit support.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|