@polymorphism-tech/morph-spec 9.8.0 → 10.1.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/CLAUDE.md +12 -10
- package/README.md +4 -4
- package/bin/morph-spec.js +40 -43
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +28 -36
- package/docs/QUICKSTART.md +31 -191
- package/framework/CLAUDE.md +24 -30
- package/framework/MORPH.md +47 -123
- package/framework/agents.json +6 -374
- package/framework/commands/morph-apply.md +1 -1
- package/framework/commands/morph-archive.md +4 -3
- package/framework/commands/morph-hotfix.md +8 -30
- package/framework/commands/morph-infra.md +2 -2
- package/framework/commands/morph-media.md +10 -9
- package/framework/commands/morph-preflight.md +3 -3
- package/framework/commands/morph-review.md +15 -0
- package/framework/commands/morph-status.md +1 -1
- package/framework/docs/CLI.md +84 -95
- package/framework/evals/review-checklist.md +45 -53
- package/framework/hooks/README.md +4 -4
- package/framework/hooks/claude-code/core/README.md +1 -1
- package/framework/hooks/claude-code/core/denylist.json +4 -4
- package/framework/hooks/claude-code/core/gate-guard.js +9 -0
- package/framework/hooks/claude-code/core/masked-exit.js +49 -0
- package/framework/hooks/claude-code/core/state-sync.js +4 -1
- package/framework/hooks/claude-code/core/telemetry-log.js +1 -2
- package/framework/hooks/claude-code/core/test-budget.js +10 -70
- package/framework/hooks/claude-code/core/validate-completion.js +11 -24
- package/framework/hooks/claude-code/core/worktree-context.js +5 -22
- package/framework/hooks/claude-code/core/worktree-create.js +6 -45
- package/framework/hooks/claude-code/core/worktree-env-inject.js +2 -10
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/gate-event.js +2 -2
- package/framework/hooks/shared/graph-refresh.js +20 -3
- package/framework/hooks/shared/heavy-command.js +32 -1
- package/framework/hooks/shared/heavy-config.js +1 -1
- package/framework/hooks/shared/next-step.js +63 -24
- package/framework/hooks/shared/phase-utils.js +6 -9
- package/framework/hooks/shared/report-progress.js +86 -0
- package/framework/hooks/shared/state-reader.js +3 -2
- package/framework/hooks/statusline.js +332 -0
- package/framework/mcp/registry.json +4 -4
- package/framework/phases.json +32 -10
- package/framework/rules/ai-agents-standards.md +10 -2
- package/framework/rules/csharp-standards.md +4 -0
- package/framework/rules/data-standards.md +1 -1
- package/framework/rules/ef-standards.md +20 -0
- package/framework/rules/frontend-standards.md +1 -1
- package/framework/rules/hangfire-standards.md +1 -1
- package/framework/rules/implement-report.md +25 -0
- package/framework/rules/infrastructure-standards.md +2 -0
- package/framework/rules/neon-auth-standards.md +1 -1
- package/framework/rules/neon-standards.md +3 -3
- package/framework/rules/nextjs-standards.md +7 -0
- package/framework/rules/plan-grammar.md +53 -0
- package/framework/rules/ui-design.md +27 -0
- package/framework/schemas/config.schema.json +11 -18
- package/framework/schemas/feature.schema.json +7 -1
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/create-umbraco-lp/references/umbraco-lp-patterns.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +2 -2
- package/framework/skills/core/morph-apply/SKILL.md +39 -166
- package/framework/skills/core/morph-apply/references/debugging.md +8 -0
- package/framework/skills/core/morph-apply/references/hotfix.md +42 -0
- package/framework/skills/core/morph-apply/references/machine.md +29 -0
- package/framework/skills/core/{morph-media/SKILL.md → morph-apply/references/media.md} +11 -74
- package/framework/skills/core/morph-apply/references/review.md +65 -0
- package/framework/skills/core/morph-plan/SKILL.md +49 -109
- package/framework/skills/core/morph-plan/references/critique.md +43 -0
- package/framework/skills/core/morph-plan/references/interview.md +37 -0
- package/framework/skills/core/morph-uiux/SKILL.md +47 -64
- package/framework/skills/core/morph-uiux/surfaces.json +32 -0
- package/framework/standards/STANDARDS.json +51 -28
- package/framework/standards/STANDARDS.meta.json +16 -19
- package/framework/standards/ai-agents/agent-session.md +2 -3
- package/framework/standards/ai-agents/context-providers.md +2 -2
- package/framework/standards/ai-agents/durable-workflows-hitl.md +2 -2
- package/framework/standards/ai-agents/providers/model-registry.md +2 -2
- package/framework/standards/ai-agents/rag-custom-pgvector.md +7 -6
- package/framework/standards/ai-agents/setup.md +1 -1
- package/framework/standards/ai-agents/tool-adapters.md +2 -2
- package/framework/standards/architecture/stack-baseline.md +70 -0
- package/framework/standards/backend/database/postgresql/database.md +22 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +33 -1
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +2 -1
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +12 -13
- package/framework/standards/frontend/design-system/ai-image-generation.md +51 -12
- package/framework/standards/frontend/design-system/ai-video-generation.md +50 -4
- package/framework/standards/frontend/design-system/art-direction.md +2 -2
- package/framework/standards/frontend/scroll-driven/frame-scrub.md +12 -2
- package/framework/standards/frontend/scroll-driven/scroll-components.md +76 -4
- package/framework/standards/infrastructure/docker/local-compose-isolation.md +2 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +62 -20
- package/framework/standards/infrastructure/neon/neon-platform.md +61 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +14 -13
- package/framework/standards/integration/mcp/mcp-tools.md +20 -20
- package/framework/templates/REGISTRY.json +1 -2
- package/framework/templates/context/ARCHITECTURE.md +1 -1
- package/framework/templates/docs/plan.md +15 -12
- package/framework/templates/docs/ui-mockups.md +17 -105
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +1 -1
- package/package.json +1 -1
- package/src/commands/e2e/e2e.js +88 -23
- package/src/commands/graph/diff.js +74 -0
- package/src/commands/graph/status.js +1 -1
- package/src/commands/observability/cost.js +2 -4
- package/src/commands/observability/telemetry.js +1 -1
- package/src/commands/project/doctor.js +23 -39
- package/src/commands/project/fleet.js +5 -6
- package/src/commands/project/init.js +63 -36
- package/src/commands/project/stack-scan.js +3 -42
- package/src/commands/project/stack-set.js +26 -0
- package/src/commands/project/status.js +12 -13
- package/src/commands/project/update.js +39 -3
- package/src/commands/project/worktree.js +3 -14
- package/src/commands/state/advance.js +17 -17
- package/src/commands/state/approve.js +0 -6
- package/src/commands/state/archive.js +27 -1
- package/src/commands/state/auto-approval.js +2 -2
- package/src/commands/state/create.js +1 -6
- package/src/commands/state/gate-check.js +38 -31
- package/src/commands/state/gate-decision.js +3 -2
- package/src/commands/state/next.js +1 -0
- package/src/commands/state/recap.js +67 -0
- package/src/commands/state/report-check.js +36 -178
- package/src/commands/validation/plan-check.js +16 -11
- package/src/commands/validation/validate-feature.js +3 -3
- package/src/commands/validation/verify.js +3 -6
- package/src/core/paths/output-schema.js +3 -3
- package/src/core/state/state-manager.js +2 -4
- package/src/dashboard/app/components/CommandPalette.jsx +2 -5
- package/src/dashboard/app/components/GatePauses.jsx +116 -0
- package/src/dashboard/app/components/SessionMap.jsx +77 -0
- package/src/dashboard/app/pages/Activity.jsx +4 -0
- package/src/dashboard/app/pages/AgentMap.jsx +1 -2
- package/src/dashboard/app/pages/FeatureDetail.jsx +129 -186
- package/src/dashboard/app/pages/Features.jsx +7 -7
- package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
- package/src/dashboard/app/pages/Portfolio.jsx +40 -5
- package/src/dashboard/scanner/activity-scanner.js +29 -0
- package/src/dashboard/scanner/agents-scanner.js +11 -14
- package/src/dashboard/scanner/features-scanner.js +45 -24
- package/src/dashboard/scanner/project-api.js +11 -2
- package/src/dashboard/scanner/skills-scanner.js +11 -1
- package/src/lib/detectors/index.js +1 -1
- package/src/lib/e2e/applicability.js +3 -1
- package/src/lib/git/tree-state.js +1 -16
- package/src/lib/graph/diff-tree.js +127 -0
- package/src/lib/graph/graphify-runtime.js +12 -5
- package/src/lib/installers/memory-installer.js +3 -3
- package/src/lib/installers/rules-installer.js +57 -0
- package/src/lib/installers/stack-assets.js +17 -0
- package/src/lib/installers/stack-sync.js +219 -0
- package/src/lib/plan/checks.js +61 -109
- package/src/lib/plan/critique.js +28 -0
- package/src/lib/plan/media.js +42 -0
- package/src/lib/plan/plan-html.js +125 -0
- package/src/lib/plan/plan-parser.js +34 -45
- package/src/lib/recap/piper.js +36 -0
- package/src/lib/recap/recap.js +232 -0
- package/src/lib/review-reports.js +28 -4
- package/src/lib/risk-detector.js +90 -11
- package/src/lib/specs/screen-checklist.js +33 -48
- package/src/lib/stack/dotnet-build-ignores.js +8 -9
- package/src/lib/telemetry/metrics.js +27 -29
- package/src/lib/validators/reuse/reuse-validator.js +1 -9
- package/src/lib/validators/verify-runner.js +0 -7
- package/src/lib/worktree/fleet-scanner.js +7 -20
- package/src/lib/worktree/worktree-audit.js +0 -37
- package/src/scripts/setup-infra.js +15 -50
- package/src/utils/agents-installer.js +27 -201
- package/src/utils/hooks-installer.js +11 -95
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +0 -23
- package/framework/hooks/claude-code/statusline.py +0 -699
- package/framework/hooks/claude-code/statusline.sh +0 -11
- package/framework/hooks/shared/agent-reap.js +0 -74
- package/framework/hooks/shared/slice-progress.js +0 -110
- package/framework/skills/core/morph-hotfix/SKILL.md +0 -133
- package/framework/skills/core/morph-machine/SKILL.md +0 -46
- package/framework/skills/core/morph-review/SKILL.md +0 -129
- package/framework/skills/core/morph-standards/SKILL.md +0 -52
- package/framework/standards/PROVENANCE.json +0 -119
- package/framework/standards/infrastructure/neon/neon-pgrag.md +0 -243
- package/src/commands/project/worktree-reap.js +0 -34
- package/src/commands/state/handoff.js +0 -65
- package/src/commands/validation/mutate.js +0 -263
- package/src/commands/validation/scout-check.js +0 -28
- package/src/lib/generators/handoff-generator.js +0 -172
- package/src/lib/mutation/adapters.js +0 -79
- package/src/lib/mutation/commands.js +0 -61
- package/src/lib/mutation/dotnet-introspection.js +0 -281
- package/src/lib/mutation/manifest.js +0 -144
- package/src/lib/mutation/plan.js +0 -44
- package/src/lib/mutation/report.js +0 -68
- package/src/lib/mutation/runner.js +0 -301
- package/src/lib/mutation/schemata.js +0 -60
- package/src/lib/mutation/snapshot.js +0 -65
- package/src/lib/mutation/subset.js +0 -109
- package/src/lib/mutation/trx.js +0 -50
- package/src/lib/scout/scout-check.js +0 -293
- package/src/lib/validators/traceability-check.js +0 -103
- package/src/lib/worktree/agent-reaper.js +0 -247
package/CLAUDE.md
CHANGED
|
@@ -8,6 +8,8 @@ morph-spec is a spec-driven development harness CLI (`@polymorphism-tech/morph-s
|
|
|
8
8
|
|
|
9
9
|
This repo is the **framework source code** — not a project that uses morph-spec.
|
|
10
10
|
|
|
11
|
+
**Do not run the morph-spec workflow here.** No `init`, `create`, `plan-check`, `gate-check`, `approve`, `advance`, `verify`, `context refresh` or `finish`, and no `/morph-plan` or `/morph-apply` as a process, even if a prompt starts with one: confirm first. Work here is ordinary: a normal branch, `npm test`, `npm run generate:check`, a PR. `framework/skills/` and `framework/CLAUDE.md` are source to edit, not instructions to follow. `/.morph/` is gitignored: this repo keeps no morph-spec state.
|
|
12
|
+
|
|
11
13
|
## Build & Test Commands
|
|
12
14
|
|
|
13
15
|
```bash
|
|
@@ -40,7 +42,7 @@ No build step — pure ESM JavaScript, runs directly via Node.js 22+.
|
|
|
40
42
|
|
|
41
43
|
### Module Layout
|
|
42
44
|
|
|
43
|
-
- **`bin/morph-spec.js`** — Commander.js CLI entry point: install/inspect commands plus the deterministic steps of the loop (`create`, `plan-check`, `gate-check`, `approve`/`advance`, `verify`, `report-check`, `
|
|
45
|
+
- **`bin/morph-spec.js`** — Commander.js CLI entry point: install/inspect commands plus the deterministic steps of the loop (`create`, `plan-check`, `gate-check`, `approve`/`advance`, `verify`, `report-check`, `e2e`, `finish`).
|
|
44
46
|
- **`src/commands/`** — CLI command handlers organized by domain (project/, state/, validation/, scaffold/, mcp/, context/, dashboard/).
|
|
45
47
|
- **`src/core/`** — Core domain logic:
|
|
46
48
|
- `state/state-manager.js` — Atomic state I/O with process-ID temp files
|
|
@@ -49,14 +51,14 @@ No build step — pure ESM JavaScript, runs directly via Node.js 22+.
|
|
|
49
51
|
- `workflows/` — Workflow type detector
|
|
50
52
|
- **`src/lib/`** — Libraries and subsystems:
|
|
51
53
|
- `validators/` — Validators run by the `verify` validators node (code-budget, contracts, nextjs, packages, reuse)
|
|
52
|
-
- `generators/` — Code generation (architecture context,
|
|
54
|
+
- `generators/` — Code generation (architecture context, scaffold, settings)
|
|
53
55
|
- `stack-filter.js` — Stack-aware asset filtering via YAML frontmatter `stacks:` tags
|
|
54
56
|
- `installers/` — Agents, skills, hooks installers
|
|
55
57
|
- **`src/utils/`** — Shared utilities (logger, banner, file-copier, claude-settings-manager, agents-installer, skills-installer, hooks-installer)
|
|
56
58
|
- **`framework/`** — Metadata installed into target projects (READ-ONLY at runtime):
|
|
57
|
-
- `MORPH.md` — NLH charter (the single source of behavioral truth; ≤
|
|
58
|
-
- `CLAUDE.md` — Runtime instructions injected into target's `.claude/CLAUDE.md` (≤
|
|
59
|
-
- `agents.json` —
|
|
59
|
+
- `MORPH.md` — NLH charter (the single source of behavioral truth; ≤ 8k chars, `resident-size` canary)
|
|
60
|
+
- `CLAUDE.md` — Runtime instructions injected into target's `.claude/CLAUDE.md` (≤ 3k chars)
|
|
61
|
+
- `agents.json` — the 3 Gate 3 personas (see below); `maxTurns` per persona
|
|
60
62
|
- `phases.json` — 4 phases (plan, uiux, implement, review)
|
|
61
63
|
- `standards/STANDARDS.json` — index of available standards
|
|
62
64
|
- `hooks/claude-code/core/` — fail-open guardrail hooks (+ `hooks/shared/` for what hooks and `src/` both read)
|
|
@@ -79,7 +81,7 @@ No build step — pure ESM JavaScript, runs directly via Node.js 22+.
|
|
|
79
81
|
|
|
80
82
|
**Stack-aware filtering:** Assets declare `stacks: ['dotnet']` in YAML frontmatter or `stack: ['dotnet']` in `agents.json`. `setup-infra.js` reads `config.json → project.stack`, splits into tags, and installs only matching assets.
|
|
81
83
|
|
|
82
|
-
**
|
|
84
|
+
**Single loop:** the main session plans, implements the whole plan in one window, fixes and finishes; domain know-how lives in the stack rules `framework/rules/*-standards.md`, loaded by `paths:` when the session touches a matching file and installed by `syncStackRules` from `plan-check`/`verify`/`update` (`docs/specs/single-loop/decisions.md`, ADR-010). `agents.json` has only the 3 read-only Gate 3 roles — `verifier` (executes each `Cn`), `reviewer` (plan.md + diff), `security` (sensitive paths) — dispatched in fresh context in the same response. `reviewer` is `sonnet`, `security` is `opus`; the dispatch routes the verifier to `opus` when `verifierModelFor` (risk-detector.js, read by `report-check --before-eval`) sees prompt/model or media.
|
|
83
85
|
|
|
84
86
|
### Phase Sequence
|
|
85
87
|
|
|
@@ -87,7 +89,7 @@ No build step — pure ESM JavaScript, runs directly via Node.js 22+.
|
|
|
87
89
|
plan → [uiux] → implement → review
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
Gates: `plan` (plan.md + `checks.json` from `plan-check`), `uiux` (optional, after the plan gate, `1-design/`), `review` (Gate 3: `verifier.md` + `reviewer.md` [+ `security.md`]). Folders keep their ids: `2-plan/`, `1-design/`, `3-implement/`, `4-review/`. `chore`/`hotfix` are born with `plan` stamped by policy.
|
|
92
|
+
Gates: `plan` (plan.md + `checks.json` from `plan-check`), `uiux` (optional, after the plan gate, `1-design/`), `review` (Gate 3: `verifier.md` + `reviewer.md` [+ `security.md`]). Folders keep their ids: `2-plan/`, `1-design/`, `3-implement/`, `4-review/`. `chore`/`hotfix` are born with `plan` stamped by policy. Done-when = the scenarios `C1..Cn` of plan.md; progress = `3-implement/report.md` (one row per `Cn`: `pendente`/`feito`/`bloqueado`). The archive keeps `feature.json` + `2-plan/plan.md`.
|
|
91
93
|
|
|
92
94
|
### State Schema
|
|
93
95
|
|
|
@@ -96,7 +98,7 @@ Authoritative, committed state: `.morph/features/{f}/feature.json` (status, appr
|
|
|
96
98
|
## Testing Conventions
|
|
97
99
|
|
|
98
100
|
- **Framework:** Node.js native `node:test` — no Jest or Mocha
|
|
99
|
-
- **Concurrency:** files run in parallel (`scripts/run-tests.mjs`) — `node --test` gives each file its own process, so `process.chdir()` stays inside the file. A test never writes a tracked file of this repo: a script under test reads its root from `MORPH_REPO_ROOT`, and the test points it at `copyTrackedRepo()` (`test/helpers/repo-copy.js`, a temp git repo with the tracked files). The runner fails if a run changes the tracked tree
|
|
101
|
+
- **Concurrency:** files run in parallel (`scripts/run-tests.mjs`) — `node --test` gives each file its own process, so `process.chdir()` stays inside the file. A test never writes a tracked file of this repo: a script under test reads its root from `MORPH_REPO_ROOT`, and the test points it at `copyTrackedRepo()` (`test/helpers/repo-copy.js`, a temp git repo with the tracked files). The runner fails if a run changes the tracked tree. Each file has a 10-minute `--test-timeout` (it bounds the whole file under process isolation): a hang fails by name. A test that imports a hook sets `MORPH_HOOK_CHAINED=1` first, or the hook's `runStandalone` waits on stdin, which `node --test` never closes
|
|
100
102
|
- **Subprocesses:** drive the CLI through `test/helpers/cli.js` (`runCli`, no shell) and git through `test/helpers/git.js` (`git(cwd, ...args)`) — `execSync('git …')` pays a cmd.exe per call on Windows. Hooks that export `run(payload)` can be called in-process (see `test/hooks/loop-detect.test.js`); keep one spawn per hook for the standalone wiring
|
|
101
103
|
- **Temp dirs:** `createTempDir()` / `cleanupTempDir()` from `test/helpers/test-utils.js`
|
|
102
104
|
- **Home:** a suite that runs `setupInfra`/`updateCommand`/`initCommand` calls `isolateHome()` (test-utils) at the top — the installers write `~/.claude/settings.json` through `os.homedir()`. Canary: `test/meta/home-isolation.test.js`
|
|
@@ -125,8 +127,8 @@ A matriz "mexeu em X → verifique Y" mora em `.claude/rules/matrix-*.md`, uma r
|
|
|
125
127
|
| `.claude/rules/matrix-hooks.md` | Hooks, telemetria e comment-guard |
|
|
126
128
|
| `.claude/rules/matrix-charter.md` | Carta NLH, skills e docs instaláveis |
|
|
127
129
|
| `.claude/rules/matrix-templates-ai.md` | Fases, templates, ai-kit e CI |
|
|
128
|
-
| `.claude/rules/matrix-plan-review.md` | Plano,
|
|
129
|
-
| `.claude/rules/matrix-verify.md` | Verify, testes
|
|
130
|
+
| `.claude/rules/matrix-plan-review.md` | Plano, progresso, gates e Gate 3 |
|
|
131
|
+
| `.claude/rules/matrix-verify.md` | Verify, testes e CI |
|
|
130
132
|
| `.claude/rules/matrix-worktree-git.md` | Worktrees, finish e git |
|
|
131
133
|
| `.claude/rules/matrix-graph.md` | Grafo de codebase e validador de reuso |
|
|
132
134
|
| `.claude/rules/matrix-platform.md` | MCP, installers, procs, heavy e dashboard |
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.
|
|
4
4
|
|
|
5
5
|
**Package:** `@polymorphism-tech/morph-spec`
|
|
6
|
-
**Version:**
|
|
6
|
+
**Version:** 10.1.1
|
|
7
7
|
**Requires:** Node.js 22+, Claude Code
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -244,11 +244,11 @@ Guardrail hooks are installed into `.claude/settings.local.json` across 13 event
|
|
|
244
244
|
| --------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
245
245
|
| `SessionStart` | `worktree-context.js` | Injects feature identity (worktree) or active-feature summary (root) |
|
|
246
246
|
| `PreToolUse` (Write\|Edit) | `protect-spec-files.js`, `enforce-phase-writes.js` | Freezes `plan.md` after the plan gate (only `plan-check` writes `checks.json`); enforces phase folders |
|
|
247
|
-
| `PreToolUse` (Bash) | `pre-bash-denylist.js`, `block-destructive-worktree-removal.js`, `block-raw-worktree-add.js`, `
|
|
247
|
+
| `PreToolUse` (Bash) | `pre-bash-denylist.js`, `block-destructive-worktree-removal.js`, `block-raw-worktree-add.js`, `heavy-gate.js`, `worktree-env-inject.js` | Destructive-command guards, worktree governance, heavy-node semaphore, per-worktree env |
|
|
248
248
|
| `WorktreeCreate` / `WorktreeRemove` | `worktree-create.js`, `worktree-remove.js` | Native worktrees delegate to the CLI |
|
|
249
249
|
| `PostToolUse` (Write\|Edit) | `comment-guard.js` | Blocks added comments the comment standard forbids |
|
|
250
250
|
| `PostToolUse` | `state-sync.js`, `gate-guard.js` | Syncs feature state; enforces gate ordering |
|
|
251
|
-
| `PostToolUse`, `PostToolUseFailure`, `PostToolBatch`, `SubagentStop`, `UserPromptSubmit` | `telemetry-log.js`, `loop-detect.js`, `graph-refresh-kick.js`, `heavy-release.js` | Telemetry, repeated-action loops, graph refresh, heavy-slot release |
|
|
251
|
+
| `PostToolUse`, `PostToolUseFailure`, `PostToolBatch`, `SubagentStop`, `UserPromptSubmit` | `telemetry-log.js`, `loop-detect.js`, `graph-refresh-kick.js`, `heavy-release.js`, `masked-exit.js` | Telemetry, repeated-action loops, graph refresh, heavy-slot release, masked test exit warning |
|
|
252
252
|
| `Stop` | `validate-completion.js` | Warns about incomplete tasks, missing outputs, or pending approval gates |
|
|
253
253
|
|
|
254
254
|
|
|
@@ -380,4 +380,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
|
|
|
380
380
|
|
|
381
381
|
---
|
|
382
382
|
|
|
383
|
-
*morph-spec
|
|
383
|
+
*morph-spec v10.1.1 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/bin/morph-spec.js
CHANGED
|
@@ -23,16 +23,15 @@ const worktreeProvisionCommand = lazy('../src/commands/project/worktree.js', 'wo
|
|
|
23
23
|
const worktreeLinkCommand = lazy('../src/commands/project/worktree.js', 'worktreeLinkCommand');
|
|
24
24
|
const worktreeListCommand = lazy('../src/commands/project/worktree.js', 'worktreeListCommand');
|
|
25
25
|
const worktreeRemoveCommand = lazy('../src/commands/project/worktree.js', 'worktreeRemoveCommand');
|
|
26
|
-
const worktreeReapCommand = lazy('../src/commands/project/worktree-reap.js', 'worktreeReapCommand');
|
|
27
26
|
const branchPruneCommand = lazy('../src/commands/project/branch.js', 'branchPruneCommand');
|
|
28
27
|
const fleetCommand = lazy('../src/commands/project/fleet.js', 'fleetCommand');
|
|
29
28
|
const envCommand = lazy('../src/commands/project/env.js', 'envCommand');
|
|
30
29
|
const claimCommand = lazy('../src/commands/project/claim.js', 'claimCommand');
|
|
31
30
|
const standardsCommand = lazy('../src/commands/project/standards.js', 'standardsCommand');
|
|
32
31
|
const reportCheckCommand = lazy('../src/commands/state/report-check.js', 'reportCheckCommand');
|
|
33
|
-
const scoutCheckCommand = lazy('../src/commands/validation/scout-check.js', 'scoutCheckCommand');
|
|
34
32
|
const planCheckCommand = lazy('../src/commands/validation/plan-check.js', 'planCheckCommand');
|
|
35
33
|
const stackScanCommand = lazy('../src/commands/project/stack-scan.js', 'stackScanCommand');
|
|
34
|
+
const stackSetCommand = lazy('../src/commands/project/stack-set.js', 'stackSetCommand');
|
|
36
35
|
const testsAuditCommand = lazy('../src/commands/validation/tests-audit.js', 'testsAuditCommand');
|
|
37
36
|
|
|
38
37
|
const approveCommand = lazy('../src/commands/state/approve.js', 'approveCommand');
|
|
@@ -40,12 +39,12 @@ const approvalStatusCommand = lazy('../src/commands/state/approve.js', 'approval
|
|
|
40
39
|
const unapproveCommand = lazy('../src/commands/state/approve.js', 'unapproveCommand');
|
|
41
40
|
const advanceCommand = lazy('../src/commands/state/advance.js', 'advanceCommand');
|
|
42
41
|
const archiveCommand = lazy('../src/commands/state/archive.js', 'archiveCommand');
|
|
42
|
+
const recapCommand = lazy('../src/commands/state/recap.js', 'recapCommand');
|
|
43
43
|
const finishCommand = lazy('../src/commands/state/finish.js', 'finishCommand');
|
|
44
44
|
const gateDecisionCommand = lazy('../src/commands/state/gate-decision.js', 'gateDecisionCommand');
|
|
45
45
|
const gateCheckCommand = lazy('../src/commands/state/gate-check.js', 'gateCheckCommand');
|
|
46
46
|
const createCommand = lazy('../src/commands/state/create.js', 'createCommand');
|
|
47
47
|
const retypeCommand = lazy('../src/commands/state/retype.js', 'retypeCommand');
|
|
48
|
-
const handoffCommand = lazy('../src/commands/state/handoff.js', 'handoffCommand');
|
|
49
48
|
const nextCommand = lazy('../src/commands/state/next.js', 'nextCommand');
|
|
50
49
|
const listCommand = lazy('../src/commands/state/list.js', 'listCommand');
|
|
51
50
|
const deleteCommand = lazy('../src/commands/state/delete.js', 'deleteCommand');
|
|
@@ -54,14 +53,15 @@ const graphStatusCommand = lazy('../src/commands/graph/status.js', 'graphStatusC
|
|
|
54
53
|
const graphBuildCommand = lazy('../src/commands/graph/build.js', 'graphBuildCommand');
|
|
55
54
|
const graphAffectedCommand = lazy('../src/commands/graph/affected.js', 'graphAffectedCommand');
|
|
56
55
|
const graphExplainCommand = lazy('../src/commands/graph/explain.js', 'graphExplainCommand');
|
|
56
|
+
const graphDiffCommand = lazy('../src/commands/graph/diff.js', 'graphDiffCommand');
|
|
57
57
|
|
|
58
58
|
const validateCommand = lazy('./validate.js', 'validateCommand');
|
|
59
59
|
const validateFeatureCommand = lazy('../src/commands/validation/validate-feature.js', 'validateFeatureCommand');
|
|
60
60
|
const verifyCommand = lazy('../src/commands/validation/verify.js', 'verifyCommand');
|
|
61
|
-
const mutateCommand = lazy('../src/commands/validation/mutate.js', 'mutateCommand');
|
|
62
61
|
const e2eUpCommand = lazy('../src/commands/e2e/e2e.js', 'e2eUpCommand');
|
|
63
62
|
const e2eStatusCommand = lazy('../src/commands/e2e/e2e.js', 'e2eStatusCommand');
|
|
64
63
|
const e2eDownCommand = lazy('../src/commands/e2e/e2e.js', 'e2eDownCommand');
|
|
64
|
+
const e2eResetCommand = lazy('../src/commands/e2e/e2e.js', 'e2eResetCommand');
|
|
65
65
|
|
|
66
66
|
const scaffoldDotnetCommand = lazy('../src/commands/scaffold/scaffold.js', 'scaffoldDotnetCommand');
|
|
67
67
|
const scaffoldNextjsCommand = lazy('../src/commands/scaffold/scaffold.js', 'scaffoldNextjsCommand');
|
|
@@ -102,6 +102,8 @@ program
|
|
|
102
102
|
.option('-f, --force', 'Overwrite existing MORPH installation')
|
|
103
103
|
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
104
104
|
.option('--skip-mcp', 'Skip MCP server auto-setup')
|
|
105
|
+
.option('--stack <stack>', 'Empty project: declare the stack without asking (dotnet, nextjs or dotnet+nextjs)')
|
|
106
|
+
.option('--with <integrations>', 'With --stack: comma-separated integrations (neon, maf, docker)')
|
|
105
107
|
.action(initCommand);
|
|
106
108
|
|
|
107
109
|
program
|
|
@@ -181,6 +183,14 @@ program
|
|
|
181
183
|
.option('--force', 'Archive even if Gate 3 (review) is not approved')
|
|
182
184
|
.action((feature, options) => archiveCommand(feature, options));
|
|
183
185
|
|
|
186
|
+
program
|
|
187
|
+
.command('recap <feature>')
|
|
188
|
+
.description('Recap animado da feature (cenários provados, estados, o que mudou, gates), com legenda e narração; o finish já gera')
|
|
189
|
+
.option('--piper', 'Narra com o Piper local (áudio embutido, gravado no temp); sem ele, voz do sistema')
|
|
190
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
191
|
+
.option('--json', 'Output as JSON')
|
|
192
|
+
.action((feature, options) => recapCommand(feature, options));
|
|
193
|
+
|
|
184
194
|
program
|
|
185
195
|
.command('finish <feature>')
|
|
186
196
|
.description('Close a feature: archive → integrate. --merge merges morph/{f} into the default (local); --pr pushes it + opens a PR. Works with and without a worktree')
|
|
@@ -259,13 +269,6 @@ program
|
|
|
259
269
|
.option('--json', 'Output as JSON')
|
|
260
270
|
.action((feature, newType, options) => retypeCommand(feature, newType, options));
|
|
261
271
|
|
|
262
|
-
program
|
|
263
|
-
.command('handoff <feature>')
|
|
264
|
-
.description('Generate the compressed session-handoff document (.morph/features/{f}/handoff.md) — pointers, not copies. Resolves the tree that owns the feature\'s state (worktree, or morph/{feature} if only committed) and writes there — not necessarily cwd.')
|
|
265
|
-
.option('--json', 'Output as JSON')
|
|
266
|
-
.option('--here', 'Force building/writing in the current directory, even if another tree owns this feature')
|
|
267
|
-
.action((feature, options) => handoffCommand(feature, options));
|
|
268
|
-
|
|
269
272
|
program
|
|
270
273
|
.command('next <feature>')
|
|
271
274
|
.description('The next step of the loop, decided from disk (phase, gates, slice reports, verify stamp, fail streak) in the tree that owns the feature. Read-only.')
|
|
@@ -313,6 +316,14 @@ graphCommand
|
|
|
313
316
|
.option('--json', 'Output as JSON')
|
|
314
317
|
.action((symbol, options) => graphExplainCommand(symbol, options));
|
|
315
318
|
|
|
319
|
+
graphCommand
|
|
320
|
+
.command('diff')
|
|
321
|
+
.description('Árvore de chamadas do que mudou (+ novo, ~ alterado), do merge-base ao HEAD; recusa grafo que não é deste commit')
|
|
322
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
323
|
+
.option('--base <ref>', 'Base do diff (default: merge-base com a branch padrão)')
|
|
324
|
+
.option('--json', 'Output as JSON')
|
|
325
|
+
.action((options) => graphDiffCommand(options));
|
|
326
|
+
|
|
316
327
|
program
|
|
317
328
|
.command('validate [validator]')
|
|
318
329
|
.description('Run project validations (all | packages | next-components | spec-tasks)')
|
|
@@ -356,18 +367,6 @@ program
|
|
|
356
367
|
verifyCommand(feature, { ...options, noPersist: options.persist === false })
|
|
357
368
|
);
|
|
358
369
|
|
|
359
|
-
program
|
|
360
|
-
.command('mutate [feature]')
|
|
361
|
-
.description('Prova de mutação do Gate 3 em lote: lê o manifesto de mutantes, roda todos (um build de schemata em .NET, subconjunto primeiro, suíte inteira só para sobrevivente), restaura os bytes e imprime a seção `## Mutações`')
|
|
362
|
-
.option('--plan <file>', 'Manifesto JSON (default: .morph/features/<feature>/4-review/mutants.json)')
|
|
363
|
-
.option('--out <file>', 'Onde gravar a seção `## Mutações` (default: 4-review/mutation-section.md)')
|
|
364
|
-
.option('--allow-dirty', 'Permite mutar arquivo com alteração não commitada (o snapshot é o único caminho de volta)')
|
|
365
|
-
.option('--jobs <n>', 'Rodadas de subconjunto em paralelo (default 2); cada worker toma um slot heavy livre, e sem slot livre a rodada degrada para sequencial', (v) => Number.parseInt(v, 10))
|
|
366
|
-
.option('--timeout <ms>', 'Teto de cada comando de build/teste', (v) => Number.parseInt(v, 10))
|
|
367
|
-
.option('--restore', 'Recupera o disco de uma rodada que morreu no meio: restaura os bytes do journal, sem rodar nada')
|
|
368
|
-
.option('--json', 'Output as JSON')
|
|
369
|
-
.action((feature, options) => mutateCommand(feature, options));
|
|
370
|
-
|
|
371
370
|
const scaffoldCmd = program
|
|
372
371
|
.command('scaffold')
|
|
373
372
|
.description('Generate feature files from templates');
|
|
@@ -443,6 +442,12 @@ e2eCommand
|
|
|
443
442
|
.option('--json', 'Output as JSON')
|
|
444
443
|
.action((feature, options) => e2eDownCommand(feature, options));
|
|
445
444
|
|
|
445
|
+
e2eCommand
|
|
446
|
+
.command('reset <feature>')
|
|
447
|
+
.description('Put the running stack\'s data back in a known state between verification flows: e2e.resetCommand, or recreate the non-built services that own a named volume; then the auth seed. App services and e2e.hostServices are not restarted. Exit 1 when the stack is not up')
|
|
448
|
+
.option('--json', 'Output as JSON')
|
|
449
|
+
.action((feature, options) => e2eResetCommand(feature, options));
|
|
450
|
+
|
|
446
451
|
const heavyCommand = program
|
|
447
452
|
.command('heavy')
|
|
448
453
|
.description('Slots por usuário para os nós pesados (build, testes, e2e), compartilhados entre as sessões');
|
|
@@ -496,14 +501,6 @@ worktreeCommand
|
|
|
496
501
|
.option('--json', 'Output as JSON (always JSON)')
|
|
497
502
|
.action((feature, options) => worktreeRemoveCommand(feature, options));
|
|
498
503
|
|
|
499
|
-
worktreeCommand
|
|
500
|
-
.command('reap')
|
|
501
|
-
.description('Remove the worktrees and branches of sub-agents that stopped clean (nothing uncommitted, no commit only they hold); everything else is listed with the reason and left alone')
|
|
502
|
-
.option('--dry-run', 'Report what would be removed without touching anything')
|
|
503
|
-
.option('--grace <minutes>', 'Minutes a stopped agent must stay quiet before its tree is reaped (default 30, or worktree.reap.graceMinutes)')
|
|
504
|
-
.option('--json', 'Output as a single JSON line')
|
|
505
|
-
.action((options) => worktreeReapCommand(options));
|
|
506
|
-
|
|
507
504
|
worktreeCommand
|
|
508
505
|
.command('list')
|
|
509
506
|
.description('List active feature worktrees with their phase and gate status')
|
|
@@ -532,7 +529,7 @@ program
|
|
|
532
529
|
|
|
533
530
|
program
|
|
534
531
|
.command('fleet')
|
|
535
|
-
.description('Fleet view — every active feature across primary root and worktrees (phase, gates,
|
|
532
|
+
.description('Fleet view — every active feature across primary root and worktrees (phase, gates, scenarios, ports, activity)')
|
|
536
533
|
.option('--json', 'Output as JSON')
|
|
537
534
|
.action((options) => fleetCommand(options));
|
|
538
535
|
|
|
@@ -556,18 +553,11 @@ program
|
|
|
556
553
|
.action((options) => standardsCommand(options));
|
|
557
554
|
|
|
558
555
|
program
|
|
559
|
-
.command('report-check <feature>
|
|
560
|
-
.description('
|
|
556
|
+
.command('report-check <feature>')
|
|
557
|
+
.description('State of the Gate 3 reports (4-review/), scenario progress of 3-implement/report.md and the tree they were written against')
|
|
561
558
|
.option('--before-eval', 'Save a snapshot of the tree before dispatching the review agents and print their models; later runs report what changed since')
|
|
562
559
|
.option('--json', 'Output as JSON')
|
|
563
|
-
.action((feature,
|
|
564
|
-
|
|
565
|
-
program
|
|
566
|
-
.command('scout-check <map>')
|
|
567
|
-
.description('Audit a scout map: every path:line citation must exist and carry the literal line it quotes (±2 lines); absence/liveness verdicts only as hypotheses with the search command and its raw count. Exits 0 only when nothing failed')
|
|
568
|
-
.option('--root <dir>', 'Tree the citations are relative to (default: top of the current worktree)')
|
|
569
|
-
.option('--json', 'Output as JSON')
|
|
570
|
-
.action((map, options) => scoutCheckCommand(map, options));
|
|
560
|
+
.action((feature, options) => reportCheckCommand(feature, options));
|
|
571
561
|
|
|
572
562
|
program
|
|
573
563
|
.command('plan-check <feature>')
|
|
@@ -579,10 +569,17 @@ program
|
|
|
579
569
|
|
|
580
570
|
program
|
|
581
571
|
.command('stack-scan [feature]')
|
|
582
|
-
.description('Audit the code against config.project.stack, judging only the configured stacks (runtime, ORM, database, Guid.NewGuid, generic repository, service layer, raw SQL, sealed, router, UI library) by severity.
|
|
572
|
+
.description('Audit the code against config.project.stack, judging only the configured stacks (runtime, ORM, database, Guid.NewGuid, generic repository, service layer, raw SQL, sealed, router, UI library) by severity. Prints the report (markdown, or --json); never writes a file')
|
|
583
573
|
.option('--json', 'Output as JSON')
|
|
584
574
|
.action((feature, options) => stackScanCommand(feature, options));
|
|
585
575
|
|
|
576
|
+
program
|
|
577
|
+
.command('stack-set <stack>')
|
|
578
|
+
.description('Declare the project stack (dotnet, nextjs or dotnet+nextjs) in config.json and install its domain rules into .claude/rules/; rules load when a Claude Code session starts')
|
|
579
|
+
.option('--with <integrations>', 'Comma-separated integrations (neon, maf, docker)')
|
|
580
|
+
.option('--json', 'Output as JSON')
|
|
581
|
+
.action((stack, options) => stackSetCommand(stack, options));
|
|
582
|
+
|
|
586
583
|
program
|
|
587
584
|
.command('tests-audit')
|
|
588
585
|
.description('Read-only audit of the tracked test files: case count, largest files, tests that pin prose or a constant, [Fact] families that are [Theory] candidates, and one subject tested in several layers — candidates to delete or merge, never verdicts')
|
package/claude-plugin.json
CHANGED
package/docs/CHEATSHEET.md
CHANGED
|
@@ -23,18 +23,17 @@ morph-spec --version
|
|
|
23
23
|
## Phase workflow
|
|
24
24
|
|
|
25
25
|
```
|
|
26
|
-
|
|
26
|
+
plan → [uiux] → implement → review
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
`uiux` is optional
|
|
29
|
+
`uiux` is optional and runs after the plan gate. Which phases actually run for a given feature is also shaped by its **work type** (see below): a `chore` writes a short plan and goes straight to implement, a `hotfix` follows its own path.
|
|
30
30
|
|
|
31
31
|
| Phase | Folder | Gate |
|
|
32
32
|
|-------|--------|------|
|
|
33
|
-
|
|
|
34
|
-
| uiux *(optional)* | `1-design/` | ✅ |
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
| review | `4-review/` | ✅ Gate 3 |
|
|
33
|
+
| plan | `2-plan/` | ✅ `plan` (`plan.md` + `checks.json`) |
|
|
34
|
+
| uiux *(optional)* | `1-design/` | ✅ `uiux` |
|
|
35
|
+
| implement | `3-implement/` | — (one row per `Cn` in `report.md`) |
|
|
36
|
+
| review | `4-review/` | ✅ `review` (Gate 3) |
|
|
38
37
|
|
|
39
38
|
---
|
|
40
39
|
|
|
@@ -42,9 +41,9 @@ proposal → [uiux] → plan → implement → review
|
|
|
42
41
|
|
|
43
42
|
| Command | Purpose |
|
|
44
43
|
|---------|---------|
|
|
45
|
-
| `/morph-
|
|
46
|
-
| `/morph-hotfix {feature}` |
|
|
47
|
-
| `/morph-apply {feature}` |
|
|
44
|
+
| `/morph-plan {feature or issue link}` | From a request to the approved plan: routes by work type (`feature`/`bug`/`chore`/`hotfix`), opens with a thesis against the code |
|
|
45
|
+
| `/morph-hotfix {feature}` | Production incident: surgical fix, Gate 3 always human |
|
|
46
|
+
| `/morph-apply {feature}` | Implements the whole plan, runs `verify` and Gate 3, closes with `finish` |
|
|
48
47
|
| `/morph-status [feature]` | Status of the active (or specified) feature |
|
|
49
48
|
| `/morph-archive {feature}` | Archive **without integrating** (legacy feature / cleanup) — normal close is `morph-spec finish --pr\|--merge` |
|
|
50
49
|
| `/morph-preflight` | Pre-deploy validation (specs, contracts, tests, infra) |
|
|
@@ -69,14 +68,15 @@ morph-spec archive {feature} [--force] [--no-git] # archive WITHOUT integ
|
|
|
69
68
|
|
|
70
69
|
## CLI — feature birth & work-type routing
|
|
71
70
|
|
|
72
|
-
Every feature is born with a **work type** that dimensions its pipeline: `feature` (full
|
|
71
|
+
Every feature is born with a **work type** that dimensions its pipeline: `feature` (full plan → [uiux] → implement → review), `bug` (same flow, lean plan), `chore` (short plan, straight to implement), `hotfix` (surgical fix, human Gate 3 always, even under `trust: auto`).
|
|
73
72
|
|
|
74
|
-
Every feature is also born with an **identity**:
|
|
73
|
+
Every feature is also born with an **identity**: a description is required (`create` refuses a nameless scaffold without it), `name` defaults to the slug. `--request` is kept literally in `feature.json → description`, and the plan critique checks the plan against it.
|
|
75
74
|
|
|
76
75
|
```bash
|
|
76
|
+
morph-spec create {feature} --request '<free text>' # detector classifies the type AND seeds the description
|
|
77
|
+
morph-spec create {feature} --type <t> --request '<title> <url>' # issue link: the type is picked, the body stays out of the argument
|
|
77
78
|
morph-spec create {feature} --type feature|bug|chore|hotfix --description "<what/why>"
|
|
78
|
-
morph-spec
|
|
79
|
-
morph-spec retype {feature} {newType} # change type mid-flight (blocked after Gate 3)
|
|
79
|
+
morph-spec retype {feature} {newType} # change type mid-flight (blocked after Gate 3)
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
---
|
|
@@ -84,7 +84,9 @@ morph-spec retype {feature} {newType} # change type mid-flig
|
|
|
84
84
|
## CLI — state (server-side, timestamped)
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
morph-spec
|
|
87
|
+
morph-spec next {feature} [--json] # the next step, decided from disk
|
|
88
|
+
morph-spec gate-check {feature} {gate} [--json] # decide + record whether the gate pauses
|
|
89
|
+
morph-spec gate-decision {feature} {gate} --pause <bool> [--reason] [--signals json] # writes gateDecisions by hand
|
|
88
90
|
```
|
|
89
91
|
|
|
90
92
|
Never hand-edit `gateDecisions`/`approvalGates` in `feature.json` — always go through these commands (they collide with the `state-sync` hook otherwise).
|
|
@@ -94,25 +96,18 @@ Never hand-edit `gateDecisions`/`approvalGates` in `feature.json` — always go
|
|
|
94
96
|
## CLI — validation
|
|
95
97
|
|
|
96
98
|
```bash
|
|
97
|
-
morph-spec
|
|
99
|
+
morph-spec plan-check {feature} [--json] # validate plan.md, write checks.json
|
|
100
|
+
morph-spec validate [packages|next-components]
|
|
98
101
|
morph-spec validate-feature {feature} [--phase {phase}] [--json] # alias: vf
|
|
99
|
-
morph-spec verify {feature} [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## CLI — DAG
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
morph-spec dag {feature} [--json] # sequential vs parallel dispatch decision (effort-weighted)
|
|
108
|
-
morph-spec dag {feature} --mermaid # emit the tasks.json DAG as a Mermaid flowchart
|
|
102
|
+
morph-spec verify {feature} [--json] [--filter <ids>] [--skip-tests] [--skip-build] [--skip-e2e] # deterministic build+test+validator+e2e chain; the gate reads the unfiltered run
|
|
103
|
+
morph-spec report-check {feature} [--before-eval] [--json] # state of the implement and of the Gate 3 reports
|
|
109
104
|
```
|
|
110
105
|
|
|
111
106
|
---
|
|
112
107
|
|
|
113
108
|
## CLI — worktrees (parallel development / fleet)
|
|
114
109
|
|
|
115
|
-
One feature = one git worktree = one Claude Code instance. Each worktree gets its own deterministic port block (`.morph/worktree.env`)
|
|
110
|
+
One feature = one git worktree = one Claude Code instance. Each worktree gets its own deterministic port block (`.morph/worktree.env`).
|
|
116
111
|
|
|
117
112
|
```bash
|
|
118
113
|
morph-spec create {feature} --description "<what/why>" --worktree # birth the feature already isolated in its own worktree
|
|
@@ -120,9 +115,8 @@ morph-spec worktree setup {feature} # create worktrees/{feature}/ on bran
|
|
|
120
115
|
morph-spec worktree link [--all] # relink shared infra (node_modules[, .claude, .morph/framework])
|
|
121
116
|
morph-spec worktree list [--json] # active feature worktrees with phase/gate status
|
|
122
117
|
# Close a worktree feature with `morph-spec finish {feature} --pr|--merge` (see above) — it absorbed `worktree finish`.
|
|
123
|
-
morph-spec handoff {feature} [--json] [--here] # regenerate the handoff doc — resolves the owning tree and writes THERE, safe to run from the root
|
|
124
118
|
morph-spec doctor --worktrees [--prune] # reconcile git's registry × disk × features; --prune also clears a dangling root worktree.path pointer
|
|
125
|
-
morph-spec fleet [--json] # every active feature (root + worktrees) with phase/gates/ports/
|
|
119
|
+
morph-spec fleet [--json] # every active feature (root + worktrees) with phase/gates/ports/activity
|
|
126
120
|
```
|
|
127
121
|
|
|
128
122
|
---
|
|
@@ -145,14 +139,13 @@ morph-spec dashboard [--port 3200] # open the ins
|
|
|
145
139
|
.morph/
|
|
146
140
|
├── config/config.json # project config (editable)
|
|
147
141
|
├── framework/ # READ-ONLY
|
|
148
|
-
│ ├── agents.json #
|
|
142
|
+
│ ├── agents.json # the 3 Gate 3 personas
|
|
149
143
|
│ ├── standards/ # standards registry
|
|
150
|
-
│ └──
|
|
144
|
+
│ └── CLI.md # every command in detail
|
|
151
145
|
├── context/ # project context (editable)
|
|
152
146
|
├── features/{feature}/
|
|
153
147
|
│ ├── feature.json # authoritative, committed
|
|
154
|
-
│
|
|
155
|
-
│ └── 0-proposal/ 1-design/ 2-plan/ 3-implement/ 4-review/
|
|
148
|
+
│ └── 1-design/ 2-plan/ 3-implement/ 4-review/
|
|
156
149
|
└── state.json # gitignored, derived index — never hand-edited
|
|
157
150
|
|
|
158
151
|
.claude/
|
|
@@ -171,18 +164,17 @@ Never edited directly — go through CLI commands or `morph-spec update` instead
|
|
|
171
164
|
| Path | Protected by |
|
|
172
165
|
|------|-------------|
|
|
173
166
|
| `.morph/state.json`, `.morph/framework/**` | `permissions.deny` |
|
|
174
|
-
| `
|
|
167
|
+
| `2-plan/checks.json`, and the body of `2-plan/plan.md` after the plan gate (only `## Errata` is appended) | `protect-spec-files` hook |
|
|
175
168
|
|
|
176
169
|
---
|
|
177
170
|
|
|
178
171
|
## Links
|
|
179
172
|
|
|
180
173
|
- [QUICKSTART.md](QUICKSTART.md) — step-by-step guide
|
|
181
|
-
- [ARCHITECTURE.md](ARCHITECTURE.md) — system design
|
|
182
174
|
- [CHANGELOG.md](../CHANGELOG.md) — release history
|
|
183
175
|
- [npm](https://www.npmjs.com/package/@polymorphism-tech/morph-spec)
|
|
184
176
|
- support@polymorphism.com.br
|
|
185
177
|
|
|
186
178
|
---
|
|
187
179
|
|
|
188
|
-
*morph-spec
|
|
180
|
+
*morph-spec v10.1.1 by Polymorphism Tech*
|