@polymorphism-tech/morph-spec 8.47.0 → 9.1.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 +51 -43
- package/README.md +39 -38
- package/bin/morph-spec.js +41 -113
- package/bin/validate.js +1 -147
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +41 -101
- package/framework/MORPH.md +95 -252
- package/framework/agents.json +86 -21
- package/framework/commands/morph-apply.md +5 -28
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-hotfix.md +8 -8
- package/framework/commands/morph-infra.md +1 -1
- package/framework/commands/morph-preflight.md +2 -3
- package/framework/commands/morph-status.md +4 -4
- package/framework/docs/CLI.md +574 -286
- package/framework/evals/review-checklist.md +82 -41
- package/framework/hooks/README.md +10 -11
- package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
- package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
- package/framework/hooks/claude-code/core/chain.js +4 -65
- package/framework/hooks/claude-code/core/comment-guard.js +3 -17
- package/framework/hooks/claude-code/core/denylist.json +33 -3
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
- package/framework/hooks/claude-code/core/gate-guard.js +9 -78
- package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
- package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
- package/framework/hooks/claude-code/core/heavy-release.js +2 -13
- package/framework/hooks/claude-code/core/loop-detect.js +2 -31
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
- package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
- package/framework/hooks/claude-code/core/state-sync.js +15 -85
- package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
- package/framework/hooks/claude-code/core/validate-completion.js +37 -147
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
- package/framework/hooks/claude-code/core/worktree-context.js +15 -114
- package/framework/hooks/claude-code/core/worktree-create.js +6 -70
- package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
- package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
- package/framework/hooks/claude-code/statusline.py +55 -41
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/shared/activity-logger.js +9 -89
- package/framework/hooks/shared/agent-reap.js +2 -17
- package/framework/hooks/shared/build-check.js +11 -76
- package/framework/hooks/shared/claim-registry.js +9 -119
- package/framework/hooks/shared/command-tokens.js +168 -44
- package/framework/hooks/shared/comment-rules.js +5 -20
- package/framework/hooks/shared/comment-scanner.js +11 -43
- package/framework/hooks/shared/comment-stripper.js +11 -85
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/errata.js +59 -0
- package/framework/hooks/shared/feature-locator.js +11 -95
- package/framework/hooks/shared/frontend-locations.js +4 -0
- package/framework/hooks/shared/gate-question.js +12 -0
- package/framework/hooks/shared/git-exclude.js +3 -20
- package/framework/hooks/shared/git-paths.js +8 -104
- package/framework/hooks/shared/graph-freshness.js +22 -166
- package/framework/hooks/shared/graph-refresh.js +21 -149
- package/framework/hooks/shared/heavy-command.js +4 -12
- package/framework/hooks/shared/hook-response.js +8 -83
- package/framework/hooks/shared/morph-cli.js +8 -52
- package/framework/hooks/shared/payload-utils.js +10 -132
- package/framework/hooks/shared/phase-utils.js +14 -72
- package/framework/hooks/shared/redact-secrets.js +4 -15
- package/framework/hooks/shared/reparse-scan.js +6 -66
- package/framework/hooks/shared/slice-progress.js +99 -0
- package/framework/hooks/shared/source-files.js +4 -17
- package/framework/hooks/shared/spawn-command.js +23 -0
- package/framework/hooks/shared/state-reader.js +51 -247
- package/framework/hooks/shared/state-writer.js +9 -54
- package/framework/hooks/shared/stdin-reader.js +1 -11
- package/framework/hooks/shared/telemetry-logger.js +7 -67
- package/framework/hooks/shared/transcript-usage.js +7 -29
- package/framework/hooks/shared/worktree-root.js +7 -29
- package/framework/mcp/registry.json +3 -4
- package/framework/phases.json +23 -39
- package/framework/rules/csharp-standards.md +1 -1
- package/framework/rules/frontend-standards.md +1 -0
- package/framework/rules/hangfire-standards.md +1 -1
- package/framework/rules/neon-standards.md +1 -1
- package/framework/schemas/config.schema.json +14 -9
- package/framework/schemas/feature.schema.json +15 -50
- package/framework/skills/README.md +3 -4
- 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 +149 -222
- package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
- package/framework/skills/core/morph-machine/SKILL.md +2 -2
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +137 -299
- package/framework/skills/core/morph-review/SKILL.md +111 -136
- package/framework/skills/core/morph-standards/SKILL.md +27 -39
- package/framework/skills/core/morph-uiux/SKILL.md +94 -152
- package/framework/standards/STANDARDS.json +109 -1219
- package/framework/standards/STANDARDS.meta.json +1319 -0
- package/framework/standards/ai-agents/agent-archetypes.md +2 -2
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
- package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
- package/framework/standards/ai-agents/evals-with-cache.md +1 -2
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
- package/framework/standards/ai-agents/observability-patterns.md +1 -1
- package/framework/standards/ai-agents/production.md +1 -1
- package/framework/standards/ai-agents/prompt-sources.md +2 -2
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
- package/framework/standards/ai-agents/setup.md +3 -3
- package/framework/standards/ai-agents/sweet-spot.md +2 -2
- package/framework/standards/ai-agents/tool-adapters.md +0 -2
- package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/standards/architecture/code-comments.md +7 -7
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
- package/framework/standards/backend/api/validation.md +1 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
- package/framework/standards/data/nosql/cache/redis.md +1 -1
- package/framework/standards/data/nosql/cosmos-db.md +3 -3
- package/framework/standards/frontend/admin-app/forms.md +1 -1
- package/framework/standards/frontend/design-system/art-direction.md +88 -0
- package/framework/standards/frontend/design-system/premium-finish.md +77 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
- package/framework/standards/integration/mcp/mcp-tools.md +7 -7
- package/framework/templates/CLAUDE.md.core.template +3 -3
- package/framework/templates/README.md +2 -3
- package/framework/templates/REGISTRY.json +15 -179
- package/framework/templates/docs/plan.md +72 -0
- package/framework/templates/docs/ui-mockups.md +4 -0
- package/framework/templates/dotnet/ai-kit/README.md +1 -9
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
- package/package.json +1 -1
- package/src/commands/context/context-refresh.js +0 -16
- package/src/commands/dashboard/dashboard.js +2 -8
- package/src/commands/e2e/e2e.js +18 -105
- package/src/commands/graph/affected.js +0 -14
- package/src/commands/graph/build.js +11 -50
- package/src/commands/graph/explain.js +0 -16
- package/src/commands/graph/status.js +1 -12
- package/src/commands/mcp/mcp-setup.js +4 -62
- package/src/commands/observability/cost.js +17 -111
- package/src/commands/observability/telemetry.js +1 -14
- package/src/commands/project/branch.js +4 -45
- package/src/commands/project/claim.js +4 -48
- package/src/commands/project/doctor-procs.js +1 -1
- package/src/commands/project/doctor.js +53 -307
- package/src/commands/project/env.js +1 -27
- package/src/commands/project/fleet.js +6 -35
- package/src/commands/project/heavy.js +3 -3
- package/src/commands/project/init.js +8 -68
- package/src/commands/project/install-plugin-cmd.js +0 -1
- package/src/commands/project/setup-infra-cmd.js +2 -1
- package/src/commands/project/stack-scan.js +58 -0
- package/src/commands/project/standards.js +65 -72
- package/src/commands/project/status.js +28 -121
- package/src/commands/project/update.js +31 -223
- package/src/commands/project/worktree.js +109 -883
- package/src/commands/scaffold/scaffold.js +0 -25
- package/src/commands/state/advance.js +65 -120
- package/src/commands/state/approve.js +87 -229
- package/src/commands/state/archive.js +23 -139
- package/src/commands/state/auto-approval.js +65 -0
- package/src/commands/state/create.js +49 -109
- package/src/commands/state/delete.js +11 -63
- package/src/commands/state/finish.js +105 -494
- package/src/commands/state/gate-check.js +74 -183
- package/src/commands/state/gate-decision.js +8 -42
- package/src/commands/state/handoff.js +4 -31
- package/src/commands/state/list.js +21 -91
- package/src/commands/state/report-check.js +134 -338
- package/src/commands/state/retype.js +12 -28
- package/src/commands/validation/index.js +0 -3
- package/src/commands/validation/mutate.js +79 -19
- package/src/commands/validation/plan-check.js +81 -0
- package/src/commands/validation/validate-feature.js +52 -216
- package/src/commands/validation/verify.js +45 -160
- package/src/core/paths/output-schema.js +9 -155
- package/src/core/state/feature-identity.js +1 -25
- package/src/core/state/gate-order.js +2 -30
- package/src/core/state/lifecycle-audit.js +8 -100
- package/src/core/state/state-manager.js +32 -395
- package/src/core/templates/template-registry.js +2 -97
- package/src/core/templates/template-renderer.js +13 -93
- package/src/core/templates/template-seed.js +21 -0
- package/src/core/work-types.js +10 -45
- package/src/dashboard/app/App.jsx +1 -8
- package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
- package/src/dashboard/app/components/CommandPalette.jsx +4 -11
- package/src/dashboard/app/components/DetailPanel.jsx +1 -5
- package/src/dashboard/app/components/EntityLink.jsx +0 -12
- package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
- package/src/dashboard/app/components/Markdown.jsx +0 -9
- package/src/dashboard/app/components/PhaseRail.jsx +0 -11
- package/src/dashboard/app/components/SearchFilter.jsx +0 -4
- package/src/dashboard/app/components/Sidebar.jsx +0 -5
- package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
- package/src/dashboard/app/hooks/usePref.js +1 -5
- package/src/dashboard/app/lib/format.js +0 -2
- package/src/dashboard/app/lib/phases.js +3 -9
- package/src/dashboard/app/lib/project.js +0 -12
- package/src/dashboard/app/pages/Activity.jsx +1 -1
- package/src/dashboard/app/pages/AgentMap.jsx +1 -8
- package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
- package/src/dashboard/app/pages/Features.jsx +9 -16
- package/src/dashboard/app/pages/Guide.jsx +2 -3
- package/src/dashboard/app/pages/HookInspector.jsx +2 -23
- package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
- package/src/dashboard/app/pages/Portfolio.jsx +0 -1
- package/src/dashboard/app/pages/RulesMap.jsx +1 -16
- package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
- package/src/dashboard/app/pages/Standards.jsx +2 -17
- package/src/dashboard/scanner/activity-scanner.js +14 -83
- package/src/dashboard/scanner/agents-scanner.js +1 -23
- package/src/dashboard/scanner/docs-scanner.js +1 -7
- package/src/dashboard/scanner/feature-status.js +2 -5
- package/src/dashboard/scanner/features-scanner.js +92 -113
- package/src/dashboard/scanner/hooks-scanner.js +5 -28
- package/src/dashboard/scanner/index.js +0 -4
- package/src/dashboard/scanner/portfolio.js +5 -29
- package/src/dashboard/scanner/project-api.js +8 -54
- package/src/dashboard/scanner/rules-scanner.js +1 -2
- package/src/dashboard/scanner/skills-scanner.js +2 -12
- package/src/dashboard/scanner/standards-scanner.js +4 -7
- package/src/dashboard/vite-plugin-morph-data.js +5 -19
- package/src/lib/ai/ai-checks.js +7 -52
- package/src/lib/ai/ai-project-scan.js +14 -108
- package/src/lib/ai/code-audit.js +7 -63
- package/src/lib/ai/pin-drift.js +8 -51
- package/src/lib/ai/registry-audit.js +11 -90
- package/src/lib/ci/ci-verify.js +14 -13
- package/src/lib/ci/github-ci.js +9 -37
- package/src/lib/ci/workflow-scaffold.js +2 -10
- package/src/lib/detectors/claude-config-detector.js +13 -74
- package/src/lib/detectors/index.js +8 -59
- package/src/lib/e2e/compose-env.js +5 -66
- package/src/lib/e2e/stack-teardown.js +6 -40
- package/src/lib/generators/architecture-scanner.js +18 -156
- package/src/lib/generators/handoff-generator.js +37 -112
- package/src/lib/generators/scaffold-generator.js +5 -101
- package/src/lib/generators/settings-generator.js +11 -122
- package/src/lib/git/branch-classifier.js +11 -84
- package/src/lib/git/default-branch.js +14 -169
- package/src/lib/git/evidence-staleness.js +2 -1
- package/src/lib/git/gh.js +2 -17
- package/src/lib/git/pending-prs.js +6 -37
- package/src/lib/git/pr-files.js +3 -28
- package/src/lib/git/pr-index.js +3 -34
- package/src/lib/git/tree-fingerprint.js +17 -17
- package/src/lib/git/tree-state.js +6 -33
- package/src/lib/graph/god-nodes.js +2 -22
- package/src/lib/graph/graph-health.js +3 -24
- package/src/lib/graph/graph-loader.js +5 -56
- package/src/lib/graph/graphify-runtime.js +7 -37
- package/src/lib/graph/graphifyignore.js +8 -74
- package/src/lib/graph/sanitize.js +16 -136
- package/src/lib/heavy/cleanup.js +2 -6
- package/src/lib/installers/effects.js +8 -93
- package/src/lib/installers/mcp-installer.js +9 -169
- package/src/lib/installers/memory-installer.js +8 -33
- package/src/lib/installers/templates-reconcile.js +5 -60
- package/src/lib/mutation/commands.js +3 -2
- package/src/lib/mutation/dotnet-introspection.js +281 -0
- package/src/lib/mutation/plan.js +14 -6
- package/src/lib/mutation/runner.js +1 -1
- package/src/lib/mutation/subset.js +47 -13
- package/src/lib/plan/artifact-vocabulary.js +40 -0
- package/src/lib/plan/checks.js +208 -0
- package/src/lib/plan/plan-parser.js +204 -0
- package/src/lib/plan/plan-template.js +18 -0
- package/src/lib/projects/registry.js +7 -44
- package/src/lib/review-reports.js +204 -0
- package/src/lib/risk-detector.js +131 -274
- package/src/lib/specs/adr-index.js +38 -85
- package/src/lib/specs/design-seed.js +18 -0
- package/src/lib/specs/frontmatter.js +31 -0
- package/src/lib/specs/gfm-table.js +11 -0
- package/src/lib/specs/revocations.js +31 -102
- package/src/lib/specs/screen-checklist.js +56 -132
- package/src/lib/stack/dotnet-build-ignores.js +43 -0
- package/src/lib/stack/stack-profile.js +1 -28
- package/src/lib/stack/stack-scan.js +260 -0
- package/src/lib/stack-filter.js +4 -27
- package/src/lib/standards/registry.js +37 -0
- package/src/lib/standards/sections.js +47 -0
- package/src/lib/standards/verified-against.js +19 -191
- package/src/lib/tasks/eval-node.js +23 -179
- package/src/lib/tasks/linux-runner.js +18 -142
- package/src/lib/tasks/test-nodes.js +43 -313
- package/src/lib/tasks/test-runner.js +107 -447
- package/src/lib/telemetry/metrics.js +13 -103
- package/src/lib/telemetry/telemetry-reader.js +13 -238
- package/src/lib/telemetry/verify-event.js +4 -34
- package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
- package/src/lib/validators/code-budget/index.js +0 -7
- package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
- package/src/lib/validators/contracts/index.js +0 -6
- package/src/lib/validators/nextjs/index.js +0 -5
- package/src/lib/validators/nextjs/next-component-validator.js +4 -81
- package/src/lib/validators/packages/index.js +0 -6
- package/src/lib/validators/packages/package-validator.js +6 -56
- package/src/lib/validators/reuse/index.js +0 -8
- package/src/lib/validators/reuse/reuse-validator.js +24 -137
- package/src/lib/validators/reuse/symbol-scanner.js +6 -62
- package/src/lib/validators/traceability-check.js +54 -156
- package/src/lib/validators/validation-runner.js +20 -125
- package/src/lib/validators/verify-runner.js +152 -575
- package/src/lib/work-type-detector.js +5 -67
- package/src/lib/worktree/docker-audit.js +17 -137
- package/src/lib/worktree/env-allocator.js +10 -98
- package/src/lib/worktree/feature-truth.js +12 -115
- package/src/lib/worktree/finish-backup.js +32 -242
- package/src/lib/worktree/fleet-scanner.js +31 -126
- package/src/lib/worktree/ignored-triage.js +15 -91
- package/src/lib/worktree/vscode-settings.js +2 -3
- package/src/lib/worktree/worktree-audit.js +21 -213
- package/src/lib/worktree/worktree-include.js +3 -5
- package/src/scripts/global-install.js +3 -9
- package/src/scripts/install-plugin.js +1 -13
- package/src/scripts/setup-infra.js +17 -138
- package/src/utils/agents-installer.js +92 -272
- package/src/utils/banner.js +4 -25
- package/src/utils/claude-md-injector.js +1 -37
- package/src/utils/claude-settings-manager.js +1 -87
- package/src/utils/file-copier.js +32 -90
- package/src/utils/hooks-installer.js +26 -296
- package/src/utils/skills-installer.js +4 -102
- package/src/utils/version-checker.js +4 -83
- package/framework/commands/morph-proposal.md +0 -57
- package/framework/evals/trace-schema.md +0 -67
- package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
- package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
- package/framework/hooks/git/pre-commit/specs.sh +0 -50
- package/framework/hooks/shared/tasks-validator.js +0 -111
- package/framework/rules/morph-task-tracking.md +0 -54
- package/framework/rules/morph-workflow.md +0 -244
- package/framework/schemas/tasks.schema.json +0 -79
- package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
- package/framework/skills/core/morph-implement/SKILL.md +0 -194
- package/framework/skills/core/morph-proposal/SKILL.md +0 -152
- package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
- package/framework/templates/docs/proposal.md +0 -192
- package/framework/templates/docs/spec.md +0 -57
- package/framework/templates/docs/ui-components.md +0 -52
- package/framework/templates/docs/ui-design-system.md +0 -76
- package/framework/templates/docs/ui-flows.md +0 -167
- package/framework/templates/examples/spec-examples.md +0 -91
- package/framework/templates/feature/decisions.md +0 -124
- package/framework/templates/feature/recap.md +0 -145
- package/framework/templates/tasks.template.json +0 -17
- package/src/commands/state/usecase.js +0 -143
- package/src/commands/tasks/dag.js +0 -181
- package/src/commands/utils/index.js +0 -3
- package/src/lib/agents/output-collector.js +0 -76
- package/src/lib/detectors/design-system-detector.js +0 -188
- package/src/lib/evaluator-report.js +0 -104
- package/src/lib/generators/design-system-generator.js +0 -508
- package/src/lib/specs/acervo-format.js +0 -70
- package/src/lib/specs/acervo-lifecycle.js +0 -264
- package/src/lib/specs/done-criteria-check.js +0 -200
- package/src/lib/specs/usecase-check.js +0 -301
- package/src/lib/specs/usecase-promoter.js +0 -301
- package/src/lib/specs/usecase-registry.js +0 -237
- package/src/lib/tasks/dispatch-planner.js +0 -319
- package/src/lib/tasks/dotnet-test-introspection.js +0 -632
- package/src/lib/tasks/mermaid-renderer.js +0 -132
- package/src/lib/tasks/task-classifier.js +0 -30
- package/src/lib/tasks/task-parser.js +0 -209
- package/src/lib/tasks/tasks-json-parser.js +0 -296
- package/src/lib/tasks/test-scope.js +0 -597
- package/src/utils/agent-id-mapper.js +0 -11
|
@@ -4,40 +4,16 @@ import { basename, join } from 'path';
|
|
|
4
4
|
import { derivePhase } from '../../core/state/state-manager.js';
|
|
5
5
|
import { gateOrderViolations } from '../../core/state/gate-order.js';
|
|
6
6
|
import { missingIdentity } from '../../core/state/feature-identity.js';
|
|
7
|
-
import { derivePhaseFrom } from '../../../framework/hooks/shared/state-reader.js';
|
|
7
|
+
import { derivePhaseFrom, fileSetArtifactProbe } from '../../../framework/hooks/shared/state-reader.js';
|
|
8
8
|
import { isGitRepo } from '../project/worktree.js';
|
|
9
9
|
import { morphBranches, currentBranch, branchView } from '../../lib/worktree/feature-truth.js';
|
|
10
10
|
import { buildPrIndex } from '../../lib/git/pr-index.js';
|
|
11
11
|
import { pendingPrFeatures, prForFeature } from '../../lib/git/pending-prs.js';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
* One row per feature: slug × workType × status × phase × gates (G1/G2/G3) ×
|
|
17
|
-
* description, plus a flags column for anomalies (missing description, gate
|
|
18
|
-
* order, dangling worktree pointer). Complements `delete`: see what's dead
|
|
19
|
-
* before removing it. Replaces the ad-hoc "loop over every feature.json in
|
|
20
|
-
* python" audit.
|
|
21
|
-
*
|
|
22
|
-
* Read-only by construction — reads feature.json straight off disk (never
|
|
23
|
-
* `loadState`, which mutates), so listing can never resurrect or prune state.
|
|
24
|
-
* Always exits 0 (fail-open — an empty board is an answer).
|
|
25
|
-
*
|
|
26
|
-
* WORKTREE TRUTH: `create --worktree` writes a COMPLETE feature.json into the
|
|
27
|
-
* primary root, then the branch-committed copy (`morph/{f}`) becomes the
|
|
28
|
-
* truth and the root's copy never changes again. By default this command
|
|
29
|
-
* reads that branch when it disagrees with the disk — same mechanism fleet
|
|
30
|
-
* already uses (`branchToReadFrom`/`branchView`, moved to feature-truth.js so
|
|
31
|
-
* both consumers share the one place this condition lives). `--no-branch`
|
|
32
|
-
* turns that off for a faster, disk-only read.
|
|
33
|
-
*
|
|
34
|
-
* NOT AN OBJECTIVE: this command only enumerates what exists IN THIS TREE.
|
|
35
|
-
* A feature that lives solely on a branch with no local `.morph/features/`
|
|
36
|
-
* copy in any tree never appears here — aggregating across trees is
|
|
37
|
-
* `morph-spec fleet`'s job, not this one's.
|
|
38
|
-
*/
|
|
13
|
+
// Read-only: feature.json straight off disk, never `loadState` (which mutates). By default the
|
|
14
|
+
// branch `morph/{f}` wins over a stale root copy; `--no-branch` reads only the disk.
|
|
39
15
|
|
|
40
|
-
const G = ['
|
|
16
|
+
const G = ['plan', 'uiux', 'review'];
|
|
41
17
|
|
|
42
18
|
function readFeaturesIn(baseDir, subdir, location) {
|
|
43
19
|
const root = join(baseDir, '.morph', subdir);
|
|
@@ -59,34 +35,23 @@ function readFeaturesIn(baseDir, subdir, location) {
|
|
|
59
35
|
return rows;
|
|
60
36
|
}
|
|
61
37
|
|
|
62
|
-
/** The feature's `worktree` pointer, normalized with a computed `exists`. */
|
|
63
38
|
function readWorktreePointer(fj) {
|
|
64
39
|
const w = fj?.worktree;
|
|
65
40
|
if (!w?.path) return null;
|
|
66
41
|
return { path: w.path, branch: w.branch || null, exists: existsSync(w.path) };
|
|
67
42
|
}
|
|
68
43
|
|
|
69
|
-
|
|
70
|
-
* Build a row's flags/gates/identity shape from a `feature.json` object, given
|
|
71
|
-
* an already-resolved phase and provenance. Shared by the disk read
|
|
72
|
-
* (`buildRow`) and the branch read (`resolveBranchTruth`) so the two never
|
|
73
|
-
* drift on what counts as an anomaly.
|
|
74
|
-
*/
|
|
44
|
+
// Shared by the disk and branch reads so the two never drift on what counts as an anomaly.
|
|
75
45
|
function shapeRow(name, fj, location, phase, { corruptDisk = false, worktree = null, source = 'disk', branch = null } = {}) {
|
|
76
46
|
const gates = {};
|
|
77
47
|
for (const g of G) gates[g] = fj.approvalGates?.[g]?.approved === true;
|
|
78
48
|
|
|
79
|
-
//
|
|
80
|
-
// A recorded degradation is only worth recording if it is visible — this is
|
|
81
|
-
// the surface that makes it so (D2).
|
|
49
|
+
// Review approved via `--self-assessed`: a recorded degradation is only worth it if visible.
|
|
82
50
|
const selfAssessed = fj.approvalGates?.review?.selfAssessed === true;
|
|
83
51
|
|
|
84
52
|
const flags = [];
|
|
85
53
|
if (corruptDisk) flags.push('corrupt');
|
|
86
54
|
if (selfAssessed) flags.push('self-assessed-g3');
|
|
87
|
-
// Identity + gate-order anomalies come from the shared rules
|
|
88
|
-
// (core/state/feature-identity.js, core/state/gate-order.js) — same source
|
|
89
|
-
// doctor reports from.
|
|
90
55
|
for (const field of missingIdentity(fj)) flags.push(`missing-${field}`);
|
|
91
56
|
for (const v of gateOrderViolations(fj.approvalGates)) flags.push(`gate-order:${v.gate}`);
|
|
92
57
|
if (worktree && !worktree.exists) flags.push('worktree-missing');
|
|
@@ -104,10 +69,7 @@ function shapeRow(name, fj, location, phase, { corruptDisk = false, worktree = n
|
|
|
104
69
|
location,
|
|
105
70
|
createdAt: fj.createdAt || null,
|
|
106
71
|
updatedAt: fj.updatedAt || null,
|
|
107
|
-
//
|
|
108
|
-
// read from the LOCAL disk copy (root-owned bookkeeping, stripped from
|
|
109
|
-
// branch-committed copies at birth) regardless of where `source` reads
|
|
110
|
-
// status/phase/gates from.
|
|
72
|
+
// `worktree` always comes from the local disk copy, whatever `source` reads the rest from.
|
|
111
73
|
source,
|
|
112
74
|
branch,
|
|
113
75
|
worktree,
|
|
@@ -124,14 +86,7 @@ function buildRow(name, fj, fdir, location) {
|
|
|
124
86
|
});
|
|
125
87
|
}
|
|
126
88
|
|
|
127
|
-
|
|
128
|
-
* Refresh active rows from the branch that owns their truth, when the disk
|
|
129
|
-
* copy in THIS tree is not that owner. Never throws — a git hiccup or a
|
|
130
|
-
* corrupt blob just leaves the disk-read row in place.
|
|
131
|
-
*
|
|
132
|
-
* @param {string} cwd
|
|
133
|
-
* @param {object[]} rows - mutated in place (active rows only)
|
|
134
|
-
*/
|
|
89
|
+
// Never throws: a git hiccup or a corrupt blob leaves the disk-read row in place.
|
|
135
90
|
function resolveBranchTruth(cwd, rows) {
|
|
136
91
|
if (!isGitRepo(cwd)) return;
|
|
137
92
|
let head;
|
|
@@ -150,7 +105,7 @@ function resolveBranchTruth(cwd, rows) {
|
|
|
150
105
|
if (head === featureBranch) continue; // cwd IS the checkout — disk is freshest, never go backwards
|
|
151
106
|
const view = branchView(cwd, row.feature, featureBranch);
|
|
152
107
|
if (!view?.fj) continue;
|
|
153
|
-
const phase = derivePhaseFrom(view.fj, (
|
|
108
|
+
const phase = derivePhaseFrom(view.fj, fileSetArtifactProbe(view.files));
|
|
154
109
|
rows[i] = shapeRow(row.feature, view.fj, row.location, phase, {
|
|
155
110
|
corruptDisk: row.flags.includes('corrupt'),
|
|
156
111
|
worktree: row.worktree, // root-owned — never trust the branch copy for this
|
|
@@ -160,15 +115,8 @@ function resolveBranchTruth(cwd, rows) {
|
|
|
160
115
|
}
|
|
161
116
|
}
|
|
162
117
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
* the signature left behind when a feature is merged and archived on its
|
|
166
|
-
* branch (or via GitHub) without `morph-spec finish` ever running here:
|
|
167
|
-
* the untracked root skeleton from `create` survives `git pull` (it was
|
|
168
|
-
* never tracked, so pull has nothing to remove) while `.morph/archive/{f}`
|
|
169
|
-
* arrives for real. Flagging beats suppressing the row — a read-only board
|
|
170
|
-
* that resurrects or prunes nothing must not silently hide the anomaly either.
|
|
171
|
-
*/
|
|
118
|
+
// The untracked root skeleton survives a `git pull` that brings `.morph/archive/{f}`. Flagged,
|
|
119
|
+
// never hidden: a read-only board must not silently suppress the anomaly.
|
|
172
120
|
function flagArchivedElsewhere(cwd, rows) {
|
|
173
121
|
for (const row of rows) {
|
|
174
122
|
if (row.location !== 'active') continue;
|
|
@@ -178,13 +126,8 @@ function flagArchivedElsewhere(cwd, rows) {
|
|
|
178
126
|
}
|
|
179
127
|
}
|
|
180
128
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
* arquivada nesta árvore. É o estado que o `finish --pr` deixa: o scaffold do
|
|
184
|
-
* root foi apagado pelo shed e o archive viaja no diff do PR, chegando na
|
|
185
|
-
* default apenas no merge. Sem esta linha o trabalho fica sem dono no quadro,
|
|
186
|
-
* e uma branch sem dono é candidata a poda.
|
|
187
|
-
*/
|
|
129
|
+
// O estado que o `finish --pr` deixa: sem esta linha o trabalho fica sem dono no quadro, e
|
|
130
|
+
// uma branch sem dono é candidata a poda.
|
|
188
131
|
function pendingRow(p) {
|
|
189
132
|
return {
|
|
190
133
|
feature: p.feature,
|
|
@@ -193,7 +136,7 @@ function pendingRow(p) {
|
|
|
193
136
|
workType: null,
|
|
194
137
|
status: 'in_progress',
|
|
195
138
|
phase: 'aguardando-merge',
|
|
196
|
-
gates: {
|
|
139
|
+
gates: { plan: false, uiux: false, review: false },
|
|
197
140
|
selfAssessed: false,
|
|
198
141
|
flags: ['pr-pending'],
|
|
199
142
|
location: 'pr-pending',
|
|
@@ -232,15 +175,8 @@ export function listCommand(options = {}) {
|
|
|
232
175
|
// Commander's `--no-branch` sets options.branch = false; anything else (undefined/true) reads the branch.
|
|
233
176
|
if (options.branch !== false) resolveBranchTruth(cwd, rows);
|
|
234
177
|
|
|
235
|
-
//
|
|
236
|
-
// coluna e
|
|
237
|
-
//
|
|
238
|
-
// `prIndex` continua `null` quando a pergunta não pôde ser feita (sem `gh`,
|
|
239
|
-
// sem auth, remoto não-GitHub, ou `--no-branch`). É o mesmo sinal que
|
|
240
|
-
// `--json` já expõe como `pr: null` por linha — a tabela texto usa o mesmo
|
|
241
|
-
// fato para decidir se a coluna PR sequer aparece (achado #2): índice `null`
|
|
242
|
-
// degrada para o comportamento de antes, sem coluna e sem `-` que afirme
|
|
243
|
-
// ausência.
|
|
178
|
+
// Uma consulta ao `gh` por invocação. `prIndex` `null` = a pergunta não pôde ser feita: sem
|
|
179
|
+
// coluna PR, e sem `-` que afirme "sem PR" para o que é "não sabemos".
|
|
244
180
|
let prIndex = null;
|
|
245
181
|
if (options.branch !== false) {
|
|
246
182
|
prIndex = buildPrIndex(cwd);
|
|
@@ -249,8 +185,7 @@ export function listCommand(options = {}) {
|
|
|
249
185
|
row.pr = pr ? { number: pr.number, state: pr.state, url: pr.url, ageDays: null } : null;
|
|
250
186
|
}
|
|
251
187
|
const known = new Set(rows.map((r) => r.feature));
|
|
252
|
-
// `null` propaga desconhecido: nenhuma linha sintetizada
|
|
253
|
-
// afirmação de que não há pendência.
|
|
188
|
+
// `null` propaga desconhecido: nenhuma linha sintetizada.
|
|
254
189
|
for (const p of pendingPrFeatures(cwd, { index: prIndex }) || []) {
|
|
255
190
|
if (!known.has(p.feature)) rows.push(pendingRow(p));
|
|
256
191
|
}
|
|
@@ -271,17 +206,12 @@ export function listCommand(options = {}) {
|
|
|
271
206
|
}
|
|
272
207
|
|
|
273
208
|
const col = (s, w) => String(s ?? '-').padEnd(w);
|
|
274
|
-
// A coluna PR só aparece quando o índice foi construído com sucesso (achado
|
|
275
|
-
// #2) — um índice `null` não vira uma coluna cheia de `-`, que afirmaria
|
|
276
|
-
// "sem PR" para algo que na verdade é "não sabemos".
|
|
277
209
|
const showPr = Boolean(prIndex);
|
|
278
|
-
// `pr-pending` é
|
|
279
|
-
// não deve marcar `⚠` nem contar no rodapé (achado #6). Continua em
|
|
280
|
-
// `flags` no `--json`: é metadado real, só não é anomalia.
|
|
210
|
+
// `pr-pending` é trabalho em voo, não anomalia: segue em `flags` no `--json`, sem `⚠`.
|
|
281
211
|
const warnFlags = (r) => r.flags.filter((f) => f !== 'pr-pending');
|
|
282
212
|
console.log(chalk.white.bold(
|
|
283
213
|
col('FEATURE', 22) + col('TYPE', 9) + col('STATUS', 13) + col('PHASE', 17) + col('WHERE', 22) + (showPr ? col('PR', 12) : '')
|
|
284
|
-
+ col('G1', 4) + col('
|
|
214
|
+
+ col('G1', 4) + col('Gd', 4) + col('G3', 4) + col('', 3) + 'DESCRIPTION',
|
|
285
215
|
));
|
|
286
216
|
for (const r of rows) {
|
|
287
217
|
const flag = warnFlags(r).length ? chalk.yellow('⚠') : ' ';
|
|
@@ -292,7 +222,7 @@ export function listCommand(options = {}) {
|
|
|
292
222
|
// padEnd counts the invisible color codes; pad the plain marks manually.
|
|
293
223
|
console.log(
|
|
294
224
|
col(r.feature, 22) + col(r.workType, 9) + col(r.status, 13) + col(r.phase, 17) + col(whereLabel(r), 22) + (showPr ? col(prCell(r.pr), 12) : '')
|
|
295
|
-
+ mark(r.gates.
|
|
225
|
+
+ mark(r.gates.plan) + ' ' + mark(r.gates.uiux) + ' ' + mark(r.gates.review) + ' '
|
|
296
226
|
+ flag + ' ' + desc,
|
|
297
227
|
);
|
|
298
228
|
}
|
|
@@ -300,6 +230,6 @@ export function listCommand(options = {}) {
|
|
|
300
230
|
if (flagged.length) {
|
|
301
231
|
console.log(chalk.gray(`\n⚠ ${flagged.length} com inconsistência — rode 'morph-spec doctor' para detalhes.`));
|
|
302
232
|
}
|
|
303
|
-
console.log(chalk.gray(`\nG1=
|
|
233
|
+
console.log(chalk.gray(`\nG1=plan · Gd=uiux (design) · G3=review${options.all || options.archived ? ' · inclui arquivadas' : ''}`));
|
|
304
234
|
process.exit(0);
|
|
305
235
|
}
|