claude-prism 0.4.0 → 0.5.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/README.md +47 -45
- package/bin/cli.mjs +4 -12
- package/hooks/scope-guard.mjs +21 -1
- package/lib/config.mjs +0 -2
- package/lib/installer.mjs +8 -21
- package/lib/messages.mjs +12 -51
- package/lib/pipeline.mjs +0 -2
- package/package.json +2 -3
- package/templates/commands/claude-prism/checkpoint.md +17 -1
- package/templates/commands/claude-prism/prism.md +19 -6
- package/templates/{rules.en.md → rules.md} +33 -3
- package/templates/skills/prism/SKILL.md +19 -6
- package/README.ko.md +0 -444
- package/templates/rules.ja.md +0 -249
- package/templates/rules.ko.md +0 -249
- package/templates/rules.zh.md +0 -249
package/README.md
CHANGED
|
@@ -21,6 +21,21 @@ An AI coding problem decomposition tool for Claude Code. Installs the **UDEC** m
|
|
|
21
21
|
|
|
22
22
|
**Core philosophy:** Never implement what you haven't understood. Never execute what you haven't decomposed.
|
|
23
23
|
|
|
24
|
+
### What's New in v0.4.0
|
|
25
|
+
|
|
26
|
+
- **Task size tags** — Every task gets `[S]`, `[M]`, or `[L]` with adaptive batch composition (S+S+M = 1 batch, L = solo)
|
|
27
|
+
- **Verification strategy per task** — `| Verify: TDD`, `| Verify: Build`, or `| Verify: Visual` in plan templates
|
|
28
|
+
- **Pre-decomposition checklist** — Mandatory type/schema/dependency check before creating plans
|
|
29
|
+
- **Progress dashboard** — Visual progress bar with phase/batch/task percentages at each checkpoint
|
|
30
|
+
- **Adaptive checkpoints** — After 3 consecutive approvals, batch size expands to 5-8 for the rest of the phase
|
|
31
|
+
- **Scope guard disk fallback** — Detects existing `docs/plans/*.md` on disk, not just in-session writes (fixes false "without a plan" warnings across sessions)
|
|
32
|
+
- **20 test runner patterns** — Added bun, pnpm, yarn, deno, rspec, dotnet, mvn, gradle detection
|
|
33
|
+
- **9 framework-specific result detectors** — Accurate pass/fail for node, jest, vitest, pytest, go, cargo, mocha, rspec, dotnet
|
|
34
|
+
- **Unified hook pipeline** — Single process per hook event instead of separate processes per rule (reduced I/O)
|
|
35
|
+
- **Session event logging** — JSONL-based per-session event recording
|
|
36
|
+
- **Alignment detection** — Scope drift tracking and major decision flagging
|
|
37
|
+
- **Custom rules** — User-defined hook rules via config
|
|
38
|
+
|
|
24
39
|
## The Problem
|
|
25
40
|
|
|
26
41
|
Without structure, Claude does this:
|
|
@@ -36,10 +51,7 @@ Without structure, Claude does this:
|
|
|
36
51
|
## Installation
|
|
37
52
|
|
|
38
53
|
```bash
|
|
39
|
-
npx claude-prism init #
|
|
40
|
-
npx claude-prism init --lang=ko # Korean
|
|
41
|
-
npx claude-prism init --lang=ja # Japanese
|
|
42
|
-
npx claude-prism init --lang=zh # Chinese
|
|
54
|
+
npx claude-prism init # Install with hooks
|
|
43
55
|
npx claude-prism init --no-hooks # Rules only, no hooks
|
|
44
56
|
npx claude-prism init --global # Install as global skill (available in all projects)
|
|
45
57
|
npx claude-prism update # Update rules and commands to latest
|
|
@@ -66,13 +78,15 @@ After running `prism init`, your project gains:
|
|
|
66
78
|
- `/claude-prism:update` — Update rules and commands to latest version
|
|
67
79
|
- `/claude-prism:help` — Command reference
|
|
68
80
|
|
|
69
|
-
**Hooks** (optional, unless `--no-hooks` is set) —
|
|
81
|
+
**Hooks** (optional, unless `--no-hooks` is set) — Six CLI guards that enforce discipline:
|
|
70
82
|
- `commit-guard` — Prevents commits when tests haven't run recently
|
|
71
83
|
- `debug-loop` — Detects divergent editing patterns on the same file (catches infinite debugging loops)
|
|
72
|
-
- `test-tracker` — Detects test
|
|
73
|
-
- `scope-guard` — Warns at 4 unique files modified, blocks at 7 (agent-aware
|
|
84
|
+
- `test-tracker` — Detects test execution (20 patterns, 9 framework-specific result detectors) and records pass/fail
|
|
85
|
+
- `scope-guard` — Warns at 4 unique files modified, blocks at 7 (agent-aware, plan-aware with disk fallback)
|
|
86
|
+
- `alignment` — Detects scope drift (new directories outside base scope) and major decisions (package installs, db migrations, destructive deletes)
|
|
87
|
+
- `turn-reporter` — Tracks turn count, warns at 5 autonomous turns without user input, provides previous turn summary
|
|
74
88
|
|
|
75
|
-
**Configuration** — `.prism.json` stores
|
|
89
|
+
**Configuration** — `.claude-prism.json` stores hook settings. Includes OMC (oh-my-claudecode) detection.
|
|
76
90
|
|
|
77
91
|
## File Structure After Installation
|
|
78
92
|
|
|
@@ -91,19 +105,23 @@ your-project/
|
|
|
91
105
|
│ │ ├── update.md # /claude-prism:update
|
|
92
106
|
│ │ └── help.md # /claude-prism:help
|
|
93
107
|
│ ├── hooks/ # (optional, if --no-hooks not set)
|
|
94
|
-
│ │ ├──
|
|
95
|
-
│ │ ├──
|
|
96
|
-
│ │
|
|
97
|
-
│ │ └── scope-guard.mjs
|
|
108
|
+
│ │ ├── pre-tool.mjs # Unified PreToolUse runner
|
|
109
|
+
│ │ ├── post-tool.mjs # Unified PostToolUse runner
|
|
110
|
+
│ │ └── user-prompt.mjs # UserPromptSubmit runner
|
|
98
111
|
│ ├── rules/ # Hook logic modules
|
|
99
112
|
│ │ ├── commit-guard.mjs
|
|
100
113
|
│ │ ├── debug-loop.mjs
|
|
101
114
|
│ │ ├── test-tracker.mjs
|
|
102
|
-
│ │
|
|
115
|
+
│ │ ├── scope-guard.mjs
|
|
116
|
+
│ │ ├── alignment.mjs
|
|
117
|
+
│ │ └── turn-reporter.mjs
|
|
103
118
|
│ ├── lib/ # Hook dependencies
|
|
104
119
|
│ │ ├── adapter.mjs
|
|
120
|
+
│ │ ├── pipeline.mjs
|
|
105
121
|
│ │ ├── state.mjs
|
|
122
|
+
│ │ ├── session.mjs
|
|
106
123
|
│ │ ├── config.mjs
|
|
124
|
+
│ │ ├── messages.mjs
|
|
107
125
|
│ │ └── utils.mjs
|
|
108
126
|
│ └── settings.json # Claude Code hook registration
|
|
109
127
|
└── docs/plans/
|
|
@@ -140,7 +158,7 @@ your-project/
|
|
|
140
158
|
| `/claude-prism:plan` | Manage plan files | List, create, or view plans |
|
|
141
159
|
| `/claude-prism:checkpoint` | Mid-project | Check batch progress, preview next batch |
|
|
142
160
|
| `/claude-prism:doctor` | Installation issues | Diagnose health, suggest fixes |
|
|
143
|
-
| `/claude-prism:stats` | Check current state | Version, hooks,
|
|
161
|
+
| `/claude-prism:stats` | Check current state | Version, hooks, plan progress |
|
|
144
162
|
| `/claude-prism:update` | After `npm update` | Update rules and commands to latest |
|
|
145
163
|
| `/claude-prism:help` | Forgot commands | Quick reference |
|
|
146
164
|
|
|
@@ -199,7 +217,7 @@ User request arrives
|
|
|
199
217
|
**Pattern 4: Quick Troubleshooting**
|
|
200
218
|
```
|
|
201
219
|
/claude-prism:doctor → Check installation health
|
|
202
|
-
/claude-prism:stats → Verify hooks,
|
|
220
|
+
/claude-prism:stats → Verify hooks, OMC status
|
|
203
221
|
```
|
|
204
222
|
|
|
205
223
|
### Before & After
|
|
@@ -268,16 +286,19 @@ Detects editing patterns on the same file. Distinguishes between **divergent** e
|
|
|
268
286
|
|
|
269
287
|
Detects test command execution and records the timestamp and pass/fail state. Used by `commit-guard` to verify tests ran recently.
|
|
270
288
|
|
|
271
|
-
**Detects:**
|
|
272
|
-
- `npm test`, `
|
|
273
|
-
- `jest`, `vitest`
|
|
274
|
-
- `node --test`
|
|
275
|
-
- `npx
|
|
276
|
-
- `pytest`
|
|
277
|
-
- `
|
|
278
|
-
- `go test`
|
|
289
|
+
**Detects (20 patterns):**
|
|
290
|
+
- `npm test`, `pnpm test`, `yarn test`, `bun test`
|
|
291
|
+
- `jest`, `vitest`, `mocha`, `rspec`
|
|
292
|
+
- `node --test`, `deno test`
|
|
293
|
+
- `npx jest`, `npx vitest`, `npx mocha`, `bunx vitest`
|
|
294
|
+
- `pytest`, `cargo test`, `go test`
|
|
295
|
+
- `dotnet test`, `mvn test`, `gradle test`
|
|
279
296
|
- `make test`
|
|
280
297
|
|
|
298
|
+
**Framework-specific result detection (9 detectors):**
|
|
299
|
+
- Node test runner, Jest, Vitest, Pytest, Go, Cargo, Mocha, RSpec, dotnet
|
|
300
|
+
- Analyzes both stdout and stderr for accurate pass/fail determination
|
|
301
|
+
|
|
281
302
|
**Configuration:**
|
|
282
303
|
```json
|
|
283
304
|
{
|
|
@@ -323,6 +344,7 @@ Tracks unique source files modified per session. Warns when scope grows without
|
|
|
323
344
|
- **Plan-aware**: When a plan file is created (`docs/plans/*.md`), thresholds are automatically doubled
|
|
324
345
|
- Standard with plan: warns at 8, blocks at 14
|
|
325
346
|
- Agent with plan: warns at 16, blocks at 24
|
|
347
|
+
- **Cross-session persistence**: Detects existing plan files on disk (`docs/plans/*.md`), not just plans created in the current session. Fixes false "without a plan" warnings when resuming work in a new session.
|
|
326
348
|
|
|
327
349
|
## Configuration
|
|
328
350
|
|
|
@@ -330,7 +352,6 @@ Edit `.claude-prism.json` to customize behavior:
|
|
|
330
352
|
|
|
331
353
|
```json
|
|
332
354
|
{
|
|
333
|
-
"language": "en",
|
|
334
355
|
"hooks": {
|
|
335
356
|
"commit-guard": { "enabled": true, "maxTestAge": 300 },
|
|
336
357
|
"debug-loop": { "enabled": true, "warnAt": 3, "blockAt": 5 },
|
|
@@ -341,7 +362,6 @@ Edit `.claude-prism.json` to customize behavior:
|
|
|
341
362
|
```
|
|
342
363
|
|
|
343
364
|
**Settings:**
|
|
344
|
-
- `language` — Rule language: `en` (English), `ko` (Korean), `ja` (Japanese), `zh` (Chinese)
|
|
345
365
|
- `hooks.*` — Enable/disable individual hooks or customize thresholds
|
|
346
366
|
- `hooks.commit-guard.maxTestAge` — Seconds before test is considered stale (default: 300)
|
|
347
367
|
- `hooks.debug-loop.warnAt/blockAt` — Edit counts that trigger warnings/blocks
|
|
@@ -404,7 +424,7 @@ If issues are found:
|
|
|
404
424
|
|
|
405
425
|
### prism stats
|
|
406
426
|
|
|
407
|
-
Show installation summary including version,
|
|
427
|
+
Show installation summary including version, hook status, plan file count, and OMC detection:
|
|
408
428
|
|
|
409
429
|
```bash
|
|
410
430
|
prism stats
|
|
@@ -412,8 +432,7 @@ prism stats
|
|
|
412
432
|
|
|
413
433
|
Output:
|
|
414
434
|
```
|
|
415
|
-
Version: v0.
|
|
416
|
-
Language: en
|
|
435
|
+
Version: v0.4.0
|
|
417
436
|
Plans: 2 file(s)
|
|
418
437
|
OMC: ✅ v4.1.1
|
|
419
438
|
Hooks:
|
|
@@ -446,23 +465,6 @@ npx claude-prism uninstall
|
|
|
446
465
|
|
|
447
466
|
This removes CLAUDE.md rules, slash commands, and hooks.
|
|
448
467
|
|
|
449
|
-
## Languages
|
|
450
|
-
|
|
451
|
-
Supported languages for UDEC rules:
|
|
452
|
-
|
|
453
|
-
- **en** — English (default)
|
|
454
|
-
- **ko** — Korean
|
|
455
|
-
- **ja** — Japanese
|
|
456
|
-
- **zh** — Chinese
|
|
457
|
-
|
|
458
|
-
Change language (or re-install with different language):
|
|
459
|
-
|
|
460
|
-
```bash
|
|
461
|
-
npx claude-prism init --lang=ko # Install Korean rules
|
|
462
|
-
npx claude-prism init --lang=ja # Install Japanese rules
|
|
463
|
-
npx claude-prism init --lang=zh # Install Chinese rules
|
|
464
|
-
```
|
|
465
|
-
|
|
466
468
|
## OMC (oh-my-claudecode) Integration
|
|
467
469
|
|
|
468
470
|
Prism auto-detects if [oh-my-claudecode](https://github.com/raidenppl/oh-my-claudecode) is installed in your environment. When OMC is present:
|
package/bin/cli.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* claude-prism CLI
|
|
5
|
-
* Usage: prism init [--
|
|
5
|
+
* Usage: prism init [--no-hooks]
|
|
6
6
|
* prism check [--ci]
|
|
7
7
|
* prism doctor
|
|
8
8
|
* prism stats
|
|
@@ -16,11 +16,6 @@ import { init, check, uninstall, update, doctor, stats, reset, initGlobal, unins
|
|
|
16
16
|
const args = process.argv.slice(2);
|
|
17
17
|
const command = args[0];
|
|
18
18
|
|
|
19
|
-
function getFlag(name) {
|
|
20
|
-
const flag = args.find(a => a.startsWith(`--${name}=`));
|
|
21
|
-
return flag ? flag.split('=')[1] : null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
19
|
function hasFlag(name) {
|
|
25
20
|
return args.includes(`--${name}`) || args.includes(`-${name}`);
|
|
26
21
|
}
|
|
@@ -47,12 +42,11 @@ switch (command) {
|
|
|
47
42
|
break;
|
|
48
43
|
}
|
|
49
44
|
|
|
50
|
-
const language = getFlag('lang') || 'en';
|
|
51
45
|
const hooks = !hasFlag('no-hooks');
|
|
52
46
|
|
|
53
47
|
if (hasFlag('dry-run')) {
|
|
54
48
|
const { dryRun } = await import('../lib/installer.mjs');
|
|
55
|
-
const result = dryRun(cwd, {
|
|
49
|
+
const result = dryRun(cwd, { hooks });
|
|
56
50
|
console.log('🌈 claude-prism init --dry-run\n');
|
|
57
51
|
console.log(' Files that would be created/updated:\n');
|
|
58
52
|
for (const action of result.actions) {
|
|
@@ -64,7 +58,7 @@ switch (command) {
|
|
|
64
58
|
}
|
|
65
59
|
|
|
66
60
|
console.log('🌈 claude-prism init\n');
|
|
67
|
-
await init(cwd, {
|
|
61
|
+
await init(cwd, { hooks });
|
|
68
62
|
|
|
69
63
|
console.log('✅ Rules injected → CLAUDE.md');
|
|
70
64
|
console.log('✅ Commands installed → /prism, /checkpoint');
|
|
@@ -121,7 +115,6 @@ switch (command) {
|
|
|
121
115
|
const result = stats(cwd);
|
|
122
116
|
console.log('🌈 claude-prism stats\n');
|
|
123
117
|
console.log(` Version: v${result.version}`);
|
|
124
|
-
console.log(` Language: ${result.language}`);
|
|
125
118
|
console.log(` Plans: ${result.planFiles} file(s)`);
|
|
126
119
|
console.log(` OMC: ${result.omc.detected ? `✅ v${result.omc.version || 'unknown'}` : '⏭️ not detected'}`);
|
|
127
120
|
console.log(' Hooks:');
|
|
@@ -182,7 +175,7 @@ switch (command) {
|
|
|
182
175
|
console.log(`🌈 claude-prism — AI coding problem decomposition tool
|
|
183
176
|
|
|
184
177
|
Usage:
|
|
185
|
-
prism init [--
|
|
178
|
+
prism init [--no-hooks] Install prism in current project
|
|
186
179
|
prism init --global Install globally (~/.claude/) + OMC skill
|
|
187
180
|
prism check [--ci] Verify installation
|
|
188
181
|
prism doctor Diagnose issues with fix suggestions
|
|
@@ -194,7 +187,6 @@ Usage:
|
|
|
194
187
|
prism uninstall --global Remove global commands + OMC skill
|
|
195
188
|
|
|
196
189
|
Options:
|
|
197
|
-
--lang=XX Language: en (default), ko, ja, zh
|
|
198
190
|
--no-hooks Skip enforcement hooks
|
|
199
191
|
--dry-run Show what init would do without making changes
|
|
200
192
|
--global Install/uninstall globally (all projects)
|
package/hooks/scope-guard.mjs
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import { readJsonState, writeJsonState } from '../lib/state.mjs';
|
|
7
7
|
import { DEFAULTS, buildSourcePattern, buildTestPattern } from '../lib/config.mjs';
|
|
8
8
|
import { getMessage } from '../lib/messages.mjs';
|
|
9
|
+
import { existsSync, readdirSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
9
11
|
|
|
10
12
|
const PLAN_PATTERN = /(?:^|\/)docs\/plans\/.*\.md$|(?:^|\/).*plan.*\.md$/i;
|
|
11
13
|
|
|
@@ -47,7 +49,25 @@ export const scopeGuard = {
|
|
|
47
49
|
let blockAt = isAgent ? (config.agentBlockAt || 12) : (config.blockAt || 7);
|
|
48
50
|
|
|
49
51
|
// Active plan → double thresholds (planned work is expected to touch many files)
|
|
50
|
-
|
|
52
|
+
let hasPlan = readJsonState(stateDir, 'scope-has-plan');
|
|
53
|
+
|
|
54
|
+
// Fallback: check disk for existing plan files (survives session restart)
|
|
55
|
+
if (!hasPlan) {
|
|
56
|
+
try {
|
|
57
|
+
const root = config.projectRoot || process.cwd();
|
|
58
|
+
const plansDir = join(root, 'docs', 'plans');
|
|
59
|
+
if (existsSync(plansDir)) {
|
|
60
|
+
const planFiles = readdirSync(plansDir).filter(f => f.endsWith('.md'));
|
|
61
|
+
if (planFiles.length > 0) {
|
|
62
|
+
hasPlan = true;
|
|
63
|
+
writeJsonState(stateDir, 'scope-has-plan', true);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
// Ignore filesystem errors — fail open
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
if (hasPlan) {
|
|
52
72
|
warnAt *= 2;
|
|
53
73
|
blockAt *= 2;
|
package/lib/config.mjs
CHANGED
|
@@ -7,7 +7,6 @@ import { readFileSync, existsSync } from 'fs';
|
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
|
|
9
9
|
const DEFAULTS = {
|
|
10
|
-
language: 'en',
|
|
11
10
|
sourceExtensions: ['ts', 'tsx', 'js', 'jsx', 'py', 'go', 'rs', 'java', 'c', 'cpp', 'h', 'svelte', 'vue', 'rb', 'kt', 'swift', 'php', 'cs', 'scala', 'ex', 'clj', 'zig', 'lua', 'dart'],
|
|
12
11
|
testPatterns: ['test', 'spec', '_test'],
|
|
13
12
|
customRules: [],
|
|
@@ -39,7 +38,6 @@ export function getHookConfig(hookName, projectRoot) {
|
|
|
39
38
|
const config = loadConfig(projectRoot);
|
|
40
39
|
const hookConfig = config.hooks?.[hookName] || DEFAULTS.hooks[hookName] || { enabled: true };
|
|
41
40
|
// Include top-level fields needed by hooks
|
|
42
|
-
hookConfig.language = config.language || DEFAULTS.language;
|
|
43
41
|
hookConfig.sourceExtensions = config.sourceExtensions || DEFAULTS.sourceExtensions;
|
|
44
42
|
hookConfig.testPatterns = config.testPatterns || DEFAULTS.testPatterns;
|
|
45
43
|
return hookConfig;
|
package/lib/installer.mjs
CHANGED
|
@@ -16,11 +16,10 @@ const TEMPLATES_DIR = join(__dirname, '..', 'templates');
|
|
|
16
16
|
* Initialize prism in a project
|
|
17
17
|
* @param {string} projectDir - Project root
|
|
18
18
|
* @param {Object} options
|
|
19
|
-
* @param {string} options.language - 'en' | 'ko'
|
|
20
19
|
* @param {boolean} options.hooks - Install enforcement hooks
|
|
21
20
|
*/
|
|
22
21
|
export async function init(projectDir, options = {}) {
|
|
23
|
-
const {
|
|
22
|
+
const { hooks = true } = options;
|
|
24
23
|
|
|
25
24
|
// 1. Create directories
|
|
26
25
|
const claudeDir = join(projectDir, '.claude');
|
|
@@ -78,13 +77,12 @@ export async function init(projectDir, options = {}) {
|
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
// 4. Inject rules into CLAUDE.md
|
|
81
|
-
injectRules(projectDir
|
|
80
|
+
injectRules(projectDir);
|
|
82
81
|
|
|
83
82
|
// 5. Create .claude-prism.json config
|
|
84
83
|
const configPath = join(projectDir, '.claude-prism.json');
|
|
85
84
|
if (!existsSync(configPath)) {
|
|
86
85
|
writeFileSync(configPath, JSON.stringify({
|
|
87
|
-
language,
|
|
88
86
|
hooks: {
|
|
89
87
|
'commit-guard': { enabled: true, maxTestAge: 300 },
|
|
90
88
|
'debug-loop': { enabled: true, warnAt: 3, blockAt: 5 },
|
|
@@ -216,12 +214,10 @@ export async function update(projectDir) {
|
|
|
216
214
|
}
|
|
217
215
|
|
|
218
216
|
const configPath = newConfigPath;
|
|
219
|
-
let language = 'en';
|
|
220
217
|
let hooks = true;
|
|
221
218
|
|
|
222
219
|
if (existsSync(configPath)) {
|
|
223
220
|
const config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
224
|
-
language = config.language || 'en';
|
|
225
221
|
hooks = config.hooks?.['commit-guard']?.enabled !== false;
|
|
226
222
|
}
|
|
227
223
|
|
|
@@ -241,7 +237,7 @@ export async function update(projectDir) {
|
|
|
241
237
|
// Remove old config so init creates a fresh one
|
|
242
238
|
if (existsSync(configPath)) rmSync(configPath);
|
|
243
239
|
|
|
244
|
-
await init(projectDir, {
|
|
240
|
+
await init(projectDir, { hooks });
|
|
245
241
|
}
|
|
246
242
|
|
|
247
243
|
/**
|
|
@@ -356,7 +352,7 @@ export function doctor(projectDir, options = {}) {
|
|
|
356
352
|
* @param {string} projectDir
|
|
357
353
|
* @param {Object} [options]
|
|
358
354
|
* @param {string} [options.homeDir] - Override home dir (for testing)
|
|
359
|
-
* @returns {{ version: string,
|
|
355
|
+
* @returns {{ version: string, hooks: Object, planFiles: number, omc: Object }}
|
|
360
356
|
*/
|
|
361
357
|
export function stats(projectDir, options = {}) {
|
|
362
358
|
// Read version from package.json
|
|
@@ -365,12 +361,10 @@ export function stats(projectDir, options = {}) {
|
|
|
365
361
|
|
|
366
362
|
// Read config
|
|
367
363
|
const configPath = join(projectDir, '.claude-prism.json');
|
|
368
|
-
let language = 'en';
|
|
369
364
|
let hookConfig = {};
|
|
370
365
|
|
|
371
366
|
if (existsSync(configPath)) {
|
|
372
367
|
const config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
373
|
-
language = config.language || 'en';
|
|
374
368
|
if (config.hooks) {
|
|
375
369
|
for (const [name, cfg] of Object.entries(config.hooks)) {
|
|
376
370
|
hookConfig[name] = cfg.enabled !== false;
|
|
@@ -390,7 +384,6 @@ export function stats(projectDir, options = {}) {
|
|
|
390
384
|
|
|
391
385
|
return {
|
|
392
386
|
version: pkg.version,
|
|
393
|
-
language,
|
|
394
387
|
hooks: hookConfig,
|
|
395
388
|
planFiles,
|
|
396
389
|
omc
|
|
@@ -463,7 +456,7 @@ export function uninstallGlobal(options = {}) {
|
|
|
463
456
|
* @returns {{ actions: Array<{type: string, path: string, status: string}> }}
|
|
464
457
|
*/
|
|
465
458
|
export function dryRun(projectDir, options = {}) {
|
|
466
|
-
const {
|
|
459
|
+
const { hooks = true } = options;
|
|
467
460
|
const claudeDir = join(projectDir, '.claude');
|
|
468
461
|
const actions = [];
|
|
469
462
|
|
|
@@ -531,16 +524,10 @@ export function dryRun(projectDir, options = {}) {
|
|
|
531
524
|
|
|
532
525
|
// ─── internal helpers ───
|
|
533
526
|
|
|
534
|
-
function injectRules(projectDir
|
|
527
|
+
function injectRules(projectDir) {
|
|
535
528
|
const claudeMdPath = join(projectDir, 'CLAUDE.md');
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
// Fallback to English if requested language not available
|
|
540
|
-
if (!existsSync(rulesPath)) {
|
|
541
|
-
rulesPath = join(TEMPLATES_DIR, 'rules.en.md');
|
|
542
|
-
if (!existsSync(rulesPath)) return;
|
|
543
|
-
}
|
|
529
|
+
const rulesPath = join(TEMPLATES_DIR, 'rules.md');
|
|
530
|
+
if (!existsSync(rulesPath)) return;
|
|
544
531
|
|
|
545
532
|
const rules = readFileSync(rulesPath, 'utf8');
|
|
546
533
|
|
package/lib/messages.mjs
CHANGED
|
@@ -1,60 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* claude-prism — Hook Message Templates
|
|
3
|
-
* Provides localized messages for hook output
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
const MESSAGES = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'test-tracker.warn.failed': '🌈 Prism 📊 Tests FAILED. Fix before committing.',
|
|
18
|
-
},
|
|
19
|
-
ko: {
|
|
20
|
-
'commit-guard.block.failed': '🌈 Prism ✋ 커밋 차단: 마지막 테스트 실패. 테스트를 수정한 후 커밋하세요.',
|
|
21
|
-
'commit-guard.warn.no-test': '🌈 Prism > 이 세션에서 테스트 실행 이력이 없습니다. 커밋 전에 테스트를 실행하세요.',
|
|
22
|
-
'commit-guard.warn.stale': '🌈 Prism > 마지막 테스트가 {minutes}분 전입니다. 커밋 전에 테스트를 실행하세요.',
|
|
23
|
-
'debug-loop.block.divergent': '🌈 Prism ✋ 디버그 루프 차단: {name}이 같은 영역에서 {count}회 수정됨. 사용자와 접근 방식을 논의하세요.',
|
|
24
|
-
'debug-loop.warn.divergent': '🌈 Prism > 디버그 루프: {name}이 같은 영역에서 {count}회 수정됨. 멈추고 근본 원인을 조사하세요.',
|
|
25
|
-
'debug-loop.warn.convergent': '🌈 Prism > 디버그 루프: {name}이 {count}회 수정됨 (다른 영역). 예상된 작업인지 확인하세요.',
|
|
26
|
-
'scope-guard.block': '🌈 Prism ✋ 스코프 가드: 계획 없이 {count}개 고유 파일 수정됨. /prism으로 분해 후 계속하세요.',
|
|
27
|
-
'scope-guard.warn': '🌈 Prism > 스코프 가드: {count}개 고유 파일 수정됨. /prism으로 작업을 분해하는 것을 고려하세요.',
|
|
28
|
-
'scope-guard.plan-detected': '🌈 Prism 📋 계획 파일 감지됨. 스코프 임계값이 상향 조정되었습니다.',
|
|
29
|
-
'test-tracker.warn.failed': '🌈 Prism 📊 테스트 실패. 커밋 전에 수정하세요.',
|
|
30
|
-
},
|
|
31
|
-
ja: {
|
|
32
|
-
'commit-guard.block.failed': '🌈 Prism ✋ コミットブロック: 最後のテストが失敗しました。テストを修正してからコミットしてください。',
|
|
33
|
-
'commit-guard.warn.no-test': '🌈 Prism > このセッションでテスト実行が検出されません。コミット前にテストを実行してください。',
|
|
34
|
-
'commit-guard.warn.stale': '🌈 Prism > 最後のテスト実行は{minutes}分前です。コミット前にテストを実行してください。',
|
|
35
|
-
'debug-loop.block.divergent': '🌈 Prism ✋ デバッグループブロック: {name}が同じ領域で{count}回編集されました。ユーザーとアプローチを議論してください。',
|
|
36
|
-
'debug-loop.warn.divergent': '🌈 Prism > デバッグループ: {name}が同じ領域で{count}回編集されました。停止して根本原因を調査してください。',
|
|
37
|
-
'debug-loop.warn.convergent': '🌈 Prism > デバッグループ: {name}が{count}回編集されました(異なる領域)。想定通りか確認してください。',
|
|
38
|
-
'scope-guard.block': '🌈 Prism ✋ スコープガード: 計画なしに{count}個のファイルが変更されました。/prismで分解してから続行してください。',
|
|
39
|
-
'scope-guard.warn': '🌈 Prism > スコープガード: {count}個のファイルが変更されました。/prismでタスクの分解を検討してください。',
|
|
40
|
-
'scope-guard.plan-detected': '🌈 Prism 📋 計画ファイルを検出。スコープ閾値を引き上げました。',
|
|
41
|
-
'test-tracker.warn.failed': '🌈 Prism 📊 テスト失敗。コミット前に修正してください。',
|
|
42
|
-
},
|
|
43
|
-
zh: {
|
|
44
|
-
'commit-guard.block.failed': '🌈 Prism ✋ 提交被阻止:上次测试失败。请修复测试后再提交。',
|
|
45
|
-
'commit-guard.warn.no-test': '🌈 Prism > 本次会话未检测到测试运行。请在提交前运行测试。',
|
|
46
|
-
'commit-guard.warn.stale': '🌈 Prism > 上次测试运行在{minutes}分钟前。请在提交前运行测试。',
|
|
47
|
-
'debug-loop.block.divergent': '🌈 Prism ✋ 调试循环阻止:{name}在同一区域被编辑了{count}次。请与用户讨论方法。',
|
|
48
|
-
'debug-loop.warn.divergent': '🌈 Prism > 调试循环:{name}在同一区域被编辑了{count}次。停止并调查根本原因。',
|
|
49
|
-
'debug-loop.warn.convergent': '🌈 Prism > 调试循环:{name}被编辑了{count}次(不同区域)。请确认这是否是预期行为。',
|
|
50
|
-
'scope-guard.block': '🌈 Prism ✋ 范围守卫:未制定计划就修改了{count}个文件。请运行/prism分解后再继续。',
|
|
51
|
-
'scope-guard.warn': '🌈 Prism > 范围守卫:已修改{count}个文件。请考虑运行/prism来分解任务。',
|
|
52
|
-
'scope-guard.plan-detected': '🌈 Prism 📋 检测到计划文件。范围阈值已提高。',
|
|
53
|
-
'test-tracker.warn.failed': '🌈 Prism 📊 测试失败。请在提交前修复。',
|
|
54
|
-
},
|
|
6
|
+
'commit-guard.block.failed': '🌈 Prism ✋ Commit blocked: last test run FAILED. Fix tests before committing.',
|
|
7
|
+
'commit-guard.warn.no-test': '🌈 Prism > No test run detected this session. Run tests before committing.',
|
|
8
|
+
'commit-guard.warn.stale': '🌈 Prism > Last test run was {minutes}min ago. Run tests before committing.',
|
|
9
|
+
'debug-loop.block.divergent': '🌈 Prism ✋ Debug Loop blocked: {name} edited {count} times on same area. Discuss approach with user before continuing.',
|
|
10
|
+
'debug-loop.warn.divergent': '🌈 Prism > Debug Loop: {name} edited {count} times on same area. Stop and investigate root cause.',
|
|
11
|
+
'debug-loop.warn.convergent': '🌈 Prism > Debug Loop: {name} edited {count} times (different areas). Consider if this is expected.',
|
|
12
|
+
'scope-guard.block': '🌈 Prism ✋ Scope Guard: {count} unique files modified without a plan. Run /prism to decompose before continuing.',
|
|
13
|
+
'scope-guard.warn': '🌈 Prism > Scope Guard: {count} unique files modified. Consider running /prism to decompose the task.',
|
|
14
|
+
'scope-guard.plan-detected': '🌈 Prism 📋 Plan file detected. Scope thresholds raised.',
|
|
15
|
+
'test-tracker.warn.failed': '🌈 Prism 📊 Tests FAILED. Fix before committing.',
|
|
55
16
|
};
|
|
56
17
|
|
|
57
|
-
export function getMessage(
|
|
58
|
-
const template = MESSAGES[
|
|
18
|
+
export function getMessage(_lang, key, params = {}) {
|
|
19
|
+
const template = MESSAGES[key] || key;
|
|
59
20
|
return template.replace(/\{(\w+)\}/g, (_, k) => params[k] ?? `{${k}}`);
|
|
60
21
|
}
|
package/lib/pipeline.mjs
CHANGED
|
@@ -80,7 +80,6 @@ export function runPipeline(rules, hookEventName) {
|
|
|
80
80
|
for (const { name, rule } of rules) {
|
|
81
81
|
// Build hook-specific config (same as getHookConfig but without re-reading file)
|
|
82
82
|
const hookConfig = fullConfig.hooks?.[name] || { enabled: true };
|
|
83
|
-
hookConfig.language = fullConfig.language || 'en';
|
|
84
83
|
hookConfig.sourceExtensions = fullConfig.sourceExtensions;
|
|
85
84
|
hookConfig.testPatterns = fullConfig.testPatterns;
|
|
86
85
|
|
|
@@ -157,7 +156,6 @@ export async function runPipelineAsync(builtInRules, hookEventName) {
|
|
|
157
156
|
|
|
158
157
|
for (const { name, rule } of rules) {
|
|
159
158
|
const hookConfig = fullConfig.hooks?.[name] || { enabled: true };
|
|
160
|
-
hookConfig.language = fullConfig.language || 'en';
|
|
161
159
|
hookConfig.sourceExtensions = fullConfig.sourceExtensions;
|
|
162
160
|
hookConfig.testPatterns = fullConfig.testPatterns;
|
|
163
161
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-prism",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "AI coding problem decomposition tool — Understand, Decompose, Execute, Checkpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,8 +33,7 @@
|
|
|
33
33
|
"lib/",
|
|
34
34
|
"hooks/",
|
|
35
35
|
"templates/",
|
|
36
|
-
"README.md"
|
|
37
|
-
"README.ko.md"
|
|
36
|
+
"README.md"
|
|
38
37
|
],
|
|
39
38
|
"repository": {
|
|
40
39
|
"type": "git",
|
|
@@ -22,13 +22,29 @@ When this command is invoked:
|
|
|
22
22
|
|
|
23
23
|
### Progress
|
|
24
24
|
|
|
25
|
+
```
|
|
26
|
+
Phase: [current phase] | Batch: [N/M] | Tasks: [done/total] ([%])
|
|
27
|
+
[████████░░] 80% — Next: [next batch name]
|
|
28
|
+
```
|
|
29
|
+
|
|
25
30
|
- Batches complete: N/M
|
|
26
31
|
- Current batch: [name] — [X/Y tasks done]
|
|
27
32
|
- Remaining: [batch names]
|
|
28
33
|
- Blockers: [any issues encountered]
|
|
29
34
|
|
|
35
|
+
### Task Size Distribution
|
|
36
|
+
|
|
37
|
+
| Size | Count | Done |
|
|
38
|
+
|------|-------|------|
|
|
39
|
+
| [S] Small | N | N |
|
|
40
|
+
| [M] Medium | N | N |
|
|
41
|
+
| [L] Large | N | N |
|
|
42
|
+
|
|
30
43
|
4. **Show summary**:
|
|
31
44
|
- Files created/modified so far
|
|
32
45
|
- Tests added and their status
|
|
33
46
|
- Commits made
|
|
34
|
-
5. **
|
|
47
|
+
5. **Checkpoint policy check**:
|
|
48
|
+
- If 3+ consecutive approvals → suggest expanding batch size to 5-8
|
|
49
|
+
- If phase boundary → always stop
|
|
50
|
+
6. **Ask**: "Continue with the current plan, adjust, or stop?"
|
|
@@ -42,8 +42,15 @@ When this command is invoked, follow the UDEC framework strictly:
|
|
|
42
42
|
- Independent verification: each unit has a pass criterion
|
|
43
43
|
- Files specified: list files to create/modify per unit
|
|
44
44
|
- Dependencies noted: mark if unit depends on a previous one
|
|
45
|
-
9. **
|
|
46
|
-
|
|
45
|
+
9. **Assign size tags** to every task: [S] <30 LOC, [M] 30-100 LOC, [L] >100 LOC
|
|
46
|
+
- Batch composition: S+S+M = 1 batch, L = 1 batch alone
|
|
47
|
+
10. **Assign verification strategy** per task: `| Verify: TDD` or `| Verify: Build` or `| Verify: Visual`
|
|
48
|
+
11. **Pre-decomposition checklist**:
|
|
49
|
+
- Required types/interfaces have the necessary fields?
|
|
50
|
+
- External package APIs behave as expected?
|
|
51
|
+
- Cross-package dependencies identified and noted as prerequisites?
|
|
52
|
+
12. **Save plan** to `docs/plans/YYYY-MM-DD-<topic>.md`
|
|
53
|
+
13. **Get approval**: "Proceed with this plan?"
|
|
47
54
|
|
|
48
55
|
## E — EXECUTE
|
|
49
56
|
|
|
@@ -70,15 +77,21 @@ When this command is invoked, follow the UDEC framework strictly:
|
|
|
70
77
|
|
|
71
78
|
## C — CHECKPOINT
|
|
72
79
|
|
|
73
|
-
|
|
80
|
+
20. After each batch, report using this format:
|
|
74
81
|
|
|
75
82
|
| Item | Before | After |
|
|
76
83
|
|------|--------|-------|
|
|
77
84
|
| [what changed] | [old behavior] | [new behavior] |
|
|
78
85
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
```
|
|
87
|
+
Phase: [current] | Batch: [N/M] | Tasks: [done/total] ([%])
|
|
88
|
+
[████████░░] 80% — Next: [next batch name]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
21. Include: verification results, files modified, tests status
|
|
92
|
+
22. **Checkpoint policy**: after 3 consecutive approvals, increase batch size to 5-8 for the rest of the phase
|
|
93
|
+
23. Ask: "Continue to next batch?"
|
|
94
|
+
24. User can redirect, adjust scope, or stop at any checkpoint
|
|
82
95
|
|
|
83
96
|
## OMC Integration
|
|
84
97
|
|