@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
|
@@ -8,7 +8,7 @@ import { useMorphQuery } from '../hooks/useMorphQuery.js';
|
|
|
8
8
|
import { apiBase, projectHref, featureHref } from '../lib/project.js';
|
|
9
9
|
|
|
10
10
|
const KIND_LABEL = {
|
|
11
|
-
page: 'Página', project: 'Projeto', feature: 'Feature',
|
|
11
|
+
page: 'Página', project: 'Projeto', feature: 'Feature', slice: 'Fatia', skill: 'Skill', persona: 'Persona',
|
|
12
12
|
standard: 'Standard', rule: 'Rule', hook: 'Hook', guide: 'Guia',
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -17,7 +17,6 @@ const PAGES = [
|
|
|
17
17
|
['Personas', '/agents'], ['Standards', '/standards'], ['Rules', '/rules'], ['Hooks', '/hooks'],
|
|
18
18
|
];
|
|
19
19
|
|
|
20
|
-
/** Everything the framework knows that has a page — built once. */
|
|
21
20
|
function knowledgeIndex() {
|
|
22
21
|
const out = PAGES.map(([title, to]) => ({ kind: 'page', title, to, hay: title }));
|
|
23
22
|
for (const s of morphData.skills || []) out.push({ kind: 'skill', title: s.id, hint: s.description, to: entityHref('skill', s.id), hay: `${s.id} ${s.description}` });
|
|
@@ -42,30 +41,24 @@ function projectIndex(portfolio) {
|
|
|
42
41
|
return (portfolio?.projects || []).map((p) => ({ kind: 'project', title: p.name, hint: p.dir, to: projectHref(p.id), hay: `${p.name} ${p.dir}` }));
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
/**
|
|
46
|
-
* Features and their tasks. `projectName` is set for another project's
|
|
47
|
-
* features, so a hit says where it lives.
|
|
48
|
-
*/
|
|
49
44
|
function featureIndex(project, features, projectName = null) {
|
|
50
45
|
const out = [];
|
|
51
46
|
const where = (text) => (projectName ? (text ? `${projectName}: ${text}` : projectName) : text);
|
|
52
47
|
for (const f of features || []) {
|
|
53
48
|
out.push({ kind: 'feature', title: f.name, hint: where(f.description), to: featureHref(project, f.name), hay: `${f.name} ${f.description || ''} ${projectName || ''}` });
|
|
54
|
-
for (const
|
|
55
|
-
out.push({ kind: '
|
|
49
|
+
for (const sl of f.sliceIndex || []) {
|
|
50
|
+
out.push({ kind: 'slice', title: `${sl.id} ${sl.title}`, hint: where(f.name), to: featureHref(project, f.name, '?tab=slices'), hay: `${sl.id} ${sl.title} ${f.name} ${projectName || ''}` });
|
|
56
51
|
}
|
|
57
52
|
}
|
|
58
53
|
return out;
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
/** The active features of the other projects, from the portfolio's summaries. */
|
|
62
56
|
function otherProjectsIndex(portfolio, project) {
|
|
63
57
|
return (portfolio?.projects || [])
|
|
64
58
|
.filter((p) => p.id !== project && p.summary)
|
|
65
59
|
.flatMap((p) => featureIndex(p.id, p.summary.activeFeatures, p.name));
|
|
66
60
|
}
|
|
67
61
|
|
|
68
|
-
/** Every query word must appear; a title that starts with the query ranks first. */
|
|
69
62
|
export function searchIndex(index, query, limit = 40) {
|
|
70
63
|
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
71
64
|
if (!words.length) return [];
|
|
@@ -119,7 +112,7 @@ export default function CommandPalette({ open, onClose, portfolio, project }) {
|
|
|
119
112
|
value={query}
|
|
120
113
|
onChange={(e) => setQuery(e.target.value)}
|
|
121
114
|
onKeyDown={onKey}
|
|
122
|
-
placeholder="Buscar features,
|
|
115
|
+
placeholder="Buscar features, fatias, skills, personas, standards, seções do guia…"
|
|
123
116
|
className="w-full bg-transparent text-base text-[var(--color-fg)] outline-none focus-visible:outline-none placeholder:text-[var(--color-faint)]"
|
|
124
117
|
aria-controls="palette-results"
|
|
125
118
|
aria-activedescendant={results[active] ? `palette-${active}` : undefined}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { X } from '@phosphor-icons/react';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* The reading drawer of the knowledge pages. Wide enough for rendered markdown,
|
|
6
|
-
* closes on Escape, and sits over the graph without a backdrop so the graph
|
|
7
|
-
* stays visible beside it.
|
|
8
|
-
*/
|
|
4
|
+
/** No backdrop: the graph stays visible beside the drawer. */
|
|
9
5
|
export default function DetailPanel({ open, title, subtitle, onClose, children }) {
|
|
10
6
|
useEffect(() => {
|
|
11
7
|
if (!open) return undefined;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { Link, useSearchParams } from 'react-router-dom';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Where each kind of thing lives in the app. The ONE map of entity → URL, so a
|
|
6
|
-
* persona, standard or skill reads as a link everywhere it is mentioned.
|
|
7
|
-
* A feature belongs to a project: its links come from `featureHref` (lib/project.js).
|
|
8
|
-
*/
|
|
9
4
|
export function entityHref(kind, id) {
|
|
10
5
|
const q = (page) => `/${page}?sel=${encodeURIComponent(id)}`;
|
|
11
6
|
switch (kind) {
|
|
@@ -20,7 +15,6 @@ export function entityHref(kind, id) {
|
|
|
20
15
|
}
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
/** `standards/backend/dotnet/testing.md` (as tasks.json cites it) → the registry `path`. */
|
|
24
18
|
export function standardKey(ref) {
|
|
25
19
|
return String(ref).replace(/^\.?\/?(\.morph\/framework\/)?standards\//, '');
|
|
26
20
|
}
|
|
@@ -34,12 +28,6 @@ export default function EntityLink({ kind, id, children, className = '', chip =
|
|
|
34
28
|
return <Link to={entityHref(kind, id)} className={cls} title={title}>{children ?? id}</Link>;
|
|
35
29
|
}
|
|
36
30
|
|
|
37
|
-
/**
|
|
38
|
-
* The selected item of a knowledge page, kept in `?sel=` so a panel can be
|
|
39
|
-
* linked, bookmarked and reached from anywhere with EntityLink.
|
|
40
|
-
*
|
|
41
|
-
* @returns {[string|null, (id: string|null) => void]}
|
|
42
|
-
*/
|
|
43
31
|
export function useSelection() {
|
|
44
32
|
const [params, setParams] = useSearchParams();
|
|
45
33
|
const sel = params.get('sel');
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Catches a page that throws while rendering and shows the error in place of
|
|
5
|
-
* the page, so the rest of the layout (the sidebar) keeps working.
|
|
6
|
-
*
|
|
7
|
-
* Without it one broken page unmounts the whole tree: 8.38.0 opened on
|
|
8
|
-
* /agents, which threw a ReferenceError, and the dashboard was a black screen.
|
|
9
|
-
*
|
|
10
4
|
* Mount it with `key={location.pathname}`: a boundary that already caught an
|
|
11
|
-
* error stays in fallback until it remounts
|
|
12
|
-
* sidebar navigates to another page.
|
|
5
|
+
* error stays in fallback until it remounts.
|
|
13
6
|
*/
|
|
14
7
|
export default class ErrorBoundary extends Component {
|
|
15
8
|
constructor(props) {
|
|
@@ -2,9 +2,6 @@ import morphData from 'virtual:morph-data';
|
|
|
2
2
|
import Markdown from './Markdown.jsx';
|
|
3
3
|
import EntityLink, { standardKey } from './EntityLink.jsx';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Names of things that have a page. Built once from the knowledge module.
|
|
7
|
-
*/
|
|
8
5
|
const skillIds = new Set((morphData.skills || []).map((s) => s.id));
|
|
9
6
|
const personaIds = new Set((morphData.agents?.list || []).map((a) => a.id));
|
|
10
7
|
const standardByKey = new Map();
|
|
@@ -13,13 +10,6 @@ for (const s of morphData.standards?.list || []) {
|
|
|
13
10
|
standardByKey.set(s.path, s.id);
|
|
14
11
|
}
|
|
15
12
|
|
|
16
|
-
/**
|
|
17
|
-
* What an inline code span names, if it names something with a page:
|
|
18
|
-
* `morph-plan` or `/morph-plan` → skill, `morph-dotnet-senior` → persona,
|
|
19
|
-
* a standard id or path → standard.
|
|
20
|
-
*
|
|
21
|
-
* @returns {{ kind: string, id: string } | null}
|
|
22
|
-
*/
|
|
23
13
|
export function resolveMention(text) {
|
|
24
14
|
const t = String(text).trim();
|
|
25
15
|
const bare = t.replace(/^\//, '');
|
|
@@ -47,7 +37,6 @@ function InlineCode({ className, children, node, ...rest }) {
|
|
|
47
37
|
return <code className={className} {...rest}>{children}</code>;
|
|
48
38
|
}
|
|
49
39
|
|
|
50
|
-
/** Markdown for framework and feature text: code spans that name a skill, persona or standard become links. */
|
|
51
40
|
export default function KnowledgeMarkdown({ components, ...props }) {
|
|
52
41
|
return <Markdown {...props} components={{ code: InlineCode, ...components }} />;
|
|
53
42
|
}
|
|
@@ -6,7 +6,6 @@ import { splitFrontmatter } from '../lib/format.js';
|
|
|
6
6
|
const REMARK = [remarkGfm];
|
|
7
7
|
const REHYPE = [rehypeSlug];
|
|
8
8
|
|
|
9
|
-
/** Frontmatter keys worth showing, in the order a reader wants them. */
|
|
10
9
|
const META_ORDER = ['name', 'description', 'when_to_use', 'user-invocable', 'stacks', 'version', 'cliVersion'];
|
|
11
10
|
|
|
12
11
|
function MetaBlock({ meta }) {
|
|
@@ -26,14 +25,6 @@ function MetaBlock({ meta }) {
|
|
|
26
25
|
);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
/**
|
|
30
|
-
* Rendered markdown for every long text in the app: feature artifacts, skills,
|
|
31
|
-
* standards, the charter. Frontmatter is lifted into a metadata block instead
|
|
32
|
-
* of being printed as text.
|
|
33
|
-
*
|
|
34
|
-
* @param {{ text: string, components?: object, className?: string, size?: 'md'|'sm' }} props
|
|
35
|
-
* `sm` is for side panels, where the reading column is narrower.
|
|
36
|
-
*/
|
|
37
28
|
export default function Markdown({ text, components, className = '', size = 'md' }) {
|
|
38
29
|
const { meta, body } = splitFrontmatter(text || '');
|
|
39
30
|
return (
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
import { PHASES, PHASE_INDEX, GATE_LABEL, phaseMeta } from '../lib/phases.js';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* The phase rail: one segment per phase, a notch after each phase that ends in
|
|
5
|
-
* an approval gate. The same motif is used in the feature list (sm) and in the
|
|
6
|
-
* feature header (lg), so a feature's progress always reads the same way.
|
|
7
|
-
*
|
|
8
|
-
* Segment state is derived, never stored:
|
|
9
|
-
* done — before the current phase, or the whole feature is completed
|
|
10
|
-
* current — the derived phase of an active feature
|
|
11
|
-
* skipped — an optional phase (uiux) the feature went past without its gate
|
|
12
|
-
* todo — after the current phase
|
|
13
|
-
*/
|
|
14
3
|
export function segmentStates(feature) {
|
|
15
4
|
const idx = PHASE_INDEX[feature.phase] ?? 0;
|
|
16
5
|
const finished = feature.status === 'completed';
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { MagnifyingGlass } from '@phosphor-icons/react';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* The toolbar of the knowledge pages: a search box and a few selects. The
|
|
6
|
-
* `value` of each filter is controlled by the page; the search text is local.
|
|
7
|
-
*/
|
|
8
4
|
export default function SearchFilter({ placeholder = 'Buscar', filters = [], onSearchChange, onFilterChange, children }) {
|
|
9
5
|
const [search, setSearch] = useState('');
|
|
10
6
|
function handleSearchChange(e) {
|
|
@@ -30,10 +30,6 @@ const linkClass = ({ isActive }) => [
|
|
|
30
30
|
isActive ? 'bg-white/[0.08] text-[var(--color-fg)] shadow-[inset_0_1px_0_rgb(255_255_255_/_0.06)]' : 'text-[var(--color-dim)] hover:bg-white/[0.04] hover:text-[var(--color-fg)]',
|
|
31
31
|
].join(' ');
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Switching project keeps the page: from a feature's detail it lands on the
|
|
35
|
-
* other project's feature list, from Activity on the other project's Activity.
|
|
36
|
-
*/
|
|
37
33
|
function ProjectSwitcher({ portfolio, current }) {
|
|
38
34
|
const navigate = useNavigate();
|
|
39
35
|
const { pathname } = useLocation();
|
|
@@ -122,7 +118,6 @@ export default function Sidebar({ portfolio, current, pulse, onSearch }) {
|
|
|
122
118
|
);
|
|
123
119
|
}
|
|
124
120
|
|
|
125
|
-
/** The same destinations as a compact bar for narrow screens. */
|
|
126
121
|
export function MobileNav({ current, onSearch }) {
|
|
127
122
|
const items = [
|
|
128
123
|
{ to: '/', label: 'Portfólio' },
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* reports that the project's `.morph/` changed in the given scope.
|
|
6
|
-
*
|
|
7
|
-
* `scope` matches the server's invalidation: 'features' (feature.json,
|
|
8
|
-
* tasks.json, artifacts) or 'activity' (events.jsonl). A refetch keeps the old
|
|
9
|
-
* data on screen until the new one arrives — no flash of "loading" while an
|
|
10
|
-
* agent is working.
|
|
11
|
-
*
|
|
4
|
+
* A refetch keeps the old data on screen until the new one arrives.
|
|
12
5
|
* @param {string|null} url - null skips the request
|
|
13
|
-
* @param {{ scope?: string|string[], project?: string }} [opts] - `scope`: 'features',
|
|
14
|
-
* 'activity' or 'projects'; `project`: only changes of this project refetch
|
|
15
|
-
* @returns {{ data: any, error: string|null, loading: boolean, refreshedAt: number|null, refetch: () => void }}
|
|
16
6
|
*/
|
|
17
7
|
export function useMorphQuery(url, { scope = 'features', project } = {}) {
|
|
18
8
|
const [state, setState] = useState({ data: null, error: null, loading: Boolean(url), refreshedAt: null });
|
|
@@ -11,10 +11,7 @@ function read(key, fallback) {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* A per-browser preference (view mode, filters). Storage can be unavailable or
|
|
16
|
-
* throw (private mode, SSR); the value then simply does not persist.
|
|
17
|
-
*/
|
|
14
|
+
/** Storage can be unavailable or throw (private mode, SSR); the value then does not persist. */
|
|
18
15
|
export function usePref(key, fallback) {
|
|
19
16
|
const [value, setValue] = useState(() => (typeof window === 'undefined' ? fallback : read(key, fallback)));
|
|
20
17
|
const set = useCallback((next) => {
|
|
@@ -27,7 +24,6 @@ export function usePref(key, fallback) {
|
|
|
27
24
|
return [value, set];
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
/** Re-render every `ms` so relative times ("há 30 s") and "working now" stay true. */
|
|
31
27
|
export function useNow(ms = 15_000) {
|
|
32
28
|
const [now, setNow] = useState(() => Date.now());
|
|
33
29
|
useEffect(() => {
|
|
@@ -8,7 +8,6 @@ const UNITS = [
|
|
|
8
8
|
['minute', 60],
|
|
9
9
|
];
|
|
10
10
|
|
|
11
|
-
/** "há 12 minutos" — or an em dash when there is no date. */
|
|
12
11
|
export function timeAgo(iso, now = Date.now()) {
|
|
13
12
|
const t = Date.parse(iso || '');
|
|
14
13
|
if (Number.isNaN(t)) return '—';
|
|
@@ -56,7 +55,6 @@ export function duration(seconds) {
|
|
|
56
55
|
return `${Math.floor(m / 60)} h ${m % 60} min`;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
/** Strip a leading YAML frontmatter block, returning both parts. */
|
|
60
58
|
export function splitFrontmatter(text) {
|
|
61
59
|
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text || '');
|
|
62
60
|
if (!m) return { meta: null, body: text || '' };
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display vocabulary for the phase pipeline. The ORDER and the optional flag
|
|
3
|
-
* come from framework/phases.json (morphData.phases); this file only adds the
|
|
4
|
-
* words and the colour token each phase is shown with.
|
|
5
|
-
*/
|
|
1
|
+
/** The ORDER and the optional flag come from framework/phases.json; this file only adds words and colours. */
|
|
6
2
|
import morphData from 'virtual:morph-data';
|
|
7
3
|
|
|
8
4
|
const LABELS = {
|
|
9
|
-
proposal: 'Proposta',
|
|
10
|
-
uiux: 'UI/UX',
|
|
11
5
|
plan: 'Plano',
|
|
6
|
+
uiux: 'UI/UX',
|
|
12
7
|
implement: 'Implementação',
|
|
13
8
|
review: 'Revisão',
|
|
14
9
|
};
|
|
@@ -29,9 +24,8 @@ export function phaseMeta(id) {
|
|
|
29
24
|
}
|
|
30
25
|
|
|
31
26
|
export const GATE_LABEL = {
|
|
32
|
-
|
|
27
|
+
plan: 'Gate do plano',
|
|
33
28
|
uiux: 'Gate UI/UX',
|
|
34
|
-
plan: 'Gate 2 (plano)',
|
|
35
29
|
review: 'Gate 3 (revisão)',
|
|
36
30
|
};
|
|
37
31
|
|
|
@@ -3,10 +3,8 @@ import { useLocation } from 'react-router-dom';
|
|
|
3
3
|
import { usePref } from '../hooks/usePref.js';
|
|
4
4
|
import { useMorphQuery } from '../hooks/useMorphQuery.js';
|
|
5
5
|
|
|
6
|
-
/** The live API of one project. */
|
|
7
6
|
export const apiBase = (id) => `/api/morph/p/${encodeURIComponent(id)}`;
|
|
8
7
|
|
|
9
|
-
/** A page of one project: `/p/{id}/features`, `/p/{id}/features/{name}`, `/p/{id}/activity`. */
|
|
10
8
|
export const projectHref = (id, sub = 'features') => `/p/${encodeURIComponent(id)}/${sub}`;
|
|
11
9
|
|
|
12
10
|
export const featureHref = (project, name, query = '') =>
|
|
@@ -14,10 +12,8 @@ export const featureHref = (project, name, query = '') =>
|
|
|
14
12
|
|
|
15
13
|
const PROJECTS_CHANGED = 'morph:projects-changed';
|
|
16
14
|
|
|
17
|
-
/** Tell every reader of the portfolio (page, sidebar, search) to read it again. */
|
|
18
15
|
export const announceProjectsChanged = () => window.dispatchEvent(new Event(PROJECTS_CHANGED));
|
|
19
16
|
|
|
20
|
-
/** The portfolio: registered projects, their summaries, and the ones found next to them. */
|
|
21
17
|
export function useProjects() {
|
|
22
18
|
const q = useMorphQuery('/api/morph/projects', { scope: 'projects' });
|
|
23
19
|
const refetch = useRef(q.refetch);
|
|
@@ -30,14 +26,6 @@ export function useProjects() {
|
|
|
30
26
|
return q;
|
|
31
27
|
}
|
|
32
28
|
|
|
33
|
-
/**
|
|
34
|
-
* The project the person is looking at: the one in the URL, else the last one
|
|
35
|
-
* they opened, else the one the dashboard was launched from. Knowledge pages
|
|
36
|
-
* have no project in the URL but the sidebar still needs one to link to.
|
|
37
|
-
*
|
|
38
|
-
* @param {{ launch?: string|null, projects?: Array<{id: string}> }|null} portfolio
|
|
39
|
-
* @returns {{ id: string|null, inUrl: boolean }}
|
|
40
|
-
*/
|
|
41
29
|
export function useCurrentProject(portfolio) {
|
|
42
30
|
const { pathname } = useLocation();
|
|
43
31
|
const m = /^\/p\/([^/]+)/.exec(pathname);
|
|
@@ -13,7 +13,7 @@ export default function Activity() {
|
|
|
13
13
|
<h1 className="mt-1 text-4xl font-semibold tracking-tight">Atividade</h1>
|
|
14
14
|
<p className="mt-3 max-w-2xl text-sm leading-relaxed text-[var(--color-dim)]">
|
|
15
15
|
O que o Claude fez no projeto, contado a partir da telemetria dos hooks: suas mensagens, as skills carregadas,
|
|
16
|
-
os sub-agents despachados,
|
|
16
|
+
os sub-agents despachados, os verifies e os gates. Atualiza sozinho enquanto ele trabalha.
|
|
17
17
|
</p>
|
|
18
18
|
</header>
|
|
19
19
|
<div className="rise-2 bezel">
|
|
@@ -10,11 +10,7 @@ import Markdown from '../components/Markdown.jsx';
|
|
|
10
10
|
import EntityLink, { useSelection } from '../components/EntityLink.jsx';
|
|
11
11
|
import { phaseMeta } from '../lib/phases.js';
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
* `agents.json → color` is a color NAME (blue, cyan…), the one Claude Code
|
|
15
|
-
* paints the sub-agent with. The map reads the same name, so a persona looks
|
|
16
|
-
* the same here and in the terminal.
|
|
17
|
-
*/
|
|
13
|
+
/** Color NAMES, the ones Claude Code paints the sub-agent with. */
|
|
18
14
|
const COLOR_HEX = {
|
|
19
15
|
blue: '#60a5fa',
|
|
20
16
|
cyan: '#22d3ee',
|
|
@@ -29,13 +25,11 @@ const COLOR_HEX = {
|
|
|
29
25
|
};
|
|
30
26
|
const FALLBACK_HEX = '#9ca3af';
|
|
31
27
|
|
|
32
|
-
/** The ONE color lookup: nodes, edges, detail badge and legend all read it. */
|
|
33
28
|
const personaColor = (agent) => COLOR_HEX[agent?.color] || FALLBACK_HEX;
|
|
34
29
|
|
|
35
30
|
/** `'*'` in a persona's `stack` means "every stack" — it is not a stack of its own. */
|
|
36
31
|
const UNIVERSAL_STACK = '*';
|
|
37
32
|
|
|
38
|
-
/** The node of the human + main thread. Never a persona id. */
|
|
39
33
|
const PRINCIPAL_ID = 'principal';
|
|
40
34
|
|
|
41
35
|
const NODE_W = 220;
|
|
@@ -81,7 +75,6 @@ function buildLayout(nodes, edges) {
|
|
|
81
75
|
});
|
|
82
76
|
}
|
|
83
77
|
|
|
84
|
-
/** Skills whose dispatch lines name this persona, or dispatch any implementer. */
|
|
85
78
|
function dispatchingSkills(agent) {
|
|
86
79
|
const implementer = (agent.activePhases || []).includes('implement');
|
|
87
80
|
return (morphData.skills || []).filter((s) => (s.dispatches || []).some(
|