sentix 2.0.1 → 2.0.21

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.
@@ -19,7 +19,15 @@ registerCommand('init', {
19
19
 
20
20
  // ── 1. CLAUDE.md ────────────────────────────────
21
21
  if (ctx.exists('CLAUDE.md')) {
22
- ctx.warn('CLAUDE.md already exists skipping');
22
+ // CLAUDE.md 이미 있지만 Sentix Governor 지시문이 없으면 주입
23
+ const existing = await ctx.readFile('CLAUDE.md');
24
+ if (!existing.includes('Sentix Governor') && !existing.includes('sentix') && !existing.includes('SENTIX')) {
25
+ const directive = generateGovernorDirective();
26
+ await ctx.writeFile('CLAUDE.md', existing + '\n' + directive);
27
+ ctx.success('CLAUDE.md updated — Sentix Governor directive injected');
28
+ } else {
29
+ ctx.warn('CLAUDE.md already has Sentix directives — skipping');
30
+ }
23
31
  } else {
24
32
  const claudeTemplate = `# CLAUDE.md — Sentix Governor 실행 지침
25
33
 
@@ -294,18 +302,39 @@ type: # api | library | framework | service
294
302
  }
295
303
 
296
304
  // ── Done ────────────────────────────────────────
305
+ // init 완료 후 자동으로 update 실행 (FRAMEWORK.md 등 동기화)
306
+ ctx.log('\n--- Syncing framework files ---\n');
307
+ try {
308
+ const { getCommand } = await import('../registry.js');
309
+ const updateCmd = getCommand('update');
310
+ if (updateCmd) {
311
+ await updateCmd.run([], ctx);
312
+ }
313
+ } catch {
314
+ ctx.warn('Auto-update skipped (run manually: sentix update)');
315
+ }
316
+
297
317
  ctx.log('\n=== Sentix initialized ===');
298
318
  ctx.log('');
299
319
  if (techStack.detected) {
300
320
  ctx.success(`Detected: ${techStack.runtime} / ${techStack.packageManager}${techStack.framework !== '# 프로젝트에 맞게 설정' ? ' / ' + techStack.framework : ''}`);
301
321
  }
302
- ctx.log('Next steps:');
303
- ctx.log(' 1. Edit CLAUDE.md 기술 스택을 프로젝트에 맞게 확인');
322
+
323
+ // init 끝에 자동으로 doctor 실행
324
+ ctx.log('\n--- Health Check ---\n');
325
+ try {
326
+ const { getCommand } = await import('../registry.js');
327
+ const doctorCmd = getCommand('doctor');
328
+ if (doctorCmd) {
329
+ await doctorCmd.run([], ctx);
330
+ }
331
+ } catch {
332
+ ctx.warn('Auto-check skipped (run manually: sentix doctor)');
333
+ }
334
+
304
335
  if (!hasSafety) {
305
- ctx.log(' 2. Run: sentix safety set <안전어>');
306
- ctx.log(' 3. Run: sentix doctor');
307
- } else {
308
- ctx.log(' 2. Run: sentix doctor');
336
+ ctx.log('');
337
+ ctx.log('Optional: sentix safety set <안전어> (LLM 인젝션 방지)');
309
338
  }
310
339
  ctx.log('');
311
340
  },
@@ -465,3 +494,62 @@ exit $?
465
494
 
466
495
  ctx.success('Installed git pre-commit hook (verification gates)');
467
496
  }
497
+
498
+ // ── Governor 강제 지시문 (기존 CLAUDE.md에 주입) ─────────
499
+
500
+ function generateGovernorDirective() {
501
+ return `
502
+ ---
503
+
504
+ # Sentix Governor — 필수 준수 사항
505
+
506
+ > **이 프로젝트는 Sentix 프레임워크로 관리된다.**
507
+ > **아래 규칙은 어떤 역할(/frontend, /backend 등)에서든 반드시 따라야 한다.**
508
+ > 상세 설계: FRAMEWORK.md, 세부 규칙: docs/
509
+
510
+ ## 코드 수정 전 필수 절차
511
+
512
+ \`\`\`
513
+ 1. 코드 수정 요청을 받으면 → 반드시 Governor 파이프라인으로 진입
514
+ 2. 직접 코드를 수정하지 않는다 — 항상 아래 순서를 따른다:
515
+ → planner (티켓 생성) → dev (구현) → pr-review (검증) → security → roadmap
516
+ 3. 테스트 스냅샷 필수: 작업 전 npm test 또는 프로젝트 테스트 실행
517
+ 4. 티켓 없이 코드 수정 금지 — sentix ticket create 또는 sentix feature add 사용
518
+ \`\`\`
519
+
520
+ ## 파괴 방지 하드 룰 6개
521
+
522
+ 1. 작업 전 테스트 스냅샷 필수
523
+ 2. 티켓 SCOPE 밖 파일 수정 금지
524
+ 3. 기존 export/API 삭제 금지
525
+ 4. 기존 테스트 삭제/약화 금지
526
+ 5. 순삭제 50줄 제한
527
+ 6. 기존 기능/핸들러 삭제 금지
528
+
529
+ > 상세: .sentix/rules/hard-rules.md
530
+ > 에이전트 범위: docs/agent-scopes.md
531
+ > Severity 분기: docs/severity.md
532
+
533
+ ## 작업 완료 체크리스트
534
+
535
+ \`\`\`
536
+ □ 하드 룰 6개 위반 없음
537
+ □ 검증 게이트 통과 (sentix run 시 자동 — scope, export, test, deletion)
538
+ □ 테스트 통과
539
+ □ 티켓 생성됨
540
+ □ README.md 업데이트됨 (변경된 기능이 있다면)
541
+ □ lessons.md 업데이트됨 (실패 패턴이 있었다면)
542
+ \`\`\`
543
+
544
+ ## Sentix CLI
545
+
546
+ \`\`\`bash
547
+ sentix run "요청" # Governor 파이프라인 실행
548
+ sentix ticket create "설명" # 버그 티켓 생성
549
+ sentix feature add "설명" # 기능 티켓 생성
550
+ sentix status # 상태 확인
551
+ sentix doctor # 설치 진단
552
+ sentix update # 프레임워크 최신화
553
+ \`\`\`
554
+ `;
555
+ }
@@ -29,13 +29,20 @@ export async function runChainedPipeline(request, cycleId, state, ctx, options =
29
29
  const phases = [];
30
30
  const startTime = Date.now();
31
31
 
32
- // lessons.md, patterns.md 로드 (있으면)
32
+ // lessons.md, patterns.md, agent-methods.md 로드 (있으면)
33
33
  const lessons = ctx.exists('tasks/lessons.md')
34
34
  ? await ctx.readFile('tasks/lessons.md')
35
35
  : '';
36
36
  const patterns = ctx.exists('tasks/patterns.md')
37
37
  ? await ctx.readFile('tasks/patterns.md')
38
38
  : '';
39
+ const agentMethods = ctx.exists('docs/agent-methods.md')
40
+ ? await ctx.readFile('docs/agent-methods.md')
41
+ : '';
42
+
43
+ const methodsDirective = agentMethods.trim()
44
+ ? `\n--- agent-methods.md (MANDATORY — follow method order strictly) ---\n${agentMethods}`
45
+ : '';
39
46
 
40
47
  const learningContext = [
41
48
  lessons.trim() ? `\n--- lessons.md ---\n${lessons.slice(0, 2000)}` : '',
@@ -56,6 +63,8 @@ export async function runChainedPipeline(request, cycleId, state, ctx, options =
56
63
  '3. List the specific files that need to be changed (SCOPE)',
57
64
  '4. Estimate complexity (low/medium/high)',
58
65
  '5. DO NOT write any code. ONLY plan.',
66
+ '6. Define WHAT and WHERE only. DO NOT specify HOW (implementation details, function names, algorithms, library choices).',
67
+ methodsDirective,
59
68
  learningContext,
60
69
  ].filter(Boolean).join('\n'), ctx);
61
70
 
@@ -78,11 +87,14 @@ export async function runChainedPipeline(request, cycleId, state, ctx, options =
78
87
  'You are the DEV agent. Your job:',
79
88
  latestTicket ? `Ticket:\n${latestTicket}` : `Request: "${request}"`,
80
89
  '',
81
- '1. Implement the changes described in the ticket',
82
- '2. Write or update tests',
83
- '3. Run: npm test — ensure all tests pass',
84
- '4. Self-verify: check hard rules (no export deletion, no test deletion, scope compliance, <50 net deletions)',
85
- '5. DO NOT update version, README, or CHANGELOG that is the FINALIZE phase',
90
+ '1. Follow dev methods: snapshot() implement() → test() → verify() → report()',
91
+ '2. Implement the changes described in the ticket — you decide HOW',
92
+ '3. Write or update tests',
93
+ '4. Run: npm test ensure all tests pass',
94
+ '5. Self-verify: hard rules ONLY (no export deletion, no test deletion, scope compliance, <50 net deletions)',
95
+ '6. DO NOT judge code quality — that is pr-review\'s job',
96
+ '7. DO NOT update version, README, or CHANGELOG — that is the FINALIZE phase',
97
+ methodsDirective,
86
98
  learningContext,
87
99
  ].filter(Boolean).join('\n'), ctx);
88
100
 
@@ -135,12 +147,18 @@ export async function runChainedPipeline(request, cycleId, state, ctx, options =
135
147
  `Test results: ${testResult.status === 0 ? 'ALL PASSED' : 'SOME FAILED — fix them'}`,
136
148
  `Verification gates: ${midGateInfo}`,
137
149
  '',
138
- '1. Review the git diff (run: git diff)',
139
- '2. If tests failed, fix the failing tests (fix code, not tests)',
140
- '3. If gate violations exist, fix them',
141
- '4. Ensure code quality and hard rule compliance',
142
- '5. Run: npm testconfirm all pass after fixes',
143
- ].join('\n'), ctx);
150
+ '1. Follow pr-review methods: diff() → validate() grade() → calibrate() → verdict()',
151
+ '2. Review the git diff (run: git diff)',
152
+ '3. Validate hard rules first any violation = immediate REJECTED',
153
+ '4. Grade on 4 criteria: Correctness, Consistency, Simplicity, Test Coverage',
154
+ ' (skip grade() for low complexity hard rule pass is sufficient)',
155
+ '5. Calibrate: check tasks/lessons.md for past missed issues — be skeptical, not generous',
156
+ '6. If tests failed, fix the failing tests (fix code, not tests)',
157
+ '7. If gate violations exist, fix them',
158
+ '8. Run: npm test — confirm all pass after fixes',
159
+ methodsDirective,
160
+ learningContext,
161
+ ].filter(Boolean).join('\n'), ctx);
144
162
 
145
163
  phases.push({ name: 'review', ...reviewResult });
146
164