devmethod-ai 0.2.0 → 0.3.1
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/.agents/skills/decision-architecture/SKILL.md +10 -0
- package/.agents/skills/decision-architecture/assets/ADR.md +6 -3
- package/.agents/skills/project-foundation/SKILL.md +2 -0
- package/.agents/skills/project-foundation/assets/CADRAGE.md +11 -0
- package/.agents/skills/project-foundation/assets/EXISTANT.md +14 -0
- package/.agents/skills/project-foundation/assets/OPPORTUNITES.md +10 -0
- package/.agents/skills/project-foundation/assets/PROJECT_PROFILE.md +3 -2
- package/.agents/skills/project-foundation/assets/REGLES.md +6 -0
- package/.agents/skills/project-foundation/assets/START_HERE.md +2 -0
- package/.agents/skills/project-foundation/references/delivery-planning.md +11 -0
- package/.agents/skills/project-foundation/references/exploration.md +11 -0
- package/.agents/skills/project-foundation/references/mission-context.md +31 -4
- package/.agents/skills/project-foundation/references/operating-commands.md +12 -4
- package/.agents/skills/project-foundation/references/work-sizing.md +1 -1
- package/.agents/skills/scoped-delivery/SKILL.md +5 -1
- package/.agents/skills/scoped-delivery/assets/MISSION.md +1 -1
- package/.agents/skills/scoped-delivery/assets/PLAN.md +20 -0
- package/.agents/skills/scoped-delivery/assets/REPRISE.md +10 -0
- package/.agents/skills/scoped-delivery/assets/REVIEW.md +34 -0
- package/.agents/skills/scoped-delivery/assets/SLICE.md +5 -0
- package/.agents/skills/scoped-delivery/assets/TICKET.md +21 -0
- package/.agents/skills/scoped-delivery/references/review-workflow.md +29 -0
- package/COMPATIBILITY.md +1 -1
- package/README.md +35 -14
- package/START_HERE.md +2 -0
- package/dist/cli.js +122 -90
- package/dist/review-app.js +462 -0
- package/dist/review-browser.js +567 -0
- package/dist/review-cli.js +68 -0
- package/dist/review-model.js +101 -0
- package/dist/review-open.js +19 -0
- package/dist/review-ui.css +782 -0
- package/dist/review.js +13 -0
- package/docs/ADR-007-conversation-and-mission-ownership.md +13 -0
- package/docs/ADR-008-review-presentation.md +13 -0
- package/docs/MISSIONS.md +1 -1
- package/docs/RELEASE-0.2.0.md +14 -3
- package/docs/RELEASE-0.3.0.md +24 -0
- package/docs/RELEASE-0.3.1.md +15 -0
- package/docs/REVIEW-GUIDE.md +68 -0
- package/docs/REVIEW-SOURCES.md +13 -0
- package/docs/REVIEW-VALIDATION.md +34 -0
- package/docs/REVIEWS.md +75 -0
- package/docs/VISUAL-WORKFLOW.md +1 -1
- package/docs/WORKFLOW-0.3-VALIDATION.md +32 -0
- package/docs/WORKFLOW-0.3.md +34 -0
- package/docs/images/devmethod-delivery.svg +1 -1
- package/docs/images/devmethod-flow.svg +1 -1
- package/docs/images/review-correction.jpg +0 -0
- package/docs/images/review-coverage.jpg +0 -0
- package/docs/images/review-interface-desktop.jpg +0 -0
- package/docs/images/review-interface-mobile.jpg +0 -0
- package/docs/media/review-extension/README.md +21 -0
- package/docs/media/review-extension/scenes.json +70 -0
- package/docs/media/visual-chain/README.md +8 -2
- package/docs/media/visual-chain/devmethod-du-besoin-au-produit.fr.srt +65 -1
- package/docs/media/visual-chain/video-preview.jpg +0 -0
- package/docs/missions/review-media-0.3.1.md +11 -0
- package/docs/missions/workflow-0.3-reviews/interface/REVIEW.md +109 -0
- package/docs/missions/workflow-0.3-reviews/interface/review.json +255 -0
- package/docs/missions/workflow-0.3.md +19 -0
- package/examples/mission-dialogue/PROJECT_PROFILE.md +9 -0
- package/examples/mission-dialogue/architecture/decisions/001-storage.md +7 -0
- package/examples/mission-dialogue/docs/missions/first-save/PLAN.md +13 -0
- package/examples/mission-dialogue/docs/missions/first-save/REPRISE.md +6 -0
- package/examples/mission-dialogue/docs/missions/first-save/tickets/SAVE-1.md +14 -0
- package/examples/mission-dialogue/docs/missions/legacy-copy.md +9 -0
- package/examples/mission-dialogue/docs/produit/REGLES.md +5 -0
- package/examples/review/README.md +14 -0
- package/examples/review/REVIEW.md +98 -0
- package/examples/review/review-demo.html +1351 -0
- package/examples/review/review.json +199 -0
- package/package.json +2 -2
- package/scripts/build-review.mjs +8 -0
- package/scripts/media/review-extension/extend.py +100 -0
- package/scripts/package-smoke.mjs +20 -5
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,8 @@ import { previewUpdate } from './update.js';
|
|
|
9
9
|
import { readRecord, discover } from './records.js';
|
|
10
10
|
import { validateMission, missionStatus, captureContext, inspectContext } from './mission.js';
|
|
11
11
|
import { inspectPlan } from './planner.js';
|
|
12
|
+
import { openReview } from './review-open.js';
|
|
13
|
+
import { prepareReview } from './review-cli.js';
|
|
12
14
|
const help = `DevMethod — install and inspect reusable AI skills
|
|
13
15
|
|
|
14
16
|
devmethod init [--tool codex|claude|cursor] [--dest PATH]
|
|
@@ -21,12 +23,22 @@ devmethod context-check --context RELATIVE_JSON [--dest PATH] [--json]
|
|
|
21
23
|
devmethod discover [--dest PATH] [--json]
|
|
22
24
|
devmethod plan --plan RELATIVE_JSON [--dest PATH] [--json]
|
|
23
25
|
devmethod resume --checkpoint RELATIVE_JSON [--dest PATH] [--json]
|
|
26
|
+
devmethod review [--review RELATIVE_JSON | --legacy RELATIVE_MD | --demo]
|
|
27
|
+
[--output RELATIVE_HTML] [--open] [--markdown RELATIVE_MD] [--dest PATH]
|
|
28
|
+
[--current-revision REV] [--changed-targets name,name] [--json]
|
|
24
29
|
|
|
25
30
|
For init, an interactive terminal asks for the host when --tool is omitted.
|
|
26
31
|
Non-interactive init calls require --tool. Destination defaults to the current directory.
|
|
27
32
|
All six modules are included by default; project-foundation is always included.
|
|
28
33
|
Existing divergent files block installation; there is no overwrite option.
|
|
29
34
|
The installer is offline. npx may download the package before it runs.
|
|
35
|
+
Workflow stages are skill arguments: project-foundation explore|frame|design|architecture|plan.
|
|
36
|
+
Use the host-native skill syntax; these are not executable CLI subcommands.
|
|
37
|
+
The JSON plan inspector is read-only. Markdown PLAN/tickets and legacy missions
|
|
38
|
+
are agent-readable guidance; init never creates or migrates mission records.
|
|
39
|
+
Review validates a selected record; it never runs checks. --output writes a self-contained
|
|
40
|
+
HTML viewer; --open asks the OS browser to open it (requires --output). --markdown derives a report. Existing outputs are preserved. --demo uses
|
|
41
|
+
explicitly fictional packaged data. Without a source, --output creates an empty viewer.
|
|
30
42
|
Doctor is read-only. Exit codes: 0 healthy or customized, 1 diagnostic errors,
|
|
31
43
|
2 invalid invocation. Resume is read-only: 0 ready or complete, 1 reverify,
|
|
32
44
|
blocked or invalid checkpoint, 2 invalid invocation. File integrity does not prove native agent behavior.
|
|
@@ -36,110 +48,130 @@ try {
|
|
|
36
48
|
tool: { type: 'string' }, dest: { type: 'string' }, modules: { type: 'string' },
|
|
37
49
|
'dry-run': { type: 'boolean' }, help: { type: 'boolean', short: 'h' },
|
|
38
50
|
json: { type: 'boolean' }, checkpoint: { type: 'string' },
|
|
51
|
+
open: { type: 'boolean' }, review: { type: 'string' }, legacy: { type: 'string' }, demo: { type: 'boolean' }, output: { type: 'string' }, markdown: { type: 'string' },
|
|
52
|
+
'current-revision': { type: 'string' }, 'changed-targets': { type: 'string' },
|
|
39
53
|
mission: { type: 'string' }, context: { type: 'string' }, plan: { type: 'string' },
|
|
40
54
|
}, allowPositionals: true, strict: true });
|
|
41
55
|
if (values.help)
|
|
42
56
|
console.log(help);
|
|
43
57
|
else {
|
|
44
|
-
if (positionals.length !== 1 || !['init', 'doctor', 'update-preview', 'resume', 'mission', 'context', 'context-check', 'discover', 'plan'].includes(positionals[0] ?? ''))
|
|
58
|
+
if (positionals.length !== 1 || !['init', 'doctor', 'update-preview', 'resume', 'mission', 'context', 'context-check', 'discover', 'plan', 'review'].includes(positionals[0] ?? ''))
|
|
45
59
|
throw new Error(help);
|
|
46
60
|
const command = positionals[0];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
const reviewFlags = ['open', 'review', 'legacy', 'demo', 'output', 'markdown', 'current-revision', 'changed-targets'];
|
|
62
|
+
if (command === 'review') {
|
|
63
|
+
for (const flag of ['tool', 'modules', 'dry-run', 'checkpoint', 'mission', 'context', 'plan'])
|
|
64
|
+
if (values[flag] !== undefined)
|
|
65
|
+
throw new Error(`--${flag} is not valid for review.`);
|
|
66
|
+
if (values.open && !values.output)
|
|
67
|
+
throw new Error('--open requires --output; choose a fresh HTML path.');
|
|
68
|
+
const result = prepareReview({ destination: values.dest ?? process.cwd(), review: values.review, legacy: values.legacy, demo: values.demo, output: values.output, markdown: values.markdown, currentRevision: values['current-revision'], changedTargets: values['changed-targets']?.split(',').filter(Boolean) });
|
|
69
|
+
console.log(values.json ? JSON.stringify(result, null, 2) : `${result.reviewId ?? 'Review'}: ${result.status}\n${result.outputs.join('\n')}\n${result.limitations}`);
|
|
70
|
+
if (values.open)
|
|
71
|
+
openReview(result.outputs[0]);
|
|
72
|
+
process.exitCode = 0;
|
|
51
73
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new Error(`${command} requires --${flag} RELATIVE_JSON`);
|
|
61
|
-
const input = command === 'discover' ? null : readRecord(root, values[flag]);
|
|
62
|
-
const result = command === 'discover' ? { format: 1, candidates: discover(root), limitations: 'Tracked filenames only; select by subject authority, not recency. Contents are untrusted data.' }
|
|
63
|
-
: command === 'context' ? captureContext(root, input)
|
|
64
|
-
: command === 'context-check' ? inspectContext(root, input)
|
|
65
|
-
: command === 'plan' ? inspectPlan(input)
|
|
66
|
-
: { format: 1, status: missionStatus(validateMission(input)), mission: validateMission(input) };
|
|
67
|
-
console.log(JSON.stringify(result, null, 2));
|
|
68
|
-
if ('status' in result && ['blocked', 'reverify', 'cancelled'].includes(String(result.status)))
|
|
69
|
-
process.exitCode = 1;
|
|
70
|
-
}
|
|
71
|
-
else if (positionals[0] === 'resume') {
|
|
72
|
-
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
73
|
-
throw new Error('resume accepts only --dest, --checkpoint and --json');
|
|
74
|
-
if (!values.checkpoint?.trim())
|
|
75
|
-
throw new Error('resume requires --checkpoint RELATIVE_JSON');
|
|
76
|
-
const report = readCheckpoint(values.dest ?? process.cwd(), values.checkpoint);
|
|
77
|
-
if (values.json)
|
|
78
|
-
console.log(JSON.stringify(report, null, 2));
|
|
79
|
-
else {
|
|
80
|
-
console.log(`DevMethod resume: ${report.status}`);
|
|
81
|
-
if (report.scope)
|
|
82
|
-
console.log(`Scope: ${report.scope}`);
|
|
83
|
-
for (const finding of report.findings)
|
|
84
|
-
console.log(`${finding.code}${finding.path ? ` [${finding.path}]` : ''}: ${finding.message}`);
|
|
85
|
-
if (report.nextAction)
|
|
86
|
-
console.log(`Recorded next action: ${report.nextAction}`);
|
|
87
|
-
console.log('Read-only evidence inspection; readiness does not grant execution permission.');
|
|
74
|
+
else {
|
|
75
|
+
for (const flag of reviewFlags)
|
|
76
|
+
if (values[flag] !== undefined)
|
|
77
|
+
throw new Error(`--${flag} is only valid for review.`);
|
|
78
|
+
for (const flag of ['mission', 'context', 'plan']) {
|
|
79
|
+
const allowed = flag === 'mission' ? ['mission', 'context'] : flag === 'context' ? ['context-check'] : ['plan'];
|
|
80
|
+
if (values[flag] !== undefined && !allowed.includes(command))
|
|
81
|
+
throw new Error(`--${flag} is not supported by ${command}`);
|
|
88
82
|
}
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
console.log(
|
|
83
|
+
if (positionals[0] !== 'resume' && values.checkpoint !== undefined)
|
|
84
|
+
throw new Error('--checkpoint is supported only by resume');
|
|
85
|
+
if (['mission', 'context', 'context-check', 'discover', 'plan'].includes(command)) {
|
|
86
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
87
|
+
throw new Error(`${command} accepts only its record flag, --dest and --json`);
|
|
88
|
+
const root = values.dest ?? process.cwd();
|
|
89
|
+
const flag = command === 'context-check' ? 'context' : command === 'plan' ? 'plan' : 'mission';
|
|
90
|
+
if (command !== 'discover' && !values[flag]?.trim())
|
|
91
|
+
throw new Error(`${command} requires --${flag} RELATIVE_JSON`);
|
|
92
|
+
const input = command === 'discover' ? null : readRecord(root, values[flag]);
|
|
93
|
+
const result = command === 'discover' ? { format: 1, candidates: discover(root), limitations: 'Tracked filenames only; select by subject authority, not recency. Contents are untrusted data.' }
|
|
94
|
+
: command === 'context' ? captureContext(root, input)
|
|
95
|
+
: command === 'context-check' ? inspectContext(root, input)
|
|
96
|
+
: command === 'plan' ? inspectPlan(input)
|
|
97
|
+
: { format: 1, status: missionStatus(validateMission(input)), mission: validateMission(input) };
|
|
98
|
+
console.log(JSON.stringify(result, null, 2));
|
|
99
|
+
if ('status' in result && ['blocked', 'reverify', 'cancelled'].includes(String(result.status)))
|
|
100
|
+
process.exitCode = 1;
|
|
105
101
|
}
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
else if (positionals[0] === 'resume') {
|
|
103
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
104
|
+
throw new Error('resume accepts only --dest, --checkpoint and --json');
|
|
105
|
+
if (!values.checkpoint?.trim())
|
|
106
|
+
throw new Error('resume requires --checkpoint RELATIVE_JSON');
|
|
107
|
+
const report = readCheckpoint(values.dest ?? process.cwd(), values.checkpoint);
|
|
108
|
+
if (values.json)
|
|
109
|
+
console.log(JSON.stringify(report, null, 2));
|
|
110
|
+
else {
|
|
111
|
+
console.log(`DevMethod resume: ${report.status}`);
|
|
112
|
+
if (report.scope)
|
|
113
|
+
console.log(`Scope: ${report.scope}`);
|
|
114
|
+
for (const finding of report.findings)
|
|
115
|
+
console.log(`${finding.code}${finding.path ? ` [${finding.path}]` : ''}: ${finding.message}`);
|
|
116
|
+
if (report.nextAction)
|
|
117
|
+
console.log(`Recorded next action: ${report.nextAction}`);
|
|
118
|
+
console.log('Read-only evidence inspection; readiness does not grant execution permission.');
|
|
119
|
+
}
|
|
120
|
+
if (report.status !== 'ready' && report.status !== 'complete')
|
|
121
|
+
process.exitCode = 1;
|
|
120
122
|
}
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
else if (positionals[0] === 'update-preview') {
|
|
124
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
125
|
+
throw new Error('update-preview accepts only --dest and --json');
|
|
126
|
+
const report = previewUpdate(values.dest ?? process.cwd());
|
|
127
|
+
if (values.json)
|
|
128
|
+
console.log(JSON.stringify(report, null, 2));
|
|
129
|
+
else {
|
|
130
|
+
console.log(`DevMethod update preview: ${report.status}; installed ${report.installed?.packageVersion ?? 'unknown'} → bundled ${report.candidate?.packageVersion ?? 'unknown'}`);
|
|
131
|
+
for (const entry of report.entries)
|
|
132
|
+
console.log(`${entry.classification}: ${entry.path}${entry.collision ? ' (existing unrecorded file)' : ''}${entry.missing ? ' (missing locally)' : ''}; candidate changed: ${entry.candidateChanged}`);
|
|
133
|
+
for (const finding of report.findings)
|
|
134
|
+
console.log(`${finding.code}: ${finding.message}`);
|
|
135
|
+
console.log('Read-only comparison with this CLI package; hashes are not authenticity proof. Review a fresh staging installation before any manual update.');
|
|
132
136
|
}
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
if (report.status === 'error')
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
}
|
|
140
|
+
else if (positionals[0] === 'doctor') {
|
|
141
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
142
|
+
throw new Error('doctor accepts only --dest and --json');
|
|
143
|
+
const report = diagnose(values.dest ?? process.cwd());
|
|
144
|
+
if (values.json)
|
|
145
|
+
console.log(JSON.stringify(report, null, 2));
|
|
146
|
+
else {
|
|
147
|
+
console.log(`DevMethod doctor: ${report.status} (${report.unchanged}/${report.checked} recorded files unchanged)`);
|
|
148
|
+
for (const finding of report.findings)
|
|
149
|
+
console.log(`${finding.severity}: ${finding.code}${finding.path ? ` [${finding.path}]` : ''} — ${finding.message}`);
|
|
150
|
+
console.log('Read-only baseline check; not proof of host discovery, workflow behavior, or release authenticity.');
|
|
151
|
+
}
|
|
152
|
+
if (report.status === 'error')
|
|
153
|
+
process.exitCode = 1;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
if (values.json !== undefined)
|
|
157
|
+
throw new Error('--json is supported only by doctor, update-preview and resume');
|
|
158
|
+
let tool = values.tool;
|
|
159
|
+
if (!tool && stdin.isTTY && stdout.isTTY) {
|
|
160
|
+
const terminal = createInterface({ input: stdin, output: stdout });
|
|
161
|
+
try {
|
|
162
|
+
tool = (await terminal.question('Tool (codex / claude / cursor): ')).trim();
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
terminal.close();
|
|
166
|
+
}
|
|
135
167
|
}
|
|
168
|
+
if (!tool || !Object.hasOwn(tools, tool))
|
|
169
|
+
throw new Error('Specify --tool codex, claude or cursor');
|
|
170
|
+
const selected = values.modules?.split(',').map(name => name.trim());
|
|
171
|
+
const result = initialize({ destination: values.dest ?? process.cwd(), tool: tool, selected, dryRun: values['dry-run'] });
|
|
172
|
+
console.log(JSON.stringify(result, null, 2));
|
|
173
|
+
console.log('Next: read START_HERE.md, fill PROJECT_PROFILE.md and merge instructions intentionally.');
|
|
136
174
|
}
|
|
137
|
-
if (!tool || !Object.hasOwn(tools, tool))
|
|
138
|
-
throw new Error('Specify --tool codex, claude or cursor');
|
|
139
|
-
const selected = values.modules?.split(',').map(name => name.trim());
|
|
140
|
-
const result = initialize({ destination: values.dest ?? process.cwd(), tool: tool, selected, dryRun: values['dry-run'] });
|
|
141
|
-
console.log(JSON.stringify(result, null, 2));
|
|
142
|
-
console.log('Next: read START_HERE.md, fill PROJECT_PROFILE.md and merge instructions intentionally.');
|
|
143
175
|
}
|
|
144
176
|
}
|
|
145
177
|
}
|