claude-prism 0.3.1 → 0.4.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.ko.md CHANGED
@@ -11,13 +11,19 @@ AI 코딩 문제 분해 도구 — Understand, Decompose, Execute, Checkpoint (U
11
11
  스펙트럼
12
12
  ```
13
13
 
14
+ [![npm version](https://img.shields.io/npm/v/claude-prism)](https://www.npmjs.com/package/claude-prism)
15
+ [![license](https://img.shields.io/npm/l/claude-prism)](https://github.com/lazysaturday91/claude-prism/blob/main/LICENSE)
16
+ [![node](https://img.shields.io/node/v/claude-prism)](https://nodejs.org)
17
+
18
+ > `ai-coding` · `problem-decomposition` · `claude-code-hooks` · `claude-code-plugin` · `udec` · `scope-guard`
19
+
14
20
  ## 무엇인가
15
21
 
16
22
  `claude-prism`은 UDEC 방법론 프레임워크를 Claude Code 프로젝트에 설치합니다.
17
23
 
18
24
  - **U**nderstand (이해) — 행동하기 전에 정보 충분성을 판별. 구조화된 질문 (한 번에 하나씩, 객관식, 최대 3라운드)
19
25
  - **D**ecompose (분해) — 복잡한 문제를 2-5분 크기의 검증 가능한 단위로 분해, TDD 기반
20
- - **E**xecute (실행) — 배치 실행 (배치당 3-4개 태스크), TDD Iron Law 준수
26
+ - **E**xecute (실행) — 적응형 배치 실행, 파일 경로별 컨텍스트 인식 검증 (TDD / 빌드 / lint-only)
21
27
  - **C**heckpoint (확인) — 매 배치 후 보고, 다음 진행 전 사용자 확인
22
28
 
23
29
  ## 핵심 철학
@@ -37,6 +43,9 @@ npx claude-prism init --lang=ja # 일본어
37
43
  npx claude-prism init --lang=zh # 중국어
38
44
  npx claude-prism init --no-hooks # 규칙만, hook 없이
39
45
  prism check # 설치 확인
46
+ npx claude-prism init --global # 글로벌 스킬로 설치 (모든 프로젝트에서 사용)
47
+ npx claude-prism update # 규칙과 커맨드를 최신으로 업데이트
48
+ npx claude-prism update --global # 글로벌 스킬도 업데이트
40
49
  ```
41
50
 
42
51
  ## 설치 후 구조
@@ -53,7 +62,8 @@ prism check # 설치 확인
53
62
  │ │ ├── plan.md # /claude-prism:plan
54
63
  │ │ ├── doctor.md # /claude-prism:doctor
55
64
  │ │ ├── stats.md # /claude-prism:stats
56
- │ │ └── help.md # /claude-prism:help
65
+ │ │ ├── help.md # /claude-prism:help
66
+ │ │ └── update.md # /claude-prism:update
57
67
  │ ├── hooks/ # (선택, --no-hooks 시 생략)
58
68
  │ │ ├── commit-guard.mjs
59
69
  │ │ ├── debug-loop.mjs
@@ -86,6 +96,7 @@ prism check # 설치 확인
86
96
  | `/claude-prism:doctor` | 설치 문제 | 건강 진단, 수정 제안 |
87
97
  | `/claude-prism:stats` | 현재 상태 | 버전, hooks, 언어, 플랜 진행률 |
88
98
  | `/claude-prism:help` | 커맨드 확인 | 커맨드 레퍼런스 |
99
+ | `/claude-prism:update` | 업데이트 후 | 규칙과 커맨드를 최신 버전으로 업데이트 |
89
100
 
90
101
  ### 워크플로우
91
102
 
@@ -224,7 +235,7 @@ prism stats
224
235
 
225
236
  출력:
226
237
  ```
227
- Version: v0.1.0
238
+ Version: v0.3.1
228
239
  Language: ko
229
240
  Plans: 2 file(s)
230
241
  OMC: ✅ v4.1.1
@@ -276,7 +287,7 @@ Hook은 선택 사항인 CLI 가드로, 개발 중 규율을 강제합니다. `p
276
287
 
277
288
  ### debug-loop
278
289
 
279
- 같은 파일을 연속으로 편집할 경고 (3회), 차단 (5회). 무한 디버깅 루프 감지.
290
+ 같은 파일의 편집 패턴을 분석합니다. **발산 편집** (같은 코드 영역 반복 — 삽질 가능성) **수렴 편집** (다른 영역: import, 로직, JSX — 정상적인 점진적 작업)을 구별합니다.
280
291
 
281
292
  ```json
282
293
  {
@@ -291,9 +302,10 @@ Hook은 선택 사항인 CLI 가드로, 개발 중 규율을 강제합니다. `p
291
302
  ```
292
303
 
293
304
  **동작:**
294
- - 세션 같은 파일의 연속 편집 추적
295
- - 3회 편집: 경고 "문제를 이해하기 위해 발 물러나세요"
296
- - 5회 편집: 차단 재평가 강제
305
+ - 스니펫 분석으로 편집 패턴 추적
306
+ - **발산 패턴** (같은 영역): 3회에서 경고, 5회에서 차단
307
+ - **수렴 패턴** (다른 영역): 조용히 통과, 차단도 경고로 다운그레이드
308
+ - 무한 디버깅 루프를 감지하면서 정상적인 다영역 편집은 허용
297
309
 
298
310
  ### test-tracker
299
311
 
@@ -322,7 +334,7 @@ Hook은 선택 사항인 CLI 가드로, 개발 중 규율을 강제합니다. `p
322
334
 
323
335
  **동작:**
324
336
  - 모든 Bash 커맨드에서 실행
325
- - 커맨드가 테스트 패턴과 일치하면 타임스탐프 기록
337
+ - 커맨드가 테스트 패턴과 일치하면 타임스탬프 기록
326
338
  - 결과 기록 (종료 코드 기반 성공/실패)
327
339
  - `commit-guard`가 이 상태를 읽어 커밋 허용/차단
328
340
 
@@ -351,6 +363,9 @@ Hook은 선택 사항인 CLI 가드로, 개발 중 규율을 강제합니다. `p
351
363
  - Agent 임계값 (OMC sub-agent 실행 중): 8개에서 경고, 12개에서 차단
352
364
  - 경고: "/claude-prism:prism을 실행하여 작업을 분해하는 것을 고려하세요"
353
365
  - 차단: "/claude-prism:prism을 실행하여 계속 진행하기 전에 분해하세요"
366
+ - **플랜 인식**: 플랜 파일 생성 시 (`docs/plans/*.md`) 임계값이 자동으로 2배
367
+ - 표준 + 플랜: 8개에서 경고, 14개에서 차단
368
+ - Agent + 플랜: 16개에서 경고, 24개에서 차단
354
369
 
355
370
  ## 설정
356
371
 
@@ -396,7 +411,7 @@ prism doctor # 진단 정보에 OMC 감지 표시
396
411
  ## 기술 사양
397
412
 
398
413
  - **패키지명**: `claude-prism`
399
- - **버전**: 0.1.0
414
+ - **버전**: 0.3.1
400
415
  - **CLI 커맨드**: `prism`
401
416
  - **Node 버전**: >= 18
402
417
  - **의존성**: 0 (순수 ESM 모듈)
@@ -416,8 +431,8 @@ prism doctor # 진단 정보에 OMC 감지 표시
416
431
  1. **정보 충분성 판별** — 요청이 명확한가? 질문이 필요한가?
417
432
  2. **최대 3라운드 질문** — 한 번에 하나씩, 객관식 우선
418
433
  3. **분해 5원칙** — 단위 크기, 테스트 선행, 독립 검증, 파일 명시, 의존성 명시
419
- 4. **배치 + 체크포인트** — 3-4 태스크씩 실행, 배치마다 보고
420
- 5. **TDD Iron Law**실패 테스트 먼저, 테스트 없이 커밋 금지
434
+ 4. **적응형 배치 + 체크포인트** — 복잡도별 배치 크기 조절 (단순 5-8 / 일반 3-4 / 복잡 1-2), 배치마다 보고
435
+ 5. **컨텍스트 인식 검증**파일 경로별 검증 전략 (lib→TDD, components→빌드, config→lint)
421
436
  6. **자기 교정** — 같은 파일 3회 편집 시 멈추고 재검토
422
437
 
423
438
  ## 라이선스
package/README.md CHANGED
@@ -1,12 +1,18 @@
1
1
  ```
2
- ╱╲
3
- ━━━━━━━━━▶ ╱ ╲ ──── U Understand
4
- complex ╱ ╲ ──── D Decompose
5
- problem ╱ PRISM╲──── E Execute
6
- ╱________╲─── C Checkpoint
7
- spectrum
2
+ ╱╲
3
+ ━━━━━━━━━▶ ╱ ╲ ──── U Understand
4
+ complex ╱ ╲ ──── D Decompose
5
+ problem ╱ PRISM╲──── E Execute
6
+ ╱________╲─── C Checkpoint
7
+ spectrum
8
8
  ```
9
9
 
10
+ [![npm version](https://img.shields.io/npm/v/claude-prism)](https://www.npmjs.com/package/claude-prism)
11
+ [![license](https://img.shields.io/npm/l/claude-prism)](https://github.com/lazysaturday91/claude-prism/blob/main/LICENSE)
12
+ [![node](https://img.shields.io/node/v/claude-prism)](https://nodejs.org)
13
+
14
+ > `ai-coding` · `problem-decomposition` · `claude-code-hooks` · `claude-code-plugin` · `udec` · `scope-guard`
15
+
10
16
  # claude-prism
11
17
 
12
18
  An AI coding problem decomposition tool for Claude Code. Installs the **UDEC** methodology — Understand, Decompose, Execute, Checkpoint — directly into your project's Claude Code environment.
@@ -15,11 +21,6 @@ An AI coding problem decomposition tool for Claude Code. Installs the **UDEC** m
15
21
 
16
22
  **Core philosophy:** Never implement what you haven't understood. Never execute what you haven't decomposed.
17
23
 
18
- - Zero dependencies
19
- - Node >= 18
20
- - MIT License
21
- - Repository: https://github.com/lazysaturday91/claude-prism
22
-
23
24
  ## The Problem
24
25
 
25
26
  Without structure, Claude does this:
@@ -29,7 +30,7 @@ Without structure, Claude does this:
29
30
  | Reads request → assumes understanding | Reads request → assesses sufficiency |
30
31
  | Starts coding immediately | Asks 1-2 clarifying questions first |
31
32
  | Builds one 30-minute mega-feature | Decomposes into 2-5 minute verifiable units |
32
- | Runs autonomously (no checkpoints) | Batches execution: 3-4 tasks → checkpoint → ask permission |
33
+ | Runs autonomously (no checkpoints) | Adaptive batches (1-8 tasks by complexity) → checkpoint → ask permission |
33
34
  | Produces working code that's wrong | Produces code that's correct *and* wanted |
34
35
 
35
36
  ## Installation
@@ -40,6 +41,9 @@ npx claude-prism init --lang=ko # Korean
40
41
  npx claude-prism init --lang=ja # Japanese
41
42
  npx claude-prism init --lang=zh # Chinese
42
43
  npx claude-prism init --no-hooks # Rules only, no hooks
44
+ npx claude-prism init --global # Install as global skill (available in all projects)
45
+ npx claude-prism update # Update rules and commands to latest
46
+ npx claude-prism update --global # Update global skill too
43
47
  prism check # Verify installation
44
48
  ```
45
49
 
@@ -50,7 +54,7 @@ After running `prism init`, your project gains:
50
54
  **UDEC Rules** — Injected into `CLAUDE.md` between `PRISM:START` and `PRISM:END` markers. Explains the four-phase methodology:
51
55
  - **U** — Assess information sufficiency before acting. Ask one question at a time, multiple choice, max 3 rounds.
52
56
  - **D** — Decompose complex problems into 2-5 minute units with TDD. Create a plan file for 6+ file changes.
53
- - **E** — Execute in batches (3-4 tasks per batch). Apply TDD Iron Law: failing test implementation verify → commit.
57
+ - **E** — Execute in adaptive batches. Apply context-aware verification by file path (TDD / build / lint-only).
54
58
  - **C** — Checkpoint after each batch. Report progress, show next batch preview, get confirmation before continuing.
55
59
 
56
60
  **Slash Commands** — Added to `.claude/commands/claude-prism/`:
@@ -59,11 +63,12 @@ After running `prism init`, your project gains:
59
63
  - `/claude-prism:plan` — List, create, or view plan files
60
64
  - `/claude-prism:doctor` — Diagnose installation health via Claude
61
65
  - `/claude-prism:stats` — Show project statistics, hook status, and plan progress
66
+ - `/claude-prism:update` — Update rules and commands to latest version
62
67
  - `/claude-prism:help` — Command reference
63
68
 
64
69
  **Hooks** (optional, unless `--no-hooks` is set) — Four CLI guards that enforce discipline:
65
70
  - `commit-guard` — Prevents commits when tests haven't run recently
66
- - `debug-loop` — Warns at 3 edits, blocks at 5 edits to same file (catches infinite debugging loops)
71
+ - `debug-loop` — Detects divergent editing patterns on the same file (catches infinite debugging loops)
67
72
  - `test-tracker` — Detects test command execution (npm test, jest, vitest, pytest, etc.) and records pass/fail state
68
73
  - `scope-guard` — Warns at 4 unique files modified, blocks at 7 (agent-aware: warns at 8, blocks at 12)
69
74
 
@@ -83,6 +88,7 @@ your-project/
83
88
  │ │ ├── plan.md # /claude-prism:plan
84
89
  │ │ ├── doctor.md # /claude-prism:doctor
85
90
  │ │ ├── stats.md # /claude-prism:stats
91
+ │ │ ├── update.md # /claude-prism:update
86
92
  │ │ └── help.md # /claude-prism:help
87
93
  │ ├── hooks/ # (optional, if --no-hooks not set)
88
94
  │ │ ├── commit-guard.mjs
@@ -116,7 +122,7 @@ your-project/
116
122
  [ DECOMPOSE ] ← Break into 2-5 min units, create plan file
117
123
  |
118
124
  v
119
- [ EXECUTE ] ← Run batch (3-4 tasks), TDD each unit
125
+ [ EXECUTE ] ← Run adaptive batch, verify each unit
120
126
  |
121
127
  v
122
128
  [ CHECKPOINT ] ← Report, show next batch, ask to continue
@@ -135,6 +141,7 @@ your-project/
135
141
  | `/claude-prism:checkpoint` | Mid-project | Check batch progress, preview next batch |
136
142
  | `/claude-prism:doctor` | Installation issues | Diagnose health, suggest fixes |
137
143
  | `/claude-prism:stats` | Check current state | Version, hooks, language, plan progress |
144
+ | `/claude-prism:update` | After `npm update` | Update rules and commands to latest |
138
145
  | `/claude-prism:help` | Forgot commands | Quick reference |
139
146
 
140
147
  ### Workflow
@@ -237,7 +244,7 @@ Blocks commits if tests haven't been run in the last 5 minutes (configurable via
237
244
 
238
245
  ### debug-loop
239
246
 
240
- Warns when the same file is edited 3 times in a row, blocks at 5 edits. Catches infinite debugging cycles.
247
+ Detects editing patterns on the same file. Distinguishes between **divergent** edits (same code area repeatedly likely thrashing) and **convergent** edits (different areas like imports, logic, JSX — normal progressive work).
241
248
 
242
249
  ```json
243
250
  {
@@ -252,9 +259,10 @@ Warns when the same file is edited 3 times in a row, blocks at 5 edits. Catches
252
259
  ```
253
260
 
254
261
  **Behavior:**
255
- - Tracks consecutive edits to same file within a session
256
- - Warns at 3 edits: "Consider stepping back to understand the problem"
257
- - Blocks at 5 edits: Forces reassessment before continuing
262
+ - Tracks edit patterns using snippet analysis
263
+ - **Divergent pattern** (same area): warns at 3 edits, blocks at 5
264
+ - **Convergent pattern** (different areas): passes silently, downgrades block to warn
265
+ - Catches infinite debugging loops while allowing normal multi-area edits
258
266
 
259
267
  ### test-tracker
260
268
 
@@ -312,6 +320,9 @@ Tracks unique source files modified per session. Warns when scope grows without
312
320
  - Agent thresholds (when OMC sub-agents running): warns at 8, blocks at 12
313
321
  - Warning: "Consider running /claude-prism:prism to decompose the task"
314
322
  - Block: "Run /claude-prism:prism to decompose before continuing"
323
+ - **Plan-aware**: When a plan file is created (`docs/plans/*.md`), thresholds are automatically doubled
324
+ - Standard with plan: warns at 8, blocks at 14
325
+ - Agent with plan: warns at 16, blocks at 24
315
326
 
316
327
  ## Configuration
317
328
 
@@ -401,7 +412,7 @@ prism stats
401
412
 
402
413
  Output:
403
414
  ```
404
- Version: v0.1.0
415
+ Version: v0.3.1
405
416
  Language: en
406
417
  Plans: 2 file(s)
407
418
  OMC: ✅ v4.1.1
@@ -469,16 +480,21 @@ prism doctor # Shows OMC detection in diagnostics
469
480
 
470
481
  This allows OMC agents (executor, architect, etc.) to modify more files per task without triggering scope warnings, recognizing that coordinated multi-agent work has different constraints than single-agent development.
471
482
 
472
- ## TDD Iron Law
483
+ ## Verification Strategy
473
484
 
474
- Every task in the EXECUTE phase follows:
485
+ Prism uses context-aware verification — the right level of rigor for each file type:
475
486
 
476
- 1. Write a failing test
477
- 2. Write minimum code to pass
478
- 3. Verify the test passes
479
- 4. Commit
487
+ | Path Pattern | Strategy | Escalation |
488
+ |---|---|---|
489
+ | `lib/`, `utils/`, `store/`, `hooks/`, `services/` | **TDD required** — failing test → implement → verify | Always TDD |
490
+ | `components/`, `pages/`, `views/` | **Build verification** — build passes + visual check | Escalate to TDD if complex logic |
491
+ | `config/`, `styles/`, `types/`, `*.json` | **Build/lint only** | Never |
480
492
 
481
- Never execute without this cycle.
493
+ **Core rules (all paths):**
494
+ 1. Never claim completion without fresh verification evidence
495
+ 2. Never commit code that doesn't build
496
+ 3. TDD paths: write failing test → minimal code → verify
497
+ 4. Build paths: run build/lint → confirm no regressions
482
498
 
483
499
  ## Design Philosophy
484
500
 
@@ -487,7 +503,7 @@ Prism is built on the insight that **AI needs structure more than humans do.** H
487
503
  - Explicit understanding phase (no assumptions)
488
504
  - Enforced decomposition (no mega-tasks)
489
505
  - Batched execution with checkpoints (human in the loop)
490
- - TDD for every unit (verified, not assumed)
506
+ - Context-aware verification (TDD, build, or lint matched to file type)
491
507
 
492
508
  The prism metaphor: white light (complex problem) enters from one side and decomposes into a spectrum of colors (manageable units). Each color (unit) is individually verified, then recombined into a working whole.
493
509
 
package/bin/cli.mjs CHANGED
@@ -35,6 +35,7 @@ if (hasFlag('version') || hasFlag('v')) {
35
35
 
36
36
  const cwd = process.cwd();
37
37
 
38
+ try {
38
39
  switch (command) {
39
40
  case 'init': {
40
41
  if (hasFlag('global')) {
@@ -49,6 +50,19 @@ switch (command) {
49
50
  const language = getFlag('lang') || 'en';
50
51
  const hooks = !hasFlag('no-hooks');
51
52
 
53
+ if (hasFlag('dry-run')) {
54
+ const { dryRun } = await import('../lib/installer.mjs');
55
+ const result = dryRun(cwd, { language, hooks });
56
+ console.log('🌈 claude-prism init --dry-run\n');
57
+ console.log(' Files that would be created/updated:\n');
58
+ for (const action of result.actions) {
59
+ const icon = action.status === 'create' ? '🆕' : '🔄';
60
+ console.log(` ${icon} [${action.status}] ${action.path}`);
61
+ }
62
+ console.log(`\n Total: ${result.actions.length} files`);
63
+ break;
64
+ }
65
+
52
66
  console.log('🌈 claude-prism init\n');
53
67
  await init(cwd, { language, hooks });
54
68
 
@@ -182,8 +196,23 @@ Usage:
182
196
  Options:
183
197
  --lang=XX Language: en (default), ko, ja, zh
184
198
  --no-hooks Skip enforcement hooks
199
+ --dry-run Show what init would do without making changes
185
200
  --global Install/uninstall globally (all projects)
186
201
  --ci Output JSON for CI integration
187
202
  --version Show version`);
188
203
  }
189
204
  }
205
+ } catch (err) {
206
+ const msg = err.message || String(err);
207
+ process.stderr.write(`🌈 Prism Error: ${msg}\n`);
208
+
209
+ if (/EACCES|permission/i.test(msg)) {
210
+ process.stderr.write('💡 Check directory permissions\n');
211
+ } else if (/JSON|parse/i.test(msg)) {
212
+ process.stderr.write('💡 Config file may be corrupted. Try `prism reset` or delete .claude-prism.json\n');
213
+ } else if (/ENOENT.*package\.json/i.test(msg)) {
214
+ process.stderr.write('💡 Not in a project directory?\n');
215
+ }
216
+
217
+ process.exit(1);
218
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * claude-prism — Alignment Detection
3
+ * Detects scope drift and major unconfirmed decisions
4
+ */
5
+
6
+ import { readJsonState, writeJsonState } from '../lib/state.mjs';
7
+ import { getMessage } from '../lib/messages.mjs';
8
+
9
+ // Major decision patterns — commands that represent significant choices
10
+ const MAJOR_DECISION_PATTERNS = [
11
+ { pattern: /\bnpm\s+install\b|\bpnpm\s+add\b|\byarn\s+add\b|\bbun\s+add\b/, label: 'package-install' },
12
+ { pattern: /\bprisma\s+migrate\b|\bsequelize\b|\bknex\s+migrate\b/, label: 'db-migration' },
13
+ { pattern: /\brm\s+-rf?\b|\brmdir\b/, label: 'destructive-delete' },
14
+ ];
15
+
16
+ // Config files that represent major changes when modified
17
+ const MAJOR_CONFIG_FILES = [
18
+ 'tsconfig.json', 'package.json', '.env', 'docker-compose.yml',
19
+ 'Dockerfile', '.github/workflows', 'webpack.config', 'vite.config',
20
+ 'next.config', 'tailwind.config',
21
+ ];
22
+
23
+ export const alignment = {
24
+ name: 'alignment',
25
+
26
+ evaluate(ctx, config, stateDir) {
27
+ if (!config.enabled) return { type: 'pass' };
28
+
29
+ const messages = [];
30
+
31
+ // 1. Directory scope tracking
32
+ if (ctx.filePath) {
33
+ const dir = ctx.filePath.split('/').slice(0, -1).join('/') || '.';
34
+ let scopeDirs = readJsonState(stateDir, 'scope-directories') || [];
35
+
36
+ if (!scopeDirs.includes(dir)) {
37
+ // First 3 unique directories establish the "base scope"
38
+ if (scopeDirs.length < 3) {
39
+ scopeDirs.push(dir);
40
+ writeJsonState(stateDir, 'scope-directories', scopeDirs);
41
+ } else {
42
+ // New directory outside base scope — potential drift
43
+ const driftCount = parseInt(
44
+ (readJsonState(stateDir, 'drift-count') || 0).toString(), 10
45
+ ) || 0;
46
+ const newDriftCount = driftCount + 1;
47
+ writeJsonState(stateDir, 'drift-count', newDriftCount);
48
+
49
+ if (newDriftCount >= (config.driftThreshold || 2)) {
50
+ return {
51
+ type: 'warn',
52
+ message: `🌈 Prism 🧭 Scope drift: editing ${dir} (outside base scope: ${scopeDirs.slice(0, 3).join(', ')}). Verify this is intended.`
53
+ };
54
+ }
55
+ }
56
+ }
57
+
58
+ // 2. Major config file detection
59
+ const fileName = ctx.filePath.split('/').pop();
60
+ const isMajorConfig = MAJOR_CONFIG_FILES.some(f =>
61
+ ctx.filePath.includes(f) || fileName === f
62
+ );
63
+ if (isMajorConfig) {
64
+ messages.push(`🌈 Prism 🔧 Config change: ${fileName}. Ensure this was discussed with user.`);
65
+ }
66
+ }
67
+
68
+ // 3. Major command detection
69
+ if (ctx.command) {
70
+ for (const { pattern, label } of MAJOR_DECISION_PATTERNS) {
71
+ if (pattern.test(ctx.command)) {
72
+ if (label === 'destructive-delete') {
73
+ return {
74
+ type: 'warn',
75
+ message: `🌈 Prism ⚠️ Destructive command detected: ${ctx.command.slice(0, 60)}. Confirm with user before proceeding.`
76
+ };
77
+ }
78
+ if (label === 'package-install') {
79
+ messages.push(`🌈 Prism 📦 New dependency being installed. Verify this was agreed upon.`);
80
+ }
81
+ if (label === 'db-migration') {
82
+ messages.push(`🌈 Prism 🗄️ Database migration detected. This is a major decision — confirm with user.`);
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ if (messages.length > 0) {
89
+ return { type: 'pass', message: messages.join('\n') };
90
+ }
91
+
92
+ return { type: 'pass' };
93
+ }
94
+ };
@@ -4,12 +4,14 @@
4
4
  */
5
5
 
6
6
  import { readState } from '../lib/state.mjs';
7
+ import { getMessage } from '../lib/messages.mjs';
7
8
 
8
9
  export const commitGuard = {
9
10
  name: 'commit-guard',
10
11
 
11
12
  evaluate(ctx, config, stateDir) {
12
13
  const command = ctx.command || '';
14
+ const lang = config.language || 'en';
13
15
 
14
16
  if (!command.includes('git commit')) return { type: 'pass' };
15
17
  if (command.includes('--allow-empty')) return { type: 'pass' };
@@ -19,7 +21,7 @@ export const commitGuard = {
19
21
  if (testResult !== null && testResult.trim() === 'fail') {
20
22
  return {
21
23
  type: 'block',
22
- message: '🌈 Prism ✋ Commit blocked: last test run FAILED. Fix tests before committing.'
24
+ message: getMessage(lang, 'commit-guard.block.failed')
23
25
  };
24
26
  }
25
27
 
@@ -28,7 +30,7 @@ export const commitGuard = {
28
30
  if (lastTestRaw === null) {
29
31
  return {
30
32
  type: 'warn',
31
- message: '🌈 Prism > No test run detected this session. Run tests before committing.'
33
+ message: getMessage(lang, 'commit-guard.warn.no-test')
32
34
  };
33
35
  }
34
36
 
@@ -39,7 +41,7 @@ export const commitGuard = {
39
41
  if (diff > (config.maxTestAge || 300)) {
40
42
  return {
41
43
  type: 'warn',
42
- message: `🌈 Prism > Last test run was ${Math.floor(diff / 60)}min ago. Run tests before committing.`
44
+ message: getMessage(lang, 'commit-guard.warn.stale', { minutes: Math.floor(diff / 60) })
43
45
  };
44
46
  }
45
47
 
@@ -5,6 +5,8 @@
5
5
 
6
6
  import { createHash } from 'crypto';
7
7
  import { readState, writeState, readJsonState, writeJsonState } from '../lib/state.mjs';
8
+ import { DEFAULTS, buildSourcePattern } from '../lib/config.mjs';
9
+ import { getMessage } from '../lib/messages.mjs';
8
10
 
9
11
  export const debugLoop = {
10
12
  name: 'debug-loop',
@@ -14,7 +16,8 @@ export const debugLoop = {
14
16
  if (!filePath) return { type: 'pass' };
15
17
 
16
18
  // Skip non-source files
17
- if (!/\.(ts|tsx|js|jsx|py|go|rs|java|c|cpp|h)$/.test(filePath)) return { type: 'pass' };
19
+ const sourcePattern = buildSourcePattern(config.sourceExtensions || DEFAULTS.sourceExtensions);
20
+ if (!sourcePattern.test(filePath)) return { type: 'pass' };
18
21
 
19
22
  const hash = createHash('md5').update(filePath).digest('hex').slice(0, 8);
20
23
  const countKey = `edit-count-${hash}`;
@@ -34,6 +37,7 @@ export const debugLoop = {
34
37
  writeJsonState(stateDir, logKey, editLog);
35
38
 
36
39
  const name = filePath.split('/').pop();
40
+ const lang = config.language || 'en';
37
41
  const pattern = count >= config.warnAt ? analyzePattern(editLog) : null;
38
42
 
39
43
  if (count >= config.blockAt) {
@@ -41,12 +45,12 @@ export const debugLoop = {
41
45
  if (pattern === 'divergent') {
42
46
  return {
43
47
  type: 'block',
44
- message: `🌈 Prism Debug Loop blocked: ${name} edited ${count} times on same area. Discuss approach with user before continuing.`
48
+ message: getMessage(lang, 'debug-loop.block.divergent', { name, count })
45
49
  };
46
50
  }
47
51
  return {
48
52
  type: 'warn',
49
- message: `🌈 Prism > Debug Loop: ${name} edited ${count} times (different areas). Consider if this is expected.`
53
+ message: getMessage(lang, 'debug-loop.warn.convergent', { name, count })
50
54
  };
51
55
  }
52
56
 
@@ -55,7 +59,7 @@ export const debugLoop = {
55
59
  if (pattern === 'divergent') {
56
60
  return {
57
61
  type: 'warn',
58
- message: `🌈 Prism > Debug Loop: ${name} edited ${count} times on same area. Stop and investigate root cause.`
62
+ message: getMessage(lang, 'debug-loop.warn.divergent', { name, count })
59
63
  };
60
64
  }
61
65
  // Convergent edits (different areas) = normal progressive work → pass
@@ -68,8 +72,19 @@ export const debugLoop = {
68
72
  function analyzePattern(log) {
69
73
  if (log.length < 3) return null;
70
74
  const recent = log.slice(-3).map(e => e.snippet);
75
+
76
+ // Filter out empty/whitespace snippets — can't determine pattern
77
+ if (recent.some(s => !s || !s.trim())) return null;
78
+
79
+ // Exact duplicates = clearly divergent (same code edited repeatedly)
71
80
  const uniqueSnippets = new Set(recent).size;
72
81
  if (uniqueSnippets === 1) return 'divergent';
73
- const overlap = recent.filter(s => recent[0] && s.includes(recent[0].slice(0, 20))).length;
82
+
83
+ // Check for meaningful overlap using longer window
84
+ const baseSnippet = recent[0].slice(0, 40);
85
+ // Skip overlap check if base is too short for meaningful comparison
86
+ if (baseSnippet.length < 10) return uniqueSnippets <= 2 ? 'divergent' : 'convergent';
87
+
88
+ const overlap = recent.filter(s => s.includes(baseSnippet)).length;
74
89
  return overlap >= 2 ? 'divergent' : 'convergent';
75
90
  }
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import { readJsonState, writeJsonState } from '../lib/state.mjs';
7
+ import { DEFAULTS, buildSourcePattern, buildTestPattern } from '../lib/config.mjs';
8
+ import { getMessage } from '../lib/messages.mjs';
7
9
 
8
- const SOURCE_PATTERN = /\.(ts|tsx|js|jsx|py|go|rs|java|c|cpp|h|svelte|vue)$/;
9
- const TEST_PATTERN = /\.(test|spec|_test)\./;
10
10
  const PLAN_PATTERN = /(?:^|\/)docs\/plans\/.*\.md$|(?:^|\/).*plan.*\.md$/i;
11
11
 
12
12
  export const scopeGuard = {
@@ -17,16 +17,20 @@ export const scopeGuard = {
17
17
  if (!filePath) return { type: 'pass' };
18
18
 
19
19
  // Plan file created → mark plan as active (thresholds will be doubled)
20
+ const lang = config.language || 'en';
20
21
  if (PLAN_PATTERN.test(filePath)) {
21
22
  writeJsonState(stateDir, 'scope-has-plan', true);
22
- return { type: 'pass', message: '🌈 Prism 📋 Plan file detected. Scope thresholds raised.' };
23
+ return { type: 'pass', message: getMessage(lang, 'scope-guard.plan-detected') };
23
24
  }
24
25
 
25
26
  // Only track source files
26
- if (!SOURCE_PATTERN.test(filePath)) return { type: 'pass' };
27
+ const sourcePattern = buildSourcePattern(config.sourceExtensions || DEFAULTS.sourceExtensions);
28
+ const testPattern = buildTestPattern(config.testPatterns || DEFAULTS.testPatterns);
29
+
30
+ if (!sourcePattern.test(filePath)) return { type: 'pass' };
27
31
 
28
32
  // Don't count test files toward scope
29
- if (TEST_PATTERN.test(filePath)) return { type: 'pass' };
33
+ if (testPattern.test(filePath)) return { type: 'pass' };
30
34
 
31
35
  // Track unique files
32
36
  let files = readJsonState(stateDir, 'scope-files') || [];
@@ -52,14 +56,14 @@ export const scopeGuard = {
52
56
  if (count >= blockAt) {
53
57
  return {
54
58
  type: 'block',
55
- message: `🌈 Prism Scope Guard: ${count} unique files modified without a plan. Run /prism to decompose before continuing.`
59
+ message: getMessage(lang, 'scope-guard.block', { count })
56
60
  };
57
61
  }
58
62
 
59
63
  if (count >= warnAt) {
60
64
  return {
61
65
  type: 'warn',
62
- message: `🌈 Prism > Scope Guard: ${count} unique files modified. Consider running /prism to decompose the task.`
66
+ message: getMessage(lang, 'scope-guard.warn', { count })
63
67
  };
64
68
  }
65
69