@polymorphism-tech/morph-spec 8.38.0 → 8.41.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 +20 -9
- package/README.md +2 -2
- package/bin/morph-spec.js +60 -43
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +4 -3
- package/framework/MORPH.md +10 -9
- package/framework/agents.json +43 -26
- package/framework/docs/CLI.md +7 -5
- package/framework/evals/rubrics/code-quality.md +4 -4
- package/framework/evals/rubrics/condensed.md +2 -2
- package/framework/hooks/README.md +1 -1
- package/framework/hooks/claude-code/core/telemetry-log.js +39 -8
- package/framework/hooks/claude-code/core/worktree-create.js +22 -6
- package/framework/hooks/shared/git-paths.js +38 -5
- package/framework/mcp/registry.json +58 -66
- package/framework/rules/infrastructure-standards.md +0 -1
- package/framework/rules/morph-workflow.md +9 -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 +59 -25
- 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 +48 -24
- package/framework/skills/core/morph-media/SKILL.md +2 -2
- package/framework/skills/core/morph-plan/SKILL.md +10 -3
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +1 -1
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +7 -6
- package/framework/standards/PROVENANCE.json +4 -4
- package/framework/standards/STANDARDS.json +9 -9
- package/framework/standards/ai-agents/context-providers.md +16 -26
- package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
- package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
- package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
- package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
- package/framework/standards/ai-agents/modalities-vision.md +1 -18
- package/framework/standards/ai-agents/prompt-sources.md +0 -4
- package/framework/standards/architecture/code-comments.md +52 -16
- package/framework/standards/backend/dotnet/testing.md +4 -2
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
- package/framework/standards/frontend/design-system/ai-image-generation.md +42 -28
- package/framework/standards/frontend/design-system/ai-video-generation.md +24 -9
- package/framework/standards/frontend/nextjs/testing.md +4 -2
- package/framework/standards/integration/mcp/mcp-tools.md +64 -126
- package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
- package/framework/templates/code/dotnet/database/migration.cs +49 -83
- package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
- package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
- package/framework/templates/code/dotnet/jobs/job.cs +2 -97
- package/framework/templates/code/dotnet/test.cs +2 -87
- package/framework/templates/code/typescript/contracts.ts +140 -167
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
- package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
- package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
- package/framework/templates/integrations/asaas-client.cs +332 -387
- package/framework/templates/integrations/asaas-webhook.cs +290 -351
- package/framework/templates/integrations/neon-auth-config.cs +9 -105
- package/framework/templates/project/validate.js +97 -120
- package/package.json +2 -2
- package/src/commands/dashboard/dashboard.js +80 -53
- package/src/commands/mcp/mcp-setup.js +37 -9
- package/src/commands/project/doctor.js +12 -6
- package/src/commands/project/init.js +6 -3
- package/src/commands/project/install-plugin-cmd.js +1 -1
- package/src/commands/project/update.js +5 -0
- package/src/commands/project/worktree.js +60 -4
- package/src/commands/state/gate-check.js +5 -0
- package/src/commands/tasks/dag.js +27 -4
- package/src/commands/validation/verify.js +22 -38
- package/src/dashboard/app/App.jsx +80 -16
- package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
- package/src/dashboard/app/components/CommandPalette.jsx +155 -0
- package/src/dashboard/app/components/DetailPanel.jsx +47 -11
- package/src/dashboard/app/components/EntityLink.jsx +55 -0
- package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
- package/src/dashboard/app/components/FlowGraph.jsx +19 -17
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
- package/src/dashboard/app/components/Markdown.jsx +47 -0
- package/src/dashboard/app/components/PhaseRail.jsx +111 -0
- package/src/dashboard/app/components/SearchFilter.jsx +40 -22
- package/src/dashboard/app/components/Sidebar.jsx +146 -37
- package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
- package/src/dashboard/app/hooks/usePref.js +38 -0
- package/src/dashboard/app/lib/format.js +69 -0
- package/src/dashboard/app/lib/phases.js +56 -0
- package/src/dashboard/app/lib/project.js +50 -0
- package/src/dashboard/app/pages/Activity.jsx +24 -0
- package/src/dashboard/app/pages/AgentMap.jsx +371 -370
- package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
- package/src/dashboard/app/pages/Features.jsx +400 -0
- package/src/dashboard/app/pages/Guide.jsx +146 -0
- package/src/dashboard/app/pages/HookInspector.jsx +357 -322
- package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
- package/src/dashboard/app/pages/Portfolio.jsx +156 -0
- package/src/dashboard/app/pages/Rubrics.jsx +101 -0
- package/src/dashboard/app/pages/RulesMap.jsx +300 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
- package/src/dashboard/app/pages/Standards.jsx +407 -332
- package/src/dashboard/app/styles/index.css +187 -47
- package/src/dashboard/index.html +14 -12
- package/src/dashboard/package.json +32 -24
- package/src/dashboard/scanner/activity-scanner.js +351 -0
- package/src/dashboard/scanner/agents-scanner.js +59 -1
- package/src/dashboard/scanner/docs-scanner.js +59 -0
- package/src/dashboard/scanner/feature-status.js +10 -0
- package/src/dashboard/scanner/features-scanner.js +360 -0
- package/src/dashboard/scanner/index.js +14 -7
- package/src/dashboard/scanner/phases-scanner.js +14 -15
- package/src/dashboard/scanner/portfolio.js +153 -0
- package/src/dashboard/scanner/project-api.js +195 -0
- package/src/dashboard/scanner/rules-scanner.js +42 -37
- package/src/dashboard/scanner/skills-scanner.js +105 -43
- package/src/dashboard/scanner/standards-scanner.js +2 -0
- package/src/dashboard/vite-plugin-morph-data.js +134 -17
- package/src/lib/detectors/claude-config-detector.js +2 -7
- package/src/lib/detectors/index.js +5 -1
- package/src/lib/evaluator-report.js +22 -0
- package/src/lib/generators/settings-generator.js +208 -209
- package/src/lib/installers/mcp-installer.js +724 -719
- package/src/lib/installers/memory-installer.js +1 -2
- package/src/lib/projects/registry.js +154 -0
- package/src/lib/risk-detector.js +13 -0
- package/src/lib/tasks/tasks-json-parser.js +21 -0
- package/src/lib/validators/code-budget/code-budget-validator.js +32 -4
- package/src/lib/worktree/env-allocator.js +9 -3
- package/src/scripts/install-plugin.js +1 -1
- package/src/scripts/setup-infra.js +2 -4
- package/src/utils/agents-installer.js +108 -13
- package/src/utils/banner.js +1 -1
- package/src/commands/index.js +0 -13
- package/src/commands/project/checkpoint.js +0 -209
- package/src/core/state/phase-state-machine.js +0 -197
- package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
- package/src/dashboard/app/pages/LiveState.jsx +0 -206
- package/src/dashboard/scanner/squads-scanner.js +0 -13
- package/src/dashboard/scanner/state-scanner.js +0 -85
- package/src/lib/generators/index.js +0 -10
- package/src/lib/hooks/hook-executor.js +0 -167
- package/src/lib/validators/checkpoint-persistence.js +0 -39
- package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
- package/src/lib/validators/shared/index.js +0 -12
- package/src/lib/validators/shared/issue-counter.js +0 -14
- package/src/lib/validators/shared/result-formatter.js +0 -124
|
@@ -58,6 +58,42 @@ function findDotGit(startDir) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* A linked worktree's `.git` FILE holds `gitdir: <path>` (absolute or relative
|
|
63
|
+
* to the file) pointing at its private gitdir. `null` when the line is absent.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} dotGitFile
|
|
66
|
+
* @returns {string|null}
|
|
67
|
+
*/
|
|
68
|
+
function privateGitDirOf(dotGitFile) {
|
|
69
|
+
const match = readFileSync(dotGitFile, 'utf8').match(/^gitdir:\s*(.+?)\s*$/m);
|
|
70
|
+
if (!match) return null;
|
|
71
|
+
return isAbsolute(match[1]) ? match[1] : resolve(dirname(dotGitFile), match[1]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const MORPH_BRANCH = /^ref:\s*refs\/heads\/morph\/([A-Za-z0-9._-]+)\s*$/;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The feature a checkout is bound to by its branch `morph/<feature>`, read from
|
|
78
|
+
* `<root>/.git` exactly (no climbing) — the primary's `.git/HEAD` or, for a
|
|
79
|
+
* linked worktree, `<gitdir>/HEAD`. `null` for any other branch (`morph-task/*`
|
|
80
|
+
* included), a detached HEAD, or no `.git` at `root`.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} root
|
|
83
|
+
* @returns {string|null}
|
|
84
|
+
*/
|
|
85
|
+
export function morphBranchFeature(root) {
|
|
86
|
+
try {
|
|
87
|
+
const dotGit = join(root, '.git');
|
|
88
|
+
const gitDir = statSync(dotGit).isDirectory() ? dotGit : privateGitDirOf(dotGit);
|
|
89
|
+
if (!gitDir) return null;
|
|
90
|
+
const name = MORPH_BRANCH.exec(readFileSync(join(gitDir, 'HEAD'), 'utf8').trim())?.[1];
|
|
91
|
+
return name && name !== '.' && name !== '..' ? name : null;
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
61
97
|
/**
|
|
62
98
|
* Is `startDir` inside a LINKED (secondary) worktree?
|
|
63
99
|
*
|
|
@@ -119,11 +155,8 @@ export function resolveGitCommonDir(startDir) {
|
|
|
119
155
|
return found.path;
|
|
120
156
|
}
|
|
121
157
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const match = content.match(/^gitdir:\s*(.+?)\s*$/m);
|
|
125
|
-
if (!match) return null;
|
|
126
|
-
const privateGitDir = isAbsolute(match[1]) ? match[1] : resolve(dirname(found.path), match[1]);
|
|
158
|
+
const privateGitDir = privateGitDirOf(found.path);
|
|
159
|
+
if (!privateGitDir) return null;
|
|
127
160
|
|
|
128
161
|
// Inside the private gitdir, `commondir` points (relative to itself, or
|
|
129
162
|
// absolute) at the real common dir.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"context7": {
|
|
6
6
|
"phases": ["proposal", "plan", "implement"],
|
|
7
7
|
"tools": ["resolve-library-id", "query-docs"],
|
|
8
|
+
"serverNames": ["context7", "plugin_context7_context7"],
|
|
8
9
|
"detection": "enabledPlugins includes context7 or mcpServers includes context7",
|
|
9
10
|
"fallback": "WebSearch + WebFetch for library documentation",
|
|
10
11
|
"usage": "Library documentation lookups, API reference, implementation patterns",
|
|
@@ -33,7 +34,8 @@
|
|
|
33
34
|
"playwright": {
|
|
34
35
|
"phases": ["uiux", "implement"],
|
|
35
36
|
"tools": ["browser_navigate", "browser_snapshot", "browser_take_screenshot", "browser_console_messages", "browser_click", "browser_resize"],
|
|
36
|
-
"
|
|
37
|
+
"serverNames": ["playwright", "plugin_playwright_playwright"],
|
|
38
|
+
"detection": "mcpServers includes playwright or enabledPlugins includes playwright",
|
|
37
39
|
"fallback": "WebFetch for read-only page content, manual testing",
|
|
38
40
|
"usage": "UI preview, smoke testing, page inspection, responsive testing, screenshot capture",
|
|
39
41
|
"healthCheck": {
|
|
@@ -165,61 +167,21 @@
|
|
|
165
167
|
"description": "Official Stitch agent skills for Claude Code — design generation, multi-page loops, design.md export"
|
|
166
168
|
}
|
|
167
169
|
},
|
|
168
|
-
"
|
|
170
|
+
"morph-assets": {
|
|
169
171
|
"phases": ["uiux", "implement"],
|
|
170
|
-
"tools": ["generate_image", "edit_image", "continue_editing", "
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
172
|
+
"tools": ["generate_image", "edit_image", "continue_editing", "generate_video", "generate_loop_video", "get_video", "media_tool", "list_models", "library", "usage"],
|
|
173
|
+
"serverNames": ["morph-assets"],
|
|
174
|
+
"detection": "mcpServers includes morph-assets",
|
|
175
|
+
"fallback": "Manual image creation, stock photos or client-provided footage; a static poster image instead of video. Canvas frame-scrub works from any frame sequence, AI-generated or not",
|
|
176
|
+
"usage": "Single MCP for AI image and video generation plus local post-production, all models via OpenRouter. Images: default openai/gpt-image-2.5-flare, drafts microsoft/mai-image-2.6-flash, google/gemini-3.1-flash-image for 2K/4K or 6-14 references; `models` compares the same request across 2-4 models. Video: default bytedance/seedance-1-5-pro (draft/loop), final bytedance/seedance-2.0 1080p via promoteFrom; generate_video with endImage produces the directional footage that frame-scrub needs (start frame differs from end frame), generate_loop_video is only for seamless ambient loops. media_tool (ffmpeg) extracts scrub frames, posters, concat, compress and builds the approval picker. library replaces the old list_images/get_image_info/list_videos",
|
|
174
177
|
"healthCheck": {
|
|
175
|
-
"toolPattern": "
|
|
176
|
-
"testCall": "Call
|
|
177
|
-
"testParams": {},
|
|
178
|
-
"successIndicator": "Returns status with valid API key configured",
|
|
179
|
-
"failureHint": "Gemini Image MCP not responding. Check that GEMINI_API_KEY is set in the MCP env config and that MORPH_HUB points at a built morph-HUB checkout."
|
|
180
|
-
},
|
|
181
|
-
"install": {
|
|
182
|
-
"autoInstall": false,
|
|
183
|
-
"transport": "stdio",
|
|
184
|
-
"config": {
|
|
185
|
-
"type": "stdio",
|
|
186
|
-
"command": "node",
|
|
187
|
-
"args": ["${MORPH_HUB}/mcps/gemini-image/dist/index.js"]
|
|
188
|
-
},
|
|
189
|
-
"credentials": [
|
|
190
|
-
{
|
|
191
|
-
"name": "Gemini API Key",
|
|
192
|
-
"envVar": "GEMINI_API_KEY",
|
|
193
|
-
"secret": true,
|
|
194
|
-
"helpUrl": "https://aistudio.google.com/apikey"
|
|
195
|
-
}
|
|
196
|
-
],
|
|
197
|
-
"prerequisites": [
|
|
198
|
-
"Google AI Studio API key",
|
|
199
|
-
"Local morph-HUB checkout with mcps/gemini-image built, exposed via the MORPH_HUB env var"
|
|
200
|
-
],
|
|
201
|
-
"stackRelevance": ["nextjs", "next"],
|
|
202
|
-
"warnings": [
|
|
203
|
-
"Internal Polymorphism MCP, not published to npm. The public gemini-image-mcp package was unpublished in 2025-04, so npx installs no longer work.",
|
|
204
|
-
"Requires GEMINI_API_KEY environment variable. Image generation costs apply per Google AI pricing."
|
|
205
|
-
],
|
|
206
|
-
"setupGuide": "1. Get an API key at https://aistudio.google.com/apikey\n2. Build the MCP: cd $MORPH_HUB/mcps/gemini-image && npm install && npm run build\n3. Run: claude mcp add gemini-image-mcp -e GEMINI_API_KEY=<key> -- node $MORPH_HUB/mcps/gemini-image/dist/index.js\n4. Verify with get_configuration_status"
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
"seedance": {
|
|
210
|
-
"phases": ["uiux", "implement"],
|
|
211
|
-
"tools": ["generate_video", "generate_loop_video", "get_video", "list_videos"],
|
|
212
|
-
"detection": "mcpServers includes seedance",
|
|
213
|
-
"fallback": "Use client-provided footage or a static poster image; canvas frame-scrub works from any frame sequence, AI-generated or not",
|
|
214
|
-
"usage": "AI video generation for scroll-driven heroes and ambient backgrounds. generate_video with endImage produces the directional footage that frame-scrub needs (start frame differs from end frame); generate_loop_video is only for seamless ambient loops",
|
|
215
|
-
"healthCheck": {
|
|
216
|
-
"toolPattern": "seedance",
|
|
217
|
-
"testCall": "Call list_videos with limit 1 to verify the server responds (reads local history, spends no credits)",
|
|
178
|
+
"toolPattern": "morph-assets",
|
|
179
|
+
"testCall": "Call usage with op 'balance' to verify the OpenRouter key (reads the credit balance, spends no credits)",
|
|
218
180
|
"testParams": {
|
|
219
|
-
"
|
|
181
|
+
"op": "balance"
|
|
220
182
|
},
|
|
221
|
-
"successIndicator": "Returns the
|
|
222
|
-
"failureHint": "
|
|
183
|
+
"successIndicator": "Returns the OpenRouter credit balance",
|
|
184
|
+
"failureHint": "morph-assets MCP not responding. Check that OPENROUTER_API_KEY is set (morph-HUB root .env or the MCP env config) and that MORPH_HUB points at a morph-HUB checkout with mcps/morph-assets built."
|
|
223
185
|
},
|
|
224
186
|
"install": {
|
|
225
187
|
"autoInstall": false,
|
|
@@ -227,28 +189,30 @@
|
|
|
227
189
|
"config": {
|
|
228
190
|
"type": "stdio",
|
|
229
191
|
"command": "node",
|
|
230
|
-
"args": ["${MORPH_HUB}/mcps/
|
|
192
|
+
"args": ["${MORPH_HUB}/mcps/morph-assets/dist/index.js"]
|
|
231
193
|
},
|
|
232
194
|
"credentials": [
|
|
233
195
|
{
|
|
234
|
-
"name": "
|
|
235
|
-
"envVar": "
|
|
196
|
+
"name": "OpenRouter API Key",
|
|
197
|
+
"envVar": "OPENROUTER_API_KEY",
|
|
236
198
|
"secret": true,
|
|
237
|
-
"helpUrl": "https://
|
|
199
|
+
"helpUrl": "https://openrouter.ai/settings/keys"
|
|
238
200
|
}
|
|
239
201
|
],
|
|
240
202
|
"prerequisites": [
|
|
241
|
-
"
|
|
242
|
-
"Local morph-HUB checkout with mcps/
|
|
243
|
-
"ffmpeg on PATH
|
|
203
|
+
"OpenRouter account with credits",
|
|
204
|
+
"Local morph-HUB checkout with mcps/morph-assets built, exposed via the MORPH_HUB env var",
|
|
205
|
+
"ffmpeg on PATH for media_tool (scrub frames, poster, concat, compress)"
|
|
244
206
|
],
|
|
245
|
-
"stackRelevance": ["next", "react", "vite", "astro"],
|
|
207
|
+
"stackRelevance": ["next", "nextjs", "react", "vite", "astro"],
|
|
246
208
|
"warnings": [
|
|
247
|
-
"Internal Polymorphism MCP, not published to npm. Requires a local morph-HUB checkout.",
|
|
248
|
-
"Paid per generation.
|
|
209
|
+
"Internal Polymorphism MCP, not published to npm. Requires a local morph-HUB checkout. Replaces the former gemini-image and seedance MCPs.",
|
|
210
|
+
"Paid per generation. Every call estimates cost first; dryRun only estimates. Above US$2, over the project budget or with unknown price it returns CONFIRMATION_REQUIRED + confirmToken: get human approval, then repeat the same call with the token.",
|
|
211
|
+
"Video is async: if generate_video returns 'generating', poll get_video with the ids. Never resend generate_video (a different request is billed again). Draft at 480p first, promote to 1080p only after the take is approved.",
|
|
212
|
+
"Video has no ZDR on OpenRouter and human faces in img2vid frames trigger moderation: keep sensitive content and faces out of the frames.",
|
|
249
213
|
"Generation is stochastic and needs a human approval gate. Do not wire it into an unattended phase."
|
|
250
214
|
],
|
|
251
|
-
"setupGuide": "1. Get a
|
|
215
|
+
"setupGuide": "1. Get a key at https://openrouter.ai/settings/keys and set OPENROUTER_API_KEY in the morph-HUB root .env\n2. Build the MCP: cd $MORPH_HUB && npm install && npm run build -w mcps/morph-assets\n3. Run: claude mcp add morph-assets -e OPENROUTER_API_KEY=<key> -- node $MORPH_HUB/mcps/morph-assets/dist/index.js\n4. Verify with usage op 'balance' (spends no credits)"
|
|
252
216
|
}
|
|
253
217
|
},
|
|
254
218
|
"graphify": {
|
|
@@ -285,14 +249,42 @@
|
|
|
285
249
|
],
|
|
286
250
|
"setupGuide": null
|
|
287
251
|
}
|
|
252
|
+
},
|
|
253
|
+
"neon": {
|
|
254
|
+
"phases": ["plan", "implement"],
|
|
255
|
+
"tools": ["list_projects", "describe_table_schema", "get_database_tables", "run_sql", "explain_sql_statement", "prepare_database_migration", "complete_database_migration", "compare_database_schema", "create_branch", "list_branches", "get_connection_string"],
|
|
256
|
+
"serverNames": ["neon", "Neon"],
|
|
257
|
+
"detection": "mcpServers includes neon (case-insensitive)",
|
|
258
|
+
"fallback": "SQL via the connection string (psql / dotnet ef) and the neonctl CLI for branches",
|
|
259
|
+
"usage": "Schema inspection, migration dry-run on a throwaway branch (prepare_database_migration → complete_database_migration), query tuning. The server exposes DESTRUCTIVE tools (delete_branch, delete_project, reset_from_parent): never call one without explicit human confirmation",
|
|
260
|
+
"healthCheck": {
|
|
261
|
+
"toolPattern": "neon",
|
|
262
|
+
"testCall": "Call list_projects with limit 1",
|
|
263
|
+
"testParams": { "limit": 1 },
|
|
264
|
+
"successIndicator": "Returns the project list (possibly empty)",
|
|
265
|
+
"failureHint": "Neon MCP not responding. Re-run the OAuth flow: claude mcp add --transport http neon https://mcp.neon.tech/mcp"
|
|
266
|
+
},
|
|
267
|
+
"install": {
|
|
268
|
+
"autoInstall": false,
|
|
269
|
+
"transport": "http",
|
|
270
|
+
"config": {
|
|
271
|
+
"type": "http",
|
|
272
|
+
"url": "https://mcp.neon.tech/mcp"
|
|
273
|
+
},
|
|
274
|
+
"credentials": [],
|
|
275
|
+
"prerequisites": [],
|
|
276
|
+
"stackRelevance": ["neon"],
|
|
277
|
+
"warnings": ["OAuth against your Neon account on first use. The server can delete branches and projects: keep destructive calls behind a human."],
|
|
278
|
+
"setupGuide": "Run: claude mcp add --transport http neon https://mcp.neon.tech/mcp"
|
|
279
|
+
}
|
|
288
280
|
}
|
|
289
281
|
},
|
|
290
|
-
"_phaseMatrixNote": "Keys must be the v5 phases from framework/phases.json. The v4 keys 'design' and 'tasks' both collapsed into 'plan'; 'review' was absent entirely, so a project in review resolved to undefined. Stack-scoped MCPs (asaas) stay out of this matrix on purpose — only universal ones are listed.",
|
|
282
|
+
"_phaseMatrixNote": "Keys must be the v5 phases from framework/phases.json. The v4 keys 'design' and 'tasks' both collapsed into 'plan'; 'review' was absent entirely, so a project in review resolved to undefined. Stack-scoped MCPs (asaas, neon) stay out of this matrix on purpose — only universal ones are listed.",
|
|
291
283
|
"phaseMatrix": {
|
|
292
284
|
"proposal": ["context7", "graphify"],
|
|
293
|
-
"uiux": ["playwright", "context7", "stitch", "
|
|
285
|
+
"uiux": ["playwright", "context7", "stitch", "morph-assets"],
|
|
294
286
|
"plan": ["context7", "graphify"],
|
|
295
|
-
"implement": ["context7", "playwright", "vercel", "
|
|
287
|
+
"implement": ["context7", "playwright", "vercel", "morph-assets", "graphify"],
|
|
296
288
|
"review": ["playwright", "context7", "graphify"]
|
|
297
289
|
}
|
|
298
290
|
}
|
|
@@ -12,7 +12,6 @@ stacks:
|
|
|
12
12
|
|
|
13
13
|
@.morph/framework/standards/infrastructure/docker/coolify-deploy.md
|
|
14
14
|
@.morph/framework/standards/infrastructure/docker/local-compose-isolation.md
|
|
15
|
-
@.morph/framework/standards/infrastructure/docker/local-compose-isolation.md
|
|
16
15
|
|
|
17
16
|
## Infrastructure Templates
|
|
18
17
|
|
|
@@ -192,16 +192,21 @@ Every task in `tasks.json` MUST reference its FR(s) in the `description` field s
|
|
|
192
192
|
|
|
193
193
|
## Debugging
|
|
194
194
|
|
|
195
|
-
When a bug or unexpected behavior shows up mid-task,
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
When a bug or unexpected behavior shows up mid-task, find the **root cause before proposing a
|
|
196
|
+
fix** — never a patch on the symptom. This is MANDATORY:
|
|
197
|
+
|
|
198
|
+
1. Reproduce it and read the full error, not the first line.
|
|
199
|
+
2. For a known .NET/Next.js error, run `/morph-troubleshoot <keywords>` first.
|
|
200
|
+
3. One hypothesis at a time, each tested by the smallest check that could refute it.
|
|
201
|
+
4. After three failed fixes, stop and question the design instead of trying a fourth.
|
|
202
|
+
5. Confirm the fix with the same check that reproduced the bug; add a test only when no existing one covers that behavior.
|
|
198
203
|
|
|
199
204
|
Everything else that a rule like this might list is owned by the flow itself, and duplicating it
|
|
200
205
|
here would put a second, staler copy in permanent context:
|
|
201
206
|
|
|
202
207
|
| Concern | Where it actually lives |
|
|
203
208
|
|---------|-------------------------|
|
|
204
|
-
|
|
|
209
|
+
| How many tests to write | The test budget copied into the feature's `mandate.md`: one test per postcondition, same-behavior cases in one table, no test that only pins text |
|
|
205
210
|
| Verifying a task before `status: "done"` | `morph-spec verify {feature} [task]` (build + tests + validators + e2e), then the `morph-eval` skill for the 0-10 score |
|
|
206
211
|
| Parallel dispatch | `morph-spec dag {feature}` decides sequential vs parallel; execution and isolation rules are in `morph-apply` §2/§3b |
|
|
207
212
|
| Closing the phase / opening the PR | `morph-review` for Gate 3, then `morph-spec finish {feature} --pr\|--merge` |
|
|
@@ -4,7 +4,7 @@ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Migra uma landing page existente (React/Vite, Next.js estático ou
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber instrução "use /migrate-lp-to-umbraco {projeto}" do usuário, ou quando o usuário descrever necessidade de migrar uma LP para Umbraco
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Orquestra a execução autônoma de tasks de uma feature morph-spec
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: após Gate 2 aprovado, ao receber instrução "use /morph-apply" ou "implementar feature"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -138,7 +138,7 @@ while (true):
|
|
|
138
138
|
options: [aceitar (marca done com ressalva no recap), continuar tentando (+3 tentativas), pular task (marca blocked)]
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
> **Loop por task filtra; Gate 3 e CI não.** No loop o filtro é **automático**: `verify {feature} {task.id}` deixa o `group` da task escolher os nós e os arquivos de teste de `outputs` estreitarem o comando — cada nó **aparece** em `nodes.tests.runs[]` com `selection` (`narrowed`/`whole`/`out-of-scope`/`full` e o motivo), nenhum some. `--filter {ids}` só força a escolha de nós (os não casados aparecem como `skip` nomeando o filtro, e um `--filter` que não casa nada é erro de uso, exit 2, nunca um verde); `--full` desliga o recorte. A verificação pós-batch e a do Gate 3 (`morph-spec verify {feature} --json`) rodam **sem filtro**, e `verify {feature}` **nunca recorta**: a prova que o avaliador lê tem de cobrir todos os nós, e o CI idem. Forma de `project.tests[]`, regras e limites do recorte, e a tabela da divisão: `.morph/framework/CLI.md`, seção "Suítes de teste".
|
|
141
|
+
> **Loop por task filtra; Gate 3 e CI não.** O sub-agent despachado não roda `verify`: só o filtro dos próprios testes, uma vez (cláusula 3). No loop o filtro é **automático**: `verify {feature} {task.id}` deixa o `group` da task escolher os nós e os arquivos de teste de `outputs` estreitarem o comando — cada nó **aparece** em `nodes.tests.runs[]` com `selection` (`narrowed`/`whole`/`out-of-scope`/`full` e o motivo), nenhum some. `--filter {ids}` só força a escolha de nós (os não casados aparecem como `skip` nomeando o filtro, e um `--filter` que não casa nada é erro de uso, exit 2, nunca um verde); `--full` desliga o recorte. A verificação pós-batch e a do Gate 3 (`morph-spec verify {feature} --json`) rodam **sem filtro**, e `verify {feature}` **nunca recorta**: a prova que o avaliador lê tem de cobrir todos os nós, e o CI idem. Forma de `project.tests[]`, regras e limites do recorte, e a tabela da divisão: `.morph/framework/CLI.md`, seção "Suítes de teste".
|
|
142
142
|
>
|
|
143
143
|
> **Verify vermelho consome uma tentativa** do loop (≤3) e devolve `feedback[]` acionável (erros de build, falhas de teste — linhas prefixadas por `[tests/{id}]`, que nomeiam a suíte —, issues de validador). O `morph-eval` NUNCA é invocado sobre código que não passou no verify — o juiz julga arquitetura/contratos/qualidade, o que o código determinístico não pega sozinho. Código roda antes, grátis; o juiz gasta tokens só no que sobra.
|
|
144
144
|
|
|
@@ -156,15 +156,18 @@ while (true):
|
|
|
156
156
|
- **Standard(s):** use `task.standards` quando presente; senão, do array `standards` do agente resolvido acima em `agents.json` (e/ou do `mandate.md`), selecione o(s) path(s) `.md` relevante(s) à task.
|
|
157
157
|
- **Fallback (tipo não registrado):** se `morph-{id}` não estiver na sua lista de subagent types (stack não instalado neste projeto), use `subagent_type: "general-purpose"` colando o campo `persona` no prompt — e **registre nas `notes` da task**: `dispatch-fallback: general-purpose ({id} não registrado)`. O recap deve refletir o mecanismo real.
|
|
158
158
|
|
|
159
|
+
**Cole o template literal**: só os campos entre `<>` mudam; não parafraseie cláusula nem omita os parágrafos de leitura, ferramentas e comentário.
|
|
160
|
+
|
|
159
161
|
```
|
|
160
162
|
dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
161
163
|
contexto: spec.md, mandate.md, task description completa, doneCriteria,
|
|
162
164
|
task.reuse (veredito REUSAR/ESTENDER/CRIAR por conceito), os paths
|
|
163
165
|
dos alvos de reuso e o que você já leu para a task (`arquivo:linhas`
|
|
164
166
|
+ o trecho)
|
|
165
|
-
|
|
167
|
+
standards: <por standard: id + digest do `standards --find` + as 3-8 regras do
|
|
168
|
+
.md que ESTA task aplica, coladas; o path só para consulta pontual>
|
|
166
169
|
instrução: |
|
|
167
|
-
|
|
170
|
+
Siga as regras dos standards acima; abra o .md só para uma dúvida pontual.
|
|
168
171
|
Implemente esta task (ou cadeia de tasks do fluxo) sem depender do trabalho
|
|
169
172
|
dos outros agentes deste batch: seu ISOLAMENTO é de ESTADO e de ÁRVORE DE
|
|
170
173
|
TRABALHO — nunca de conhecimento do codebase. Antes de criar tipo,
|
|
@@ -173,9 +176,24 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
173
176
|
(`no-graph`), caia para `grep -rn "<nome>"` e siga — a ausência de grafo
|
|
174
177
|
nunca bloqueia. Se algo cobre o caso, reuse ou estenda; se criar mesmo
|
|
175
178
|
assim, diga por que em uma linha no relatório.
|
|
176
|
-
Leitura:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
Leitura e turnos: cada turno custa ~10 s antes de a tool rodar, e o teto de
|
|
180
|
+
turnos corta sem aviso. Chamadas que não dependem uma da outra vão no MESMO
|
|
181
|
+
turno: leia de uma vez todos os arquivos que este prompt lista, dispare os
|
|
182
|
+
Grep juntos. Use Read/Grep/Glob — nunca `grep`, `sed -n`, `cat`, `find`,
|
|
183
|
+
`ls` via Bash. Não releia o que este prompt já traz. Em arquivo grande, `Grep`
|
|
184
|
+
acha a linha e `Read` com `offset`/`limit` lê só o trecho; log de build/teste
|
|
185
|
+
se lê pelo `Grep` do erro, não inteiro.
|
|
186
|
+
|
|
187
|
+
Ferramentas: antes de supor a API de uma biblioteca (MAF, EF Core, Next,
|
|
188
|
+
shadcn, SDK de provedor), consulte o MCP `context7` (`resolve-library-id` →
|
|
189
|
+
`query-docs`). Impacto e vizinhança de símbolo vêm do grafo
|
|
190
|
+
(`morph-spec graph`), não de varredura por grep. Tool `mcp__…` que não esteja
|
|
191
|
+
carregada se carrega com `ToolSearch` (`select:<nome>`); MCP ausente nunca
|
|
192
|
+
bloqueia — siga com o fallback.
|
|
193
|
+
Comentário: o padrão é nenhum. Nome, tipo e teste explicam o código; sem
|
|
194
|
+
`///`/JSDoc em membro de aplicação, cabeçalho, banner de seção ou história
|
|
195
|
+
da task. Só o porquê que o código não mostra, em uma linha
|
|
196
|
+
(`architecture-code-comments`).
|
|
179
197
|
Não modifique spec.md, mandate.md.
|
|
180
198
|
|
|
181
199
|
Contrato do relatório final:
|
|
@@ -188,17 +206,21 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
188
206
|
2. NÃO toque em tasks.json, feature.json, state.json nem no board de
|
|
189
207
|
sessão — todo estado (status de task, scores, gates) é gravado
|
|
190
208
|
exclusivamente pelo orquestrador.
|
|
191
|
-
3.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
209
|
+
3. TESTE — a prova é do orquestrador (`morph-spec verify`), não sua.
|
|
210
|
+
Escreva os testes pelo orçamento: um por pós-condição, um de regressão
|
|
211
|
+
por bug, variantes numa tabela (`[Theory]`/`it.each`). NÃO rode teste a
|
|
212
|
+
cada marco nem faça ciclo red→green: escreva código e testes, compile, e
|
|
213
|
+
rode SÓ o filtro dos seus testes UMA vez, antes do relatório; se falhar,
|
|
214
|
+
corrija e rode só os que falharam. Não rode `morph-spec verify`.
|
|
215
|
+
- Batch SEM isolamento (working tree compartilhada): só compile —
|
|
216
|
+
edições concorrentes quebram o build umas das outras; o teste roda no
|
|
217
|
+
verify do orquestrador, pós-batch.
|
|
218
|
+
- Batch COM isolamento (você recebeu `isolation: "worktree"`): a regra
|
|
219
|
+
acima vale DENTRO do seu worktree; commite seu trabalho na branch do
|
|
220
|
+
worktree como último ato antes do relatório; reporte a branch — nunca
|
|
221
|
+
faça merge nem toque na árvore principal.
|
|
222
|
+
- Ao rodar: compile uma vez e rode sem recompilar (`dotnet test
|
|
223
|
+
--no-build`), com `--filter`. Grave a saída em arquivo uma vez
|
|
202
224
|
(`… > .morph/logs/test-last.log 2>&1`, sem nada depois) e leia o arquivo:
|
|
203
225
|
rodar de novo com outro `| tail`/`| grep` repete o teste para ver outras
|
|
204
226
|
linhas, e com pipe ou `; echo` o exit é o do último comando, não o do teste.
|
|
@@ -206,8 +228,8 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
206
228
|
4. ESCOPO: no máximo 3 tasks e ~4 arquivos por dispatch. Escopo maior falha e
|
|
207
229
|
volta — fatie antes, não depois.
|
|
208
230
|
5. SOBREVIVÊNCIA: o limite de turnos (`maxTurns`, no seu system prompt)
|
|
209
|
-
corta sem aviso: commite `wip({taskId})` a cada marco (arquivo
|
|
210
|
-
|
|
231
|
+
corta sem aviso: commite `wip({taskId})` a cada marco (um arquivo ou
|
|
232
|
+
uma fatia coerente escrita — sem rodar teste para isso), não só ao fim da task — e só os seus arquivos
|
|
211
233
|
(`git add <paths>`, nunca `-A`). Sem commit, a retomada recomeça do zero.
|
|
212
234
|
A ~70% do limite, grave o relatório parcial no arquivo canônico: `PARCIAL`
|
|
213
235
|
na 1ª linha, o feito e o que falta, sem auto-score. Depois siga ou pare,
|
|
@@ -217,6 +239,9 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
217
239
|
sessões). Encerre dev server pelo PID que você mesmo subiu.
|
|
218
240
|
7. RETORNO: o relatório no arquivo canônico é o retorno. `SendMessage` não é
|
|
219
241
|
substituto do relatório e não deve ser chamado.
|
|
242
|
+
8. MUTAÇÃO: nunca altere, reverta, mova ou apague código de produção para ver
|
|
243
|
+
um teste falhar (`sed`, `mv`, `git show HEAD:… >`, `git stash`, `git
|
|
244
|
+
checkout --`). A prova de que o teste morde é do avaliador no Gate 3.
|
|
220
245
|
|
|
221
246
|
Seu relatório final deve conter APENAS: (1) o que foi feito em 2-3
|
|
222
247
|
frases, (2) arquivos modificados, (3) problemas encontrados e como foram
|
|
@@ -239,11 +264,11 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
239
264
|
> re-despache só o que falta a partir do último `wip`. Nunca pontue nem marque `done` sobre um
|
|
240
265
|
> parcial.
|
|
241
266
|
|
|
242
|
-
> Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as **mesmas
|
|
267
|
+
> Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as **mesmas 8 cláusulas** do contrato do relatório final (relatório, estado, teste, escopo, sobrevivência, processos, retorno e mutação), os mesmos parágrafos de leitura/turnos e ferramentas e os mesmos 4 itens de relatório — racional completo em `MORPH.md` §6. A única diferença é que aqui múltiplos agentes rodam ao mesmo tempo, um por fluxo independente.
|
|
243
268
|
|
|
244
269
|
> **Alternativa quando os fluxos tocam os mesmos projetos/arquivos** (ex.: o mesmo csproj de testes compartilhado): siga a §3b-w abaixo em vez desta seção — despache com `isolation: "worktree"`, cada agente trabalha numa working tree própria e o orquestrador integra ao final.
|
|
245
270
|
|
|
246
|
-
|
|
271
|
+
**Batch SEM isolamento:** aguardar todos os agentes terminarem, depois **auditar os relatórios contra o trabalho** com `morph-spec report-check {feature} {T1} {T2} … --json` (os ids do batch: sem eles o modo feature só audita tasks já `done`, e as do batch ainda não estão) — determinístico e independente da palavra dos agentes; é o passo que pega tanto o relatório ausente quanto o `report-stale` (completo, porém gravado antes do fim do trabalho: o agente relatou cedo e continuou escrevendo). Em `report-stale`, **não re-despache** — leia o campo `observed` (writes reais do `events.jsonl`) e atualize o relatório a partir dele. Vereditos e ações: `MORPH.md` §6. Em seguida **ler** `.morph/features/{feature}/3-implement/reports/{taskId}.md` de cada task — é o valor de retorno autoritativo; a mensagem de texto do dispatch, se chegou inteira, é só um atalho que economiza essa leitura. Depois, sequencialmente:
|
|
247
272
|
- **Rodar `morph-spec verify {feature} --json` uma única vez, pós-batch** (escopo feature, **sem `--filter`**) — os agentes não a rodaram (cláusula 3). Vermelho: use `verify.feedback` para corrigir/redespachar ANTES de qualquer morph-eval. (Com isolamento por worktree, cada agente já rodou o verify dentro do seu worktree; o orquestrador roda o verify compartilhado UMA vez após o merge — ver §3b-w.)
|
|
248
273
|
- Para cada relatório retornado:
|
|
249
274
|
- Aplicar `Skill(morph-eval)`.
|
|
@@ -253,13 +278,22 @@ Aguardar todos os agentes terminarem, depois **auditar os relatórios contra o t
|
|
|
253
278
|
|
|
254
279
|
Depois do batch paralelo, executar o restante em modo sequencial (passo 3a).
|
|
255
280
|
|
|
281
|
+
**Batch COM isolamento (§3b-w): dispatch rolling, não por onda.** Nenhum agente escreve na
|
|
282
|
+
árvore principal, então o orquestrador não espera o batch inteiro: a cada relatório que chega,
|
|
283
|
+
audita (`report-check {feature} {taskId}`), integra aquela branch (§3b-w passo 2), roda
|
|
284
|
+
`verify {feature} {taskId}` e `morph-eval` + `score` daquela task, e **despacha na hora** toda
|
|
285
|
+
task que ficou `ready` (`getReadyTasks`) cujos `outputs` não colidem com os das tasks em voo —
|
|
286
|
+
o worktree nasce da branch da feature, já com o merge que acabou de entrar. Cap de 4 em voo. O
|
|
287
|
+
`verify {feature}` de escopo feature roda uma vez, quando nada mais está em voo. Medido: uma task
|
|
288
|
+
esperou 43 min pela onda depois de a dependência dela já estar pronta.
|
|
289
|
+
|
|
256
290
|
### 3b-w. Batch isolado por worktree (quando o dag recomenda)
|
|
257
291
|
|
|
258
292
|
Quando o `morph-spec dag {feature}` reporta `isolation.recommended: "worktree"` (dois fluxos paralelos planejam escrever no mesmo path — colisão de `outputs`), despache cada fluxo com o parâmetro `isolation: "worktree"` do tool Agent. Cada agente trabalha numa working tree própria; build/test rodam lá dentro sem colidir.
|
|
259
293
|
|
|
260
|
-
1. **Dispatch:** mesmo `subagent_type: "morph-{id}"` e standards de §3b, mais `isolation: "worktree"`. O worktree vem do hook `WorktreeCreate` do morph: nasce em `worktrees/<n>` na branch `morph-task/<n>`, com junctions (`node_modules`, `.claude`, `.morph/framework`) e `.morph/worktree.env` já prontos — se faltar infra mesmo assim, o agente roda `morph-spec worktree link --all` (fail-open); se ainda impossível, reporta "verificação: não executada" (o verify pós-merge cobre). Dev server/compose dentro do worktree já sai nas portas do bloco (o hook `worktree-env-inject` prefixa o comando; fora do Claude, `eval "$(morph-spec env)"`). O
|
|
261
|
-
2. **Integração (orquestrador,
|
|
262
|
-
3. **Pós-merge:**
|
|
294
|
+
1. **Dispatch:** mesmo `subagent_type: "morph-{id}"` e standards de §3b, mais `isolation: "worktree"`. O worktree vem do hook `WorktreeCreate` do morph: nasce em `worktrees/<n>` na branch `morph-task/<n>`, com junctions (`node_modules`, `.claude`, `.morph/framework`) e `.morph/worktree.env` já prontos — se faltar infra mesmo assim, o agente roda `morph-spec worktree link --all` (fail-open); se ainda impossível, reporta "verificação: não executada" (o verify pós-merge cobre). Dev server/compose dentro do worktree já sai nas portas do bloco (o hook `worktree-env-inject` prefixa o comando; fora do Claude, `eval "$(morph-spec env)"`). O worktree nasce da branch `morph/<feature>` quando a sessão está nela (o trabalho já integrado da feature vem junto, sem `merge` manual) e com os `.env*` da raiz copiados — o prompt de dispatch não manda o agente preparar nada disso. Sessão fora de `morph/<feature>` (orquestrador na raiz) faz o worktree nascer da default: aí, e só aí, o prompt abre com `git merge --ff-only morph/<feature>`. O agente commita na branch do worktree como último ato e reporta a branch. Ele não roda `morph-spec verify` (cláusula 3): a prova é o verify do orquestrador depois do merge.
|
|
295
|
+
2. **Integração (orquestrador, a cada relatório que chega):** faça o merge de cada branch reportada, uma por vez, na ordem de chegada — `git merge --no-ff <branch>`. Conflito → `git merge --abort`, marque a task de volta a `pending` com nota "merge conflict — reexecutar sequencial", siga para a próxima branch. Os paths em conflito são exatamente os de `isolation.collisions` do dag.
|
|
296
|
+
3. **Pós-merge:** `verify {feature} {taskId}` no merge de cada task (dispatch rolling, §3b), depois `morph-eval` + `morph-spec score`; `morph-spec verify {feature} --json` de escopo feature UMA vez, quando nada mais está em voo (o merge é o novo ponto de integração — verificação compartilhada obrigatória).
|
|
263
297
|
4. **Cleanup:** o hook `WorktreeRemove` remove o worktree **limpo** ao fim do subagent (branch sobrevive) — mas não conte com ele: rode `morph-spec worktree remove --target <path>` por worktree que sobrou (NUNCA `git worktree remove` cru — as junctions do passo 1 seriam atravessadas e o `node_modules`/`.claude` da raiz apagados) + `git branch -d morph-task/<n>` das branches integradas + `git worktree prune` (fail-open). Worktree sujo (subagent não commitou) fica, vira `unintegrated-work` no `doctor --worktrees`, e a task volta a `pending`. Branches não integradas ficam e são registradas no recap com o motivo.
|
|
264
298
|
5. **Agente morto no meio:** se commitou, a branch sobrevive (retomável); senão, a task volta a `pending` na lane sequencial. Registre a falha de protocolo no recap.
|
|
265
299
|
|
|
@@ -4,7 +4,7 @@ description: Entende o negócio, os usuários e a arquitetura antes de qualquer
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber um novo request de feature, antes de morph-plan
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -4,7 +4,7 @@ description: Avalia a qualidade de uma tarefa ou fase com rubricas graduadas 0-1
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao completar uma tarefa ou ao finalizar uma fase de implementação
|
|
6
6
|
user-invokable: false
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-eval
|
|
@@ -4,7 +4,7 @@ description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de prod
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber "/morph-hotfix {feature}", quando a morph-proposal classifica o pedido como workType hotfix (Passo 0), ou o usuário diz "produção caiu / hotfix / urgente"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.41.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-hotfix
|
|
@@ -43,7 +43,7 @@ subagent_type: "morph-scout"
|
|
|
43
43
|
|
|
44
44
|
**Fallback** (se `morph-scout` não estiver registrado nos subagent types deste projeto): `general-purpose` com o campo `persona` do agente `scout` colado no prompt, **registrando o fallback nas notes da task**.
|
|
45
45
|
|
|
46
|
-
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as
|
|
46
|
+
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as 8 cláusulas do contrato do relatório final no prompt (template literal em `morph-implement` §4 / `morph-apply` §3b): relatório no arquivo canônico como retorno, sem `SendMessage`; não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; sem build/test da suíte compartilhada em batch paralelo; no máximo 3 tasks por dispatch; commit `wip({taskId})` ao fim de cada task; nunca `taskkill /IM node.exe`; nunca mutar código de produção para ver teste falhar.
|
|
47
47
|
|
|
48
48
|
### 3. Hotfix brief (`0-proposal/proposal.md`)
|
|
49
49
|
|