@polymorphism-tech/morph-spec 4.8.1 → 4.8.4
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/README.md +2 -2
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/hooks/dev/guard-version-numbers.js +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +1 -1
- package/package.json +4 -4
- package/.morph/analytics/threads-log.jsonl +0 -54
- package/.morph/state.json +0 -198
- package/docs/ARCHITECTURE.md +0 -328
- package/docs/COMMAND-FLOWS.md +0 -398
- package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -514
- package/docs/plans/2026-02-22-claude-settings.md +0 -517
- package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -730
- package/docs/plans/2026-02-22-morph-spec-next.md +0 -480
- package/docs/plans/2026-02-22-native-alignment-design.md +0 -201
- package/docs/plans/2026-02-22-native-alignment-impl.md +0 -927
- package/docs/plans/2026-02-22-native-enrichment-design.md +0 -246
- package/docs/plans/2026-02-22-native-enrichment.md +0 -737
- package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1155
- package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -684
- package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -439
- package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -157
- package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1256
- package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -150
- package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1848
- package/docs/plans/2026-02-24-cli-radical-simplification.md +0 -592
- package/docs/plans/2026-02-24-framework-failure-points.md +0 -125
- package/docs/plans/2026-02-24-morph-init-design.md +0 -337
- package/docs/plans/2026-02-24-morph-init-impl.md +0 -1269
- package/docs/plans/2026-02-24-tutorial-command-design.md +0 -71
- package/docs/plans/2026-02-24-tutorial-command.md +0 -298
- package/scripts/bump-version.js +0 -248
- package/scripts/generate-refs.js +0 -336
- package/scripts/generate-standards-registry.js +0 -44
- package/scripts/install-dev-hooks.js +0 -138
- package/scripts/scan-nextjs.mjs +0 -169
- package/scripts/validate-real.mjs +0 -255
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
# Claude Code Settings & Native Subagents Alignment Plan
|
|
2
|
-
|
|
3
|
-
**Status:** COMPLETE
|
|
4
|
-
|
|
5
|
-
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
6
|
-
|
|
7
|
-
**Goal:** Align morph-spec with the latest Claude Code native primitives — native subagents (`.claude/agents/`), additional settings keys, and proper CLAUDE.md scoping.
|
|
8
|
-
|
|
9
|
-
**Architecture:** Add an `agentsInstaller.js` that converts morph's tier-1/tier-2 agents into native Claude Code subagent markdown files; expand `hooks-installer.js` to configure additional settings keys ($schema, env, attribution, plansDirectory, teammateMode); split CLAUDE.md into human-readable root vs. Claude-Code-runtime `.claude/CLAUDE.md`.
|
|
10
|
-
|
|
11
|
-
**Tech Stack:** Node.js ESM, fs-extra, node:test, Claude Code settings.json schema
|
|
12
|
-
|
|
13
|
-
**Plan file should be copied to:** `docs/plans/2026-02-22-claude-settings.md`
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Context
|
|
18
|
-
|
|
19
|
-
The Claude Code settings documentation reveals three native primitives morph-spec does not yet leverage:
|
|
20
|
-
|
|
21
|
-
1. **Native Subagents** (`.claude/agents/`): Claude Code natively discovers `.md` files with YAML frontmatter in `.claude/agents/`. morph-spec has 37 agents in a custom JSON registry that are entirely invisible to this native mechanism.
|
|
22
|
-
|
|
23
|
-
2. **Missing settings keys**: `$schema`, `env`, `attribution`, `plansDirectory`, `teammateMode`, `spinnerVerbs` — all recognized by Claude Code but not written by morph-spec's init.
|
|
24
|
-
|
|
25
|
-
3. **CLAUDE.md scopes**: Claude Code explicitly supports `.claude/CLAUDE.md` (alongside settings). morph-spec installs only the root `CLAUDE.md`, mixing human documentation with Claude Code runtime instructions.
|
|
26
|
-
|
|
27
|
-
**Already well-aligned — no changes needed:**
|
|
28
|
-
- Skills flat-install to `.claude/skills/` ✓
|
|
29
|
-
- Commands install to `.claude/commands/` ✓
|
|
30
|
-
- Global statusline at `~/.claude/` ✓
|
|
31
|
-
- Native `permissions.deny` for state.json + framework/ ✓
|
|
32
|
-
- 12 lifecycle hooks with `_morph_managed` tracking ✓
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Task 1: Create `src/utils/agents-installer.js`
|
|
37
|
-
|
|
38
|
-
**Files:**
|
|
39
|
-
- Create: `src/utils/agents-installer.js`
|
|
40
|
-
- Test: `test/utils/agents-installer.test.js`
|
|
41
|
-
|
|
42
|
-
### Step 1: Write failing test
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
// test/utils/agents-installer.test.js
|
|
46
|
-
import { test, describe, before, after } from 'node:test';
|
|
47
|
-
import assert from 'node:assert/strict';
|
|
48
|
-
import { mkdtemp, rm, readdir, readFile, mkdir } from 'node:fs/promises';
|
|
49
|
-
import { join } from 'path';
|
|
50
|
-
import { tmpdir } from 'os';
|
|
51
|
-
import { installAgents } from '../../src/utils/agents-installer.js';
|
|
52
|
-
|
|
53
|
-
describe('installAgents', () => {
|
|
54
|
-
let tmpDir;
|
|
55
|
-
before(async () => { tmpDir = await mkdtemp(join(tmpdir(), 'morph-agents-')); });
|
|
56
|
-
after(async () => { await rm(tmpDir, { recursive: true, force: true }); });
|
|
57
|
-
|
|
58
|
-
test('creates .claude/agents/ with tier-1 and tier-2 agent files', async () => {
|
|
59
|
-
const frameworkDir = 'framework'; // uses real agents.json
|
|
60
|
-
await installAgents(tmpDir, frameworkDir);
|
|
61
|
-
const files = await readdir(join(tmpDir, '.claude', 'agents'));
|
|
62
|
-
assert.ok(files.length >= 6, 'should install at least 6 agents');
|
|
63
|
-
assert.ok(files.every(f => f.endsWith('.md')), 'all files should be .md');
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('each file has valid YAML frontmatter with name and description', async () => {
|
|
67
|
-
await installAgents(tmpDir, 'framework');
|
|
68
|
-
const files = await readdir(join(tmpDir, '.claude', 'agents'));
|
|
69
|
-
for (const file of files) {
|
|
70
|
-
const content = await readFile(join(tmpDir, '.claude', 'agents', file), 'utf-8');
|
|
71
|
-
assert.ok(content.startsWith('---\n'), `${file} should start with YAML frontmatter`);
|
|
72
|
-
assert.ok(content.includes('name:'), `${file} should have name`);
|
|
73
|
-
assert.ok(content.includes('description:'), `${file} should have description`);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('is idempotent — running twice does not duplicate files', async () => {
|
|
78
|
-
await installAgents(tmpDir, 'framework');
|
|
79
|
-
await installAgents(tmpDir, 'framework');
|
|
80
|
-
const files = await readdir(join(tmpDir, '.claude', 'agents'));
|
|
81
|
-
const morphFiles = files.filter(f => f.startsWith('morph-'));
|
|
82
|
-
const unique = new Set(morphFiles);
|
|
83
|
-
assert.equal(morphFiles.length, unique.size);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Step 2: Run test to verify it fails
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npm test -- test/utils/agents-installer.test.js
|
|
92
|
-
```
|
|
93
|
-
Expected: FAIL — `agents-installer.js` not found.
|
|
94
|
-
|
|
95
|
-
### Step 3: Write the implementation
|
|
96
|
-
|
|
97
|
-
```js
|
|
98
|
-
// src/utils/agents-installer.js
|
|
99
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
100
|
-
import { join } from 'path';
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Installs tier-1 and tier-2 morph agents as native Claude Code subagents
|
|
104
|
-
* in .claude/agents/ with YAML frontmatter.
|
|
105
|
-
* @param {string} projectDir - Target project directory
|
|
106
|
-
* @param {string} frameworkDir - Path to morph-spec framework/ directory
|
|
107
|
-
*/
|
|
108
|
-
export async function installAgents(projectDir, frameworkDir = 'framework') {
|
|
109
|
-
const agentsJsonPath = join(frameworkDir, 'agents.json');
|
|
110
|
-
const agentsJson = JSON.parse(readFileSync(agentsJsonPath, 'utf-8'));
|
|
111
|
-
const agents = agentsJson.agents ?? agentsJson;
|
|
112
|
-
|
|
113
|
-
const targetDir = join(projectDir, '.claude', 'agents');
|
|
114
|
-
mkdirSync(targetDir, { recursive: true });
|
|
115
|
-
|
|
116
|
-
const eligible = agents.filter(a => a.tier === 1 || a.tier === 2);
|
|
117
|
-
|
|
118
|
-
for (const agent of eligible) {
|
|
119
|
-
const slug = agent.id ?? agent.name?.toLowerCase().replace(/\s+/g, '-');
|
|
120
|
-
const filename = `morph-${slug}.md`;
|
|
121
|
-
const targetPath = join(targetDir, filename);
|
|
122
|
-
|
|
123
|
-
const description = buildDescription(agent);
|
|
124
|
-
const body = buildBody(agent);
|
|
125
|
-
|
|
126
|
-
const content = `---\nname: ${agent.title ?? agent.name}\ndescription: ${description}\n---\n\n${body}\n`;
|
|
127
|
-
writeFileSync(targetPath, content, 'utf-8');
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function buildDescription(agent) {
|
|
132
|
-
const domains = (agent.domains ?? []).join(', ');
|
|
133
|
-
const base = agent.teammate?.role ?? `Handles ${domains}`;
|
|
134
|
-
// Truncate to 200 chars for settings display
|
|
135
|
-
return base.length > 200 ? base.slice(0, 197) + '...' : base;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function buildBody(agent) {
|
|
139
|
-
const lines = [];
|
|
140
|
-
if (agent.teammate?.spawn_prompt) {
|
|
141
|
-
lines.push(agent.teammate.spawn_prompt);
|
|
142
|
-
} else {
|
|
143
|
-
lines.push(`You are the ${agent.title} agent in the MORPH-SPEC framework.`);
|
|
144
|
-
if (agent.domains?.length) lines.push(`\n## Domains\n${agent.domains.map(d => `- ${d}`).join('\n')}`);
|
|
145
|
-
}
|
|
146
|
-
if (agent.standards?.length) {
|
|
147
|
-
lines.push(`\n## Standards to Reference\n${agent.standards.map(s => `- ${s}`).join('\n')}`);
|
|
148
|
-
}
|
|
149
|
-
return lines.join('\n');
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Step 4: Run test to verify it passes
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
npm test -- test/utils/agents-installer.test.js
|
|
157
|
-
```
|
|
158
|
-
Expected: PASS (3 tests pass).
|
|
159
|
-
|
|
160
|
-
### Step 5: Commit
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
git add src/utils/agents-installer.js test/utils/agents-installer.test.js
|
|
164
|
-
git commit -m "feat(agents): add agents-installer for native .claude/agents/ subagent discovery"
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Task 2: Integrate `installAgents` into `init.js`
|
|
170
|
-
|
|
171
|
-
**Files:**
|
|
172
|
-
- Modify: `src/commands/project/init.js`
|
|
173
|
-
- Modify: `src/utils/claude-settings-manager.js` (re-export)
|
|
174
|
-
|
|
175
|
-
### Step 1: Add import and call in init.js
|
|
176
|
-
|
|
177
|
-
In `src/commands/project/init.js`, after the skills install block:
|
|
178
|
-
|
|
179
|
-
```js
|
|
180
|
-
// After: await installSkills(targetPath);
|
|
181
|
-
import { installAgents } from '../../utils/agents-installer.js';
|
|
182
|
-
// ...
|
|
183
|
-
await installAgents(targetPath, FRAMEWORK_DIR);
|
|
184
|
-
logger.success('Native subagents installed to .claude/agents/');
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Find `FRAMEWORK_DIR` in init.js (or equivalent constant pointing to `framework/`).
|
|
188
|
-
|
|
189
|
-
### Step 2: Re-export from claude-settings-manager
|
|
190
|
-
|
|
191
|
-
Add to `src/utils/claude-settings-manager.js`:
|
|
192
|
-
```js
|
|
193
|
-
export { installAgents } from './agents-installer.js';
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Step 3: Add agent files to existing integration test
|
|
197
|
-
|
|
198
|
-
In `test/commands/init.test.js`, add assertion:
|
|
199
|
-
```js
|
|
200
|
-
const agentFiles = await readdir(join(projectDir, '.claude', 'agents'));
|
|
201
|
-
assert.ok(agentFiles.some(f => f.startsWith('morph-')), 'agents should be installed');
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Step 4: Run all tests
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
npm test
|
|
208
|
-
```
|
|
209
|
-
Expected: All existing tests pass + new assertion passes.
|
|
210
|
-
|
|
211
|
-
### Step 5: Commit
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
git add src/commands/project/init.js src/utils/claude-settings-manager.js
|
|
215
|
-
git commit -m "feat(init): install native subagents to .claude/agents/ during init"
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Task 3: Settings Enhancements — `$schema`, `env`, `attribution`, `plansDirectory`
|
|
221
|
-
|
|
222
|
-
**Files:**
|
|
223
|
-
- Modify: `src/utils/hooks-installer.js`
|
|
224
|
-
- Test: existing `test/hooks/hooks-installer.test.js`
|
|
225
|
-
|
|
226
|
-
These settings go into `.claude/settings.local.json` (same file as hooks/permissions).
|
|
227
|
-
|
|
228
|
-
### Step 1: Write failing test
|
|
229
|
-
|
|
230
|
-
In `test/hooks/hooks-installer.test.js`, add:
|
|
231
|
-
|
|
232
|
-
```js
|
|
233
|
-
test('installClaudeHooks adds $schema to settings', async () => {
|
|
234
|
-
await installClaudeHooks(tmpDir);
|
|
235
|
-
const settings = JSON.parse(readFileSync(join(tmpDir, '.claude', 'settings.local.json'), 'utf-8'));
|
|
236
|
-
assert.ok(settings['$schema'], 'should include $schema key');
|
|
237
|
-
assert.equal(settings['$schema'], 'https://json.schemastore.org/claude-code-settings.json');
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
test('installClaudeHooks adds env section with MORPH vars', async () => {
|
|
241
|
-
await installClaudeHooks(tmpDir);
|
|
242
|
-
const settings = JSON.parse(readFileSync(join(tmpDir, '.claude', 'settings.local.json'), 'utf-8'));
|
|
243
|
-
assert.ok(settings.env?.MORPH_SPEC_ACTIVE, 'should set MORPH_SPEC_ACTIVE');
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
test('installClaudeHooks sets attribution', async () => {
|
|
247
|
-
await installClaudeHooks(tmpDir);
|
|
248
|
-
const settings = JSON.parse(readFileSync(join(tmpDir, '.claude', 'settings.local.json'), 'utf-8'));
|
|
249
|
-
assert.ok(settings.attribution, 'should set attribution');
|
|
250
|
-
});
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Step 2: Run test to verify it fails
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
npm test -- test/hooks/hooks-installer.test.js
|
|
257
|
-
```
|
|
258
|
-
Expected: FAIL — schema/env/attribution not in settings.
|
|
259
|
-
|
|
260
|
-
### Step 3: Implement in `hooks-installer.js`
|
|
261
|
-
|
|
262
|
-
In `installClaudeHooks(targetPath)`, before writing settings, merge:
|
|
263
|
-
|
|
264
|
-
```js
|
|
265
|
-
// Add at top of installClaudeHooks, after loading existing settings:
|
|
266
|
-
settings['$schema'] = 'https://json.schemastore.org/claude-code-settings.json';
|
|
267
|
-
|
|
268
|
-
settings.env = {
|
|
269
|
-
...settings.env,
|
|
270
|
-
MORPH_SPEC_ACTIVE: 'true',
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
if (!settings.attribution) {
|
|
274
|
-
settings.attribution = {
|
|
275
|
-
commit: '🤖 Co-authored by MORPH-SPEC',
|
|
276
|
-
pr: '',
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (!settings.plansDirectory) {
|
|
281
|
-
settings.plansDirectory = '.morph/plans';
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
### Step 4: Run test to verify it passes
|
|
286
|
-
|
|
287
|
-
```bash
|
|
288
|
-
npm test -- test/hooks/hooks-installer.test.js
|
|
289
|
-
```
|
|
290
|
-
Expected: All hooks-installer tests pass including new ones.
|
|
291
|
-
|
|
292
|
-
### Step 5: Commit
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
git add src/utils/hooks-installer.js test/hooks/hooks-installer.test.js
|
|
296
|
-
git commit -m "feat(settings): add \$schema, env, attribution, plansDirectory to installed settings"
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
---
|
|
300
|
-
|
|
301
|
-
## Task 4: Create `.claude/CLAUDE.md` (Claude Code Runtime Instructions)
|
|
302
|
-
|
|
303
|
-
The project-root `CLAUDE.md` is for humans + Claude Code. The `.claude/CLAUDE.md` file should hold Claude Code-specific runtime instructions that don't need to be in the project root.
|
|
304
|
-
|
|
305
|
-
**Files:**
|
|
306
|
-
- Create: `framework/CLAUDE_runtime.md` (source template → installs as `.claude/CLAUDE.md`)
|
|
307
|
-
- Modify: `src/commands/project/init.js` (copy runtime CLAUDE.md)
|
|
308
|
-
- Test: `test/commands/init.test.js`
|
|
309
|
-
|
|
310
|
-
### Step 1: Create runtime CLAUDE.md template
|
|
311
|
-
|
|
312
|
-
```markdown
|
|
313
|
-
<!-- framework/CLAUDE_runtime.md -->
|
|
314
|
-
# MORPH-SPEC Runtime Instructions
|
|
315
|
-
|
|
316
|
-
This file is loaded by Claude Code at runtime. For project documentation, see `CLAUDE.md` in the project root.
|
|
317
|
-
|
|
318
|
-
## Quick Reference
|
|
319
|
-
|
|
320
|
-
- Feature status: `/morph-status`
|
|
321
|
-
- Start new feature: `/morph-proposal {feature-name}`
|
|
322
|
-
- Implement feature: `/morph-apply {feature-name}`
|
|
323
|
-
- Preflight check: `/morph-preflight`
|
|
324
|
-
|
|
325
|
-
## State & Outputs
|
|
326
|
-
|
|
327
|
-
- State file: `.morph/state.json` (READ-ONLY — use `morph-spec` CLI to update)
|
|
328
|
-
- Feature outputs: `.morph/features/{feature}/{phase}/`
|
|
329
|
-
- Framework files: `.morph/framework/` (READ-ONLY)
|
|
330
|
-
|
|
331
|
-
## Phase Sequence
|
|
332
|
-
|
|
333
|
-
proposal → setup → [uiux] → design → clarify → tasks → implement → [sync]
|
|
334
|
-
|
|
335
|
-
Use `morph-spec state show {feature}` to see current phase and pending gates.
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Step 2: Write failing test
|
|
339
|
-
|
|
340
|
-
```js
|
|
341
|
-
test('init creates .claude/CLAUDE.md', async () => {
|
|
342
|
-
// run init with mocks
|
|
343
|
-
const content = readFileSync(join(projectDir, '.claude', 'CLAUDE.md'), 'utf-8');
|
|
344
|
-
assert.ok(content.includes('MORPH-SPEC Runtime'), 'should have runtime header');
|
|
345
|
-
assert.ok(content.includes('/morph-status'), 'should reference slash commands');
|
|
346
|
-
});
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### Step 3: Add copy in init.js
|
|
350
|
-
|
|
351
|
-
After the skills install block, add:
|
|
352
|
-
|
|
353
|
-
```js
|
|
354
|
-
const runtimeClaudeMdSrc = join(FRAMEWORK_DIR, 'CLAUDE_runtime.md');
|
|
355
|
-
const runtimeClaudeMdDest = join(targetPath, '.claude', 'CLAUDE.md');
|
|
356
|
-
await copyFile(runtimeClaudeMdSrc, runtimeClaudeMdDest);
|
|
357
|
-
logger.success('Runtime CLAUDE.md installed to .claude/CLAUDE.md');
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### Step 4: Run test to verify it passes
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
npm test -- test/commands/init.test.js
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### Step 5: Commit
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
git add framework/CLAUDE_runtime.md src/commands/project/init.js test/commands/init.test.js
|
|
370
|
-
git commit -m "feat(init): install .claude/CLAUDE.md with Claude Code runtime quick reference"
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
## Task 5: Add `morph-spec update-agents` command
|
|
376
|
-
|
|
377
|
-
Allow users to refresh `.claude/agents/` when framework agents are updated (similar to how `morph-spec update` refreshes framework files).
|
|
378
|
-
|
|
379
|
-
**Files:**
|
|
380
|
-
- Create: `src/commands/project/update-agents.js`
|
|
381
|
-
- Modify: `bin/morph-spec.js` (register command)
|
|
382
|
-
- Test: `test/commands/update-agents.test.js`
|
|
383
|
-
|
|
384
|
-
### Step 1: Write failing test
|
|
385
|
-
|
|
386
|
-
```js
|
|
387
|
-
// test/commands/update-agents.test.js
|
|
388
|
-
import { test } from 'node:test';
|
|
389
|
-
import assert from 'node:assert/strict';
|
|
390
|
-
import { updateAgentsCommand } from '../../src/commands/project/update-agents.js';
|
|
391
|
-
|
|
392
|
-
test('updateAgentsCommand re-installs agents from framework', async () => {
|
|
393
|
-
// Should call installAgents with projectDir and frameworkDir
|
|
394
|
-
// Should log success message
|
|
395
|
-
assert.ok(typeof updateAgentsCommand === 'function');
|
|
396
|
-
});
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Step 2: Implement
|
|
400
|
-
|
|
401
|
-
```js
|
|
402
|
-
// src/commands/project/update-agents.js
|
|
403
|
-
import { installAgents } from '../../utils/agents-installer.js';
|
|
404
|
-
import { logger } from '../../utils/logger.js';
|
|
405
|
-
import { join } from 'path';
|
|
406
|
-
import { fileURLToPath } from 'url';
|
|
407
|
-
import { dirname } from 'path';
|
|
408
|
-
|
|
409
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
410
|
-
const FRAMEWORK_DIR = join(__dirname, '..', '..', '..', 'framework');
|
|
411
|
-
|
|
412
|
-
export async function updateAgentsCommand(args, options) {
|
|
413
|
-
const projectDir = process.cwd();
|
|
414
|
-
logger.info('Updating native subagents in .claude/agents/...');
|
|
415
|
-
await installAgents(projectDir, FRAMEWORK_DIR);
|
|
416
|
-
logger.success('Native subagents updated. Claude Code will discover them on next session start.');
|
|
417
|
-
}
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
### Step 3: Register in `bin/morph-spec.js`
|
|
421
|
-
|
|
422
|
-
Find the agents command group and add:
|
|
423
|
-
```js
|
|
424
|
-
program
|
|
425
|
-
.command('update-agents')
|
|
426
|
-
.description('Refresh .claude/agents/ with latest morph orchestrator and domain agents')
|
|
427
|
-
.action(updateAgentsCommand);
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### Step 4: Run tests
|
|
431
|
-
|
|
432
|
-
```bash
|
|
433
|
-
npm test -- test/commands/update-agents.test.js
|
|
434
|
-
npm test
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
### Step 5: Commit
|
|
438
|
-
|
|
439
|
-
```bash
|
|
440
|
-
git add src/commands/project/update-agents.js bin/morph-spec.js test/commands/update-agents.test.js
|
|
441
|
-
git commit -m "feat(cli): add morph-spec update-agents command for refreshing native subagents"
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
---
|
|
445
|
-
|
|
446
|
-
## Task 6: Final integration test + docs update
|
|
447
|
-
|
|
448
|
-
**Files:**
|
|
449
|
-
- Test: `test/integration/init-full.test.js` (if it exists) or `test/commands/init.test.js`
|
|
450
|
-
- Modify: `framework/CLAUDE.md` (note new .claude/CLAUDE.md)
|
|
451
|
-
- Modify: `docs/plans/` (save plan here)
|
|
452
|
-
|
|
453
|
-
### Step 1: Run full test suite
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
npm test
|
|
457
|
-
```
|
|
458
|
-
Expected: All 552+ tests pass (0 regressions, new tests added).
|
|
459
|
-
|
|
460
|
-
### Step 2: Run coverage check
|
|
461
|
-
|
|
462
|
-
```bash
|
|
463
|
-
npm run test:coverage:summary
|
|
464
|
-
```
|
|
465
|
-
Verify new modules have reasonable coverage.
|
|
466
|
-
|
|
467
|
-
### Step 3: Manual smoke test
|
|
468
|
-
|
|
469
|
-
```bash
|
|
470
|
-
node bin/morph-spec.js init --force --skip-mcp --skip-detection
|
|
471
|
-
ls -la .claude/agents/
|
|
472
|
-
ls -la .claude/CLAUDE.md
|
|
473
|
-
cat .claude/settings.local.json | node -e "process.stdin.on('data',d=>{ const s=JSON.parse(d); console.log('schema:', s['\$schema']); console.log('env:', s.env); console.log('attribution:', s.attribution); })"
|
|
474
|
-
```
|
|
475
|
-
Expected: 6+ agent `.md` files, CLAUDE.md present, settings has `$schema` + `env` + `attribution`.
|
|
476
|
-
|
|
477
|
-
### Step 4: Save plan to docs
|
|
478
|
-
|
|
479
|
-
```bash
|
|
480
|
-
cp "C:\Users\Lucas\.claude\plans\magical-moseying-sutton.md" "docs/plans/2026-02-22-claude-settings.md"
|
|
481
|
-
git add docs/plans/2026-02-22-claude-settings.md
|
|
482
|
-
git commit -m "docs: save claude-settings alignment plan"
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
---
|
|
486
|
-
|
|
487
|
-
## Critical Files to Modify
|
|
488
|
-
|
|
489
|
-
| File | Change |
|
|
490
|
-
|------|--------|
|
|
491
|
-
| `src/utils/agents-installer.js` | **NEW** — converts agents.json tier-1/2 to `.claude/agents/` markdown |
|
|
492
|
-
| `src/utils/claude-settings-manager.js` | Re-export `installAgents` |
|
|
493
|
-
| `src/commands/project/init.js` | Call `installAgents` + copy `.claude/CLAUDE.md` |
|
|
494
|
-
| `src/utils/hooks-installer.js` | Add `$schema`, `env`, `attribution`, `plansDirectory` to settings |
|
|
495
|
-
| `src/commands/project/update-agents.js` | **NEW** — CLI command to refresh agents |
|
|
496
|
-
| `bin/morph-spec.js` | Register `update-agents` command |
|
|
497
|
-
| `framework/CLAUDE_runtime.md` | **NEW** — source for `.claude/CLAUDE.md` |
|
|
498
|
-
|
|
499
|
-
## Verification
|
|
500
|
-
|
|
501
|
-
```bash
|
|
502
|
-
# Full suite
|
|
503
|
-
npm test
|
|
504
|
-
|
|
505
|
-
# Smoke test init
|
|
506
|
-
node bin/morph-spec.js init --force --skip-mcp --skip-detection
|
|
507
|
-
|
|
508
|
-
# Verify native agents
|
|
509
|
-
ls .claude/agents/
|
|
510
|
-
cat .claude/agents/morph-standards-architect.md # Should have YAML frontmatter
|
|
511
|
-
|
|
512
|
-
# Verify settings
|
|
513
|
-
cat .claude/settings.local.json | grep -A2 "schema\|env\|attribution"
|
|
514
|
-
|
|
515
|
-
# Verify .claude/CLAUDE.md
|
|
516
|
-
cat .claude/CLAUDE.md
|
|
517
|
-
```
|