@rasensio/aidlc 1.20.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/roadmap.d.ts +66 -0
- package/dist/commands/roadmap.d.ts.map +1 -0
- package/dist/commands/roadmap.js +188 -0
- package/dist/commands/roadmap.js.map +1 -0
- package/dist/menu/roster.d.ts.map +1 -1
- package/dist/menu/roster.js +4 -0
- package/dist/menu/roster.js.map +1 -1
- package/dist/roadmap/sync/body.d.ts +37 -0
- package/dist/roadmap/sync/body.d.ts.map +1 -0
- package/dist/roadmap/sync/body.js +52 -0
- package/dist/roadmap/sync/body.js.map +1 -0
- package/dist/roadmap/sync/collect.d.ts +45 -0
- package/dist/roadmap/sync/collect.d.ts.map +1 -0
- package/dist/roadmap/sync/collect.js +93 -0
- package/dist/roadmap/sync/collect.js.map +1 -0
- package/dist/roadmap/sync/config.d.ts +95 -0
- package/dist/roadmap/sync/config.d.ts.map +1 -0
- package/dist/roadmap/sync/config.js +236 -0
- package/dist/roadmap/sync/config.js.map +1 -0
- package/dist/roadmap/sync/discover.d.ts +56 -0
- package/dist/roadmap/sync/discover.d.ts.map +1 -0
- package/dist/roadmap/sync/discover.js +126 -0
- package/dist/roadmap/sync/discover.js.map +1 -0
- package/dist/roadmap/sync/execute.d.ts +41 -0
- package/dist/roadmap/sync/execute.d.ts.map +1 -0
- package/dist/roadmap/sync/execute.js +164 -0
- package/dist/roadmap/sync/execute.js.map +1 -0
- package/dist/roadmap/sync/gh.d.ts +64 -0
- package/dist/roadmap/sync/gh.d.ts.map +1 -0
- package/dist/roadmap/sync/gh.js +86 -0
- package/dist/roadmap/sync/gh.js.map +1 -0
- package/dist/roadmap/sync/import.d.ts +73 -0
- package/dist/roadmap/sync/import.d.ts.map +1 -0
- package/dist/roadmap/sync/import.js +269 -0
- package/dist/roadmap/sync/import.js.map +1 -0
- package/dist/roadmap/sync/labels.d.ts +57 -0
- package/dist/roadmap/sync/labels.d.ts.map +1 -0
- package/dist/roadmap/sync/labels.js +80 -0
- package/dist/roadmap/sync/labels.js.map +1 -0
- package/dist/roadmap/sync/marker.d.ts +38 -0
- package/dist/roadmap/sync/marker.d.ts.map +1 -0
- package/dist/roadmap/sync/marker.js +58 -0
- package/dist/roadmap/sync/marker.js.map +1 -0
- package/dist/roadmap/sync/plan.d.ts +40 -0
- package/dist/roadmap/sync/plan.d.ts.map +1 -0
- package/dist/roadmap/sync/plan.js +272 -0
- package/dist/roadmap/sync/plan.js.map +1 -0
- package/dist/roadmap/sync/render.d.ts +28 -0
- package/dist/roadmap/sync/render.d.ts.map +1 -0
- package/dist/roadmap/sync/render.js +110 -0
- package/dist/roadmap/sync/render.js.map +1 -0
- package/dist/roadmap/sync/types.d.ts +111 -0
- package/dist/roadmap/sync/types.d.ts.map +1 -0
- package/dist/roadmap/sync/types.js +43 -0
- package/dist/roadmap/sync/types.js.map +1 -0
- package/package.json +2 -2
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAcH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAmCtC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAM,GAAG,SAA2B,GAC1C,OAAO,CAQT"}
|
package/dist/cli.js
CHANGED
|
@@ -41,6 +41,7 @@ import { registerDoctor } from './commands/doctor.js';
|
|
|
41
41
|
import { registerAddSkill } from './commands/add-skill.js';
|
|
42
42
|
import { registerCompliance } from './commands/compliance.js';
|
|
43
43
|
import { registerConstitution } from './commands/constitution.js';
|
|
44
|
+
import { registerRoadmap } from './commands/roadmap.js';
|
|
44
45
|
import { registerMenu } from './commands/menu.js';
|
|
45
46
|
import { isBareInvocation } from './menu/invocation.js';
|
|
46
47
|
import { openMenu } from './menu/index.js';
|
|
@@ -78,6 +79,7 @@ export function buildProgram() {
|
|
|
78
79
|
registerAddSkill(program);
|
|
79
80
|
registerCompliance(program);
|
|
80
81
|
registerConstitution(program);
|
|
82
|
+
registerRoadmap(program);
|
|
81
83
|
// Last, so `menu` renders last in `aidlc --help` (interactive-cli-menu/AC-5).
|
|
82
84
|
// Takes the factory, not `program`: the menu dispatches on a throwaway copy so
|
|
83
85
|
// the caller's program never carries an `exitOverride` it cannot undo.
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc roadmap` — projection of `.aidlc/roadmap/` onto GitHub Issues.
|
|
3
|
+
*
|
|
4
|
+
* Two leaves and no useful bare form:
|
|
5
|
+
*
|
|
6
|
+
* - `sync` projects eligible items onto issues. Disk is the source of truth; the tracker is
|
|
7
|
+
* a rendering. Nothing is written to disk, ever.
|
|
8
|
+
* - `import` seeds one `inbox/` item from an existing issue, once.
|
|
9
|
+
*
|
|
10
|
+
* Both command bodies are exported as plain functions taking an injectable `deps` bag and
|
|
11
|
+
* **returning** an exit code rather than setting `process.exitCode`. Without that there
|
|
12
|
+
* would be no entry point a test could call, and the consent and exit-code behaviour — the
|
|
13
|
+
* part of this feature that decides whether something gets published — would be the part
|
|
14
|
+
* with no coverage.
|
|
15
|
+
*
|
|
16
|
+
* Requirements: roadmap-issue-projection/AC-35 … roadmap-issue-projection/AC-40,
|
|
17
|
+
* roadmap-issue-projection/AC-62
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import type { Command } from 'commander';
|
|
22
|
+
import { type Prompter } from '../core/prompt.js';
|
|
23
|
+
import { type GhRunner } from '../roadmap/sync/gh.js';
|
|
24
|
+
/** Injection seam. Every default is the real implementation. */
|
|
25
|
+
export interface RoadmapDeps {
|
|
26
|
+
gh?: GhRunner;
|
|
27
|
+
prompt?: Prompter;
|
|
28
|
+
/** Where to resolve the project from. Defaults to `resolveProjectRoot()`. */
|
|
29
|
+
cwd?: string;
|
|
30
|
+
out?: (text: string) => void;
|
|
31
|
+
err?: (text: string) => void;
|
|
32
|
+
/** Overrides the TTY probe in tests. Defaults to `isInteractive()`. */
|
|
33
|
+
interactive?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface SyncOpts {
|
|
36
|
+
dryRun?: boolean;
|
|
37
|
+
yes?: boolean;
|
|
38
|
+
repo?: string;
|
|
39
|
+
retireIneligible?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Project the roadmap. Returns the process exit code.
|
|
43
|
+
*
|
|
44
|
+
* Exit codes are the interesting part of this function:
|
|
45
|
+
*
|
|
46
|
+
* - `0` — the plan was printed under `--dry-run`; or there was nothing to write; or a
|
|
47
|
+
* human was asked and declined. All three are a deliberate outcome.
|
|
48
|
+
* - `1` — a refusal, a `gh` failure, or a partly-applied plan.
|
|
49
|
+
* - `2` — writes were planned but consent could not be obtained because nothing was
|
|
50
|
+
* interactive and `--yes` was absent. **Not** zero: the caller in that situation is an
|
|
51
|
+
* automation that believed it was syncing, and a green run that wrote nothing would leave
|
|
52
|
+
* it believing that indefinitely. `--dry-run` is how a caller says it meant to look
|
|
53
|
+
* without touching anything.
|
|
54
|
+
*/
|
|
55
|
+
export declare function syncCommand(opts: SyncOpts, deps?: RoadmapDeps): Promise<number>;
|
|
56
|
+
/** Seed one `inbox/` item from an issue. Returns the process exit code. */
|
|
57
|
+
export declare function importCommand(url: string, deps?: RoadmapDeps): Promise<number>;
|
|
58
|
+
/**
|
|
59
|
+
* Register the command group.
|
|
60
|
+
*
|
|
61
|
+
* The group has no `.action()`, so bare `aidlc roadmap` prints help to stderr and exits 1 —
|
|
62
|
+
* the same shape as `add` and `knowledge`, and the reason `roadmap` belongs in the menu's
|
|
63
|
+
* `EXCLUSIONS` rather than its roster.
|
|
64
|
+
*/
|
|
65
|
+
export declare function registerRoadmap(program: Command): Command;
|
|
66
|
+
//# sourceMappingURL=roadmap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap.d.ts","sourceRoot":"","sources":["../../src/commands/roadmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAYnE,OAAO,EAA6B,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKjF,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAsBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiFrF;AAED,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBpF;AAOD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAyBzD"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc roadmap` — projection of `.aidlc/roadmap/` onto GitHub Issues.
|
|
3
|
+
*
|
|
4
|
+
* Two leaves and no useful bare form:
|
|
5
|
+
*
|
|
6
|
+
* - `sync` projects eligible items onto issues. Disk is the source of truth; the tracker is
|
|
7
|
+
* a rendering. Nothing is written to disk, ever.
|
|
8
|
+
* - `import` seeds one `inbox/` item from an existing issue, once.
|
|
9
|
+
*
|
|
10
|
+
* Both command bodies are exported as plain functions taking an injectable `deps` bag and
|
|
11
|
+
* **returning** an exit code rather than setting `process.exitCode`. Without that there
|
|
12
|
+
* would be no entry point a test could call, and the consent and exit-code behaviour — the
|
|
13
|
+
* part of this feature that decides whether something gets published — would be the part
|
|
14
|
+
* with no coverage.
|
|
15
|
+
*
|
|
16
|
+
* Requirements: roadmap-issue-projection/AC-35 … roadmap-issue-projection/AC-40,
|
|
17
|
+
* roadmap-issue-projection/AC-62
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { resolveProjectRoot } from '../core/project-root.js';
|
|
22
|
+
import { defaultPrompter } from '../core/prompt.js';
|
|
23
|
+
import { isInteractive, NO_TTY_REASON } from '../core/tty.js';
|
|
24
|
+
import { primaryCheckout } from '../roadmap/paths.js';
|
|
25
|
+
import { collectItems } from '../roadmap/sync/collect.js';
|
|
26
|
+
import { notConfiguredMessage, readSyncConfig, withRepoOverride, } from '../roadmap/sync/config.js';
|
|
27
|
+
import { buildIssueMap, truncatedMessage } from '../roadmap/sync/discover.js';
|
|
28
|
+
import { applyPlan, renderExecReport } from '../roadmap/sync/execute.js';
|
|
29
|
+
import { ghPreflight, realGhRunner } from '../roadmap/sync/gh.js';
|
|
30
|
+
import { importIssue } from '../roadmap/sync/import.js';
|
|
31
|
+
import { planProjection } from '../roadmap/sync/plan.js';
|
|
32
|
+
import { confirmMessage, renderPlan } from '../roadmap/sync/render.js';
|
|
33
|
+
function wire(deps) {
|
|
34
|
+
return {
|
|
35
|
+
gh: deps?.gh ?? realGhRunner(),
|
|
36
|
+
prompt: deps?.prompt ?? defaultPrompter,
|
|
37
|
+
cwd: deps?.cwd ?? resolveProjectRoot(),
|
|
38
|
+
out: deps?.out ?? ((t) => process.stdout.write(t)),
|
|
39
|
+
err: deps?.err ?? ((t) => process.stderr.write(t)),
|
|
40
|
+
interactive: deps?.interactive ?? isInteractive(),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Project the roadmap. Returns the process exit code.
|
|
45
|
+
*
|
|
46
|
+
* Exit codes are the interesting part of this function:
|
|
47
|
+
*
|
|
48
|
+
* - `0` — the plan was printed under `--dry-run`; or there was nothing to write; or a
|
|
49
|
+
* human was asked and declined. All three are a deliberate outcome.
|
|
50
|
+
* - `1` — a refusal, a `gh` failure, or a partly-applied plan.
|
|
51
|
+
* - `2` — writes were planned but consent could not be obtained because nothing was
|
|
52
|
+
* interactive and `--yes` was absent. **Not** zero: the caller in that situation is an
|
|
53
|
+
* automation that believed it was syncing, and a green run that wrote nothing would leave
|
|
54
|
+
* it believing that indefinitely. `--dry-run` is how a caller says it meant to look
|
|
55
|
+
* without touching anything.
|
|
56
|
+
*/
|
|
57
|
+
export async function syncCommand(opts, deps) {
|
|
58
|
+
const { gh, prompt, cwd, out, err, interactive } = wire(deps);
|
|
59
|
+
const root = primaryCheckout(cwd);
|
|
60
|
+
// Config before the gh preflight, so a bad `provider` on a machine with no gh always
|
|
61
|
+
// reports the config problem rather than the missing binary.
|
|
62
|
+
const loaded = readSyncConfig(root);
|
|
63
|
+
if (loaded.kind === 'not-configured') {
|
|
64
|
+
err(`${notConfiguredMessage()}\n`);
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
if (loaded.kind === 'invalid') {
|
|
68
|
+
err(`Error: ${loaded.error}\n`);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
const resolved = withRepoOverride(loaded.config, opts.repo);
|
|
72
|
+
if (resolved.kind !== 'ok') {
|
|
73
|
+
err(`Error: ${resolved.kind === 'invalid' ? resolved.error : notConfiguredMessage()}\n`);
|
|
74
|
+
return 1;
|
|
75
|
+
}
|
|
76
|
+
const config = resolved.config;
|
|
77
|
+
const preflight = ghPreflight(gh);
|
|
78
|
+
if (!preflight.ok) {
|
|
79
|
+
err(`Error: ${preflight.error}\n`);
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
const discovered = buildIssueMap(gh, { repo: config.repo, label: config.label });
|
|
83
|
+
if (discovered.kind === 'failed') {
|
|
84
|
+
err(`Error: could not read issues from ${repoLabelOf(config)}: ${discovered.error}\n`);
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
if (discovered.kind === 'truncated') {
|
|
88
|
+
err(`Error: ${truncatedMessage(discovered.count, discovered.limit)}\n`);
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
const collected = collectItems(cwd);
|
|
92
|
+
const planned = planProjection({
|
|
93
|
+
config,
|
|
94
|
+
items: collected.items,
|
|
95
|
+
unprojectable: collected.unprojectable,
|
|
96
|
+
issues: discovered.issues,
|
|
97
|
+
retireIneligible: opts.retireIneligible === true,
|
|
98
|
+
repoLabel: repoLabelOf(config),
|
|
99
|
+
});
|
|
100
|
+
if (planned.kind === 'refused') {
|
|
101
|
+
err(`Error: ${planned.error}\n`);
|
|
102
|
+
return 1;
|
|
103
|
+
}
|
|
104
|
+
for (const warning of planned.warnings)
|
|
105
|
+
err(`Warning: ${warning}\n`);
|
|
106
|
+
out(renderPlan(planned.plan));
|
|
107
|
+
if (planned.plan.writeCount === 0) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
if (opts.dryRun === true) {
|
|
111
|
+
out('Dry run — nothing was written.\n');
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
if (opts.yes !== true) {
|
|
115
|
+
if (!interactive) {
|
|
116
|
+
err(`Error: ${planned.plan.writeCount} write(s) are needed but consent could not be ` +
|
|
117
|
+
`obtained: ${NO_TTY_REASON}.\n` +
|
|
118
|
+
' Pass --yes to apply them, or --dry-run to say you only wanted the plan.\n');
|
|
119
|
+
return 2;
|
|
120
|
+
}
|
|
121
|
+
const answer = await prompt.confirm({ message: confirmMessage(planned.plan) });
|
|
122
|
+
if (!answer.ok || !answer.value) {
|
|
123
|
+
out('Cancelled — nothing was written.\n');
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const report = applyPlan(gh, planned.plan, config.label);
|
|
128
|
+
out(`${renderExecReport(report)}\n`);
|
|
129
|
+
return report.failure === null ? 0 : 1;
|
|
130
|
+
}
|
|
131
|
+
/** Seed one `inbox/` item from an issue. Returns the process exit code. */
|
|
132
|
+
export async function importCommand(url, deps) {
|
|
133
|
+
const { gh, cwd, out, err } = wire(deps);
|
|
134
|
+
const preflight = ghPreflight(gh);
|
|
135
|
+
if (!preflight.ok) {
|
|
136
|
+
err(`Error: ${preflight.error}\n`);
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
const result = importIssue(gh, cwd, url);
|
|
140
|
+
switch (result.kind) {
|
|
141
|
+
case 'written':
|
|
142
|
+
out(`Wrote ${result.path}\n`);
|
|
143
|
+
out('Triage it with the aidlc-roadmap skill — its Executive Summary is deliberately unfilled.\n');
|
|
144
|
+
return 0;
|
|
145
|
+
case 'duplicate':
|
|
146
|
+
err(`Error: issue #${result.coord.number} is already linked by ${result.existing}. ` +
|
|
147
|
+
'Import is one-shot; nothing was written.\n');
|
|
148
|
+
return 1;
|
|
149
|
+
case 'refused':
|
|
150
|
+
err(`Error: ${result.error}\n`);
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** What the plan header and prompt call the target. */
|
|
155
|
+
function repoLabelOf(config) {
|
|
156
|
+
return config.repo ?? 'the current repository (resolved by gh)';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Register the command group.
|
|
160
|
+
*
|
|
161
|
+
* The group has no `.action()`, so bare `aidlc roadmap` prints help to stderr and exits 1 —
|
|
162
|
+
* the same shape as `add` and `knowledge`, and the reason `roadmap` belongs in the menu's
|
|
163
|
+
* `EXCLUSIONS` rather than its roster.
|
|
164
|
+
*/
|
|
165
|
+
export function registerRoadmap(program) {
|
|
166
|
+
const group = program
|
|
167
|
+
.command('roadmap')
|
|
168
|
+
.description('Project the roadmap onto GitHub Issues, or import an issue');
|
|
169
|
+
group
|
|
170
|
+
.command('sync')
|
|
171
|
+
.description('Project eligible roadmap items onto GitHub Issues (one-way)')
|
|
172
|
+
.option('--dry-run', 'Print the plan and write nothing')
|
|
173
|
+
.option('--yes', 'Apply the plan without asking')
|
|
174
|
+
.option('--repo <owner/name>', 'Target repository (overrides roadmap.sync.repo)')
|
|
175
|
+
.option('--retire-ineligible', 'Close issues whose item has left a projected status')
|
|
176
|
+
.action(async (opts) => {
|
|
177
|
+
process.exitCode = await syncCommand(opts);
|
|
178
|
+
});
|
|
179
|
+
group
|
|
180
|
+
.command('import')
|
|
181
|
+
.description('Seed one inbox roadmap item from a GitHub issue (one-shot)')
|
|
182
|
+
.argument('<issue-url>', 'URL of the GitHub issue to import')
|
|
183
|
+
.action(async (url) => {
|
|
184
|
+
process.exitCode = await importCommand(url);
|
|
185
|
+
});
|
|
186
|
+
return group;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=roadmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap.js","sourceRoot":"","sources":["../../src/commands/roadmap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roster.d.ts","sourceRoot":"","sources":["../../src/menu/roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;CAC/B;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,SAAS,EAatC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"roster.d.ts","sourceRoot":"","sources":["../../src/menu/roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;CAC/B;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,SAAS,EAatC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BvD,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAM7C,CAAC"}
|
package/dist/menu/roster.js
CHANGED
|
@@ -58,6 +58,10 @@ export const EXCLUSIONS = {
|
|
|
58
58
|
'project a report that most have no packs for; excluding keeps the menu ' +
|
|
59
59
|
'byte-identical for a project with no pack (compliance-packs/AC-51).',
|
|
60
60
|
constitution: 'bare `aidlc constitution` exits 1; the aidlc-constitution skill is the front door to both leaves',
|
|
61
|
+
roadmap: 'bare `aidlc roadmap` exits 1; and its leaves are opt-in — `roadmap sync` refuses ' +
|
|
62
|
+
'until a `roadmap.sync` section exists in config, which the menu cannot check because ' +
|
|
63
|
+
'it reads no project state. Rostering a leaf would offer every project a command that ' +
|
|
64
|
+
'most would only see refuse. Same reasoning as `compliance` (roadmap-issue-projection/AC-61).',
|
|
61
65
|
amend: 'follows an editing act, not a starting point — an amendment must already be written into ' +
|
|
62
66
|
'requirements.md, and the menu reads no project state so it cannot tell. Offering it would ' +
|
|
63
67
|
'give most projects a command that exits 1 with "no amendment section found" ' +
|
package/dist/menu/roster.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../../src/menu/roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkBH;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAyB;IAC1C,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE;IAC1E,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACjE,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE;IAC5D,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,IAAI,EAAE;IAClF,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE;IACtE,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE;IAC9D,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE;IAC/D,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;IAC3D,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAClE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE;IACtF,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACpE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,0BAA0B,EAAE;CAC1E,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAqC;IAC1D,IAAI,EAAE,yDAAyD;IAC/D,UAAU,EAAE,kDAAkD;IAC9D,KAAK,EAAE,mCAAmC;IAC1C,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oEAAoE;IACzE,SAAS,EACP,qFAAqF;IACvF,KAAK,EAAE,mCAAmC;IAC1C,IAAI,EAAE,QAAQ;IACd,UAAU,EACR,8EAA8E;QAC9E,gFAAgF;QAChF,yEAAyE;QACzE,qEAAqE;IACvE,YAAY,EACV,kGAAkG;IACpG,KAAK,EACH,2FAA2F;QAC3F,4FAA4F;QAC5F,8EAA8E;QAC9E,4BAA4B;CAC/B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,OAAO;IACP,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;CACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"roster.js","sourceRoot":"","sources":["../../src/menu/roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkBH;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAyB;IAC1C,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE;IAC1E,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACjE,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE;IAC5D,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,IAAI,EAAE;IAClF,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE;IACtE,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE;IAC9D,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE;IAC/D,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;IAC3D,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAClE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE;IACtF,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACpE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,0BAA0B,EAAE;CAC1E,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAqC;IAC1D,IAAI,EAAE,yDAAyD;IAC/D,UAAU,EAAE,kDAAkD;IAC9D,KAAK,EAAE,mCAAmC;IAC1C,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oEAAoE;IACzE,SAAS,EACP,qFAAqF;IACvF,KAAK,EAAE,mCAAmC;IAC1C,IAAI,EAAE,QAAQ;IACd,UAAU,EACR,8EAA8E;QAC9E,gFAAgF;QAChF,yEAAyE;QACzE,qEAAqE;IACvE,YAAY,EACV,kGAAkG;IACpG,OAAO,EACL,mFAAmF;QACnF,uFAAuF;QACvF,uFAAuF;QACvF,8FAA8F;IAChG,KAAK,EACH,2FAA2F;QAC3F,4FAA4F;QAC5F,8EAA8E;QAC9E,4BAA4B;CAC/B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,OAAO;IACP,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;CACX,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The body of a created issue.
|
|
3
|
+
*
|
|
4
|
+
* Generated, fixed-shape, and carrying **no item prose except through the title** —
|
|
5
|
+
* which lives in the issue title, not here. That is a deliberate narrowing, and it
|
|
6
|
+
* closes three problems with one decision:
|
|
7
|
+
*
|
|
8
|
+
* - **Marker injection.** An item that merely *quotes* a marker — this feature's own
|
|
9
|
+
* requirements document does — would put a second marker into a different issue, making
|
|
10
|
+
* the id→issue map ambiguous enough to retitle or close the wrong issue.
|
|
11
|
+
* - **Notification side effects.** Item prose containing `@name` or `#123` sends
|
|
12
|
+
* notifications and creates cross-links the moment it is published, which is the class
|
|
13
|
+
* of harm the per-status eligibility rule exists to prevent.
|
|
14
|
+
* - **Field limits.** GitHub caps bodies at 65,536 characters. A generated body is
|
|
15
|
+
* bounded by construction, so no truncation logic exists to get wrong.
|
|
16
|
+
*
|
|
17
|
+
* The alternative considered was projecting each item's Executive Summary with
|
|
18
|
+
* marker-shaped and mention-shaped spans neutralised. Rejected: neutralising `@` and `#`
|
|
19
|
+
* mangles legitimate text, and "which spans are dangerous" becomes a judgement somebody
|
|
20
|
+
* has to maintain. A reader who wants the detail follows the link.
|
|
21
|
+
*
|
|
22
|
+
* The body is never rewritten after creation. Comments are the reason to have a tracker
|
|
23
|
+
* at all, and an update that replaced the body would delete the context around them.
|
|
24
|
+
*
|
|
25
|
+
* Requirements: roadmap-issue-projection/AC-23, roadmap-issue-projection/AC-47
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
29
|
+
import type { ProjectableItem } from './types.js';
|
|
30
|
+
/**
|
|
31
|
+
* Render the body for a newly created issue.
|
|
32
|
+
*
|
|
33
|
+
* Ends with the marker on its own line. That is a creation-time shape only — matching
|
|
34
|
+
* never depends on it (see `marker.ts`).
|
|
35
|
+
*/
|
|
36
|
+
export declare function renderIssueBody(item: ProjectableItem): string;
|
|
37
|
+
//# sourceMappingURL=body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAe7D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The body of a created issue.
|
|
3
|
+
*
|
|
4
|
+
* Generated, fixed-shape, and carrying **no item prose except through the title** —
|
|
5
|
+
* which lives in the issue title, not here. That is a deliberate narrowing, and it
|
|
6
|
+
* closes three problems with one decision:
|
|
7
|
+
*
|
|
8
|
+
* - **Marker injection.** An item that merely *quotes* a marker — this feature's own
|
|
9
|
+
* requirements document does — would put a second marker into a different issue, making
|
|
10
|
+
* the id→issue map ambiguous enough to retitle or close the wrong issue.
|
|
11
|
+
* - **Notification side effects.** Item prose containing `@name` or `#123` sends
|
|
12
|
+
* notifications and creates cross-links the moment it is published, which is the class
|
|
13
|
+
* of harm the per-status eligibility rule exists to prevent.
|
|
14
|
+
* - **Field limits.** GitHub caps bodies at 65,536 characters. A generated body is
|
|
15
|
+
* bounded by construction, so no truncation logic exists to get wrong.
|
|
16
|
+
*
|
|
17
|
+
* The alternative considered was projecting each item's Executive Summary with
|
|
18
|
+
* marker-shaped and mention-shaped spans neutralised. Rejected: neutralising `@` and `#`
|
|
19
|
+
* mangles legitimate text, and "which spans are dangerous" becomes a judgement somebody
|
|
20
|
+
* has to maintain. A reader who wants the detail follows the link.
|
|
21
|
+
*
|
|
22
|
+
* The body is never rewritten after creation. Comments are the reason to have a tracker
|
|
23
|
+
* at all, and an update that replaced the body would delete the context around them.
|
|
24
|
+
*
|
|
25
|
+
* Requirements: roadmap-issue-projection/AC-23, roadmap-issue-projection/AC-47
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
29
|
+
import { renderMarker } from './marker.js';
|
|
30
|
+
/**
|
|
31
|
+
* Render the body for a newly created issue.
|
|
32
|
+
*
|
|
33
|
+
* Ends with the marker on its own line. That is a creation-time shape only — matching
|
|
34
|
+
* never depends on it (see `marker.ts`).
|
|
35
|
+
*/
|
|
36
|
+
export function renderIssueBody(item) {
|
|
37
|
+
return [
|
|
38
|
+
'Projected from this repository’s AIDLC roadmap.',
|
|
39
|
+
'',
|
|
40
|
+
`- **Item:** \`${item.id}\``,
|
|
41
|
+
`- **File:** \`${item.relPath}\``,
|
|
42
|
+
'',
|
|
43
|
+
'The roadmap file is the source of truth. Edit it there — this issue is a rendering',
|
|
44
|
+
'of it, and its title and `aidlc:` labels are overwritten by `aidlc roadmap sync`.',
|
|
45
|
+
'Comments here are never copied back into the repository, and this description is',
|
|
46
|
+
'never rewritten after the issue is created.',
|
|
47
|
+
'',
|
|
48
|
+
renderMarker(item.id),
|
|
49
|
+
'',
|
|
50
|
+
].join('\n');
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.js","sourceRoot":"","sources":["../../../src/roadmap/sync/body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,OAAO;QACL,iDAAiD;QACjD,EAAE;QACF,iBAAiB,IAAI,CAAC,EAAE,IAAI;QAC5B,iBAAiB,IAAI,CAAC,OAAO,IAAI;QACjC,EAAE;QACF,oFAAoF;QACpF,mFAAmF;QACnF,kFAAkF;QAClF,6CAA6C;QAC7C,EAAE;QACF,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the roadmap off disk into what the planner needs.
|
|
3
|
+
*
|
|
4
|
+
* Reads only. It does not judge: every refusal lives in `planProjection`, in one tested
|
|
5
|
+
* order, so a tree with two problems always produces the same message.
|
|
6
|
+
*
|
|
7
|
+
* Two things this fixes about the obvious implementation:
|
|
8
|
+
*
|
|
9
|
+
* - `listStatus` silently skips an item whose frontmatter will not parse, because
|
|
10
|
+
* `readItem` returns null for both "absent" and "unparseable". A projection built on it
|
|
11
|
+
* alone would inherit that: an item invisible in the repo *and* on the board, with
|
|
12
|
+
* nothing anywhere saying so. Five of this project's first 49 items were invisible for
|
|
13
|
+
* up to ten days from exactly this. So `unparseableItems` is read alongside it.
|
|
14
|
+
* - An item can parse perfectly and still carry no `id` — `readItem` returns `id: null`
|
|
15
|
+
* for a missing or empty key. `unparseableItems` does not detect that class, so
|
|
16
|
+
* `aidlc doctor` is silent about it. It is collected here as its own class so the
|
|
17
|
+
* refusal message can send the user somewhere useful.
|
|
18
|
+
*
|
|
19
|
+
* Everything resolves through `primaryCheckout`. A roadmap read from a worktree's copy is
|
|
20
|
+
* a roadmap stranded on that branch, and for an inbox that is indistinguishable from
|
|
21
|
+
* losing it.
|
|
22
|
+
*
|
|
23
|
+
* Requirements: roadmap-issue-projection/AC-33, roadmap-issue-projection/AC-34,
|
|
24
|
+
* roadmap-issue-projection/AC-51
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import type { ProjectableItem, UnprojectableRef } from './types.js';
|
|
29
|
+
export interface Collected {
|
|
30
|
+
/** The primary checkout's working tree — everything below is relative to it. */
|
|
31
|
+
root: string;
|
|
32
|
+
items: readonly ProjectableItem[];
|
|
33
|
+
unprojectable: readonly UnprojectableRef[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A title for an item whose frontmatter has none.
|
|
37
|
+
*
|
|
38
|
+
* The filename slug, de-hyphenated. Refusing would be worse: the item is perfectly
|
|
39
|
+
* projectable and the slug is a serviceable title, so a missing title is a cosmetic gap
|
|
40
|
+
* and not a reason to block the whole run.
|
|
41
|
+
*/
|
|
42
|
+
export declare function titleFromFilename(filename: string): string;
|
|
43
|
+
/** Read every status directory of the primary checkout containing `cwd`. */
|
|
44
|
+
export declare function collectItems(cwd: string): Collected;
|
|
45
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;IAClC,aAAa,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA2CnD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the roadmap off disk into what the planner needs.
|
|
3
|
+
*
|
|
4
|
+
* Reads only. It does not judge: every refusal lives in `planProjection`, in one tested
|
|
5
|
+
* order, so a tree with two problems always produces the same message.
|
|
6
|
+
*
|
|
7
|
+
* Two things this fixes about the obvious implementation:
|
|
8
|
+
*
|
|
9
|
+
* - `listStatus` silently skips an item whose frontmatter will not parse, because
|
|
10
|
+
* `readItem` returns null for both "absent" and "unparseable". A projection built on it
|
|
11
|
+
* alone would inherit that: an item invisible in the repo *and* on the board, with
|
|
12
|
+
* nothing anywhere saying so. Five of this project's first 49 items were invisible for
|
|
13
|
+
* up to ten days from exactly this. So `unparseableItems` is read alongside it.
|
|
14
|
+
* - An item can parse perfectly and still carry no `id` — `readItem` returns `id: null`
|
|
15
|
+
* for a missing or empty key. `unparseableItems` does not detect that class, so
|
|
16
|
+
* `aidlc doctor` is silent about it. It is collected here as its own class so the
|
|
17
|
+
* refusal message can send the user somewhere useful.
|
|
18
|
+
*
|
|
19
|
+
* Everything resolves through `primaryCheckout`. A roadmap read from a worktree's copy is
|
|
20
|
+
* a roadmap stranded on that branch, and for an inbox that is indistinguishable from
|
|
21
|
+
* losing it.
|
|
22
|
+
*
|
|
23
|
+
* Requirements: roadmap-issue-projection/AC-33, roadmap-issue-projection/AC-34,
|
|
24
|
+
* roadmap-issue-projection/AC-51
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import { ITEM_FILENAME_RE, ROADMAP_DIR, ROADMAP_STATUSES, listStatus, primaryCheckout, unparseableItems, } from '../paths.js';
|
|
29
|
+
/**
|
|
30
|
+
* A title for an item whose frontmatter has none.
|
|
31
|
+
*
|
|
32
|
+
* The filename slug, de-hyphenated. Refusing would be worse: the item is perfectly
|
|
33
|
+
* projectable and the slug is a serviceable title, so a missing title is a cosmetic gap
|
|
34
|
+
* and not a reason to block the whole run.
|
|
35
|
+
*/
|
|
36
|
+
export function titleFromFilename(filename) {
|
|
37
|
+
const match = ITEM_FILENAME_RE.exec(filename);
|
|
38
|
+
const slug = match?.[2] ?? filename.replace(/\.md$/, '');
|
|
39
|
+
return slug.split('-').join(' ');
|
|
40
|
+
}
|
|
41
|
+
/** Read every status directory of the primary checkout containing `cwd`. */
|
|
42
|
+
export function collectItems(cwd) {
|
|
43
|
+
const root = primaryCheckout(cwd);
|
|
44
|
+
const items = [];
|
|
45
|
+
const unprojectable = [];
|
|
46
|
+
// Unparseable first, so its entries keep their own reasons rather than being
|
|
47
|
+
// overwritten by the weaker "no id" classification below.
|
|
48
|
+
const unparseableLabels = new Set();
|
|
49
|
+
for (const bad of unparseableItems(root)) {
|
|
50
|
+
unparseableLabels.add(bad.label);
|
|
51
|
+
unprojectable.push({
|
|
52
|
+
label: bad.label,
|
|
53
|
+
status: bad.status,
|
|
54
|
+
cls: 'unparseable',
|
|
55
|
+
reason: bad.detail === null ? bad.reason : `${bad.reason}: ${bad.detail}`,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
for (const status of ROADMAP_STATUSES) {
|
|
59
|
+
for (const item of listStatus(root, status)) {
|
|
60
|
+
const label = `${status}/${item.filename}`;
|
|
61
|
+
if (unparseableLabels.has(label))
|
|
62
|
+
continue;
|
|
63
|
+
if (item.id === null) {
|
|
64
|
+
unprojectable.push({
|
|
65
|
+
label,
|
|
66
|
+
status,
|
|
67
|
+
cls: 'missing-id',
|
|
68
|
+
reason: 'frontmatter has no `id:` value',
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
items.push({
|
|
73
|
+
id: item.id,
|
|
74
|
+
title: item.title ?? titleFromFilename(item.filename),
|
|
75
|
+
status,
|
|
76
|
+
filename: item.filename,
|
|
77
|
+
relPath: relPathOf(status, item.filename),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { root, items, unprojectable };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Repo-relative path of an item, with forward slashes on every platform.
|
|
85
|
+
*
|
|
86
|
+
* Built from the known layout rather than by `relative()` over the item's absolute path,
|
|
87
|
+
* so the result is identical on Windows without a separator dance. The value ends up in
|
|
88
|
+
* an issue body, where a backslash would render wrong.
|
|
89
|
+
*/
|
|
90
|
+
function relPathOf(status, filename) {
|
|
91
|
+
return `${ROADMAP_DIR}/${status}/${filename}`;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=collect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AAUrB;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAElC,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,MAAM,aAAa,GAAuB,EAAE,CAAC;IAE7C,6EAA6E;IAC7E,0DAA0D;IAC1D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,aAAa,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,aAAa;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC3C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;gBACrB,aAAa,CAAC,IAAI,CAAC;oBACjB,KAAK;oBACL,MAAM;oBACN,GAAG,EAAE,YAAY;oBACjB,MAAM,EAAE,gCAAgC;iBACzC,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACrD,MAAM;gBACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,MAAqB,EAAE,QAAgB;IACxD,OAAO,GAAG,WAAW,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;AAChD,CAAC"}
|