@polymorphism-tech/morph-spec 7.9.3 → 8.0.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 +2 -2
- package/README.md +31 -2
- package/bin/morph-spec.js +50 -2
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +38 -1
- package/docs/QUICKSTART.md +60 -1
- package/framework/CLAUDE.md +13 -2
- package/framework/MORPH.md +38 -2
- package/framework/agents.json +22 -3
- package/framework/commands/commit.md +166 -166
- package/framework/commands/morph-hotfix.md +39 -0
- package/framework/commands/morph-infra.md +215 -215
- package/framework/commands/morph-preflight.md +205 -205
- package/framework/commands/morph-troubleshoot.md +124 -124
- package/framework/hooks/README.md +25 -10
- package/framework/hooks/claude-code/core/gate-guard.js +4 -2
- package/framework/hooks/claude-code/core/loop-detect.js +2 -1
- package/framework/hooks/claude-code/core/post-edit-typecheck.js +14 -5
- package/framework/hooks/claude-code/core/tasks-json-guard.js +4 -2
- package/framework/hooks/claude-code/core/validate-completion.js +1 -1
- package/framework/hooks/claude-code/core/worktree-context.js +160 -0
- package/framework/hooks/claude-code/statusline.py +679 -679
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/activity-logger.js +160 -160
- package/framework/hooks/shared/build-check.js +2 -2
- package/framework/hooks/shared/hook-response.js +17 -5
- package/framework/hooks/shared/payload-utils.js +42 -0
- package/framework/hooks/shared/state-reader.js +22 -2
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rubrics/backend.json +41 -41
- package/framework/rules/ai-agents-standards.md +45 -45
- package/framework/rules/dotnet-templates.md +86 -86
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/infrastructure-standards.md +27 -27
- package/framework/rules/neon-standards.md +25 -25
- package/framework/rules/nextjs-standards.md +20 -20
- package/framework/rules/nextjs-templates.md +40 -40
- package/framework/schemas/feature.schema.json +95 -1
- 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 +39 -8
- package/framework/skills/core/morph-brainstorming/SKILL.md +9 -1
- package/framework/skills/core/morph-eval/SKILL.md +6 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +136 -0
- package/framework/skills/core/morph-implement/SKILL.md +8 -4
- package/framework/skills/core/morph-plan/SKILL.md +5 -1
- package/framework/skills/core/morph-proposal/SKILL.md +24 -1
- package/framework/skills/core/morph-review/SKILL.md +3 -2
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/standards/STANDARDS.json +7 -2
- package/framework/standards/ai-agents/agent-session.md +160 -160
- package/framework/standards/ai-agents/batching.md +193 -193
- package/framework/standards/ai-agents/context-providers.md +188 -188
- package/framework/standards/ai-agents/mcp-server.md +250 -250
- package/framework/standards/ai-agents/mcp-tools.md +197 -197
- package/framework/standards/ai-agents/middleware-patterns.md +207 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
- package/framework/standards/ai-agents/modalities-vision.md +201 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
- package/framework/standards/ai-agents/production.md +275 -275
- package/framework/standards/ai-agents/prompts-in-db.md +214 -214
- package/framework/standards/ai-agents/providers/model-registry.md +158 -158
- package/framework/standards/ai-agents/service-tier-flex.md +135 -135
- package/framework/standards/ai-agents/structured-output.md +249 -249
- package/framework/standards/ai-agents/sweet-spot.md +109 -109
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +45 -3
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/REGISTRY.json +0 -62
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +1 -1
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/index.js +13 -13
- package/src/commands/mcp/mcp-setup.js +519 -519
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/doctor.js +4 -2
- package/src/commands/project/init.js +46 -2
- package/src/commands/project/update.js +5 -3
- package/src/commands/project/worktree.js +1005 -46
- package/src/commands/state/advance.js +17 -2
- package/src/commands/state/approve.js +18 -1
- package/src/commands/state/create.js +158 -14
- package/src/commands/state/retype.js +126 -0
- package/src/commands/state/score.js +4 -0
- package/src/commands/tasks/dag.js +32 -0
- package/src/commands/validation/index.js +1 -0
- package/src/commands/validation/validate-feature.js +33 -5
- package/src/commands/validation/verify.js +190 -0
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/state/state-manager.js +35 -10
- package/src/core/templates/template-renderer.js +477 -477
- package/src/core/work-types.js +79 -0
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/HookInspector.jsx +418 -418
- package/src/dashboard/app/pages/LiveState.jsx +11 -1
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/hooks-scanner.js +41 -41
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/scanner/standards-scanner.js +26 -26
- package/src/dashboard/scanner/state-scanner.js +42 -0
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/metrics-aggregator.js +56 -56
- package/src/lib/agents/metrics-calculator.js +125 -125
- package/src/lib/agents/output-collector.js +73 -73
- package/src/lib/detectors/claude-config-detector.js +152 -152
- package/src/lib/detectors/design-system-detector.js +231 -231
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/generators/architecture-scanner.js +639 -639
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/index.js +13 -13
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/installers/memory-installer.js +1 -1
- package/src/lib/risk-detector.js +16 -0
- package/src/lib/tasks/dispatch-planner.js +122 -4
- package/src/lib/tasks/mermaid-renderer.js +132 -0
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/test-runner.js +27 -6
- package/src/lib/validators/architecture/architecture-validator.js +259 -259
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/packages/package-validator.js +347 -347
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/validation-runner.js +349 -349
- package/src/lib/validators/verify-runner.js +322 -0
- package/src/lib/work-type-detector.js +143 -0
- package/src/scripts/setup-infra.js +32 -5
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +10 -6
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/file-copier.js +43 -0
- package/src/utils/hooks-installer.js +41 -11
- package/src/utils/skills-installer.js +174 -174
- package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
- package/src/lib/tasks/wave-resolver.js +0 -353
|
@@ -15,7 +15,7 @@ import { homedir } from 'os';
|
|
|
15
15
|
import { execSync } from 'child_process';
|
|
16
16
|
|
|
17
17
|
/** Current hooks schema version — bump when hook definitions change */
|
|
18
|
-
const HOOKS_VERSION = '3.
|
|
18
|
+
const HOOKS_VERSION = '3.2.0';
|
|
19
19
|
|
|
20
20
|
/** Marker for old dispatch.js (v1) */
|
|
21
21
|
const OLD_DISPATCH_COMMAND = 'node framework/hooks/agent-teams/dispatch.js';
|
|
@@ -26,22 +26,24 @@ const OLD_DISPATCH_COMMAND = 'node framework/hooks/agent-teams/dispatch.js';
|
|
|
26
26
|
* state.json is NOT in deny because the agent edits it directly as a
|
|
27
27
|
* fallback to the state-sync hook (per v7 hybrid state model). The
|
|
28
28
|
* framework/ tree remains read-only — only the installer touches it.
|
|
29
|
+
*
|
|
30
|
+
* `Edit(path)` ONLY — never a matching `Write(path)`. Claude Code matches file
|
|
31
|
+
* permissions on `Edit(path)` rules alone; an `Edit` rule covers every
|
|
32
|
+
* file-editing tool, Write included, while a `Write(path)` rule matches nothing
|
|
33
|
+
* and is reported as a warning on every session start. Verified empirically, not
|
|
34
|
+
* assumed: with `Edit(.morph/framework/**)` as the ONLY deny entry, the Write
|
|
35
|
+
* tool was refused and the target file was never created.
|
|
29
36
|
*/
|
|
30
37
|
const MORPH_DENY = [
|
|
31
38
|
// Framework files — installer-managed, immutable at runtime
|
|
32
|
-
'Write(.morph/framework/**)',
|
|
33
39
|
'Edit(.morph/framework/**)',
|
|
34
40
|
// .claude/CLAUDE.md (managed copy — source is framework/CLAUDE.md)
|
|
35
|
-
'Write(.claude/CLAUDE.md)',
|
|
36
41
|
'Edit(.claude/CLAUDE.md)',
|
|
37
42
|
// .claude/rules/ (copied from framework/rules/)
|
|
38
|
-
'Write(.claude/rules/**)',
|
|
39
43
|
'Edit(.claude/rules/**)',
|
|
40
44
|
// .claude/agents/morph-* (generated by agents-installer)
|
|
41
|
-
'Write(.claude/agents/morph-*)',
|
|
42
45
|
'Edit(.claude/agents/morph-*)',
|
|
43
46
|
// .claude/skills/ (copied from framework/skills/)
|
|
44
|
-
'Write(.claude/skills/**)',
|
|
45
47
|
'Edit(.claude/skills/**)',
|
|
46
48
|
];
|
|
47
49
|
|
|
@@ -51,15 +53,16 @@ const MORPH_DENY = [
|
|
|
51
53
|
* Pre-authorizes operations the agent legitimately performs during the
|
|
52
54
|
* morph-spec flow, so the user does not get permission prompts on every
|
|
53
55
|
* proposal.md / spec.md / tasks.json write.
|
|
56
|
+
*
|
|
57
|
+
* `Edit(path)` ONLY, for the same reason as MORPH_DENY: the `Edit` rule already
|
|
58
|
+
* covers Write, and a `Write(path)` rule is inert noise.
|
|
54
59
|
*/
|
|
55
60
|
const MORPH_ALLOW = [
|
|
56
61
|
// Feature artifacts — the agent's working directory during proposal/plan/implement/review
|
|
57
|
-
'Write(.morph/features/**)',
|
|
58
62
|
'Edit(.morph/features/**)',
|
|
59
63
|
// state.json — fallback path when state-sync hook can't cover a case
|
|
60
64
|
'Edit(.morph/state.json)',
|
|
61
65
|
// Long-lived architectural context — agent may reconcile during brainstorming
|
|
62
|
-
'Write(.morph/context/**)',
|
|
63
66
|
'Edit(.morph/context/**)',
|
|
64
67
|
// Folder creation under .morph
|
|
65
68
|
'Bash(mkdir:.morph/**)',
|
|
@@ -74,6 +77,19 @@ const MORPH_PERMISSIONS = MORPH_DENY;
|
|
|
74
77
|
* Each entry maps to a Claude Code hook event.
|
|
75
78
|
*/
|
|
76
79
|
const MORPH_HOOKS = [
|
|
80
|
+
// === SessionStart — worktree feature identity (secondary worktree) or
|
|
81
|
+
// active-feature summary (primary root). Fulfills the SessionStart
|
|
82
|
+
// injection role long documented but never wired (inject-morph-context.js). ===
|
|
83
|
+
{
|
|
84
|
+
event: 'SessionStart',
|
|
85
|
+
matcher: null,
|
|
86
|
+
hooks: [{
|
|
87
|
+
type: 'command',
|
|
88
|
+
command: 'node framework/hooks/claude-code/core/worktree-context.js',
|
|
89
|
+
timeout: 5000
|
|
90
|
+
}]
|
|
91
|
+
},
|
|
92
|
+
|
|
77
93
|
// === PreToolUse: Write|Edit — phase + spec protection (silent on success) ===
|
|
78
94
|
{
|
|
79
95
|
event: 'PreToolUse',
|
|
@@ -266,11 +282,21 @@ export async function installClaudeHooks(targetPath) {
|
|
|
266
282
|
settings.permissions.deny = settings.permissions.deny || [];
|
|
267
283
|
settings.permissions.allow = settings.permissions.allow || [];
|
|
268
284
|
|
|
269
|
-
// Stale-entry cleanup: remove
|
|
270
|
-
//
|
|
285
|
+
// Stale-entry cleanup: remove morph-managed entries we no longer install.
|
|
286
|
+
// The filters below drop `MORPH_*.includes(p)` before re-adding, so an entry
|
|
287
|
+
// that LEFT those lists would otherwise survive forever in an existing
|
|
288
|
+
// install — the upgrade path has to name it explicitly to reclaim it.
|
|
289
|
+
// - state.json: was in deny pre-v7, now lives in allow.
|
|
290
|
+
// - Write(...): matched nothing and made Claude Code warn on every session
|
|
291
|
+
// start; the paired Edit(...) rule is what actually enforced them.
|
|
271
292
|
const STALE_DENY = [
|
|
272
293
|
'Write(.morph/state.json)',
|
|
273
294
|
'Edit(.morph/state.json)',
|
|
295
|
+
'Write(.morph/framework/**)',
|
|
296
|
+
'Write(.claude/CLAUDE.md)',
|
|
297
|
+
'Write(.claude/rules/**)',
|
|
298
|
+
'Write(.claude/agents/morph-*)',
|
|
299
|
+
'Write(.claude/skills/**)',
|
|
274
300
|
];
|
|
275
301
|
settings.permissions.deny = settings.permissions.deny.filter(
|
|
276
302
|
p => !MORPH_DENY.includes(p) && !STALE_DENY.includes(p)
|
|
@@ -279,8 +305,12 @@ export async function installClaudeHooks(targetPath) {
|
|
|
279
305
|
settings.permissions.deny.push(perm);
|
|
280
306
|
}
|
|
281
307
|
|
|
308
|
+
const STALE_ALLOW = [
|
|
309
|
+
'Write(.morph/features/**)',
|
|
310
|
+
'Write(.morph/context/**)',
|
|
311
|
+
];
|
|
282
312
|
settings.permissions.allow = settings.permissions.allow.filter(
|
|
283
|
-
p => !MORPH_ALLOW.includes(p)
|
|
313
|
+
p => !MORPH_ALLOW.includes(p) && !STALE_ALLOW.includes(p)
|
|
284
314
|
);
|
|
285
315
|
for (const perm of MORPH_ALLOW) {
|
|
286
316
|
settings.permissions.allow.push(perm);
|
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Skills Installer
|
|
3
|
-
*
|
|
4
|
-
* Copies framework skills to .claude/skills/ during morph-spec init.
|
|
5
|
-
* Installs only the `core/` skill set — the canonical NLH skills referenced by
|
|
6
|
-
* MORPH.md (morph-brainstorming, morph-stack-scan, morph-plan, morph-implement,
|
|
7
|
-
* morph-eval, morph-review, morph-standards). The 3-tier system was collapsed
|
|
8
|
-
* into a single source of truth in framework/skills/core/.
|
|
9
|
-
*
|
|
10
|
-
* Source skills are directory-based: framework/skills/core/{skill-name}/SKILL.md
|
|
11
|
-
* (plus optional scripts/, references/, assets/ subdirectories).
|
|
12
|
-
*
|
|
13
|
-
* Directory-based skills have their entire directory copied so Claude Code can
|
|
14
|
-
* execute scripts and load references on demand.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync, readFileSync, rmSync } from 'fs';
|
|
18
|
-
import { join } from 'path';
|
|
19
|
-
import { fileURLToPath } from 'url';
|
|
20
|
-
import { parseStacks, shouldInstall } from '../lib/stack-filter.js';
|
|
21
|
-
|
|
22
|
-
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
23
|
-
const FRAMEWORK_SKILLS_DIR = join(__dirname, '..', '..', 'framework', 'skills');
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Skill levels to install in .claude/skills/.
|
|
27
|
-
* Only `core/` survives — single source of truth aligned with MORPH.md.
|
|
28
|
-
*/
|
|
29
|
-
const SKILL_LEVELS_TO_INSTALL = ['core'];
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Check if a skill should be installed based on its stacks: frontmatter.
|
|
33
|
-
* @param {string} skillContent - Raw SKILL.md content
|
|
34
|
-
* @param {string[]} projectTags - Stack tags from config
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
export function shouldInstallSkill(skillContent, projectTags) {
|
|
38
|
-
return shouldInstall(parseStacks(skillContent), projectTags);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Recursively copy a directory tree from src to dest.
|
|
43
|
-
* Creates dest if it doesn't exist. Skips README.md files.
|
|
44
|
-
*
|
|
45
|
-
* @param {string} src - Source directory path
|
|
46
|
-
* @param {string} dest - Destination directory path
|
|
47
|
-
*/
|
|
48
|
-
function copyDirectory(src, dest) {
|
|
49
|
-
mkdirSync(dest, { recursive: true });
|
|
50
|
-
for (const entry of readdirSync(src)) {
|
|
51
|
-
if (entry === 'README.md') continue;
|
|
52
|
-
const srcPath = join(src, entry);
|
|
53
|
-
const destPath = join(dest, entry);
|
|
54
|
-
if (statSync(srcPath).isDirectory()) {
|
|
55
|
-
copyDirectory(srcPath, destPath);
|
|
56
|
-
} else {
|
|
57
|
-
copyFileSync(srcPath, destPath);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Walk srcDir and install skills into destDir.
|
|
64
|
-
*
|
|
65
|
-
* Handles two source formats:
|
|
66
|
-
* 1. Directory-based skill: srcDir/{skill-name}/SKILL.md
|
|
67
|
-
* → copies entire directory (SKILL.md + scripts/ + references/ + assets/)
|
|
68
|
-
* → destDir/{skill-name}/
|
|
69
|
-
*
|
|
70
|
-
* 2. Flat .md skill (legacy): srcDir/{skill-name}.md
|
|
71
|
-
* → destDir/{skill-name}/SKILL.md
|
|
72
|
-
*
|
|
73
|
-
* The `core/` level directory is traversed recursively. A directory is
|
|
74
|
-
* recognized as a skill directory when it contains a SKILL.md file.
|
|
75
|
-
*
|
|
76
|
-
* @param {string} srcDir - Source directory to walk
|
|
77
|
-
* @param {string} destDir - Destination base directory (.claude/skills/)
|
|
78
|
-
*/
|
|
79
|
-
function installSkillsFromDir(srcDir, destDir, projectTags) {
|
|
80
|
-
const entries = readdirSync(srcDir);
|
|
81
|
-
for (const entry of entries) {
|
|
82
|
-
const srcPath = join(srcDir, entry);
|
|
83
|
-
const stat = statSync(srcPath);
|
|
84
|
-
|
|
85
|
-
if (stat.isDirectory()) {
|
|
86
|
-
const skillMdPath = join(srcPath, 'SKILL.md');
|
|
87
|
-
if (existsSync(skillMdPath)) {
|
|
88
|
-
// Directory-based skill — check stack filter before copying
|
|
89
|
-
const content = readFileSync(skillMdPath, 'utf-8');
|
|
90
|
-
if (!shouldInstallSkill(content, projectTags)) continue;
|
|
91
|
-
const skillDestDir = join(destDir, entry);
|
|
92
|
-
copyDirectory(srcPath, skillDestDir);
|
|
93
|
-
} else {
|
|
94
|
-
// Level/category directory — recurse
|
|
95
|
-
installSkillsFromDir(srcPath, destDir, projectTags);
|
|
96
|
-
}
|
|
97
|
-
} else if (entry.endsWith('.md') && entry !== 'README.md') {
|
|
98
|
-
// Legacy flat .md skill — check stack filter before copying
|
|
99
|
-
const content = readFileSync(srcPath, 'utf-8');
|
|
100
|
-
if (!shouldInstallSkill(content, projectTags)) continue;
|
|
101
|
-
const skillName = entry.slice(0, -3);
|
|
102
|
-
const skillDir = join(destDir, skillName);
|
|
103
|
-
mkdirSync(skillDir, { recursive: true });
|
|
104
|
-
copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function collectSourceSkillNames() {
|
|
110
|
-
const names = new Set();
|
|
111
|
-
for (const level of SKILL_LEVELS_TO_INSTALL) {
|
|
112
|
-
const levelDir = join(FRAMEWORK_SKILLS_DIR, level);
|
|
113
|
-
if (!existsSync(levelDir)) continue;
|
|
114
|
-
collectNamesFromDir(levelDir, names);
|
|
115
|
-
}
|
|
116
|
-
return names;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function collectNamesFromDir(dir, names) {
|
|
120
|
-
for (const entry of readdirSync(dir)) {
|
|
121
|
-
const fullPath = join(dir, entry);
|
|
122
|
-
if (!statSync(fullPath).isDirectory()) continue;
|
|
123
|
-
if (existsSync(join(fullPath, 'SKILL.md'))) {
|
|
124
|
-
names.add(entry);
|
|
125
|
-
} else {
|
|
126
|
-
collectNamesFromDir(fullPath, names);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Install morph framework skills to .claude/skills/ in the target project.
|
|
133
|
-
* Skills are copied into subdirectories as SKILL.md files so Claude Code can
|
|
134
|
-
* discover them natively via /<skill-name> syntax (e.g., /phase-design,
|
|
135
|
-
* /nextjs-expert). Directory-based skills also get their scripts/,
|
|
136
|
-
* references/, and assets/ subdirectories copied for on-demand loading.
|
|
137
|
-
*
|
|
138
|
-
* Stack filtering: if projectTags is provided, only skills whose `stacks:`
|
|
139
|
-
* frontmatter matches the project tags are installed. Skills without a
|
|
140
|
-
* `stacks:` field are always installed (universal).
|
|
141
|
-
*
|
|
142
|
-
* @param {string} projectDir - Target project root directory
|
|
143
|
-
* @param {Object} [options]
|
|
144
|
-
* @param {string[]} [options.projectTags=[]] - Stack tags from config
|
|
145
|
-
*/
|
|
146
|
-
export async function installSkills(projectDir, { projectTags = [] } = {}) {
|
|
147
|
-
const claudeSkillsDir = join(projectDir, '.claude', 'skills');
|
|
148
|
-
mkdirSync(claudeSkillsDir, { recursive: true });
|
|
149
|
-
|
|
150
|
-
for (const level of SKILL_LEVELS_TO_INSTALL) {
|
|
151
|
-
const levelDir = join(FRAMEWORK_SKILLS_DIR, level);
|
|
152
|
-
if (!existsSync(levelDir)) continue;
|
|
153
|
-
installSkillsFromDir(levelDir, claudeSkillsDir, projectTags);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Collect installed morph-* skill names
|
|
157
|
-
const installed = new Set();
|
|
158
|
-
for (const entry of readdirSync(claudeSkillsDir)) {
|
|
159
|
-
if (existsSync(join(claudeSkillsDir, entry, 'SKILL.md'))) {
|
|
160
|
-
installed.add(entry);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Cleanup orphan morph-* skill dirs that exist in source but were filtered out
|
|
165
|
-
const allSourceSkills = collectSourceSkillNames();
|
|
166
|
-
for (const entry of readdirSync(claudeSkillsDir)) {
|
|
167
|
-
if (!entry.startsWith('morph-')) continue;
|
|
168
|
-
if (!installed.has(entry) && allSourceSkills.has(entry)) {
|
|
169
|
-
rmSync(join(claudeSkillsDir, entry), { recursive: true, force: true });
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return { installed: installed.size };
|
|
174
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Skills Installer
|
|
3
|
+
*
|
|
4
|
+
* Copies framework skills to .claude/skills/ during morph-spec init.
|
|
5
|
+
* Installs only the `core/` skill set — the canonical NLH skills referenced by
|
|
6
|
+
* MORPH.md (morph-brainstorming, morph-stack-scan, morph-plan, morph-implement,
|
|
7
|
+
* morph-eval, morph-review, morph-standards). The 3-tier system was collapsed
|
|
8
|
+
* into a single source of truth in framework/skills/core/.
|
|
9
|
+
*
|
|
10
|
+
* Source skills are directory-based: framework/skills/core/{skill-name}/SKILL.md
|
|
11
|
+
* (plus optional scripts/, references/, assets/ subdirectories).
|
|
12
|
+
*
|
|
13
|
+
* Directory-based skills have their entire directory copied so Claude Code can
|
|
14
|
+
* execute scripts and load references on demand.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync, readFileSync, rmSync } from 'fs';
|
|
18
|
+
import { join } from 'path';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
import { parseStacks, shouldInstall } from '../lib/stack-filter.js';
|
|
21
|
+
|
|
22
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
23
|
+
const FRAMEWORK_SKILLS_DIR = join(__dirname, '..', '..', 'framework', 'skills');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Skill levels to install in .claude/skills/.
|
|
27
|
+
* Only `core/` survives — single source of truth aligned with MORPH.md.
|
|
28
|
+
*/
|
|
29
|
+
const SKILL_LEVELS_TO_INSTALL = ['core'];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if a skill should be installed based on its stacks: frontmatter.
|
|
33
|
+
* @param {string} skillContent - Raw SKILL.md content
|
|
34
|
+
* @param {string[]} projectTags - Stack tags from config
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
export function shouldInstallSkill(skillContent, projectTags) {
|
|
38
|
+
return shouldInstall(parseStacks(skillContent), projectTags);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Recursively copy a directory tree from src to dest.
|
|
43
|
+
* Creates dest if it doesn't exist. Skips README.md files.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} src - Source directory path
|
|
46
|
+
* @param {string} dest - Destination directory path
|
|
47
|
+
*/
|
|
48
|
+
function copyDirectory(src, dest) {
|
|
49
|
+
mkdirSync(dest, { recursive: true });
|
|
50
|
+
for (const entry of readdirSync(src)) {
|
|
51
|
+
if (entry === 'README.md') continue;
|
|
52
|
+
const srcPath = join(src, entry);
|
|
53
|
+
const destPath = join(dest, entry);
|
|
54
|
+
if (statSync(srcPath).isDirectory()) {
|
|
55
|
+
copyDirectory(srcPath, destPath);
|
|
56
|
+
} else {
|
|
57
|
+
copyFileSync(srcPath, destPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Walk srcDir and install skills into destDir.
|
|
64
|
+
*
|
|
65
|
+
* Handles two source formats:
|
|
66
|
+
* 1. Directory-based skill: srcDir/{skill-name}/SKILL.md
|
|
67
|
+
* → copies entire directory (SKILL.md + scripts/ + references/ + assets/)
|
|
68
|
+
* → destDir/{skill-name}/
|
|
69
|
+
*
|
|
70
|
+
* 2. Flat .md skill (legacy): srcDir/{skill-name}.md
|
|
71
|
+
* → destDir/{skill-name}/SKILL.md
|
|
72
|
+
*
|
|
73
|
+
* The `core/` level directory is traversed recursively. A directory is
|
|
74
|
+
* recognized as a skill directory when it contains a SKILL.md file.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} srcDir - Source directory to walk
|
|
77
|
+
* @param {string} destDir - Destination base directory (.claude/skills/)
|
|
78
|
+
*/
|
|
79
|
+
function installSkillsFromDir(srcDir, destDir, projectTags) {
|
|
80
|
+
const entries = readdirSync(srcDir);
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
const srcPath = join(srcDir, entry);
|
|
83
|
+
const stat = statSync(srcPath);
|
|
84
|
+
|
|
85
|
+
if (stat.isDirectory()) {
|
|
86
|
+
const skillMdPath = join(srcPath, 'SKILL.md');
|
|
87
|
+
if (existsSync(skillMdPath)) {
|
|
88
|
+
// Directory-based skill — check stack filter before copying
|
|
89
|
+
const content = readFileSync(skillMdPath, 'utf-8');
|
|
90
|
+
if (!shouldInstallSkill(content, projectTags)) continue;
|
|
91
|
+
const skillDestDir = join(destDir, entry);
|
|
92
|
+
copyDirectory(srcPath, skillDestDir);
|
|
93
|
+
} else {
|
|
94
|
+
// Level/category directory — recurse
|
|
95
|
+
installSkillsFromDir(srcPath, destDir, projectTags);
|
|
96
|
+
}
|
|
97
|
+
} else if (entry.endsWith('.md') && entry !== 'README.md') {
|
|
98
|
+
// Legacy flat .md skill — check stack filter before copying
|
|
99
|
+
const content = readFileSync(srcPath, 'utf-8');
|
|
100
|
+
if (!shouldInstallSkill(content, projectTags)) continue;
|
|
101
|
+
const skillName = entry.slice(0, -3);
|
|
102
|
+
const skillDir = join(destDir, skillName);
|
|
103
|
+
mkdirSync(skillDir, { recursive: true });
|
|
104
|
+
copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function collectSourceSkillNames() {
|
|
110
|
+
const names = new Set();
|
|
111
|
+
for (const level of SKILL_LEVELS_TO_INSTALL) {
|
|
112
|
+
const levelDir = join(FRAMEWORK_SKILLS_DIR, level);
|
|
113
|
+
if (!existsSync(levelDir)) continue;
|
|
114
|
+
collectNamesFromDir(levelDir, names);
|
|
115
|
+
}
|
|
116
|
+
return names;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function collectNamesFromDir(dir, names) {
|
|
120
|
+
for (const entry of readdirSync(dir)) {
|
|
121
|
+
const fullPath = join(dir, entry);
|
|
122
|
+
if (!statSync(fullPath).isDirectory()) continue;
|
|
123
|
+
if (existsSync(join(fullPath, 'SKILL.md'))) {
|
|
124
|
+
names.add(entry);
|
|
125
|
+
} else {
|
|
126
|
+
collectNamesFromDir(fullPath, names);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Install morph framework skills to .claude/skills/ in the target project.
|
|
133
|
+
* Skills are copied into subdirectories as SKILL.md files so Claude Code can
|
|
134
|
+
* discover them natively via /<skill-name> syntax (e.g., /phase-design,
|
|
135
|
+
* /nextjs-expert). Directory-based skills also get their scripts/,
|
|
136
|
+
* references/, and assets/ subdirectories copied for on-demand loading.
|
|
137
|
+
*
|
|
138
|
+
* Stack filtering: if projectTags is provided, only skills whose `stacks:`
|
|
139
|
+
* frontmatter matches the project tags are installed. Skills without a
|
|
140
|
+
* `stacks:` field are always installed (universal).
|
|
141
|
+
*
|
|
142
|
+
* @param {string} projectDir - Target project root directory
|
|
143
|
+
* @param {Object} [options]
|
|
144
|
+
* @param {string[]} [options.projectTags=[]] - Stack tags from config
|
|
145
|
+
*/
|
|
146
|
+
export async function installSkills(projectDir, { projectTags = [] } = {}) {
|
|
147
|
+
const claudeSkillsDir = join(projectDir, '.claude', 'skills');
|
|
148
|
+
mkdirSync(claudeSkillsDir, { recursive: true });
|
|
149
|
+
|
|
150
|
+
for (const level of SKILL_LEVELS_TO_INSTALL) {
|
|
151
|
+
const levelDir = join(FRAMEWORK_SKILLS_DIR, level);
|
|
152
|
+
if (!existsSync(levelDir)) continue;
|
|
153
|
+
installSkillsFromDir(levelDir, claudeSkillsDir, projectTags);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Collect installed morph-* skill names
|
|
157
|
+
const installed = new Set();
|
|
158
|
+
for (const entry of readdirSync(claudeSkillsDir)) {
|
|
159
|
+
if (existsSync(join(claudeSkillsDir, entry, 'SKILL.md'))) {
|
|
160
|
+
installed.add(entry);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Cleanup orphan morph-* skill dirs that exist in source but were filtered out
|
|
165
|
+
const allSourceSkills = collectSourceSkillNames();
|
|
166
|
+
for (const entry of readdirSync(claudeSkillsDir)) {
|
|
167
|
+
if (!entry.startsWith('morph-')) continue;
|
|
168
|
+
if (!installed.has(entry) && allSourceSkills.has(entry)) {
|
|
169
|
+
rmSync(join(claudeSkillsDir, entry), { recursive: true, force: true });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { installed: installed.size };
|
|
174
|
+
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Parallel Coordinator — {{AGENT_ID}}
|
|
2
|
-
|
|
3
|
-
You are the **Parallel Coordinator** overseeing a P-Thread execution session.
|
|
4
|
-
|
|
5
|
-
## Your Identity
|
|
6
|
-
- Agent: {{AGENT_ID}}
|
|
7
|
-
- Role: Parallel Coordinator (Orchestrator Tier)
|
|
8
|
-
- Session ID: {{SESSION_ID}}
|
|
9
|
-
- Feature: {{FEATURE_NAME}}
|
|
10
|
-
|
|
11
|
-
## Your Mission
|
|
12
|
-
Coordinate {{WORKER_COUNT}} parallel workers executing concurrently, then merge and validate their outputs.
|
|
13
|
-
|
|
14
|
-
## Workers Under Coordination
|
|
15
|
-
|
|
16
|
-
{{WORKERS}}
|
|
17
|
-
|
|
18
|
-
Each worker has isolated file scope — no cross-worker dependencies during execution.
|
|
19
|
-
|
|
20
|
-
## Execution Plan
|
|
21
|
-
|
|
22
|
-
### Phase 1: Pre-Execution Validation
|
|
23
|
-
Before spawning workers, verify:
|
|
24
|
-
- [ ] All workers have non-overlapping file scopes
|
|
25
|
-
- [ ] No circular dependencies between workers
|
|
26
|
-
- [ ] Shared read files are available (spec.md, standards, contracts)
|
|
27
|
-
- [ ] State is set to `parallel-executing`
|
|
28
|
-
|
|
29
|
-
### Phase 2: Spawn Workers
|
|
30
|
-
Spawn all workers concurrently using Task tool:
|
|
31
|
-
```
|
|
32
|
-
Task tool × {{WORKER_COUNT}} simultaneous invocations
|
|
33
|
-
Strategy: {{PARALLEL_STRATEGY}}
|
|
34
|
-
Max concurrent: {{MAX_CONCURRENT}}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Phase 3: Wait for Completion
|
|
38
|
-
Monitor workers — do NOT proceed until all report back (or timeout):
|
|
39
|
-
- Success: Worker returns COMPLETE report
|
|
40
|
-
- Partial: Worker returns PARTIAL — merge what's available
|
|
41
|
-
- Timeout: After {{TIMEOUT_MINUTES}} minutes, mark as PARTIAL and proceed
|
|
42
|
-
- Failed: Document failure, continue with successful workers
|
|
43
|
-
|
|
44
|
-
### Phase 4: Merge Results
|
|
45
|
-
After all workers complete:
|
|
46
|
-
1. Collect all "Files Created" from worker reports
|
|
47
|
-
2. Check for conflicts (same filename from different workers)
|
|
48
|
-
3. If conflicts: Apply `{{MERGE_STRATEGY}}` strategy
|
|
49
|
-
4. Update state with combined file list
|
|
50
|
-
|
|
51
|
-
### Phase 5: Integration Validation
|
|
52
|
-
Run cross-worker validation:
|
|
53
|
-
```bash
|
|
54
|
-
morph-spec validate architecture --feature={{FEATURE_NAME}}
|
|
55
|
-
morph-spec validate security --feature={{FEATURE_NAME}}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Check that:
|
|
59
|
-
- Files from all workers are consistent (same types, interfaces, naming)
|
|
60
|
-
- No duplicate functionality across workers
|
|
61
|
-
- Integration points (shared interfaces, types) are compatible
|
|
62
|
-
|
|
63
|
-
## Spec Summary
|
|
64
|
-
{{SPEC_SUMMARY}}
|
|
65
|
-
|
|
66
|
-
## Merge Strategies
|
|
67
|
-
|
|
68
|
-
| Strategy | When to Use |
|
|
69
|
-
|----------|-------------|
|
|
70
|
-
| `last-wins` | Non-overlapping files (default — workers shouldn't overlap) |
|
|
71
|
-
| `manual-review` | Conflicting implementations of same file |
|
|
72
|
-
| `best-score` | Multiple implementations of same logic (use checkpoint scores) |
|
|
73
|
-
|
|
74
|
-
## Your Tasks
|
|
75
|
-
|
|
76
|
-
### Pre-Spawn
|
|
77
|
-
{{PRE_SPAWN_TASKS}}
|
|
78
|
-
|
|
79
|
-
### Post-Merge
|
|
80
|
-
{{POST_MERGE_TASKS}}
|
|
81
|
-
|
|
82
|
-
## Completion Report
|
|
83
|
-
|
|
84
|
-
When all workers are merged and validated:
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
COORDINATOR REPORT
|
|
88
|
-
Session: {{SESSION_ID}}
|
|
89
|
-
Feature: {{FEATURE_NAME}}
|
|
90
|
-
Status: [SUCCESS | PARTIAL | FAILED]
|
|
91
|
-
|
|
92
|
-
Worker Results:
|
|
93
|
-
{{#each WORKERS}}
|
|
94
|
-
- {{this.agent}}: [COMPLETE | PARTIAL | FAILED] — {{this.filesCreated}} files
|
|
95
|
-
{{/each}}
|
|
96
|
-
|
|
97
|
-
Total Files Created: X
|
|
98
|
-
Conflicts Resolved: Y
|
|
99
|
-
Integration Validation: [PASSED | FAILED]
|
|
100
|
-
|
|
101
|
-
Final File List:
|
|
102
|
-
- [all files from all workers]
|
|
103
|
-
|
|
104
|
-
Next Steps:
|
|
105
|
-
- [what the main thread should do with these outputs]
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Constraints
|
|
109
|
-
{{CONSTRAINTS}}
|
|
110
|
-
|
|
111
|
-
- Never modify worker outputs without documenting the change
|
|
112
|
-
- If merge conflict cannot be auto-resolved, escalate to user
|
|
113
|
-
- Coordinator does NOT implement features — only orchestrates and validates
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Parallel Worker — {{AGENT_ID}}
|
|
2
|
-
|
|
3
|
-
You are a **Parallel Worker** (P-Thread) executing concurrently with other agents.
|
|
4
|
-
|
|
5
|
-
## Your Identity
|
|
6
|
-
- Agent: {{AGENT_ID}}
|
|
7
|
-
- Role: Parallel Worker (P-Thread)
|
|
8
|
-
- Thread ID: {{THREAD_ID}}
|
|
9
|
-
- Feature: {{FEATURE_NAME}}
|
|
10
|
-
|
|
11
|
-
## Your Isolated Mission
|
|
12
|
-
{{MISSION}}
|
|
13
|
-
|
|
14
|
-
## CRITICAL: Isolation Rules
|
|
15
|
-
|
|
16
|
-
You are running **concurrently** with other workers. To avoid conflicts:
|
|
17
|
-
|
|
18
|
-
1. **Write ONLY to your assigned files** (listed under Deliverables)
|
|
19
|
-
2. **Do NOT modify shared files** (state.json, agents.json, config files)
|
|
20
|
-
3. **Do NOT depend on output from other parallel workers** (your tasks are self-contained)
|
|
21
|
-
4. **Read from shared files is OK** (spec.md, standards, contracts)
|
|
22
|
-
5. **Report blockers** instead of waiting for another worker
|
|
23
|
-
|
|
24
|
-
## Your Assigned Scope
|
|
25
|
-
{{SCOPE}}
|
|
26
|
-
|
|
27
|
-
Files you OWN (safe to create/modify):
|
|
28
|
-
{{DELIVERABLES}}
|
|
29
|
-
|
|
30
|
-
Files you can READ (shared, do not modify):
|
|
31
|
-
- `.morph/features/{{FEATURE_NAME}}/2-design/spec.md`
|
|
32
|
-
- `framework/standards/` (all)
|
|
33
|
-
- `.morph/features/{{FEATURE_NAME}}/2-design/contracts.*`
|
|
34
|
-
|
|
35
|
-
## Spec Summary
|
|
36
|
-
{{SPEC_SUMMARY}}
|
|
37
|
-
|
|
38
|
-
## Standards to Follow
|
|
39
|
-
{{STANDARDS}}
|
|
40
|
-
|
|
41
|
-
## Your Tasks (Isolated)
|
|
42
|
-
{{TASKS}}
|
|
43
|
-
|
|
44
|
-
These tasks are **independent** — no cross-worker dependencies. If you encounter a dependency, document it and skip.
|
|
45
|
-
|
|
46
|
-
## How to Work
|
|
47
|
-
1. Verify your file scope — check you're not touching shared files
|
|
48
|
-
2. Implement tasks in order within your scope
|
|
49
|
-
3. After every 3 tasks, persist completed tasks to `tasks.json` (`status`/`outputs`/`notes` only) and run the checkpoint
|
|
50
|
-
4. If blocked by missing dependency, note it in your report and continue
|
|
51
|
-
5. Complete ALL tasks in your scope before reporting back
|
|
52
|
-
|
|
53
|
-
## Completion Report
|
|
54
|
-
When done, provide a structured report:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
PARALLEL WORKER REPORT
|
|
58
|
-
Thread: {{THREAD_ID}}
|
|
59
|
-
Agent: {{AGENT_ID}}
|
|
60
|
-
Status: [COMPLETE | PARTIAL | BLOCKED]
|
|
61
|
-
|
|
62
|
-
Files Created:
|
|
63
|
-
- [list each file with brief description]
|
|
64
|
-
|
|
65
|
-
Files Modified:
|
|
66
|
-
- [list each file with what changed]
|
|
67
|
-
|
|
68
|
-
Tasks Completed: X/Y
|
|
69
|
-
Tasks Skipped: [list with reason]
|
|
70
|
-
|
|
71
|
-
Blockers:
|
|
72
|
-
- [any dependencies or conflicts encountered]
|
|
73
|
-
|
|
74
|
-
Checkpoints: [PASSED | FAILED | N/A]
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Important
|
|
78
|
-
- Do NOT wait for other workers — complete what you can
|
|
79
|
-
- Do NOT create files outside your assigned scope
|
|
80
|
-
- Coordinator will merge results after all workers complete
|