devmethod-ai 0.1.0-rc.2 → 0.2.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/.agents/skills/decision-architecture/SKILL.md +15 -13
- package/.agents/skills/decision-architecture/assets/ADR.md +18 -17
- package/.agents/skills/decision-architecture/references/api-contracts.md +21 -16
- package/.agents/skills/decision-architecture/references/backend-boundaries.md +21 -18
- package/.agents/skills/decision-architecture/references/product-decisions.md +14 -17
- package/.agents/skills/design-to-code/SKILL.md +18 -11
- package/.agents/skills/design-to-code/assets/UI_ACCEPTANCE.md +13 -12
- package/.agents/skills/design-to-code/references/ux-contract.md +20 -15
- package/.agents/skills/design-to-code/references/visual-creation.md +37 -0
- package/.agents/skills/project-foundation/SKILL.md +39 -30
- package/.agents/skills/project-foundation/assets/AGENTS.foundation.md +16 -15
- package/.agents/skills/project-foundation/assets/PROJECT_PROFILE.md +24 -23
- package/.agents/skills/project-foundation/assets/START_HERE.md +17 -14
- package/.agents/skills/project-foundation/references/mission-context.md +30 -0
- package/.agents/skills/project-foundation/references/operating-commands.md +49 -34
- package/.agents/skills/project-foundation/references/profiles/README.md +18 -0
- package/.agents/skills/project-foundation/references/profiles/ci.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/cloud-delivery.md +13 -0
- package/.agents/skills/project-foundation/references/profiles/messaging.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/mongodb.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/node-nest.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/postgres-drizzle.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/react-next.md +11 -0
- package/.agents/skills/project-foundation/references/profiles/typescript.md +11 -0
- package/.agents/skills/project-foundation/references/work-sizing.md +31 -0
- package/.agents/skills/react-feature-engineering/SKILL.md +26 -22
- package/.agents/skills/react-feature-engineering/references/review-and-sources.md +41 -37
- package/.agents/skills/reliable-ai-integration/SKILL.md +13 -10
- package/.agents/skills/reliable-ai-integration/assets/AI_EVALUATION.md +19 -18
- package/.agents/skills/reliable-ai-integration/references/evidence-and-media.md +22 -18
- package/.agents/skills/reliable-ai-integration/references/jobs-and-costs.md +20 -15
- package/.agents/skills/scoped-delivery/SKILL.md +25 -18
- package/.agents/skills/scoped-delivery/assets/CHECKPOINT.md +22 -11
- package/.agents/skills/scoped-delivery/assets/MISSION.md +35 -0
- package/.agents/skills/scoped-delivery/assets/SLICE.md +15 -14
- package/.agents/skills/scoped-delivery/assets/VERIFICATION.md +19 -0
- package/.agents/skills/scoped-delivery/references/verification-and-cost.md +21 -18
- package/COMPATIBILITY.md +3 -3
- package/CONTRIBUTING.md +13 -0
- package/README.md +94 -9
- package/START_HERE.md +24 -0
- package/VALIDATION.md +37 -0
- package/dist/checkpoint.js +171 -0
- package/dist/cli.js +118 -17
- package/dist/doctor.js +113 -0
- package/dist/filesystem.js +32 -0
- package/dist/init.js +38 -34
- package/dist/mission.js +85 -0
- package/dist/planner.js +65 -0
- package/dist/records.js +76 -0
- package/dist/update.js +57 -0
- package/docs/ADR-001-distribution.md +13 -0
- package/docs/ADR-002-read-only-diagnostics.md +25 -0
- package/docs/ADR-003-installation-provenance.md +15 -0
- package/docs/ADR-004-checkpoint-resumption.md +23 -0
- package/docs/ADR-005-mission-context.md +11 -0
- package/docs/ADR-006-opt-in-native-pilot.md +15 -0
- package/docs/BMAD-COMPARISON.md +34 -0
- package/docs/CODEX-ADAPTER-VALIDATION.md +20 -0
- package/docs/COMPARISON-ITERATION.md +25 -0
- package/docs/DOCTOR.md +23 -0
- package/docs/EVALUATION.md +39 -0
- package/docs/EVOLUTION.md +34 -0
- package/docs/GREENFIELD-VALIDATION.md +36 -0
- package/docs/MILESTONES.md +39 -0
- package/docs/MISSIONS.md +47 -0
- package/docs/NATIVE-PILOT-RESULTS.md +22 -0
- package/docs/NATIVE-PILOT.md +17 -0
- package/docs/ORCHESTRATION.md +11 -0
- package/docs/RC2-VALIDATION.md +50 -0
- package/docs/RELEASE-0.1.0.md +60 -0
- package/docs/RELEASE-0.2.0.md +37 -0
- package/docs/RELEASE-CHECKLIST.md +13 -0
- package/docs/RELEASE-NOTES-0.1.0-rc.2.md +32 -0
- package/docs/RELEASE-NOTES-0.1.0.md +11 -0
- package/docs/RESUMPTION.md +87 -0
- package/docs/ROADMAP.md +39 -0
- package/docs/STACK-PROFILES.md +9 -0
- package/docs/TROUBLESHOOTING.md +16 -0
- package/docs/UPDATES.md +30 -0
- package/docs/VISUAL-CREATION-PROPOSAL.md +21 -0
- package/docs/VISUAL-WORKFLOW.md +75 -0
- package/docs/images/devmethod-delivery.svg +10 -0
- package/docs/images/devmethod-flow.svg +13 -0
- package/docs/media/from-zero/README.md +17 -0
- package/docs/media/from-zero/devmethod-demo.fr.srt +59 -0
- package/docs/media/from-zero/scenes.json +50 -0
- package/docs/media/full-chain-4k/README.md +37 -0
- package/docs/media/full-chain-4k/devmethod-chaine-complete.fr.srt +435 -0
- package/docs/media/full-chain-4k/scenes.json +173 -0
- package/docs/media/full-chain-4k/transcripts.fr.md +315 -0
- package/docs/media/visual-chain/README.md +44 -0
- package/docs/media/visual-chain/assets/add-book-v1.png +0 -0
- package/docs/media/visual-chain/assets/completed-v1.png +0 -0
- package/docs/media/visual-chain/devmethod-du-besoin-au-produit.fr.srt +147 -0
- package/docs/media/visual-chain/execution.fr.md +30 -0
- package/docs/media/visual-chain/image-prompts.json +9 -0
- package/docs/media/visual-chain/reference-hashes.json +5 -0
- package/docs/media/visual-chain/scenes.json +232 -0
- package/docs/media/visual-chain/video-preview.jpg +0 -0
- package/docs/missions/visual-workflow.md +46 -0
- package/evaluation/COMPARISONS.md +33 -0
- package/evaluation/README.md +35 -0
- package/evaluation/candidate-setup.json +33 -0
- package/evaluation/comparison-v2-readiness.json +18 -0
- package/evaluation/comparison-v2-results.json +58 -0
- package/evaluation/fixtures/dependency/CONTRIBUTING.md +3 -0
- package/evaluation/fixtures/dependency/TICKET.md +3 -0
- package/evaluation/fixtures/dependency/acceptance.test.mjs +4 -0
- package/evaluation/fixtures/dependency/api.mjs +1 -0
- package/evaluation/fixtures/failing-verification/CONTRIBUTING.md +3 -0
- package/evaluation/fixtures/failing-verification/acceptance.test.mjs +4 -0
- package/evaluation/fixtures/failing-verification/total.mjs +1 -0
- package/evaluation/fixtures/stale-handoff/CHECKPOINT.md +3 -0
- package/evaluation/fixtures/stale-handoff/CONTRACT.md +3 -0
- package/evaluation/fixtures/stale-handoff/CONTRIBUTING.md +3 -0
- package/evaluation/fixtures/stale-handoff/acceptance.test.mjs +4 -0
- package/evaluation/fixtures/stale-handoff/label.mjs +1 -0
- package/evaluation/fixtures/update-customization/README.md +13 -0
- package/evaluation/fixtures.json +85 -0
- package/evaluation/greenfield/acceptance.test.mjs +57 -0
- package/evaluation/greenfield/security.test.mjs +28 -0
- package/evaluation/native-pilot-results.json +155 -0
- package/examples/README.md +36 -0
- package/examples/bugfix/acceptance.test.mjs +17 -0
- package/examples/bugfix/page-size.mjs +4 -0
- package/examples/clair-from-zero/AGENT-EVALUATION.md +15 -0
- package/examples/clair-from-zero/MISSION.md +41 -0
- package/examples/clair-from-zero/README.md +24 -0
- package/examples/clair-from-zero/app/app.mjs +69 -0
- package/examples/clair-from-zero/app/domain.mjs +30 -0
- package/examples/clair-from-zero/app/index.html +20 -0
- package/examples/clair-from-zero/app/storage.mjs +4 -0
- package/examples/clair-from-zero/app/styles.css +128 -0
- package/examples/clair-from-zero/browser-check.cjs +2 -0
- package/examples/clair-from-zero/tests/domain.test.mjs +37 -0
- package/examples/fullstack/CONTRACT.md +23 -0
- package/examples/fullstack/DEPENDENCIES.md +18 -0
- package/examples/fullstack/README.md +100 -0
- package/examples/fullstack/api/application/tasks.ts +13 -0
- package/examples/fullstack/api/domain/task.ts +12 -0
- package/examples/fullstack/api/http.ts +26 -0
- package/examples/fullstack/api/infrastructure/migrate.ts +15 -0
- package/examples/fullstack/api/infrastructure/postgres.ts +18 -0
- package/examples/fullstack/api/infrastructure/schema.ts +6 -0
- package/examples/fullstack/api/main.ts +17 -0
- package/examples/fullstack/api/tsconfig.json +17 -0
- package/examples/fullstack/compose.yaml +14 -0
- package/examples/fullstack/migrations/0000_tasks.sql +5 -0
- package/examples/fullstack/migrations/meta/_journal.json +13 -0
- package/examples/fullstack/mission.json +34 -0
- package/examples/fullstack/package-lock.json +2661 -0
- package/examples/fullstack/package.json +45 -0
- package/examples/fullstack/tests/e2e.test.cjs +54 -0
- package/examples/fullstack/tests/http.test.cjs +33 -0
- package/examples/fullstack/tests/postgres.test.cjs +29 -0
- package/examples/fullstack/tests/unit.test.cjs +20 -0
- package/examples/fullstack/tests/web-model.test.cjs +23 -0
- package/examples/fullstack/web/app/layout.tsx +4 -0
- package/examples/fullstack/web/app/page.tsx +11 -0
- package/examples/fullstack/web/features/tasks/components/task-list.tsx +11 -0
- package/examples/fullstack/web/features/tasks/hooks/use-task-filter.ts +7 -0
- package/examples/fullstack/web/features/tasks/model/tasks.ts +12 -0
- package/examples/fullstack/web/features/tasks/server/list-tasks.ts +8 -0
- package/examples/fullstack/web/next.config.mjs +2 -0
- package/examples/fullstack/web/tsconfig.json +36 -0
- package/examples/mission/CONTRACT.md +3 -0
- package/examples/mission/mission.json +18 -0
- package/examples/mission/plan.json +11 -0
- package/examples/pocket-tasks/BRIEF.md +21 -0
- package/examples/pocket-tasks/PROJECT_PROFILE.md +19 -0
- package/examples/pocket-tasks/README.md +43 -0
- package/examples/pocket-tasks/docs/ADR-001.md +7 -0
- package/examples/pocket-tasks/docs/HANDOFF.md +16 -0
- package/examples/pocket-tasks/docs/MISSION.md +15 -0
- package/examples/pocket-tasks/docs/VERIFICATION.md +58 -0
- package/examples/pocket-tasks/package.json +1 -0
- package/examples/pocket-tasks/public/app.js +84 -0
- package/examples/pocket-tasks/public/index.html +12 -0
- package/examples/pocket-tasks/public/styles.css +1 -0
- package/examples/pocket-tasks/server.mjs +79 -0
- package/examples/pocket-tasks/src/domain.mjs +31 -0
- package/examples/pocket-tasks/src/store.mjs +49 -0
- package/examples/pocket-tasks/tests/app.test.mjs +132 -0
- package/examples/pocket-tasks/tests/ui-errors.test.mjs +49 -0
- package/examples/visual-pilot/README.md +11 -0
- package/examples/visual-pilot/app/app.js +10 -0
- package/examples/visual-pilot/app/index.html +1 -0
- package/examples/visual-pilot/app/reference.png +0 -0
- package/examples/visual-pilot/app/style.css +3 -0
- package/examples/visual-pilot/browser-check.cjs +3 -0
- package/examples/visual-pilot/desktop-actual.png +0 -0
- package/examples/visual-pilot/directions-prompt.txt +1 -0
- package/examples/visual-pilot/directions-v1.png +0 -0
- package/examples/visual-pilot/editorial-mockup-prompt.txt +1 -0
- package/examples/visual-pilot/editorial-mockup-v1.png +0 -0
- package/examples/visual-pilot/mismatch-probe.png +0 -0
- package/examples/visual-pilot/mobile-actual.png +0 -0
- package/examples/visual-pilot/quick-filter/AGENT-RESULT.md +25 -0
- package/examples/visual-pilot/quick-filter/baseline.log +42 -0
- package/examples/visual-pilot/quick-filter/filter.mjs +3 -0
- package/examples/visual-pilot/quick-filter/filter.test.mjs +9 -0
- package/package.json +15 -3
- package/scripts/check-codex-git.mjs +20 -0
- package/scripts/check-docs.mjs +14 -0
- package/scripts/check-native-sandbox.mjs +11 -0
- package/scripts/comparison-readiness.mjs +26 -0
- package/scripts/comparison.mjs +42 -0
- package/scripts/evaluation.mjs +64 -0
- package/scripts/fullstack-mission.mjs +30 -0
- package/scripts/hosts/checks.mjs +13 -0
- package/scripts/hosts/codex-meter.mjs +17 -0
- package/scripts/hosts/codex-rpc.mjs +44 -0
- package/scripts/hosts/codex-task.mjs +29 -0
- package/scripts/hosts/codex.mjs +28 -0
- package/scripts/media/demo-actions.cjs +16 -0
- package/scripts/media/encode-demo.py +22 -0
- package/scripts/media/record-demo.cjs +30 -0
- package/scripts/media/visual-short/check.cjs +1 -0
- package/scripts/media/visual-short/encode.py +16 -0
- package/scripts/media/visual-short/record.cjs +4 -0
- package/scripts/media/visual-short/story.py +34 -0
- package/scripts/native-host.mjs +55 -0
- package/scripts/package-smoke.mjs +64 -0
- package/scripts/probe-codex-children.mjs +41 -0
- package/scripts/run-comparison-v2.mjs +45 -0
- package/scripts/run-native-pilot.mjs +76 -0
- package/scripts/summarize-native-pilot.mjs +7 -0
package/README.md
CHANGED
|
@@ -2,29 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
From idea to delivery with your AI coding agents.
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/devmethod-ai) [](LICENSE) [](https://github.com/montassarkhalloufi/DevMethod/actions/workflows/platform-tests.yml)
|
|
6
|
+
|
|
7
|
+
## Watch DevMethod build Lisière — 2 min 58 s
|
|
8
|
+
|
|
9
|
+
[](https://github.com/montassarkhalloufi/DevMethod/raw/refs/heads/main/docs/media/visual-chain/devmethod-du-besoin-au-produit-4k.fr.mp4)
|
|
10
|
+
|
|
11
|
+
**[▶ Watch the video — 4K, French narration](https://github.com/montassarkhalloufi/DevMethod/raw/refs/heads/main/docs/media/visual-chain/devmethod-du-besoin-au-produit-4k.fr.mp4)** · [Subtitles and execution evidence](docs/media/visual-chain/README.md) · [Download the working prototype](https://github.com/montassarkhalloufi/DevMethod/raw/refs/heads/main/docs/media/visual-chain/lisiere-visual-source.zip)
|
|
12
|
+
|
|
13
|
+
**Concrete example: Lisière, a personal reading library.** Start with an idea, compare three visual directions, approve a master screen, derive the other screen images, choose a suitable architecture, then build and verify the application.
|
|
14
|
+
|
|
15
|
+
| Step shown | Concrete result |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| Explore and frame | Add books, filter readings and track three statuses |
|
|
18
|
+
| Design | Three alternatives → selected editorial master → add-book and completed-reading images |
|
|
19
|
+
| Architecture | HTML/CSS/JavaScript, testable book rules and browser-local storage |
|
|
20
|
+
| Plan, ready and implement | Working form, filters, status changes and saved books |
|
|
21
|
+
| Review and verify | Corrected alert/focus behavior, 6 tests and real Chrome desktop/mobile journeys |
|
|
22
|
+
| Integrate and handoff | Local prototype, references, evidence and resumption context |
|
|
23
|
+
|
|
24
|
+
The video uses illustrative Codex commands with real generated images and recorded application interactions. DevMethod guides the coding agent; image generation requires an available host tool. The visual workflow is in the current GitHub source and is not included in npm 0.1.0. [Follow the visual workflow](docs/VISUAL-WORKFLOW.md).
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
5
28
|
DevMethod is the public name of the kit. Its entry-point skill remains `project-foundation`, preserving existing invocations and the six-module structure.
|
|
6
29
|
|
|
7
30
|
A reusable workflow for taking a software project from exploration to delivery: decisions, UX, architecture, tickets, development, tests, review and handoff. Six focused skills support fourteen workflow stages, each ending with evidence, limitations and one suggested next command.
|
|
8
31
|
|
|
9
|
-
**0.1 release candidate.**
|
|
32
|
+
**npm stable: 0.1.0 (`latest`). Next release candidate: 0.2.0.** [0.2.0 changes and publication status](docs/RELEASE-0.2.0.md). The release includes mission/context inspection, Git-aware evidence resumption, explicit update conflicts, manual task planning and optional stack profiles. See the [release record](docs/RELEASE-0.1.0.md) for publication status and verification.
|
|
33
|
+
|
|
34
|
+
For developers and small teams using coding agents in new or existing repositories. Requires Node.js 22+ and npm; Git is required for context provenance. Application examples have separate framework/database prerequisites. DevMethod records scope, decisions and verification; it does not certify agent output, infer all dependencies, deploy applications or run an autonomous backlog. Installation and deterministic fixture results are separate from native host validation. See [compatibility](COMPATIBILITY.md).
|
|
35
|
+
|
|
36
|
+
Start with [missions and the tested source quick start](docs/MISSIONS.md), the [tested from-zero Pocket Tasks project](examples/pocket-tasks/README.md), then the [complete Next.js/NestJS example](examples/fullstack/README.md). Advanced references: [context and sizing](docs/MISSIONS.md), [safe updates](docs/UPDATES.md), [resumption](docs/RESUMPTION.md), [optional stack profiles](docs/STACK-PROFILES.md), [bounded manual planning](docs/ORCHESTRATION.md), [troubleshooting](docs/TROUBLESHOOTING.md), and [release status and evidence](docs/RELEASE-0.1.0.md).
|
|
10
37
|
|
|
11
38
|
## Install in a project
|
|
12
39
|
|
|
13
|
-
Requires Node.js 22+ and npm.
|
|
40
|
+
Requires Node.js 22+ and npm. Install into a fresh staging directory first:
|
|
14
41
|
|
|
15
42
|
```bash
|
|
16
|
-
npx --yes --
|
|
43
|
+
npx --yes devmethod-ai@0.1.0 init --tool codex --dest ../foundation-staging
|
|
17
44
|
```
|
|
18
45
|
|
|
19
|
-
Choose
|
|
46
|
+
Choose `codex`, `claude` or `cursor`. If you omit `--tool`, an interactive terminal asks. For example:
|
|
20
47
|
|
|
21
48
|
```bash
|
|
22
|
-
npx --yes
|
|
49
|
+
npx --yes devmethod-ai@0.1.0 init --tool claude --dest ../foundation-staging --dry-run
|
|
23
50
|
```
|
|
24
51
|
|
|
25
|
-
Remove `--dry-run` to write. Select a subset with `--modules decision-architecture,scoped-delivery`; `project-foundation` is always included. Without `--modules`, all six modules are installed. The installer refuses divergent files and duplicate skills across host directories. It never edits AGENTS.md, CLAUDE.md or your package.json.
|
|
52
|
+
Remove `--dry-run` to write. Select a subset with `--modules decision-architecture,scoped-delivery`; `project-foundation` is always included. Without `--modules`, all six modules are installed. The installer refuses divergent files and duplicate skills across host directories. It never edits AGENTS.md, CLAUDE.md or your package.json. Review the staging output, then merge only what the project needs.
|
|
26
53
|
|
|
27
|
-
The
|
|
54
|
+
The installer has no runtime dependencies and makes no network requests after npm obtains the package. To pin the final version, use `npx --yes devmethod-ai@0.1.0 init ...`. To use the visual workflow before 0.2.0 is published, use a reviewed repository commit: `npx --yes --package=github:montassarkhalloufi/DevMethod#<commit-sha> devmethod init ...`.
|
|
28
55
|
|
|
29
56
|
Complete PROJECT_PROFILE.md with your real stack, commands, scope, deployment permissions and data requirements. Merge AGENTS.foundation.md into the project's existing instructions only after review. Claude Code reads CLAUDE.md: preserve its current content and, if the project has AGENTS.md, optionally add `@AGENTS.md` to import it. Keep existing accepted architecture decisions authoritative.
|
|
30
57
|
|
|
@@ -32,6 +59,44 @@ The installer includes `DEVMETHOD-LICENSE` so it preserves your application's LI
|
|
|
32
59
|
|
|
33
60
|
Installation copies the reusable method and blank templates, not another project's context. Preserve filled profiles, decisions, tickets and instruction files separately. Manifest hashes describe the initial installation; local template customization is expected to change them. To install elsewhere, run the CLI again.
|
|
34
61
|
|
|
62
|
+
## Verify the source checkout
|
|
63
|
+
|
|
64
|
+
From a reviewed source checkout:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
npm ci
|
|
68
|
+
npm test
|
|
69
|
+
npm run check:docs
|
|
70
|
+
npm pack --dry-run
|
|
71
|
+
node dist/cli.js init --tool codex --dest ../candidate-staging
|
|
72
|
+
node dist/cli.js doctor --dest ../candidate-staging --json
|
|
73
|
+
node dist/cli.js update-preview --dest ../candidate-staging --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The package includes advanced docs and fictional examples. `init` copies only the skills and adoption templates, preserving the application. Read the package docs from its checkout or extracted tarball. The core CLI has no runtime dependencies; example applications install their own pinned dependencies separately.
|
|
77
|
+
|
|
78
|
+
## Inspect an adopted installation
|
|
79
|
+
|
|
80
|
+
From a reviewed source checkout, inspect an installed project without changing it:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
node dist/cli.js doctor --dest /path/to/project --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Doctor reports missing files, changes from the initial manifest and duplicate host copies. Customized profiles and skills produce warnings; they are preserved. It does not execute an agent or certify application quality. See [diagnostic codes and exit statuses](docs/DOCTOR.md).
|
|
87
|
+
|
|
88
|
+
## Choose the amount of process
|
|
89
|
+
|
|
90
|
+
The stages below are available entry points, not fourteen mandatory conversations.
|
|
91
|
+
|
|
92
|
+
| Path | Typical work | Expected process |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| Quick | Clear bug fix inside existing contracts | Inline readiness, implementation, focused verification and review |
|
|
95
|
+
| Standard | Feature spanning components or sessions | Ready slice, relevant contracts, checks and resumable evidence |
|
|
96
|
+
| Major | New product decisions or consequential architecture changes | Resolve decisions, split into slices, verify integration |
|
|
97
|
+
|
|
98
|
+
Risk and repository policy override apparent size. Reuse accepted UI, architecture and project context; only fill actual gaps. See [work sizing](.agents/skills/project-foundation/references/work-sizing.md) and [starter exercises](examples/README.md).
|
|
99
|
+
|
|
35
100
|
## Run the workflow
|
|
36
101
|
|
|
37
102
|
In Codex: `$project-foundation status`.
|
|
@@ -44,7 +109,7 @@ Replace `status` with an action below. These are prompts to the skill, not shell
|
|
|
44
109
|
|---|---|
|
|
45
110
|
| `explore` | Problem, users, alternatives and constraints |
|
|
46
111
|
| `frame` | Product scope, exclusions and success measures |
|
|
47
|
-
| `design` |
|
|
112
|
+
| `design` | Visual directions, selected mockups and UX criteria; image tooling depends on the host |
|
|
48
113
|
| `architecture` | Decisions, boundaries and contracts |
|
|
49
114
|
| `plan` | Milestones and tickets with dependencies |
|
|
50
115
|
| `ready TASK-1` | Readiness assessment before implementation |
|
|
@@ -59,12 +124,30 @@ Replace `status` with an action below. These are prompts to the skill, not shell
|
|
|
59
124
|
|
|
60
125
|
See the [full command contract](.agents/skills/project-foundation/references/operating-commands.md). A failed check returns to correction; a blocked gate leads to handoff or replanning. Tests, code review and native permissions remain necessary.
|
|
61
126
|
|
|
127
|
+

|
|
128
|
+
|
|
129
|
+
## More recorded examples
|
|
130
|
+
|
|
131
|
+
[Detailed recorded Lisière chain](docs/media/full-chain-4k/README.md) · [Short Clair demo](docs/media/from-zero/README.md) · [Run Clair](examples/clair-from-zero/README.md). Clair is a separate from-zero example; the featured video above follows Lisière throughout.
|
|
132
|
+
|
|
133
|
+
## Visual design and architecture
|
|
134
|
+
|
|
135
|
+
DevMethod connects art-direction selection, an approved master screen, derived image mockups and browser fidelity checks with technology and architecture decisions. Follow the [visual workflow guide](docs/VISUAL-WORKFLOW.md) and [recorded Lisière pilot](examples/visual-pilot/README.md). These capabilities are included in the 0.2.0 candidate; npm 0.1.0 predates them. See the [0.2.0 release record](docs/RELEASE-0.2.0.md) for publication status.
|
|
136
|
+
|
|
62
137
|
## Included modules
|
|
63
138
|
|
|
64
139
|
`project-foundation`, `decision-architecture`, `design-to-code`, `react-feature-engineering`, `reliable-ai-integration`, `scoped-delivery`.
|
|
65
140
|
|
|
66
141
|
Use the modules your project needs. Adapt the workflow to your stack, architecture and delivery process.
|
|
67
142
|
|
|
143
|
+
## Where DevMethod can improve
|
|
144
|
+
|
|
145
|
+
The target is a compact engineering workflow for verifiable changes in existing repositories. BMad already documents adaptive planning, existing-codebase workflows and broader automation; DevMethod has not demonstrated parity or superiority. Read the [sourced comparison](docs/BMAD-COMPARISON.md), [prioritized roadmap](docs/ROADMAP.md), and [evaluation protocol](docs/EVALUATION.md). We aim to measure correct outcomes, honest evidence, context cost and reliable resumption under matched conditions.
|
|
146
|
+
|
|
147
|
+
## Demo material
|
|
148
|
+
|
|
149
|
+
The workflow illustration above is kept in the repository as an SVG so it remains reviewable and usable in dark mode. Try the [runnable bug-fix exercise](examples/README.md), which includes an intentionally failing baseline and an explicit task. It is a fixture, not a recorded model success. A real demonstration should preserve the observed failures, changes and checks; use the [native smoke protocol](COMPATIBILITY.md#native-smoke-protocol) to assess the host workflow.
|
|
150
|
+
|
|
68
151
|
## Verify and contribute
|
|
69
152
|
|
|
70
153
|
```bash
|
|
@@ -73,4 +156,6 @@ npm test
|
|
|
73
156
|
npm pack --dry-run
|
|
74
157
|
```
|
|
75
158
|
|
|
76
|
-
Read [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
159
|
+
Read [CONTRIBUTING.md](CONTRIBUTING.md), [COMPATIBILITY.md](COMPATIBILITY.md), and the [release checklist](docs/RELEASE-CHECKLIST.md). Licensed under [MIT](LICENSE).
|
|
160
|
+
|
|
161
|
+
A bounded [native Codex pilot](docs/NATIVE-PILOT-RESULTS.md) now records actual fixture execution and independent review. It covers one matched B1 triple and two DevMethod probes, not a completed comparative campaign or general autonomous dispatch.
|
package/START_HERE.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Start the kit
|
|
2
|
+
|
|
3
|
+
DevMethod offers six independent modules; this installation contains the modules you selected. If this is a staging directory, review and copy its installed skill folder into the project while preserving existing files. If you installed directly into the project, the selected skills are already in place. If a version already exists, compare changes before updating it. Keep `PROJECT_PROFILE.md` and complete the stack, commands, scope, deployment permissions, and data requirements from the project before adoption. `ENGINEERING_POLICY.template.md` retains the included policy; merge it with `CONTRIBUTING.md` and existing instructions.
|
|
4
|
+
|
|
5
|
+
In Codex, start with `$project-foundation status`. In Claude Code or Cursor, start with `/project-foundation status`. For an open-ended request:
|
|
6
|
+
|
|
7
|
+
> Use the `project-foundation` skill for this project. Read existing instructions and sources, complete the profile without reinventing decisions, then deliver the following scope: [my objective]. Apply only relevant modules. Preserve the approved mockup, architecture boundaries, and React rules. Progress to a verified result within this scope.
|
|
8
|
+
|
|
9
|
+
The installer copies the method and its blank templates, not the adopted project's context. Keep the completed profile, decisions, tickets, and instructions separately. The manifest describes the initial installation: local adaptations normally change its hashes. To update, install into a fresh folder and compare changes.
|
|
10
|
+
|
|
11
|
+
If skills are not discovered automatically:
|
|
12
|
+
|
|
13
|
+
> Read `.agents/skills/project-foundation/SKILL.md` and only its relevant references, then complete: [my objective].
|
|
14
|
+
|
|
15
|
+
`AGENTS.foundation.md` provides a fragment to merge into existing instructions. It never replaces an `AGENTS.md`. The kit does not include third-party Vercel skills: apply versions already approved by the project; adding them is separate.
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
|
|
19
|
+
- “Resume this ticket and deliver its complete slice.”
|
|
20
|
+
- “Here is the approved mockup: implement this page and verify desktop/mobile.”
|
|
21
|
+
- “Compare these two architectures against my budget and propose an ADR.”
|
|
22
|
+
- “Fix the view/hooks/business separation of this feature without a global rewrite.”
|
|
23
|
+
|
|
24
|
+
This kit reduces repetitive framing; it does not by itself prove application quality or production readiness.
|
package/VALIDATION.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Release candidate validation
|
|
2
|
+
|
|
3
|
+
## Diagnostics and workflow improvement candidate
|
|
4
|
+
|
|
5
|
+
Source change based on `758491c3e85621c6adae6b5c71d1b32c28a380af`; npm release pending. Local runtime: Linux x64, Node.js 24.19.0. The platform results below belong to the earlier candidate, not this change.
|
|
6
|
+
|
|
7
|
+
- `npm ci --ignore-scripts --prefer-offline`, `npm test` (strict TypeScript build and 16 passing tests), and `npm pack --dry-run` passed.
|
|
8
|
+
- The actual local tarball installed all three host profiles and their scoped-delivery subsets via offline npx. Packaged `doctor --json` returned healthy reports, and retained customized profiles with warning status.
|
|
9
|
+
- Doctor accepted a format 2 installation produced by the previous source CLI (29 recorded files), as well as the new payload (31 recorded files).
|
|
10
|
+
- Updated skill frontmatter passed the skill validator; local Markdown file links and `git diff --check` passed.
|
|
11
|
+
- The B1 exercise produced the expected two failing tests. A temporary reference implementation passed both, confirming fixture solvability. This was a fixture check, not an independent model or BMad benchmark.
|
|
12
|
+
|
|
13
|
+
The existing platform CI now also checks packaged diagnostics. Record that run's conclusions before claiming this change passed on macOS/Windows. Authenticated host behavior, matched comparative evaluations and npm publication remain separate pending gates. Review performed locally by the implementing agent; no independent review is claimed.
|
|
14
|
+
|
|
15
|
+
## Earlier 0.1 candidate
|
|
16
|
+
|
|
17
|
+
Date: 2026-09-12. Candidate: 0.1.
|
|
18
|
+
|
|
19
|
+
Executed `npm test`: strict TypeScript build and 7 Node.js tests passed. Coverage: three host layouts, six skill names and relative references, SHA-256 manifests, MIT notice, selected modules, dry-run without writes, identical installation, conflict rejection before writes, preserved project instructions, invalid arguments, duplicate host detection, blocked paths and symlink rejection.
|
|
20
|
+
|
|
21
|
+
`npm pack` produced the compiled CLI and skill payload without runtime dependencies. An actual offline `npx --package=<local-tarball> devmethod init --tool claude` installed all six modules successfully. Installation never migrates existing project context; customized templates normally differ from initial manifest hashes.
|
|
22
|
+
|
|
23
|
+
These checks validate installation and documentation; they do not execute a Claude or Cursor model. Native authenticated evaluations remain pending, as documented in COMPATIBILITY.md.
|
|
24
|
+
|
|
25
|
+
## Native operating-system results
|
|
26
|
+
|
|
27
|
+
[GitHub Actions run 34720121631](https://github.com/montassarkhalloufi/DevMethod/actions/runs/34720121631) completed successfully for commit `0790845289eccfe4aa3cfd0fe9e849eeca11b0a7` with Node.js 22.23.2 on all three runners:
|
|
28
|
+
|
|
29
|
+
| System | Architecture | Unit tests | Packaged npx installations |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| Ubuntu | x64 | 7 passed | Codex, Claude Code, Cursor passed |
|
|
32
|
+
| macOS | ARM64 | 7 passed | Codex, Claude Code, Cursor passed |
|
|
33
|
+
| Windows Server 2025 | x64 | 7 passed | Codex, Claude Code, Cursor passed |
|
|
34
|
+
|
|
35
|
+
Each job rebuilt strict TypeScript, verified the committed build, packed the actual package and invoked npx against that tarball for each host. It checked all six installed modules and the SHA-256 manifest. Installation paths included spaces. This establishes the tested runtime combinations, not every OS version or an authenticated host session. Windows shell commands used Git Bash; PowerShell-specific interaction was not evaluated.
|
|
36
|
+
|
|
37
|
+
Publication target: https://github.com/montassarkhalloufi/DevMethod. This report covers the 0.1 candidate source and local checks, not a stable release certification. Native authenticated compatibility remains pending.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { parseJson, checkPath } from './filesystem.js';
|
|
5
|
+
import { gitState, validGit } from './records.js';
|
|
6
|
+
const object = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
7
|
+
const identifier = (value) => typeof value === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(value);
|
|
8
|
+
const nonempty = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
9
|
+
// Portable repository-relative paths only: no Windows aliases, drives or streams.
|
|
10
|
+
function safePath(value) {
|
|
11
|
+
return typeof value === 'string' && value.length > 0 && !/[\\:\x00-\x1f\x7f]/.test(value)
|
|
12
|
+
&& value.split('/').every(part => part.length > 0 && part !== '.' && part !== '..'
|
|
13
|
+
&& !/[. ]$/.test(part) && !/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(part));
|
|
14
|
+
}
|
|
15
|
+
function pinned(value) {
|
|
16
|
+
return object(value) && identifier(value.id) && safePath(value.path)
|
|
17
|
+
&& typeof value.sha256 === 'string' && /^[a-f0-9]{64}$/.test(value.sha256);
|
|
18
|
+
}
|
|
19
|
+
function ids(value) {
|
|
20
|
+
return Array.isArray(value) && value.every(identifier) && new Set(value).size === value.length;
|
|
21
|
+
}
|
|
22
|
+
function validate(input) {
|
|
23
|
+
if (!object(input) || input.format !== 1)
|
|
24
|
+
throw new Error('Expected checkpoint format 1. Markdown checkpoints remain a manual workflow.');
|
|
25
|
+
if (!nonempty(input.scope) || typeof input.status !== 'string' || !['active', 'blocked', 'complete'].includes(input.status))
|
|
26
|
+
throw new Error('Checkpoint needs a nonempty scope and status active, blocked or complete.');
|
|
27
|
+
if (input.nextAction !== null && !nonempty(input.nextAction))
|
|
28
|
+
throw new Error('nextAction must be a nonempty string or null.');
|
|
29
|
+
if (input.status === 'complete' && input.nextAction !== null)
|
|
30
|
+
throw new Error('Completed scope must have nextAction null; completion authorizes no new work.');
|
|
31
|
+
if (input.status !== 'complete' && !nonempty(input.nextAction))
|
|
32
|
+
throw new Error('Active or blocked scope needs an explicit nextAction.');
|
|
33
|
+
if (!Array.isArray(input.sources) || !input.sources.every(pinned) || input.sources.length === 0)
|
|
34
|
+
throw new Error('sources must contain pinned IDs, safe relative paths and lowercase SHA-256 hashes.');
|
|
35
|
+
if (!Array.isArray(input.evidence) || !input.evidence.every(item => pinned(item) && object(item)
|
|
36
|
+
&& ids(item.sourceIds) && item.sourceIds.length > 0 && ids(item.dependsOn)
|
|
37
|
+
&& typeof item.outcome === 'string' && ['passed', 'failed', 'blocked', 'not-run'].includes(item.outcome)))
|
|
38
|
+
throw new Error('evidence needs pinned artifacts, sourceIds, dependsOn and outcome passed, failed or not-run.');
|
|
39
|
+
if (input.sources.length > 256 || input.evidence.length > 256)
|
|
40
|
+
throw new Error('Checkpoint supports at most 256 sources and evidence items.');
|
|
41
|
+
if (input.git !== undefined && !validGit(input.git))
|
|
42
|
+
throw new Error('Invalid Git checkpoint provenance.');
|
|
43
|
+
if (input.blockers !== undefined && (!Array.isArray(input.blockers) || !input.blockers.every(nonempty)))
|
|
44
|
+
throw new Error('blockers must be nonempty strings.');
|
|
45
|
+
for (const item of input.evidence) {
|
|
46
|
+
if (item.criterionIds !== undefined && (!ids(item.criterionIds) || !item.criterionIds.length))
|
|
47
|
+
throw new Error('criterionIds must be nonempty unique IDs.');
|
|
48
|
+
if (item.kind !== undefined && (typeof item.kind !== 'string' || !['automated', 'manual', 'design-review', 'recommendation'].includes(item.kind)))
|
|
49
|
+
throw new Error('Invalid verification kind.');
|
|
50
|
+
if (item.revision !== undefined && !nonempty(item.revision))
|
|
51
|
+
throw new Error('Invalid evidence revision.');
|
|
52
|
+
}
|
|
53
|
+
const state = input;
|
|
54
|
+
const sources = new Set(state.sources.map(source => source.id));
|
|
55
|
+
const evidence = new Map(state.evidence.map(item => [item.id, item]));
|
|
56
|
+
if (sources.size !== state.sources.length || evidence.size !== state.evidence.length)
|
|
57
|
+
throw new Error('Source IDs and evidence IDs must each be unique.');
|
|
58
|
+
if (new Set(state.sources.map(source => source.path)).size !== state.sources.length
|
|
59
|
+
|| new Set(state.evidence.map(item => item.path)).size !== state.evidence.length)
|
|
60
|
+
throw new Error('Source paths and evidence paths must each be unique.');
|
|
61
|
+
for (const item of state.evidence) {
|
|
62
|
+
if (item.sourceIds.some(id => !sources.has(id)) || item.dependsOn.some(id => !evidence.has(id)))
|
|
63
|
+
throw new Error(`Evidence ${item.id} references an unknown source or evidence ID.`);
|
|
64
|
+
}
|
|
65
|
+
// Iterative topological traversal avoids stack exhaustion on an untrusted graph.
|
|
66
|
+
const done = new Set();
|
|
67
|
+
while (done.size < evidence.size) {
|
|
68
|
+
let progress = false;
|
|
69
|
+
for (const item of state.evidence)
|
|
70
|
+
if (!done.has(item.id) && item.dependsOn.every(id => done.has(id))) {
|
|
71
|
+
done.add(item.id);
|
|
72
|
+
progress = true;
|
|
73
|
+
}
|
|
74
|
+
if (!progress)
|
|
75
|
+
throw new Error('Evidence dependencies contain a cycle.');
|
|
76
|
+
}
|
|
77
|
+
return state;
|
|
78
|
+
}
|
|
79
|
+
function readPinned(destination, relative) {
|
|
80
|
+
if (!safePath(relative))
|
|
81
|
+
throw new Error('Expected a safe repository-relative path.');
|
|
82
|
+
const file = path.join(destination, relative);
|
|
83
|
+
checkPath(file);
|
|
84
|
+
if (!fs.lstatSync(file).isFile() || fs.lstatSync(file).size > 1024 * 1024)
|
|
85
|
+
throw new Error('Expected a regular file.');
|
|
86
|
+
return fs.readFileSync(file);
|
|
87
|
+
}
|
|
88
|
+
function emptyReport(destination) {
|
|
89
|
+
return { format: 1, destination: path.resolve(destination), status: 'invalid', findings: [], sources: [], evidence: [] };
|
|
90
|
+
}
|
|
91
|
+
/** Read-only inspection; report readiness never grants execution or integration permission. */
|
|
92
|
+
export function inspectCheckpoint(destination, input) {
|
|
93
|
+
const report = emptyReport(destination);
|
|
94
|
+
let state;
|
|
95
|
+
try {
|
|
96
|
+
state = validate(input);
|
|
97
|
+
checkPath(report.destination);
|
|
98
|
+
if (!fs.statSync(report.destination).isDirectory())
|
|
99
|
+
throw new Error('Destination must be a directory.');
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
report.findings.push({ code: 'invalid-checkpoint', message: error.message });
|
|
103
|
+
return report;
|
|
104
|
+
}
|
|
105
|
+
report.scope = state.scope;
|
|
106
|
+
report.nextAction = state.nextAction;
|
|
107
|
+
const compare = (item, kind) => {
|
|
108
|
+
try {
|
|
109
|
+
const digest = createHash('sha256').update(readPinned(report.destination, item.path)).digest('hex');
|
|
110
|
+
if (digest === item.sha256)
|
|
111
|
+
return 'unchanged';
|
|
112
|
+
report.findings.push({ code: `${kind}-changed`, id: item.id, path: item.path, message: `Pinned ${kind} content changed; inspect the difference and repeat affected verification.` });
|
|
113
|
+
return 'changed';
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
report.findings.push({ code: `${kind}-unavailable`, id: item.id, path: item.path, message: `Cannot inspect pinned ${kind}: ${error.message}` });
|
|
117
|
+
return 'unavailable';
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
report.sources = state.sources.map(source => ({ id: source.id, state: compare(source, 'source') }));
|
|
121
|
+
const sourceStates = new Map(report.sources.map(source => [source.id, source.state]));
|
|
122
|
+
const artifactStates = new Map(state.evidence.map(item => [item.id, compare(item, 'evidence')]));
|
|
123
|
+
const evidenceStates = new Map();
|
|
124
|
+
while (evidenceStates.size < state.evidence.length) {
|
|
125
|
+
for (const item of state.evidence) {
|
|
126
|
+
if (evidenceStates.has(item.id) || !item.dependsOn.every(id => evidenceStates.has(id)))
|
|
127
|
+
continue;
|
|
128
|
+
const invalidated = artifactStates.get(item.id) !== 'unchanged'
|
|
129
|
+
|| item.sourceIds.some(id => sourceStates.get(id) !== 'unchanged')
|
|
130
|
+
|| item.dependsOn.some(id => evidenceStates.get(id) !== 'valid');
|
|
131
|
+
const result = invalidated ? 'invalidated' : item.outcome === 'passed' ? 'valid' : item.outcome;
|
|
132
|
+
evidenceStates.set(item.id, result);
|
|
133
|
+
if (result !== 'valid')
|
|
134
|
+
report.findings.push({ code: `evidence-${result}`, id: item.id, path: item.path,
|
|
135
|
+
message: `Evidence ${item.id} is ${result}; it cannot support resumption until affected verification is recorded again.` });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
report.evidence = state.evidence.map(item => ({ id: item.id, state: evidenceStates.get(item.id) }));
|
|
139
|
+
let gitChanged = false;
|
|
140
|
+
if (state.git) {
|
|
141
|
+
try {
|
|
142
|
+
const current = gitState(report.destination);
|
|
143
|
+
gitChanged = Object.entries(state.git).some(([key, value]) => current[key] !== value);
|
|
144
|
+
if (gitChanged)
|
|
145
|
+
report.findings.push({ code: 'git-changed', message: 'Branch, commit or worktree changed; reassess scope and omitted dependencies. Independent pins are retained.' });
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
gitChanged = true;
|
|
149
|
+
report.findings.push({ code: 'git-unavailable', message: 'Cannot compare recorded Git provenance.' });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const blocker of state.blockers ?? [])
|
|
153
|
+
report.findings.push({ code: 'dependency-blocked', message: blocker });
|
|
154
|
+
const needsVerification = gitChanged || report.sources.some(source => source.state !== 'unchanged')
|
|
155
|
+
|| report.evidence.some(item => item.state !== 'valid') || report.evidence.length === 0;
|
|
156
|
+
if (!report.evidence.length)
|
|
157
|
+
report.findings.push({ code: 'evidence-empty', message: 'No evidence was pinned; establish verification before relying on this checkpoint.' });
|
|
158
|
+
report.status = state.status === 'blocked' || (state.blockers?.length ?? 0) > 0 || state.evidence.some(item => item.outcome === 'blocked') ? 'blocked' : needsVerification ? 'reverify' : state.status === 'complete' ? 'complete' : 'ready';
|
|
159
|
+
return report;
|
|
160
|
+
}
|
|
161
|
+
/** Load a JSON checkpoint within the project; never follows symbolic paths or changes files. */
|
|
162
|
+
export function readCheckpoint(destination, checkpointPath) {
|
|
163
|
+
try {
|
|
164
|
+
return inspectCheckpoint(destination, parseJson(readPinned(path.resolve(destination), checkpointPath).toString('utf8')));
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const report = emptyReport(destination);
|
|
168
|
+
report.findings.push({ code: 'invalid-checkpoint', path: checkpointPath, message: error.message });
|
|
169
|
+
return report;
|
|
170
|
+
}
|
|
171
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -3,43 +3,144 @@ import { parseArgs } from 'node:util';
|
|
|
3
3
|
import { createInterface } from 'node:readline/promises';
|
|
4
4
|
import { stdin, stdout } from 'node:process';
|
|
5
5
|
import { initialize, tools } from './init.js';
|
|
6
|
-
|
|
6
|
+
import { diagnose } from './doctor.js';
|
|
7
|
+
import { readCheckpoint } from './checkpoint.js';
|
|
8
|
+
import { previewUpdate } from './update.js';
|
|
9
|
+
import { readRecord, discover } from './records.js';
|
|
10
|
+
import { validateMission, missionStatus, captureContext, inspectContext } from './mission.js';
|
|
11
|
+
import { inspectPlan } from './planner.js';
|
|
12
|
+
const help = `DevMethod — install and inspect reusable AI skills
|
|
7
13
|
|
|
8
14
|
devmethod init [--tool codex|claude|cursor] [--dest PATH]
|
|
9
15
|
[--modules name,name] [--dry-run]
|
|
16
|
+
devmethod doctor [--dest PATH] [--json]
|
|
17
|
+
devmethod update-preview [--dest PATH] [--json]
|
|
18
|
+
devmethod mission --mission RELATIVE_JSON [--dest PATH] [--json]
|
|
19
|
+
devmethod context --mission RELATIVE_JSON [--dest PATH] [--json]
|
|
20
|
+
devmethod context-check --context RELATIVE_JSON [--dest PATH] [--json]
|
|
21
|
+
devmethod discover [--dest PATH] [--json]
|
|
22
|
+
devmethod plan --plan RELATIVE_JSON [--dest PATH] [--json]
|
|
23
|
+
devmethod resume --checkpoint RELATIVE_JSON [--dest PATH] [--json]
|
|
10
24
|
|
|
11
|
-
|
|
12
|
-
Non-interactive calls require --tool. Destination defaults to the current directory.
|
|
25
|
+
For init, an interactive terminal asks for the host when --tool is omitted.
|
|
26
|
+
Non-interactive init calls require --tool. Destination defaults to the current directory.
|
|
13
27
|
All six modules are included by default; project-foundation is always included.
|
|
14
28
|
Existing divergent files block installation; there is no overwrite option.
|
|
15
29
|
The installer is offline. npx may download the package before it runs.
|
|
30
|
+
Doctor is read-only. Exit codes: 0 healthy or customized, 1 diagnostic errors,
|
|
31
|
+
2 invalid invocation. Resume is read-only: 0 ready or complete, 1 reverify,
|
|
32
|
+
blocked or invalid checkpoint, 2 invalid invocation. File integrity does not prove native agent behavior.
|
|
16
33
|
`;
|
|
17
34
|
try {
|
|
18
35
|
const { values, positionals } = parseArgs({ options: {
|
|
19
36
|
tool: { type: 'string' }, dest: { type: 'string' }, modules: { type: 'string' },
|
|
20
37
|
'dry-run': { type: 'boolean' }, help: { type: 'boolean', short: 'h' },
|
|
38
|
+
json: { type: 'boolean' }, checkpoint: { type: 'string' },
|
|
39
|
+
mission: { type: 'string' }, context: { type: 'string' }, plan: { type: 'string' },
|
|
21
40
|
}, allowPositionals: true, strict: true });
|
|
22
41
|
if (values.help)
|
|
23
42
|
console.log(help);
|
|
24
43
|
else {
|
|
25
|
-
if (positionals.length !== 1 || positionals[0]
|
|
44
|
+
if (positionals.length !== 1 || !['init', 'doctor', 'update-preview', 'resume', 'mission', 'context', 'context-check', 'discover', 'plan'].includes(positionals[0] ?? ''))
|
|
26
45
|
throw new Error(help);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
const command = positionals[0];
|
|
47
|
+
for (const flag of ['mission', 'context', 'plan']) {
|
|
48
|
+
const allowed = flag === 'mission' ? ['mission', 'context'] : flag === 'context' ? ['context-check'] : ['plan'];
|
|
49
|
+
if (values[flag] !== undefined && !allowed.includes(command))
|
|
50
|
+
throw new Error(`--${flag} is not supported by ${command}`);
|
|
51
|
+
}
|
|
52
|
+
if (positionals[0] !== 'resume' && values.checkpoint !== undefined)
|
|
53
|
+
throw new Error('--checkpoint is supported only by resume');
|
|
54
|
+
if (['mission', 'context', 'context-check', 'discover', 'plan'].includes(command)) {
|
|
55
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
56
|
+
throw new Error(`${command} accepts only its record flag, --dest and --json`);
|
|
57
|
+
const root = values.dest ?? process.cwd();
|
|
58
|
+
const flag = command === 'context-check' ? 'context' : command === 'plan' ? 'plan' : 'mission';
|
|
59
|
+
if (command !== 'discover' && !values[flag]?.trim())
|
|
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.');
|
|
88
|
+
}
|
|
89
|
+
if (report.status !== 'ready' && report.status !== 'complete')
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
}
|
|
92
|
+
else if (positionals[0] === 'update-preview') {
|
|
93
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
94
|
+
throw new Error('update-preview accepts only --dest and --json');
|
|
95
|
+
const report = previewUpdate(values.dest ?? process.cwd());
|
|
96
|
+
if (values.json)
|
|
97
|
+
console.log(JSON.stringify(report, null, 2));
|
|
98
|
+
else {
|
|
99
|
+
console.log(`DevMethod update preview: ${report.status}; installed ${report.installed?.packageVersion ?? 'unknown'} → bundled ${report.candidate?.packageVersion ?? 'unknown'}`);
|
|
100
|
+
for (const entry of report.entries)
|
|
101
|
+
console.log(`${entry.classification}: ${entry.path}${entry.collision ? ' (existing unrecorded file)' : ''}${entry.missing ? ' (missing locally)' : ''}; candidate changed: ${entry.candidateChanged}`);
|
|
102
|
+
for (const finding of report.findings)
|
|
103
|
+
console.log(`${finding.code}: ${finding.message}`);
|
|
104
|
+
console.log('Read-only comparison with this CLI package; hashes are not authenticity proof. Review a fresh staging installation before any manual update.');
|
|
32
105
|
}
|
|
33
|
-
|
|
34
|
-
|
|
106
|
+
if (report.status === 'error')
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
}
|
|
109
|
+
else if (positionals[0] === 'doctor') {
|
|
110
|
+
if (values.tool !== undefined || values.modules !== undefined || values['dry-run'] !== undefined)
|
|
111
|
+
throw new Error('doctor accepts only --dest and --json');
|
|
112
|
+
const report = diagnose(values.dest ?? process.cwd());
|
|
113
|
+
if (values.json)
|
|
114
|
+
console.log(JSON.stringify(report, null, 2));
|
|
115
|
+
else {
|
|
116
|
+
console.log(`DevMethod doctor: ${report.status} (${report.unchanged}/${report.checked} recorded files unchanged)`);
|
|
117
|
+
for (const finding of report.findings)
|
|
118
|
+
console.log(`${finding.severity}: ${finding.code}${finding.path ? ` [${finding.path}]` : ''} — ${finding.message}`);
|
|
119
|
+
console.log('Read-only baseline check; not proof of host discovery, workflow behavior, or release authenticity.');
|
|
120
|
+
}
|
|
121
|
+
if (report.status === 'error')
|
|
122
|
+
process.exitCode = 1;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
if (values.json !== undefined)
|
|
126
|
+
throw new Error('--json is supported only by doctor, update-preview and resume');
|
|
127
|
+
let tool = values.tool;
|
|
128
|
+
if (!tool && stdin.isTTY && stdout.isTTY) {
|
|
129
|
+
const terminal = createInterface({ input: stdin, output: stdout });
|
|
130
|
+
try {
|
|
131
|
+
tool = (await terminal.question('Tool (codex / claude / cursor): ')).trim();
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
terminal.close();
|
|
135
|
+
}
|
|
35
136
|
}
|
|
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.');
|
|
36
143
|
}
|
|
37
|
-
if (!tool || !Object.hasOwn(tools, tool))
|
|
38
|
-
throw new Error('Specify --tool codex, claude or cursor');
|
|
39
|
-
const selected = values.modules?.split(',').map(name => name.trim());
|
|
40
|
-
const result = initialize({ destination: values.dest ?? process.cwd(), tool: tool, selected, dryRun: values['dry-run'] });
|
|
41
|
-
console.log(JSON.stringify(result, null, 2));
|
|
42
|
-
console.log('Next: read START_HERE.md, fill PROJECT_PROFILE.md and merge instructions intentionally.');
|
|
43
144
|
}
|
|
44
145
|
}
|
|
45
146
|
catch (error) {
|