@polymorphism-tech/morph-spec 8.29.0 → 8.32.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/CLAUDE.md +11 -1
- package/README.md +13 -2
- package/bin/morph-spec.js +67 -1
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +4 -1
- package/framework/MORPH.md +4 -3
- package/framework/agents.json +6 -6
- package/framework/commands/morph-status.md +1 -1
- package/framework/docs/CLI.md +68 -45
- package/framework/evals/rubrics/code-quality.md +17 -0
- package/framework/evals/rubrics/condensed.md +3 -1
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/phase-utils.js +2 -0
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/mcp/registry.json +39 -4
- package/framework/rubrics/backend.json +2 -2
- package/framework/rubrics/default.json +2 -2
- package/framework/rubrics/frontend.json +2 -2
- package/framework/schemas/tasks.schema.json +25 -0
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +14 -4
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
- package/framework/skills/core/morph-implement/SKILL.md +12 -2
- package/framework/skills/core/morph-plan/SKILL.md +45 -3
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +12 -4
- package/framework/skills/core/morph-stack-scan/SKILL.md +13 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +160 -160
- package/framework/standards/ai-agents/batching.md +193 -193
- package/framework/standards/ai-agents/context-providers.md +188 -188
- package/framework/standards/ai-agents/mcp-server.md +250 -250
- package/framework/standards/ai-agents/mcp-tools.md +197 -197
- package/framework/standards/ai-agents/middleware-patterns.md +207 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
- package/framework/standards/ai-agents/modalities-vision.md +201 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
- package/framework/standards/ai-agents/production.md +231 -231
- package/framework/standards/ai-agents/prompts-in-db.md +214 -214
- package/framework/standards/ai-agents/providers/model-registry.md +158 -158
- package/framework/standards/ai-agents/service-tier-flex.md +135 -135
- package/framework/standards/ai-agents/structured-output.md +249 -249
- package/framework/standards/ai-agents/sweet-spot.md +109 -109
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/context/ARCHITECTURE.md +20 -0
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +1 -1
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/graph/affected.js +89 -0
- package/src/commands/graph/build.js +94 -0
- package/src/commands/graph/explain.js +96 -0
- package/src/commands/graph/status.js +93 -0
- package/src/commands/index.js +13 -13
- package/src/commands/project/branch.js +170 -0
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/doctor.js +148 -9
- package/src/commands/project/fleet.js +10 -3
- package/src/commands/project/worktree.js +73 -50
- package/src/commands/state/finish.js +41 -26
- package/src/commands/state/list.js +79 -6
- package/src/core/paths/output-schema.js +7 -0
- package/src/core/state/lifecycle-audit.js +127 -0
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/HookInspector.jsx +418 -418
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/generators/architecture-scanner.js +45 -4
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/git/branch-classifier.js +177 -0
- package/src/lib/git/gh.js +30 -0
- package/src/lib/git/pending-prs.js +89 -0
- package/src/lib/git/pr-index.js +70 -0
- package/src/lib/graph/god-nodes.js +75 -0
- package/src/lib/graph/graph-health.js +61 -0
- package/src/lib/graph/graph-loader.js +86 -0
- package/src/lib/graph/graphify-runtime.js +100 -0
- package/src/lib/graph/graphifyignore.js +86 -0
- package/src/lib/graph/sanitize.js +280 -0
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/tasks-json-parser.js +26 -0
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/reuse/index.js +10 -0
- package/src/lib/validators/reuse/reuse-validator.js +324 -0
- package/src/lib/validators/reuse/symbol-scanner.js +144 -0
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/validation-runner.js +40 -1
- package/src/lib/worktree/fleet-scanner.js +51 -21
- package/src/lib/worktree/ignored-triage.js +197 -0
- package/src/lib/worktree/worktree-audit.js +200 -35
- package/src/scripts/setup-infra.js +60 -1
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/file-copier.js +40 -0
- package/src/utils/skills-installer.js +187 -187
package/CLAUDE.md
CHANGED
|
@@ -37,7 +37,7 @@ No build step — pure ESM JavaScript, runs directly via Node.js 18+.
|
|
|
37
37
|
- **`src/commands/`** — CLI command handlers organized by domain (project/, state/, validation/, scaffold/, mcp/, context/, dashboard/).
|
|
38
38
|
- **`src/core/`** — Core domain logic:
|
|
39
39
|
- `state/state-manager.js` — Atomic state I/O with process-ID temp files
|
|
40
|
-
- `paths/output-schema.js` — **Single source of truth** for the
|
|
40
|
+
- `paths/output-schema.js` — **Single source of truth** for the 14 v5 output types
|
|
41
41
|
- `templates/` — Handlebars template registry and renderer
|
|
42
42
|
- `workflows/` — Workflow type detector
|
|
43
43
|
- **`src/lib/`** — Libraries and subsystems:
|
|
@@ -114,7 +114,17 @@ When modifying framework components, verify the full scope of related files.
|
|
|
114
114
|
| `framework/templates/**` | REGISTRY.json (template registered), valid Handlebars helpers |
|
|
115
115
|
| `src/core/paths/output-schema.js`| Run `npm run generate` to update phase-utils.js |
|
|
116
116
|
| `framework/MORPH.md` | All core skills (cross-references), CLAUDE.md (slash command list) |
|
|
117
|
+
| `src/lib/worktree/ignored-triage.js` | `worktree.js` (`classifyIgnoredLeftovers`), `test/lib/worktree/ignored-triage.test.js`, e os canários de `test/commands/finish.test.js` que pinam "o exemplar único nunca morre" — mudar um bucket muda o que o `finish` apaga |
|
|
118
|
+
| `src/lib/git/pr-index.js` | os QUATRO leitores do mesmo fato "esta branch tem PR": `fleet-scanner.js` (coluna PR), `branch-classifier.js` (o que NÃO apagar), `worktree-audit.js` (o que NÃO sugerir remover) e `pending-prs.js` (a síntese "aguardando merge"). `null` é UNKNOWN, nunca "sem PR" |
|
|
119
|
+
| `src/lib/git/branch-classifier.js` | `src/commands/project/branch.js`, `worktree-audit.js` (`unintegratedWork` reusa `classifyBranch` — o `doctor` e o `branch prune` não podem discordar sobre a mesma branch), `test/commands/branch-prune.test.js`, e `lifecycle-audit.js` (`abandoned-scaffold` conta commit próprio pelo mesmo `resolveBaseRef` + `commitsAhead`) |
|
|
120
|
+
| `src/lib/git/pending-prs.js` | os TRÊS consumidores da mesma síntese "aguardando merge": `list.js` (linha sintetizada), `fleet-scanner.js` (entrada `pr-pending`) e `doctor.js` (`auditPullRequests`). Uma feature visível numa superfície e invisível na outra é o bug que este módulo existe para impedir |
|
|
121
|
+
| `src/lib/git/gh.js` | `pr-index.js` e `finish.js` — as DUAS formas de invocar o `gh` viraram uma; uma segunda cópia de `resolveGh` volta a tornar o caminho de sucesso do índice intestável |
|
|
117
122
|
| `src/lib/worktree/feature-truth.js` | The four leaders reading the same "which tree owns this feature" predicate: `fleet-scanner.js`, `list.js`, `handoff.js`, and the mutator guard (`approve.js`/`advance.js`/`score.js`/`gate-decision.js`/`gate-check.js`) |
|
|
123
|
+
| `src/lib/graph/**` | `test/lib/graph/*.test.js`, the committed fixture `test/fixtures/graph/namespace-hierarchy.graph.json` (ADR-003 regression — never hand-edit it), `doctor.js` (`codebase graph` check), `architecture-scanner.js` (centrality section), `setup-infra.js` step 18b |
|
|
124
|
+
| `src/lib/validators/reuse/**` | `validation-runner.js` (case + push universal), `framework/rubrics/*.json` (o id `reuse` mapeado numa categoria, senão o achado não pesa no score), `test/fixtures/graph/prospectpro-reuse.graph.json` (recorte do grafo real — regerar com `build-reuse-fixture.mjs`, nunca editar à mão) |
|
|
125
|
+
| o ciclo de reuso (`reuse-map.md`) | `output-schema.js` (+ `npm run generate`), `framework/schemas/tasks.schema.json` + `tasks-json-parser.js` (campo `reuse`), `morph-plan` §1c/§5b, template de dispatch de `morph-implement`/`morph-apply`, personas de `agents.json`, `evals/rubrics/code-quality.md` + `condensed.md`, `morph-review` (insumo do avaliador), `test/framework/graph-fallback.test.js` |
|
|
126
|
+
| `framework/mcp/registry.json` | mcp-installer.js, claude-config-detector.js, agents-installer.js (personas' `mcp` field), `scripts/validate-framework.js` Check 8, `test/framework/mcp-registry.test.js` |
|
|
127
|
+
| Any `framework/` file that calls `morph-spec graph` | The fallback to grep must be declared in the SAME file — `test/framework/graph-fallback.test.js` enforces it (ADR-002: a skill that requires the graph with no fallback is a bug) |
|
|
118
128
|
|
|
119
129
|
### Test Coverage
|
|
120
130
|
|
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:** 8.
|
|
6
|
+
**Version:** 8.32.0
|
|
7
7
|
**Requires:** Node.js 22+, Claude Code
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -203,6 +203,17 @@ morph-spec worktree list [--json] # List active feature worktrees with ph
|
|
|
203
203
|
# Close a worktree feature with `morph-spec finish {feature} --pr|--merge` (see Feature workflow) — it absorbed `worktree finish`.
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
+
**Codebase graph** — optional, fail-open. `init` installs [graphify](https://pypi.org/project/graphifyy/) (pinned 0.9.50) when a Python toolchain is available and writes a stack-aware `.graphifyignore`; without one, it records the fact and moves on. Everything degrades to grep.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
morph-spec graph build # Extract the graph (local AST, zero tokens)
|
|
210
|
+
morph-spec graph status # Size, freshness, sanitizer health
|
|
211
|
+
morph-spec graph affected {symbol} --uses-only # Who actually uses it (not who implements it)
|
|
212
|
+
morph-spec graph explain {symbol} # Neighbourhood, cited file:line
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The gain is **precision, not recall**: the graph finds nothing grep would miss, but it drops 58% of the noise and tells you *what kind* of relationship each hit is — the difference between "20 types implement this interface" and "2 actually use it". The graph is never consumed raw: a sanitizing layer fixes the C# namespace-scope resolution gap that would otherwise report **zero** consumers where two exist.
|
|
216
|
+
|
|
206
217
|
---
|
|
207
218
|
|
|
208
219
|
## Agent model
|
|
@@ -368,4 +379,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
|
|
|
368
379
|
|
|
369
380
|
---
|
|
370
381
|
|
|
371
|
-
*morph-spec v8.
|
|
382
|
+
*morph-spec v8.32.0 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/bin/morph-spec.js
CHANGED
|
@@ -24,6 +24,7 @@ import { updateCommand } from '../src/commands/project/update.js';
|
|
|
24
24
|
import { doctorCommand } from '../src/commands/project/doctor.js';
|
|
25
25
|
import { statusCommand } from '../src/commands/project/status.js';
|
|
26
26
|
import { worktreeSetupCommand, worktreeLinkCommand, worktreeListCommand, worktreeRemoveCommand } from '../src/commands/project/worktree.js';
|
|
27
|
+
import { branchPruneCommand } from '../src/commands/project/branch.js';
|
|
27
28
|
import { fleetCommand } from '../src/commands/project/fleet.js';
|
|
28
29
|
import { claimCommand } from '../src/commands/project/claim.js';
|
|
29
30
|
import { standardsCommand } from '../src/commands/project/standards.js';
|
|
@@ -47,6 +48,12 @@ import { usecaseReserveCommand } from '../src/commands/state/usecase.js';
|
|
|
47
48
|
// === Tasks ===
|
|
48
49
|
import { dagCommand } from '../src/commands/tasks/dag.js';
|
|
49
50
|
|
|
51
|
+
// === Codebase graph ===
|
|
52
|
+
import { graphStatusCommand } from '../src/commands/graph/status.js';
|
|
53
|
+
import { graphBuildCommand } from '../src/commands/graph/build.js';
|
|
54
|
+
import { graphAffectedCommand } from '../src/commands/graph/affected.js';
|
|
55
|
+
import { graphExplainCommand } from '../src/commands/graph/explain.js';
|
|
56
|
+
|
|
50
57
|
// === Validation ===
|
|
51
58
|
import { validateCommand } from './validate.js';
|
|
52
59
|
import { validateFeatureCommand } from '../src/commands/validation/validate-feature.js';
|
|
@@ -285,6 +292,48 @@ program
|
|
|
285
292
|
.option('--mermaid', 'Emit the tasks.json DAG as a Mermaid flowchart (flowchart TD)')
|
|
286
293
|
.action((feature, options) => dagCommand(feature, options));
|
|
287
294
|
|
|
295
|
+
// ─── Codebase graph ───────────────────────────────────────────────────────
|
|
296
|
+
const graphCommand = program
|
|
297
|
+
.command('graph')
|
|
298
|
+
.description('Grafo de codebase (graphify) com saneamento determinístico — fail-open: sem grafo, tudo segue por grep');
|
|
299
|
+
|
|
300
|
+
graphCommand
|
|
301
|
+
.command('status')
|
|
302
|
+
.description('Existência, tamanho, frescor e saúde do saneamento. Grafo ausente não é erro (exit 0)')
|
|
303
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
304
|
+
.option('--json', 'Output as JSON')
|
|
305
|
+
.action((options) => graphStatusCommand(options));
|
|
306
|
+
|
|
307
|
+
graphCommand
|
|
308
|
+
.command('build')
|
|
309
|
+
.description('Extração completa (graphify extract --code-only); gera o .graphifyignore stack-aware antes')
|
|
310
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
311
|
+
.option('--json', 'Output as JSON')
|
|
312
|
+
.action((options) => graphBuildCommand(options));
|
|
313
|
+
|
|
314
|
+
graphCommand
|
|
315
|
+
.command('refresh')
|
|
316
|
+
.description('Atualização incremental (graphify update) — 2 a 3x mais rápida que o build')
|
|
317
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
318
|
+
.option('--json', 'Output as JSON')
|
|
319
|
+
.action((options) => graphBuildCommand({ ...options, refresh: true }));
|
|
320
|
+
|
|
321
|
+
graphCommand
|
|
322
|
+
.command('affected <symbol>')
|
|
323
|
+
.description('Blast radius saneado: quem depende do símbolo. Em frontend responde "quem importa", não "quem chama"')
|
|
324
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
325
|
+
.option('--prod', 'Descarta consumidores em projeto de teste')
|
|
326
|
+
.option('--uses-only', 'Só uso real: exclui inherits/implements/extends')
|
|
327
|
+
.option('--json', 'Output as JSON')
|
|
328
|
+
.action((symbol, options) => graphAffectedCommand(symbol, options));
|
|
329
|
+
|
|
330
|
+
graphCommand
|
|
331
|
+
.command('explain <symbol>')
|
|
332
|
+
.description('Vizinhança do símbolo com citação arquivo:linha — preferido a query, que trunca por budget')
|
|
333
|
+
.option('-p, --path <path>', 'Target path (default: current directory)')
|
|
334
|
+
.option('--json', 'Output as JSON')
|
|
335
|
+
.action((symbol, options) => graphExplainCommand(symbol, options));
|
|
336
|
+
|
|
288
337
|
// ─── Validation ───────────────────────────────────────────────────────────
|
|
289
338
|
program
|
|
290
339
|
.command('validate [validator]')
|
|
@@ -424,7 +473,7 @@ worktreeCommand
|
|
|
424
473
|
.command('remove [feature]')
|
|
425
474
|
.description('Safely tear down a worktree (drops infra junctions first, PROVE-or-DECLINE) — does NOT close the feature; that is `finish`')
|
|
426
475
|
.option('--target <path>', 'Remove the worktree at this path (for worktrees with no feature registration)')
|
|
427
|
-
.option('--discard-ignored', '
|
|
476
|
+
.option('--discard-ignored', 'Skip the backup: gitignored files unique to the worktree are deleted instead of copied to .git/morph-spec/finish-backup (by default they are backed up and the removal proceeds anyway)')
|
|
428
477
|
.option('--delete-branch', 'Also delete the branch (default: kept — unintegrated commits live there)')
|
|
429
478
|
.action((feature, options) => worktreeRemoveCommand(feature, options));
|
|
430
479
|
|
|
@@ -434,6 +483,23 @@ worktreeCommand
|
|
|
434
483
|
.option('--json', 'Output as JSON')
|
|
435
484
|
.action((options) => worktreeListCommand(options));
|
|
436
485
|
|
|
486
|
+
// ─── Branch housekeeping ──────────────────────────────────────────────────
|
|
487
|
+
// `git branch --merged` cannot see a squash-merge, so the only command left for
|
|
488
|
+
// a squash-merged branch is `git branch -D` — indistinguishable from discarding
|
|
489
|
+
// real work. `prune` makes the distinction itself and deletes only what it
|
|
490
|
+
// proved is already integrated.
|
|
491
|
+
const branchCommand = program
|
|
492
|
+
.command('branch')
|
|
493
|
+
.description('Local branch housekeeping');
|
|
494
|
+
|
|
495
|
+
branchCommand
|
|
496
|
+
.command('prune')
|
|
497
|
+
.description('Delete local branches whose work is already in the default branch — including squash-merged ones git cannot see. Never touches a branch with an OPEN PR, one in use by a worktree, or one whose integration could not be proven')
|
|
498
|
+
.option('--remote', 'Also delete origin/<branch> for each pruned branch (default: remote branches are left alone)')
|
|
499
|
+
.option('--dry-run', 'Classify and report without deleting anything')
|
|
500
|
+
.option('--json', 'Output as JSON')
|
|
501
|
+
.action((options) => branchPruneCommand(options));
|
|
502
|
+
|
|
437
503
|
// ─── Fleet ────────────────────────────────────────────────────────────────
|
|
438
504
|
program
|
|
439
505
|
.command('fleet')
|