@rasensio/aidlc-content 1.37.1 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ import type { HowTo } from './types.js';
2
+ /**
3
+ * The only headings a how-to body may contain at level 1 or 2, in this order
4
+ * (docs-how-to-recipes/AC-3). Holding the list exact — no `#` heading, no extra
5
+ * `##` — is also what keeps the page to a single `h1` (AC-7): the title comes
6
+ * from frontmatter, so a `# Title` in the body would be a second one.
7
+ */
8
+ export declare const HOWTO_SECTIONS: readonly ["What you'll do", "Steps", "Check it worked"];
9
+ /** Parse one how-to. `filename` only labels errors. */
10
+ export declare function parseHowToSource(raw: string, filename?: string): HowTo;
11
+ /**
12
+ * Every how-to, sorted by `order` (AC-5). Throws on the first bad file — this
13
+ * runs inside `next build`, so a bad recipe fails the build rather than shipping.
14
+ */
15
+ export declare function loadHowTos(dir?: string): HowTo[];
16
+ export declare function getHowTo(slug: string): HowTo | undefined;
17
+ //# sourceMappingURL=howto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"howto.d.ts","sourceRoot":"","sources":["../src/howto.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOxC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,yDAA0D,CAAC;AA0FtF,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAGtE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAkB,GAAG,KAAK,EAAE,CAwB3D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAExD"}
package/dist/howto.js ADDED
@@ -0,0 +1,121 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { readdirSync, readFileSync, existsSync } from 'node:fs';
4
+ import { parse as parseYaml } from 'yaml';
5
+ const CONTENT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
6
+ const HOWTO_DIR = resolve(CONTENT_ROOT, 'howto');
7
+ const SLUG_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
8
+ /**
9
+ * The only headings a how-to body may contain at level 1 or 2, in this order
10
+ * (docs-how-to-recipes/AC-3). Holding the list exact — no `#` heading, no extra
11
+ * `##` — is also what keeps the page to a single `h1` (AC-7): the title comes
12
+ * from frontmatter, so a `# Title` in the body would be a second one.
13
+ */
14
+ export const HOWTO_SECTIONS = ["What you'll do", 'Steps', 'Check it worked'];
15
+ function fail(filename, message) {
16
+ throw new Error(filename ? `How-to "${filename}": ${message}` : message);
17
+ }
18
+ function parseFrontmatter(raw, filename) {
19
+ const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
20
+ if (!match)
21
+ fail(filename, 'missing YAML frontmatter');
22
+ const parsed = (parseYaml(match[1]) ?? {});
23
+ const { title, description, order, slug } = parsed;
24
+ // Same four rules as tutorials, so one mental model covers both (AC-2).
25
+ if (typeof title !== 'string' || title.length === 0 || title.length > 100) {
26
+ fail(filename, 'invalid title: must be a string of 1-100 characters');
27
+ }
28
+ if (typeof description !== 'string' || description.length === 0 || description.length > 300) {
29
+ fail(filename, 'invalid description: must be a string of 1-300 characters');
30
+ }
31
+ if (typeof order !== 'number' || !Number.isInteger(order) || order < 1 || order > 999) {
32
+ fail(filename, 'invalid order: must be an integer between 1 and 999');
33
+ }
34
+ if (typeof slug !== 'string' || slug.length === 0 || slug.length > 80 || !SLUG_PATTERN.test(slug)) {
35
+ fail(filename, 'invalid slug: must be lowercase alphanumeric with hyphens, max 80 characters');
36
+ }
37
+ return { meta: { title, description, order, slug }, body: match[2] };
38
+ }
39
+ /**
40
+ * Level-1 and level-2 headings outside code fences. A recipe may well show a
41
+ * Markdown file in a fence, and a `## ` inside it is content, not structure.
42
+ */
43
+ function topHeadings(lines) {
44
+ const headings = [];
45
+ let fence = null;
46
+ lines.forEach((line, index) => {
47
+ const marker = line.match(/^\s*(```|~~~)/)?.[1];
48
+ if (marker) {
49
+ if (fence === null)
50
+ fence = marker;
51
+ else if (fence === marker)
52
+ fence = null;
53
+ return;
54
+ }
55
+ if (fence !== null)
56
+ return;
57
+ const m = line.match(/^(#{1,2})\s+(.+?)\s*#*\s*$/);
58
+ if (m)
59
+ headings.push({ level: m[1].length, text: m[2], line: index });
60
+ });
61
+ return headings;
62
+ }
63
+ function splitSections(body, filename) {
64
+ const lines = body.split('\n');
65
+ const headings = topHeadings(lines);
66
+ const stray = headings.find((h) => h.level === 1);
67
+ if (stray) {
68
+ fail(filename, `level-1 heading "# ${stray.text}" is not allowed — the title comes from frontmatter`);
69
+ }
70
+ HOWTO_SECTIONS.forEach((expected, i) => {
71
+ const found = headings[i];
72
+ if (!found)
73
+ fail(filename, `missing heading "## ${expected}"`);
74
+ if (found.text !== expected) {
75
+ fail(filename, `expected heading "## ${expected}" but found "## ${found.text}"`);
76
+ }
77
+ });
78
+ if (headings.length > HOWTO_SECTIONS.length) {
79
+ fail(filename, `unexpected heading "## ${headings[HOWTO_SECTIONS.length].text}"`);
80
+ }
81
+ const text = (i) => {
82
+ const start = headings[i].line + 1;
83
+ const end = i + 1 < headings.length ? headings[i + 1].line : lines.length;
84
+ return lines.slice(start, end).join('\n').trim();
85
+ };
86
+ return { whatYoullDo: text(0), steps: text(1), checkItWorked: text(2) };
87
+ }
88
+ /** Parse one how-to. `filename` only labels errors. */
89
+ export function parseHowToSource(raw, filename) {
90
+ const { meta, body } = parseFrontmatter(raw, filename);
91
+ return { ...meta, body, sections: splitSections(body, filename) };
92
+ }
93
+ /**
94
+ * Every how-to, sorted by `order` (AC-5). Throws on the first bad file — this
95
+ * runs inside `next build`, so a bad recipe fails the build rather than shipping.
96
+ */
97
+ export function loadHowTos(dir = HOWTO_DIR) {
98
+ if (!existsSync(dir))
99
+ return [];
100
+ const entries = readdirSync(dir)
101
+ .filter((f) => f.endsWith('.md'))
102
+ .sort()
103
+ .map((filename) => ({
104
+ filename,
105
+ howTo: parseHowToSource(readFileSync(resolve(dir, filename), 'utf8'), filename),
106
+ }));
107
+ // A property of the set, not of one file, so it lives here (AC-4).
108
+ const owners = new Map();
109
+ for (const { filename, howTo } of entries) {
110
+ const first = owners.get(howTo.slug);
111
+ if (first !== undefined) {
112
+ throw new Error(`How-to slug "${howTo.slug}" is used by both "${first}" and "${filename}" — two pages would share one URL`);
113
+ }
114
+ owners.set(howTo.slug, filename);
115
+ }
116
+ return entries.map((e) => e.howTo).sort((a, b) => a.order - b.order);
117
+ }
118
+ export function getHowTo(slug) {
119
+ return loadHowTos().find((h) => h.slug === slug);
120
+ }
121
+ //# sourceMappingURL=howto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"howto.js","sourceRoot":"","sources":["../src/howto.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,5 +7,6 @@ export { loadPhases, getPhase } from './phases.js';
7
7
  export { loadRules } from './rules.js';
8
8
  export { loadBoardWorkflow, BOARD_WORKFLOW_PATH } from './recipes.js';
9
9
  export { loadTutorials, getTutorial, getSeries, parseTutorialSource } from './tutorials.js';
10
- export type { Skill, WorkflowTemplate, GuidanceLayer, GlossaryTerm, CapabilityMap, QuestionRendering, PhaseDefinition, Rule, CodeSample, ContentReference, TutorialStep, Tutorial, WidgetKind, WidgetReference } from './types.js';
10
+ export { loadHowTos, getHowTo, parseHowToSource, HOWTO_SECTIONS } from './howto.js';
11
+ export type { Skill, WorkflowTemplate, GuidanceLayer, GlossaryTerm, CapabilityMap, QuestionRendering, PhaseDefinition, Rule, CodeSample, ContentReference, TutorialStep, Tutorial, WidgetKind, WidgetReference, HowTo } from './types.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC5F,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACpF,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -7,4 +7,5 @@ export { loadPhases, getPhase } from './phases.js';
7
7
  export { loadRules } from './rules.js';
8
8
  export { loadBoardWorkflow, BOARD_WORKFLOW_PATH } from './recipes.js';
9
9
  export { loadTutorials, getTutorial, getSeries, parseTutorialSource } from './tutorials.js';
10
+ export { loadHowTos, getHowTo, parseHowToSource, HOWTO_SECTIONS } from './howto.js';
10
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
package/dist/types.d.ts CHANGED
@@ -133,4 +133,22 @@ export interface Tutorial {
133
133
  /** Position within `series`. Falls back to `order` when absent (AC-9). */
134
134
  seriesOrder?: number;
135
135
  }
136
+ /**
137
+ * One task-shaped page: the steps to do one thing, and how to check it worked
138
+ * (docs-how-to-recipes). Unlike a tutorial it teaches nothing, so its shape is
139
+ * fixed to exactly three sections, in order.
140
+ */
141
+ export interface HowTo {
142
+ title: string;
143
+ description: string;
144
+ order: number;
145
+ slug: string;
146
+ /** The full body after the frontmatter. */
147
+ body: string;
148
+ sections: {
149
+ whatYoullDo: string;
150
+ steps: string;
151
+ checkItWorked: string;
152
+ };
153
+ }
136
154
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ ---
2
+ title: Add AIDLC to a project you already have
3
+ description: Install AIDLC into an existing repository so your AI assistant starts with real knowledge of the code.
4
+ order: 10
5
+ slug: add-to-existing-project
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Install the CLI and run `init` in your repository. It adds the AIDLC files and writes a
11
+ first description of your code for your AI assistant to read. None of your code is changed.
12
+
13
+ ## Steps
14
+
15
+ 1. Install the CLI once, so `aidlc` is on your path:
16
+
17
+ ```bash
18
+ npm install -g @rasensio/aidlc
19
+ ```
20
+
21
+ 2. Go to the root of your repository and run `init`. It asks which AI tools you use:
22
+
23
+ ```bash
24
+ cd path/to/your-repo
25
+ aidlc init
26
+ ```
27
+
28
+ To skip the questions and set up one tool, name it instead:
29
+
30
+ ```bash
31
+ aidlc init --platform claude-code
32
+ ```
33
+
34
+ The other names are `codex`, `copilot`, `cursor`, `kiro` and `windsurf`. To see what
35
+ `init` would write before it writes anything, add `--dry-run`.
36
+
37
+ 3. Read the two files `init` wrote in `.aidlc/context/`: `architecture.md` and
38
+ `style-guide.md`. They describe your code, and your assistant reads them before every
39
+ phase, so fix anything they get wrong now. A mistake here repeats in every piece of work.
40
+
41
+ 4. See the new files, then commit them:
42
+
43
+ ```bash
44
+ git status
45
+ git add .aidlc .claude CLAUDE.md .gitattributes
46
+ git commit -m "chore: add AIDLC"
47
+ ```
48
+
49
+ The tool folder and instructions file depend on the tool you chose — for example
50
+ `.cursor/` for Cursor or `.kiro/` for Kiro. Add whatever `git status` lists as new.
51
+
52
+ ## Check it worked
53
+
54
+ Run `aidlc status`. You should see `No active lifecycle instances.` That means AIDLC is set
55
+ up and waiting for your first piece of work.
@@ -0,0 +1,60 @@
1
+ ---
2
+ title: Change a requirement after its phase is finished
3
+ description: Record a change to finished requirements as an amendment, so the gates, the tasks and the code stay in step.
4
+ order: 30
5
+ slug: change-a-finished-requirement
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Add an amendment to `requirements.md` that says which criteria are retired, which are new,
11
+ and which phase to reopen. Then run `aidlc amend`. Editing the finished file directly leaves
12
+ every gate passing while the requirements and the code disagree.
13
+
14
+ ## Steps
15
+
16
+ 1. Open `.aidlc/state/<instance>/requirements.md`. Change each criterion you are dropping
17
+ into its retired form, in place — never delete it or reuse its number:
18
+
19
+ ```markdown
20
+ - AC-4 (retired 2026-09-07, superseded by AC-31): export as CSV only
21
+ ```
22
+
23
+ Add each new criterion with the next free number, for example `AC-31`. Then add an
24
+ amendment section at the end of the file:
25
+
26
+ ```markdown
27
+ ## Amendment 1 — 2026-09-07
28
+ - **Retires:** AC-4
29
+ - **Issues:** AC-31
30
+ - **Reopens:** design
31
+ - **Reason:** the customer needs JSON as well as CSV
32
+ ```
33
+
34
+ List each criterion by its full name. `AC-4..AC-6` is not read as a range.
35
+
36
+ 2. See what still depends on the criteria you are retiring. This writes nothing:
37
+
38
+ ```bash
39
+ aidlc amend <instance> --impact
40
+ ```
41
+
42
+ It prints a line starting `Reopens:` that names the earliest phase the change must
43
+ reopen, or `none`. If your `Reopens:` is later than that, move it earlier.
44
+
45
+ 3. Apply the amendment:
46
+
47
+ ```bash
48
+ aidlc amend <instance>
49
+ ```
50
+
51
+ If the work is already in testing or later, add `--confirm`. Reopening that far is
52
+ costly, and the flag makes you say so.
53
+
54
+ 4. Ask your assistant to continue. It resumes in the reopened phase.
55
+
56
+ The full rules for amendments are on the {{ref:phase/requirements}} phase page.
57
+
58
+ ## Check it worked
59
+
60
+ Run `aidlc status`. The instance's phase should now be the one you named in `Reopens:`.
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: Keep AIDLC up to date
3
+ description: Update the CLI and your project's AIDLC files, then let doctor tidy what older versions left behind.
4
+ order: 60
5
+ slug: keep-aidlc-up-to-date
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Update the CLI and refresh the AIDLC files in your project with one command, then run
11
+ `doctor` to fix anything older versions left behind. Your own context documents in
12
+ `.aidlc/context/` are not overwritten.
13
+
14
+ ## Steps
15
+
16
+ 1. See what an update would change. This writes nothing:
17
+
18
+ ```bash
19
+ aidlc update --dry-run
20
+ ```
21
+
22
+ 2. Update:
23
+
24
+ ```bash
25
+ aidlc update
26
+ ```
27
+
28
+ It updates the CLI if a newer version exists, then refreshes the skills and instruction
29
+ files for each tool you set up. Text you wrote outside the AIDLC markers in files like
30
+ `CLAUDE.md` is kept.
31
+
32
+ 3. Tidy up. `doctor` applies safe fixes on its own and asks before it changes what git
33
+ tracks:
34
+
35
+ ```bash
36
+ aidlc doctor
37
+ ```
38
+
39
+ To preview first, run `aidlc doctor --dry-run`. In CI, where nothing can answer a
40
+ question, use `aidlc doctor --yes`.
41
+
42
+ 4. See what changed, then commit it:
43
+
44
+ ```bash
45
+ git status
46
+ git add .aidlc
47
+ git commit -m "chore: update AIDLC"
48
+ ```
49
+
50
+ Also add any tool folder or instructions file `git status` lists, such as `.claude/` or
51
+ `CLAUDE.md`.
52
+
53
+ ## Check it worked
54
+
55
+ Run `aidlc update --dry-run` again. You should see `CLI: <version> (already up to date)`, and
56
+ every project file listed under `Unchanged:`.
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: Run two pieces of work at the same time
3
+ description: Give each piece of work its own folder and branch, so two sessions never overwrite each other's files.
4
+ order: 20
5
+ slug: run-two-pieces-of-work
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Start the second piece of work in a separate folder with its own branch. Two AI sessions in
11
+ one folder share every file on disk, so one session's `git add -A` picks up the other's
12
+ half-finished work. A separate folder removes that problem.
13
+
14
+ ## Steps
15
+
16
+ 1. From your main folder, start the new work with `--worktree`:
17
+
18
+ ```bash
19
+ aidlc start bugfix --name login-500 --worktree
20
+ ```
21
+
22
+ AIDLC creates a new branch from `main` and a new folder next to your repository, named
23
+ after the repository and the work — for example `../your-repo-login-500`. It prints both.
24
+
25
+ 2. Open a new terminal and AI session in that folder:
26
+
27
+ ```bash
28
+ cd ../your-repo-login-500
29
+ ```
30
+
31
+ Do all the work for this piece there. Your first session keeps working in the main folder.
32
+
33
+ 3. If the second piece of work needs no code yet — say, only requirements — you can skip
34
+ the folder and start it with `--no-code` instead. It stays in your main folder and
35
+ cannot reach implementation until it has a branch.
36
+
37
+ 4. When the work is merged, remove the folder:
38
+
39
+ ```bash
40
+ git worktree remove ../your-repo-login-500
41
+ ```
42
+
43
+ Git refuses if the folder still has changes that are not committed. That protects work
44
+ you have not saved.
45
+
46
+ ## Check it worked
47
+
48
+ Run `aidlc status` from either folder. You should see both pieces of work. The one that
49
+ lives in the other folder shows `(remote worktree)` in the Template column.
@@ -0,0 +1,52 @@
1
+ ---
2
+ title: See what a piece of work cost
3
+ description: Read the AI spend for one piece of work, split by phase, and the cost across all your work.
4
+ order: 50
5
+ slug: see-what-work-cost
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Check that cost capture is on, then read the spend for one piece of work, phase by phase.
11
+ Cost is read from your AI tool's own session records on your machine. Nothing is sent
12
+ anywhere.
13
+
14
+ ## Steps
15
+
16
+ 1. Check that capture is on for your tool:
17
+
18
+ ```bash
19
+ aidlc cost hooks status
20
+ ```
21
+
22
+ `init` turns it on. If your tool shows `not installed`, turn it on:
23
+
24
+ ```bash
25
+ aidlc cost hooks install --platform claude-code
26
+ ```
27
+
28
+ Use the name of your tool in place of `claude-code`.
29
+
30
+ 2. Read the cost of one piece of work:
31
+
32
+ ```bash
33
+ aidlc cost <instance>
34
+ ```
35
+
36
+ You get one line per phase with its cost and time, then a total.
37
+
38
+ 3. See every piece of work at once, or the average per template:
39
+
40
+ ```bash
41
+ aidlc cost
42
+ aidlc cost --by-template
43
+ ```
44
+
45
+ 4. To see what a piece of work cost including the bugfixes it later caused, run
46
+ `aidlc metrics`. Its true-cost figure adds those fixes to the work's own cost.
47
+
48
+ ## Check it worked
49
+
50
+ Run `aidlc cost <instance>` on a piece of work you have spent time on. You should see a
51
+ dollar amount on its `total:` line. `no data` means capture was off while you worked — turn
52
+ it on as in step 1, and the next session is counted.
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: Send your roadmap to GitHub Issues and a Project board
3
+ description: Turn roadmap items into GitHub issues, and optionally keep a Project board's Status column in step with them.
4
+ order: 40
5
+ slug: send-roadmap-to-github
6
+ ---
7
+
8
+ ## What you'll do
9
+
10
+ Copy your roadmap items to GitHub Issues with one command. Items in `backlog/`,
11
+ `in-progress/` and `done/` become issues; `inbox/` and `hold/` stay private. The copy is one
12
+ way: the files in `.aidlc/roadmap/` stay the source, and GitHub follows them. Moving cards
13
+ on a Project board is an optional second part.
14
+
15
+ ## Steps
16
+
17
+ 1. Install the GitHub CLI and sign in. AIDLC uses its login and never asks for a token:
18
+
19
+ ```bash
20
+ gh auth login
21
+ ```
22
+
23
+ 2. Preview what would change. This writes nothing:
24
+
25
+ ```bash
26
+ aidlc roadmap sync --dry-run
27
+ ```
28
+
29
+ It uses the repository your folder points at. To target another one, add
30
+ `--repo <owner/name>`.
31
+
32
+ 3. Apply it:
33
+
34
+ ```bash
35
+ aidlc roadmap sync
36
+ ```
37
+
38
+ It shows the plan and asks before it writes. Run it again whenever items move — it
39
+ updates labels, and closes an issue when its item reaches `done/`.
40
+
41
+ 4. Optional — move a Project board too. Save the workflow AIDLC ships into your repository:
42
+
43
+ ```bash
44
+ aidlc roadmap board-workflow > .github/workflows/aidlc-project-status.yml
45
+ ```
46
+
47
+ Then, in your repository's settings on GitHub:
48
+
49
+ - Create a classic token with the `project` and `read:org` scopes (add `repo` if the
50
+ repository is private). Store it as the repository secret `AIDLC_PROJECT_TOKEN`, with
51
+ `<your-github-token>` as the value. Never paste it into a file you commit.
52
+ - Set the repository variable `AIDLC_PROJECT_NUMBER` to your project's number — the
53
+ digits in its URL.
54
+
55
+ The top of the workflow file lists the Status columns it expects and how to rename them.
56
+
57
+ ## Check it worked
58
+
59
+ Open your repository's Issues tab on GitHub. You should see one issue per roadmap item in
60
+ `backlog/`, `in-progress/` and `done/`, each labelled `aidlc`. If you set up the board, move
61
+ an item and run `aidlc roadmap sync` again: once the workflow run shows in your Actions tab,
62
+ its card should be in the new column.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc-content",
3
- "version": "1.37.1",
3
+ "version": "1.39.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,6 +20,7 @@
20
20
  "capabilities/",
21
21
  "phases/",
22
22
  "tutorials/",
23
+ "howto/",
23
24
  "resources/",
24
25
  "glossary.yaml"
25
26
  ],
@@ -0,0 +1,38 @@
1
+ # The next-steps rule
2
+
3
+ This file is the only statement of the rule. The phase skills and the review skill point here instead of restating it.
4
+
5
+ **Never end a phase or a review on a state.** "26 findings", "gate failed" and "phase in progress" tell the user where things are and leave them to work out the path. End instead with what they must decide, what you can fix, and one command.
6
+
7
+ ## When it applies
8
+
9
+ - At the end of a phase, once its exit criteria are met or it cannot go further without the user.
10
+ - At the end of a review, after the findings file is written.
11
+ - After an `aidlc gate` or `aidlc transition` failure you are reporting.
12
+
13
+ ## Sort what is still open
14
+
15
+ Put every open item — finding, gap, failed criterion — into exactly one of two groups:
16
+
17
+ 1. **Needs your decision.** Different answers would change an artifact, the scope, or the product: which principal is refused, whether production behaviour changes, what an edge case should return. Ask these through the **Question Protocol** (`.aidlc/resources/rules/question-protocol.md`) — in place when the options fit one line, in `.aidlc/state/<instance>/<phase>-questions.md` when they need context. Name the item each question came from.
18
+ 2. **I can fix these.** One correct answer exists and you can apply it: a wrong rule id, a stale sentence, an over-broad permission, a missing test, a task out of order. List them, one line each, and offer to apply them all in one step. Do not ask about each one separately.
19
+
20
+ An item you cannot place is a decision. Do not quietly fix something that was the user's to choose.
21
+
22
+ When both groups are empty, say so in one line.
23
+
24
+ ## End with one next command
25
+
26
+ Close the turn with exactly one next step. It names a command the user can run as written — the real instance name, the real phase or artifact — or, when decisions are open, says to answer them first.
27
+
28
+ - Decisions are open → answer them first; no command yet.
29
+ - Fixes are offered and not yet applied → the fixes, then the command below.
30
+ - The phase's exit criteria are met → `aidlc transition <instance>`. That is the step that marks the phase complete; `aidlc gate` only checks, and fails on an open phase until it runs.
31
+ - A review finished with no open critical finding → `aidlc transition <instance>` for the phase the artifact belongs to.
32
+ - The instance's last phase is done → the retrospective (**aidlc-retrospective**).
33
+
34
+ If the CLI printed a `Next steps:` block, use it — it names the fix for each failure it reported.
35
+
36
+ ## What this rule does not do
37
+
38
+ It changes what you report, not what you write. It adds no writer of `phase-<name>.yaml` or `transitions.log`: the Completion section of each skill still says how the phase is closed.
@@ -92,6 +92,10 @@ On each lifecycle event — `on-instance-start`, `on-phase-enter`, `on-phase-exi
92
92
 
93
93
  When to ask the user something, how the question is written, and where it is recorded. The rule is in `.aidlc/resources/rules/question-protocol.md`.
94
94
 
95
+ ## Ending a Phase or a Review
96
+
97
+ How to end a turn: decisions asked, fixes offered together, and one next command. The rule is in `.aidlc/resources/rules/next-steps.md`.
98
+
95
99
  ## Roadmap Capture
96
100
 
97
101
  When the user shares an idea tangential to the current work, offer to record it in `.aidlc/roadmap/inbox/` (see **aidlc-roadmap**) and continue the current phase — do not derail into ideation. Capture touches no instance state, so it is safe at any point in any phase.
@@ -66,3 +66,5 @@ If any ideation option involves sensitive operations (new credentials, infrastru
66
66
  ## Completion
67
67
 
68
68
  When exit criteria are met, update `phase-ideation.yaml` status to `complete` and append a transition record to `transitions.log`.
69
+
70
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
@@ -85,6 +85,8 @@ If requirements reference sensitive data handling, authentication flows, or acce
85
85
 
86
86
  When exit criteria are met, update `phase-requirements.yaml` status to `complete` and append a transition record to `transitions.log`.
87
87
 
88
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
89
+
88
90
  ## Amending a Completed Phase
89
91
 
90
92
  A completed phase's artifact is changed **only through an amendment**. Editing
@@ -89,6 +89,8 @@ You MUST flag these explicitly in the design document and note that implementati
89
89
 
90
90
  When exit criteria are met, update `phase-design.yaml` status to `complete` and append a transition record to `transitions.log`.
91
91
 
92
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
93
+
92
94
  **Changing a completed phase's artifact.** Do it only through an amendment — append an
93
95
  `## Amendment <n> — YYYY-MM-DD` section to `requirements.md` with `Retires:`, `Issues:`,
94
96
  `Reopens:` and `Reason:` bullets, then run `aidlc amend <instance>` (start with `--impact`
@@ -82,6 +82,8 @@ Never store credentials, API keys, tokens, or passwords in source code or state
82
82
 
83
83
  When exit criteria are met, update `phase-implementation.yaml` status to `complete` and append a transition record to `transitions.log`.
84
84
 
85
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
86
+
85
87
  **Changing a completed phase's artifact.** Do it only through an amendment — append an
86
88
  `## Amendment <n> — YYYY-MM-DD` section to `requirements.md` with `Retires:`, `Issues:`,
87
89
  `Reopens:` and `Reason:` bullets, then run `aidlc amend <instance>` (start with `--impact`
@@ -100,6 +100,8 @@ You MUST describe the action, confirm it targets a safe environment, and wait fo
100
100
 
101
101
  When exit criteria are met, update `phase-testing.yaml` status to `complete` and append a transition record to `transitions.log`.
102
102
 
103
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
104
+
103
105
  **Changing a completed phase's artifact.** Do it only through an amendment — append an
104
106
  `## Amendment <n> — YYYY-MM-DD` section to `requirements.md` with `Retires:`, `Issues:`,
105
107
  `Reopens:` and `Reason:` bullets, then run `aidlc amend <instance>` (start with `--impact`
@@ -100,3 +100,5 @@ Never deploy without explicit user confirmation. If the user cancels, halt and l
100
100
  When exit criteria are met, update `phase-deployment.yaml` status to `complete` and append a transition record to `transitions.log`.
101
101
 
102
102
  Then check for the **completion moment**: derive the instance's applicable phases (template × scope). If deployment is the last applicable phase, or the next phase is maintenance (maintenance-terminal templates complete on maintenance *entry*, since maintenance is open-ended), this transition completes the instance — run the **aidlc-retrospective** skill now, before any completion cleanup (worktree removal, claim release), and fire the `on-instance-complete` event.
103
+
104
+ End the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
@@ -78,3 +78,5 @@ You MUST describe the change, confirm the target environment, and wait for expli
78
78
  For maintenance-terminal instances the completion moment already fired on maintenance *entry* (see **aidlc-deployment**) — entering this phase means the instance is complete and its retrospective has run or is pending. Do not fire `on-instance-complete` again when closing the phase.
79
79
 
80
80
  When exit criteria are met, update `phase-maintenance.yaml` status to `complete` and append a transition record to `transitions.log`. If no retrospective exists for the instance (legacy completion paths), offer to run the **aidlc-retrospective** skill.
81
+
82
+ Then end the turn as **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`) says.
@@ -150,4 +150,11 @@ If the review identifies security vulnerabilities:
150
150
 
151
151
  ## Completion
152
152
 
153
- After writing the findings file, report the review summary: total findings count by severity, and whether any critical findings block phase transition.
153
+ After writing the findings file, report the review summary in two lines: total findings count by severity, and whether any critical findings block phase transition.
154
+
155
+ The summary is not the end of the turn. A review's output is mostly decisions, and a count leaves the user to dig them out. Follow **The next-steps rule** (`.aidlc/resources/rules/next-steps.md`):
156
+
157
+ 1. Split the open findings into **needs your decision** and **I can fix these**. A finding whose fix changes what the product does, who it refuses, or what it returns is a decision, whatever its severity.
158
+ 2. Ask the decisions through the **Question Protocol** (`.aidlc/resources/rules/question-protocol.md`), each naming its finding id. When the reviewed artifact belongs to a phase, the question file is that phase's `<phase>-questions.md`.
159
+ 3. List the fixes one line each, by finding id, and offer to apply them together. When the user accepts, apply them and mark each finding `resolved` in the findings file.
160
+ 4. End with one next command — usually `aidlc transition <instance>` once no critical finding is open.