@polymorphism-tech/morph-spec 4.2.0 → 4.3.1
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 +108 -946
- package/bin/morph-spec.js +284 -9
- package/bin/task-manager.cjs +102 -14
- package/bin/validate.js +4 -4
- package/docs/{v3.0 → next-generation}/AGENTS.md +1 -1
- package/docs/next-generation/CONTEXT-OPTIMIZATION.md +267 -0
- package/docs/next-generation/EXECUTION-FLOW.md +274 -0
- package/docs/next-generation/META-PROMPTS.md +235 -0
- package/docs/next-generation/MIGRATION-GUIDE.md +253 -0
- package/docs/next-generation/THREAD-MANAGEMENT.md +240 -0
- package/package.json +5 -5
- package/src/commands/agents/agents-fuse.js +97 -0
- package/src/commands/agents/micro-agent.js +112 -0
- package/src/commands/agents/spawn-team.js +69 -4
- package/src/commands/agents/squad-template.js +146 -0
- package/src/commands/analytics/analytics.js +176 -0
- package/src/commands/context/context-prime.js +63 -0
- package/src/commands/context/core-four.js +54 -0
- package/src/commands/mcp/mcp.js +102 -0
- package/src/commands/project/detect-agents.js +32 -2
- package/src/commands/project/detect.js +11 -1
- package/src/commands/project/doctor.js +573 -356
- package/src/commands/project/init.js +9 -2
- package/src/commands/project/update.js +13 -3
- package/src/commands/state/advance-phase.js +448 -416
- package/src/commands/state/state.js +14 -12
- package/src/commands/tasks/task.js +1 -1
- package/src/commands/templates/template-render.js +80 -1
- package/src/commands/threads/thread-template.js +103 -0
- package/src/commands/threads/threads.js +261 -0
- package/src/commands/trust/trust.js +205 -0
- package/src/{orchestrator.js → core/orchestrator.js} +8 -8
- package/src/core/state/state-manager.js +37 -17
- package/src/core/workflows/workflow-detector.js +114 -3
- package/src/lib/agents/micro-agent-factory.js +161 -0
- package/src/lib/analytics/analytics-engine.js +345 -0
- package/src/lib/checkpoints/checkpoint-hooks.js +298 -258
- package/src/lib/context/context-bundler.js +240 -0
- package/src/lib/context/context-optimizer.js +212 -0
- package/src/lib/context/context-tracker.js +273 -0
- package/src/lib/context/core-four-tracker.js +201 -0
- package/src/lib/context/mcp-optimizer.js +200 -0
- package/src/lib/detectors/index.js +1 -1
- package/src/lib/detectors/standards-generator.js +77 -17
- package/src/lib/detectors/structure-detector.js +67 -39
- package/src/lib/execution/fusion-executor.js +304 -0
- package/src/lib/execution/parallel-executor.js +270 -0
- package/src/lib/generators/context-generator.js +3 -3
- package/src/lib/generators/recap-generator.js +32 -12
- package/src/lib/hooks/hook-executor.js +169 -0
- package/src/lib/hooks/stop-hook-executor.js +286 -0
- package/src/lib/hops/hop-composer.js +221 -0
- package/src/lib/threads/thread-coordinator.js +238 -0
- package/src/lib/threads/thread-manager.js +317 -0
- package/src/lib/tracking/artifact-trail.js +202 -0
- package/src/lib/trust/trust-manager.js +269 -0
- package/src/lib/validators/design-system/design-system-validator.js +2 -2
- package/src/lib/validators/validation-runner.js +14 -30
- package/src/utils/hooks-installer.js +69 -0
- package/stacks/blazor-azure/.morph/config/agents.json +72 -3
- package/stacks/nextjs-supabase/.morph/config/agents.json +3 -3
- package/docs/llm-interaction-config.md +0 -735
- package/docs/v3.0/EXECUTION-FLOW.md +0 -1304
- package/src/commands/utils/migrate-state.js +0 -158
- package/src/commands/utils/upgrade.js +0 -346
- package/src/lib/validators/architecture-validator.js +0 -60
- package/src/lib/validators/content-validator.js +0 -164
- package/src/lib/validators/package-validator.js +0 -61
- package/src/lib/validators/ui-contrast-validator.js +0 -44
- package/stacks/blazor-azure/.claude/commands/morph-apply.md +0 -221
- package/stacks/blazor-azure/.claude/commands/morph-archive.md +0 -79
- package/stacks/blazor-azure/.claude/commands/morph-deploy.md +0 -529
- package/stacks/blazor-azure/.claude/commands/morph-infra.md +0 -209
- package/stacks/blazor-azure/.claude/commands/morph-preflight.md +0 -227
- package/stacks/blazor-azure/.claude/commands/morph-proposal.md +0 -122
- package/stacks/blazor-azure/.claude/commands/morph-status.md +0 -86
- package/stacks/blazor-azure/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/blazor-azure/.claude/skills/level-0-meta/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-0-meta/code-review.md +0 -226
- package/stacks/blazor-azure/.claude/skills/level-0-meta/morph-checklist.md +0 -117
- package/stacks/blazor-azure/.claude/skills/level-0-meta/simulation-checklist.md +0 -77
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/morph-replicate.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-clarify.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-design.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-setup.md +0 -106
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-tasks.md +0 -164
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-uiux.md +0 -169
- package/stacks/blazor-azure/.claude/skills/level-2-domains/README.md +0 -14
- package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -192
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -197
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -189
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -320
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -156
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +0 -59
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -77
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -58
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -45
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -210
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -154
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -191
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -699
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -130
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -108
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +0 -64
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/resend-email.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -235
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-3-technologies/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-4-patterns/README.md +0 -7
- package/stacks/blazor-azure/.morph/archive/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/features/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/schemas/agent.schema.json +0 -296
- package/stacks/blazor-azure/.morph/schemas/tasks.schema.json +0 -220
- package/stacks/blazor-azure/.morph/specs/.gitkeep +0 -20
- package/stacks/blazor-azure/.morph/test-infra/example.bicep +0 -59
- package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +0 -221
- package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +0 -79
- package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +0 -529
- package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +0 -209
- package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +0 -227
- package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +0 -122
- package/stacks/nextjs-supabase/.claude/commands/morph-status.md +0 -86
- package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/nextjs-supabase/.claude/settings.local.json +0 -6
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +0 -244
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +0 -335
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +0 -189
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +0 -50
- /package/docs/{v3.0 → next-generation}/ANALYSIS.md +0 -0
- /package/docs/{v3.0 → next-generation}/ARCHITECTURE.md +0 -0
- /package/docs/{v3.0 → next-generation}/FEATURES.md +0 -0
- /package/docs/{v3.0 → next-generation}/README.md +0 -0
- /package/docs/{v3.0 → next-generation}/ROADMAP.md +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Thread Management — MORPH-SPEC v3.0
|
|
2
|
+
|
|
3
|
+
Thread management is the v3.0 system for coordinating multi-agent execution within a single feature. Threads allow parallel, sequential, and hybrid agent workflows with full lifecycle tracking.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Thread Types
|
|
8
|
+
|
|
9
|
+
| Thread | Code | Purpose | Auto-kill? |
|
|
10
|
+
|--------|------|---------|------------|
|
|
11
|
+
| **Base Thread** | B | Single agent, sequential implementation | No |
|
|
12
|
+
| **Parallel Thread** | P | Isolated domain worker in a parallel squad | No |
|
|
13
|
+
| **Fusion Thread** | F | One of N agents solving the same problem | No |
|
|
14
|
+
| **Long-Running** | L | Persistent background agent with stop hooks | Yes (on stop hook) |
|
|
15
|
+
| **Zero-Touch** | Z | Autonomous agent with auto-approval (requires max trust) | No |
|
|
16
|
+
|
|
17
|
+
### Choosing a Thread Type
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Is this a single, sequential implementation?
|
|
21
|
+
└─ YES → B-Thread (Base)
|
|
22
|
+
|
|
23
|
+
Do you want N agents working on different domains simultaneously?
|
|
24
|
+
└─ YES → P-Thread (Parallel) per domain
|
|
25
|
+
|
|
26
|
+
Do you want N agents solving the SAME problem (pick best result)?
|
|
27
|
+
└─ YES → F-Thread (Fusion)
|
|
28
|
+
|
|
29
|
+
Will the agent run for >30 minutes or need periodic check-ins?
|
|
30
|
+
└─ YES → L-Thread (Long-Running)
|
|
31
|
+
|
|
32
|
+
Is trust level "maximum" (>95% checkpoint pass rate)?
|
|
33
|
+
└─ YES → Z-Thread (Zero-Touch) eligible
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Thread Lifecycle
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pending → running → completed
|
|
42
|
+
└→ failed
|
|
43
|
+
└→ killed
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Each thread stores its state in `.morph/state.json` under `threads`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"threads": {
|
|
51
|
+
"thr_abc12345": {
|
|
52
|
+
"id": "thr_abc12345",
|
|
53
|
+
"type": "parallel",
|
|
54
|
+
"feature": "user-auth",
|
|
55
|
+
"agent": "dotnet-senior",
|
|
56
|
+
"status": "running",
|
|
57
|
+
"startedAt": "2026-02-19T10:00:00Z",
|
|
58
|
+
"completedAt": null,
|
|
59
|
+
"metrics": {
|
|
60
|
+
"tasksCompleted": 3,
|
|
61
|
+
"filesCreated": 5,
|
|
62
|
+
"filesModified": 2,
|
|
63
|
+
"checkpointsPassed": 1,
|
|
64
|
+
"checkpointsFailed": 0
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## CLI Reference
|
|
74
|
+
|
|
75
|
+
### List threads
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
morph-spec threads list
|
|
79
|
+
morph-spec threads list --feature user-auth
|
|
80
|
+
morph-spec threads list --status running
|
|
81
|
+
morph-spec threads list --type parallel
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Thread status
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
morph-spec threads status thr_abc12345
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Kill a thread
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
morph-spec threads kill thr_abc12345
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Analytics
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
morph-spec threads analytics --feature user-auth
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Wait for completion
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Wait for ALL threads in a feature
|
|
106
|
+
morph-spec threads wait-all user-auth --timeout 60
|
|
107
|
+
|
|
108
|
+
# Wait for ANY thread to complete
|
|
109
|
+
morph-spec threads wait-any user-auth --timeout 30
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## P-Thread Isolation Rules
|
|
115
|
+
|
|
116
|
+
Parallel threads (P-Threads) MUST follow strict isolation:
|
|
117
|
+
|
|
118
|
+
| Rule | Description |
|
|
119
|
+
|------|-------------|
|
|
120
|
+
| **File ownership** | Each P-Thread writes ONLY to its assigned file set |
|
|
121
|
+
| **Read-only shared** | Shared files (spec.md, contracts, standards) are READ-ONLY |
|
|
122
|
+
| **No cross-writes** | Never write to another thread's files |
|
|
123
|
+
| **Report on done** | Submit PARALLEL WORKER REPORT when complete |
|
|
124
|
+
| **No external calls** | Don't spawn additional threads |
|
|
125
|
+
|
|
126
|
+
### P-Thread Report Format
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
## PARALLEL WORKER REPORT
|
|
130
|
+
|
|
131
|
+
**Thread ID:** {id}
|
|
132
|
+
**Status:** completed | failed | blocked
|
|
133
|
+
|
|
134
|
+
**Files Created:**
|
|
135
|
+
- path/to/file1.cs
|
|
136
|
+
- path/to/file2.cs
|
|
137
|
+
|
|
138
|
+
**Tasks Completed:** T001, T002, T003
|
|
139
|
+
|
|
140
|
+
**Blockers (if any):** None
|
|
141
|
+
|
|
142
|
+
**Notes:** Any important implementation decisions
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## L-Thread Stop Hooks
|
|
148
|
+
|
|
149
|
+
Long-running threads respond to stop hooks. Configure in `.claude/settings.local.json`:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"hooks": {
|
|
154
|
+
"Stop": [
|
|
155
|
+
{
|
|
156
|
+
"matcher": "",
|
|
157
|
+
"hooks": [
|
|
158
|
+
{
|
|
159
|
+
"type": "command",
|
|
160
|
+
"command": "node framework/hooks/agent-teams/validate-and-continue.js {feature}"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Stop hooks run every N seconds (configurable in `zero-touch.json`):
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"monitoring": {
|
|
174
|
+
"stopHooks": {
|
|
175
|
+
"enabled": true,
|
|
176
|
+
"interval": 30,
|
|
177
|
+
"hooks": ["validate-and-continue", "validate-checkpoints"]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Thread Metrics Tracking
|
|
186
|
+
|
|
187
|
+
Each feature tracks aggregate thread metrics in `state.json`:
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"features": {
|
|
192
|
+
"user-auth": {
|
|
193
|
+
"threadMetrics": {
|
|
194
|
+
"totalThreads": 3,
|
|
195
|
+
"completedThreads": 2,
|
|
196
|
+
"failedThreads": 0,
|
|
197
|
+
"parallelBatches": 1
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Access via:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
morph-spec analytics feature user-auth
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Decision Tree: When to Use Threads
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
Feature complexity?
|
|
216
|
+
SIMPLE (1-5 files) → B-Thread only, no parallelization
|
|
217
|
+
MEDIUM (6-15 files) → Consider P-Threads by domain
|
|
218
|
+
HIGH (>15 files) → P-Threads mandatory for speed
|
|
219
|
+
|
|
220
|
+
Multiple independent domains?
|
|
221
|
+
YES → Spawn P-Thread per domain (backend, frontend, infra)
|
|
222
|
+
NO → Single B-Thread is fine
|
|
223
|
+
|
|
224
|
+
Need best-quality output from N attempts?
|
|
225
|
+
YES → F-Thread (Fusion) with aggregation
|
|
226
|
+
|
|
227
|
+
Long implementation (>30 mins estimated)?
|
|
228
|
+
YES → L-Thread with stop hooks for periodic validation
|
|
229
|
+
|
|
230
|
+
Trust level maximum + fully automated pipeline?
|
|
231
|
+
YES → Z-Thread (check with: morph-spec trust status)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Related
|
|
237
|
+
|
|
238
|
+
- [Parallel Execution](PARALLEL-EXECUTION.md) — Squad templates and P-Thread coordination
|
|
239
|
+
- [Context Optimization](CONTEXT-OPTIMIZATION.md) — Token efficiency during thread execution
|
|
240
|
+
- [Migration Guide](MIGRATION-GUIDE.md) — Upgrading state.json to v3.0 thread schema
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polymorphism-tech/morph-spec",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "MORPH-SPEC
|
|
3
|
+
"version": "4.3.1",
|
|
4
|
+
"description": "MORPH-SPEC: AI-First development framework with validation pipeline and multi-stack support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
7
7
|
"claude",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"scripts": {
|
|
41
41
|
"postinstall": "node scripts/postinstall.js",
|
|
42
42
|
"start": "node bin/morph-spec.js",
|
|
43
|
-
"test": "node --test",
|
|
44
|
-
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov node --test",
|
|
45
|
-
"test:coverage:summary": "c8 --reporter=text-summary node --test",
|
|
43
|
+
"test": "node --test --test-concurrency=1",
|
|
44
|
+
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov node --test --test-concurrency=1",
|
|
45
|
+
"test:coverage:summary": "c8 --reporter=text-summary node --test --test-concurrency=1",
|
|
46
46
|
"docs": "jsdoc -c jsdoc.json",
|
|
47
47
|
"docs:watch": "jsdoc -c jsdoc.json --watch",
|
|
48
48
|
"docs:serve": "npx http-server docs/api -p 8080 -o"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agents Fuse CLI command — F-Thread fusion execution
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* morph-spec agents fuse --prompt "..." --count=3 --strategy=best-of-n [--feature=<f>]
|
|
6
|
+
* morph-spec agents review aggregate <feature> --agents=a1,a2,a3
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import { runFusion, aggregateResults, displayFusionSummary } from '../../lib/execution/fusion-executor.js';
|
|
11
|
+
|
|
12
|
+
export async function agentsFuseCommand(options) {
|
|
13
|
+
if (!options.prompt) {
|
|
14
|
+
console.error(chalk.red('--prompt is required'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const count = parseInt(options.count || '3', 10);
|
|
19
|
+
const strategy = options.strategy || 'best-of-n';
|
|
20
|
+
const feature = options.feature || 'fusion-session';
|
|
21
|
+
const agents = options.agents ? options.agents.split(',').map(a => a.trim()) : null;
|
|
22
|
+
|
|
23
|
+
console.log(chalk.cyan(`\n F-Thread Fusion Execution\n`));
|
|
24
|
+
console.log(` Strategy: ${strategy}`);
|
|
25
|
+
console.log(` Agents: ${count}`);
|
|
26
|
+
console.log(` Feature: ${feature}`);
|
|
27
|
+
console.log(` Prompt: ${options.prompt.substring(0, 80)}${options.prompt.length > 80 ? '...' : ''}`);
|
|
28
|
+
console.log('');
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const fusionSession = await runFusion(options.prompt, {
|
|
32
|
+
feature,
|
|
33
|
+
count,
|
|
34
|
+
strategy,
|
|
35
|
+
agents
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log(chalk.cyan(` ${fusionSession.threads.length} fusion threads spawned:\n`));
|
|
39
|
+
for (let i = 0; i < fusionSession.threads.length; i++) {
|
|
40
|
+
const thread = fusionSession.threads[i];
|
|
41
|
+
const agent = fusionSession.agentConfigs[i];
|
|
42
|
+
console.log(` ${chalk.gray(thread.id.substring(0, 8))} — Agent: ${agent.agentId} (${thread.status})`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log(chalk.yellow('\n ⚠ Fusion threads spawned. To aggregate results:'));
|
|
46
|
+
console.log(chalk.gray(' 1. Execute each thread using the Task tool with the agent configs'));
|
|
47
|
+
console.log(chalk.gray(' 2. Collect results from each agent'));
|
|
48
|
+
console.log(chalk.gray(' 3. Run: morph-spec agents fuse-aggregate --results=<file> --strategy=' + strategy));
|
|
49
|
+
console.log('');
|
|
50
|
+
|
|
51
|
+
if (options.json) {
|
|
52
|
+
console.log(JSON.stringify({
|
|
53
|
+
threads: fusionSession.threads.map(t => ({ id: t.id, agent: t.agent, status: t.status })),
|
|
54
|
+
agentConfigs: fusionSession.agentConfigs,
|
|
55
|
+
strategy,
|
|
56
|
+
feature
|
|
57
|
+
}, null, 2));
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function agentsReviewAggregateCommand(feature, options) {
|
|
66
|
+
if (!options.agents) {
|
|
67
|
+
console.error(chalk.red('--agents is required (comma-separated list)'));
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const agentList = options.agents.split(',').map(a => a.trim());
|
|
72
|
+
const strategy = options.strategy || 'best-of-n';
|
|
73
|
+
|
|
74
|
+
console.log(chalk.yellow('\n ⚠ [STUB] This command returns mock data. Real aggregation not yet implemented.\n'));
|
|
75
|
+
console.log(chalk.cyan(` Aggregate Reviews — ${feature}\n`));
|
|
76
|
+
console.log(` Agents: ${agentList.join(', ')}`);
|
|
77
|
+
console.log(` Strategy: ${strategy}`);
|
|
78
|
+
console.log('');
|
|
79
|
+
|
|
80
|
+
// Mock results for demo — in real usage, results come from agent output files
|
|
81
|
+
const mockResults = agentList.map((agentId, i) => ({
|
|
82
|
+
agentId,
|
|
83
|
+
content: `Agent ${agentId} review for ${feature}`,
|
|
84
|
+
checkpointsPassed: Math.floor(Math.random() * 3) + 2,
|
|
85
|
+
checkpointsFailed: Math.floor(Math.random() * 2),
|
|
86
|
+
errors: Math.floor(Math.random() * 2),
|
|
87
|
+
warnings: Math.floor(Math.random() * 3)
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const aggregated = aggregateResults(mockResults, strategy);
|
|
92
|
+
displayFusionSummary(aggregated);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Micro Agent CLI command
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* morph-spec micro-agent create <name> --base-agent=<agent> --mission="..." [--standards=file1,file2]
|
|
6
|
+
* morph-spec micro-agent list
|
|
7
|
+
* morph-spec micro-agent show <name>
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import {
|
|
12
|
+
createMicroAgent, saveMicroAgent, listMicroAgents, getMicroAgent
|
|
13
|
+
} from '../../lib/agents/micro-agent-factory.js';
|
|
14
|
+
|
|
15
|
+
export async function microAgentCreateCommand(name, options) {
|
|
16
|
+
try {
|
|
17
|
+
if (!options.baseAgent) {
|
|
18
|
+
console.error(chalk.red('--base-agent is required'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
if (!options.mission) {
|
|
22
|
+
console.error(chalk.red('--mission is required'));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const standards = options.standards ? options.standards.split(',').map(s => s.trim()) : [];
|
|
27
|
+
|
|
28
|
+
const agent = createMicroAgent({
|
|
29
|
+
name,
|
|
30
|
+
baseAgent: options.baseAgent,
|
|
31
|
+
standards,
|
|
32
|
+
mission: options.mission,
|
|
33
|
+
tools: options.tools ? options.tools.split(',').map(t => t.trim()) : null
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const filePath = saveMicroAgent(agent);
|
|
37
|
+
|
|
38
|
+
console.log(chalk.green(`\n ✓ Micro-agent created: ${name}`));
|
|
39
|
+
console.log(` Base agent: ${options.baseAgent}`);
|
|
40
|
+
console.log(` Standards: ${standards.length > 0 ? standards.join(', ') : '(none)'}`);
|
|
41
|
+
console.log(` Context estimate: ${agent.contextEstimate.total.toLocaleString()} tokens`);
|
|
42
|
+
console.log(` Saved to: ${chalk.gray(filePath)}`);
|
|
43
|
+
console.log('');
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function microAgentListCommand(options) {
|
|
51
|
+
try {
|
|
52
|
+
const agents = listMicroAgents();
|
|
53
|
+
|
|
54
|
+
if (agents.length === 0) {
|
|
55
|
+
console.log(chalk.gray('\n No micro-agents found. Create one with: morph-spec micro-agent create\n'));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(chalk.cyan(`\n Micro-Agents (${agents.length})\n`));
|
|
60
|
+
console.log(' ' + 'Name'.padEnd(20) + ' ' + 'Base'.padEnd(20) + ' ' + 'Standards'.padEnd(12) + ' ' + 'Context');
|
|
61
|
+
console.log(' ' + '─'.repeat(70));
|
|
62
|
+
|
|
63
|
+
for (const agent of agents) {
|
|
64
|
+
console.log(
|
|
65
|
+
' ' +
|
|
66
|
+
agent.id.padEnd(20) + ' ' +
|
|
67
|
+
(agent.baseAgent || '—').padEnd(20) + ' ' +
|
|
68
|
+
String(agent.standards).padEnd(12) + ' ' +
|
|
69
|
+
`${(agent.contextEstimate / 1000).toFixed(1)}K tokens`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
console.log('');
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function microAgentShowCommand(name, options) {
|
|
80
|
+
try {
|
|
81
|
+
const agent = getMicroAgent(name);
|
|
82
|
+
if (!agent) {
|
|
83
|
+
console.error(chalk.red(`Micro-agent not found: ${name}`));
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(chalk.cyan(`\n Micro-Agent: ${name}\n`));
|
|
88
|
+
console.log(` Base agent: ${agent.baseAgent}`);
|
|
89
|
+
console.log(` Domain: ${agent.domain}`);
|
|
90
|
+
console.log(` Created: ${agent.createdAt}`);
|
|
91
|
+
console.log(`\n Mission:\n ${agent.mission}`);
|
|
92
|
+
|
|
93
|
+
if (agent.standards?.length > 0) {
|
|
94
|
+
console.log('\n Standards:');
|
|
95
|
+
agent.standards.forEach(s => console.log(` - ${s}`));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log('\n Context estimate:');
|
|
99
|
+
console.log(` Standards: ${agent.contextEstimate?.standards?.toLocaleString() || 0} tokens`);
|
|
100
|
+
console.log(` Overhead: ${agent.contextEstimate?.overhead?.toLocaleString() || 0} tokens`);
|
|
101
|
+
console.log(` Total: ${agent.contextEstimate?.total?.toLocaleString() || 0} tokens`);
|
|
102
|
+
|
|
103
|
+
if (options.showPrompt) {
|
|
104
|
+
console.log(chalk.cyan('\n Generated Prompt:'));
|
|
105
|
+
console.log(agent.prompt);
|
|
106
|
+
}
|
|
107
|
+
console.log('');
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
+
import { join } from 'path';
|
|
3
4
|
import { getFeature } from '../../core/state/state-manager.js';
|
|
4
5
|
import { orchestrateTeam } from '../../lib/orchestration/team-orchestrator.js';
|
|
6
|
+
import { spawnParallel } from '../../lib/execution/parallel-executor.js';
|
|
7
|
+
import { renderHOP } from '../../lib/hops/hop-composer.js';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* Spawn Team Command - Generate agent team configurations
|
|
@@ -15,6 +18,35 @@ const program = new Command();
|
|
|
15
18
|
/**
|
|
16
19
|
* Spawn team action function
|
|
17
20
|
*/
|
|
21
|
+
/**
|
|
22
|
+
* Spawn team in parallel mode
|
|
23
|
+
* --parallel backend,frontend,infra
|
|
24
|
+
*/
|
|
25
|
+
export async function spawnTeamParallelCommand(featureName, squads, options = {}) {
|
|
26
|
+
const squadList = squads.split(',').map(s => s.trim());
|
|
27
|
+
const maxConcurrent = parseInt(options.maxConcurrent || '3', 10);
|
|
28
|
+
|
|
29
|
+
console.log(chalk.cyan(`\n Spawning ${squadList.length} parallel squads for: ${featureName}\n`));
|
|
30
|
+
|
|
31
|
+
const threadConfigs = squadList.map(squad => ({
|
|
32
|
+
agent: squad,
|
|
33
|
+
mission: `Implement ${squad} domain for ${featureName}`,
|
|
34
|
+
meta: { squad }
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const threads = await spawnParallel({ feature: featureName, threadConfigs, maxConcurrent });
|
|
39
|
+
console.log(chalk.green(` ✓ ${threads.length} threads spawned in parallel`));
|
|
40
|
+
for (const t of threads) {
|
|
41
|
+
console.log(` ${chalk.gray(t.id.substring(0, 8))} — ${t.agent} (${t.status})`);
|
|
42
|
+
}
|
|
43
|
+
console.log(`\n Monitor with: morph-spec threads wait-all ${featureName}\n`);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error(chalk.red(` Error: ${err.message}`));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
18
50
|
export async function spawnTeamCommand(featureName, options = {}) {
|
|
19
51
|
try {
|
|
20
52
|
// Get feature state
|
|
@@ -94,12 +126,44 @@ export async function spawnTeamCommand(featureName, options = {}) {
|
|
|
94
126
|
});
|
|
95
127
|
}
|
|
96
128
|
|
|
97
|
-
// Show Task tool usage
|
|
129
|
+
// Show Task tool usage (with HOP rendering)
|
|
98
130
|
console.log(chalk.bold('\n📝 Task Tool Usage:'));
|
|
99
131
|
console.log(chalk.gray('\nUse the following pattern to spawn the team:\n'));
|
|
100
132
|
|
|
101
|
-
|
|
102
|
-
|
|
133
|
+
// Try to render backend squad HOP if applicable
|
|
134
|
+
let hopPrompt = null;
|
|
135
|
+
const hasBackend = teamConfig.teammates.some(t => t.id.includes('dotnet') || t.id.includes('api') || t.id.includes('ef'));
|
|
136
|
+
if (hasBackend && options.useHop !== false) {
|
|
137
|
+
try {
|
|
138
|
+
const frameworkRoot = join(process.cwd(), 'framework');
|
|
139
|
+
const domainLeaders = teamConfig.teammates
|
|
140
|
+
.filter(t => t.tier === 2)
|
|
141
|
+
.map(t => `- ${t.id}: ${t.role}`)
|
|
142
|
+
.join('\n');
|
|
143
|
+
hopPrompt = renderHOP('hop-backend-squad', {
|
|
144
|
+
AGENT_ID: teamConfig.teamHierarchy.teamLead,
|
|
145
|
+
MISSION: `Implement ${featureName}`,
|
|
146
|
+
SPEC_SUMMARY: `Feature: ${featureName}. See spec.md for full details.`,
|
|
147
|
+
ADDITIONAL_LEADERS: domainLeaders,
|
|
148
|
+
TASKS: teamConfig.teammates.filter(t => t.tier === 3).map((t, i) => `- T${String(i+1).padStart(3,'0')}: ${t.role}`).join('\n'),
|
|
149
|
+
DELIVERABLES: 'See spec.md deliverables section',
|
|
150
|
+
CONSTRAINTS: 'Follow all architecture and security standards',
|
|
151
|
+
FEATURE_NAME: featureName
|
|
152
|
+
}, { frameworkRoot });
|
|
153
|
+
} catch {
|
|
154
|
+
hopPrompt = null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (hopPrompt) {
|
|
159
|
+
console.log(chalk.cyan('HOP-rendered prompt (backend squad):'));
|
|
160
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
161
|
+
console.log(chalk.white(hopPrompt.substring(0, 800) + (hopPrompt.length > 800 ? '\n...[truncated]' : '')));
|
|
162
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
163
|
+
console.log(chalk.dim('\nFull HOP: morph-spec hop render hop-backend-squad output.md \'{...}\''));
|
|
164
|
+
} else {
|
|
165
|
+
console.log(chalk.cyan('```typescript'));
|
|
166
|
+
console.log(chalk.white(`{
|
|
103
167
|
subagent_type: "general-purpose",
|
|
104
168
|
description: "Implement ${featureName}",
|
|
105
169
|
prompt: \`You are the Team Lead (${teamConfig.teamHierarchy.teamLead})...
|
|
@@ -123,7 +187,8 @@ Standards to follow: [coding.md, architecture.md]
|
|
|
123
187
|
Deliverables: [list specific outputs]
|
|
124
188
|
\`
|
|
125
189
|
}`));
|
|
126
|
-
|
|
190
|
+
console.log(chalk.cyan('```\n'));
|
|
191
|
+
}
|
|
127
192
|
|
|
128
193
|
// Show individual teammates
|
|
129
194
|
console.log(chalk.bold('Individual Teammates:'));
|