@wooojin/forgen 0.1.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.
Files changed (268) hide show
  1. package/.claude-plugin/plugin.json +20 -0
  2. package/CHANGELOG.md +353 -0
  3. package/CONTRIBUTING.md +98 -0
  4. package/LICENSE +21 -0
  5. package/README.ja.md +469 -0
  6. package/README.ko.md +469 -0
  7. package/README.md +483 -0
  8. package/README.zh.md +469 -0
  9. package/agents/analyst.md +98 -0
  10. package/agents/architect.md +62 -0
  11. package/agents/code-reviewer.md +120 -0
  12. package/agents/code-simplifier.md +197 -0
  13. package/agents/critic.md +70 -0
  14. package/agents/debugger.md +117 -0
  15. package/agents/designer.md +131 -0
  16. package/agents/executor.md +54 -0
  17. package/agents/explore.md +145 -0
  18. package/agents/git-master.md +212 -0
  19. package/agents/performance-reviewer.md +172 -0
  20. package/agents/planner.md +29 -0
  21. package/agents/qa-tester.md +158 -0
  22. package/agents/refactoring-expert.md +168 -0
  23. package/agents/scientist.md +144 -0
  24. package/agents/security-reviewer.md +137 -0
  25. package/agents/test-engineer.md +153 -0
  26. package/agents/verifier.md +133 -0
  27. package/agents/writer.md +184 -0
  28. package/commands/api-design.md +268 -0
  29. package/commands/architecture-decision.md +314 -0
  30. package/commands/ci-cd.md +270 -0
  31. package/commands/code-review.md +233 -0
  32. package/commands/compound.md +117 -0
  33. package/commands/database.md +263 -0
  34. package/commands/debug-detective.md +99 -0
  35. package/commands/docker.md +274 -0
  36. package/commands/documentation.md +276 -0
  37. package/commands/ecomode.md +51 -0
  38. package/commands/frontend.md +271 -0
  39. package/commands/git-master.md +90 -0
  40. package/commands/incident-response.md +292 -0
  41. package/commands/migrate.md +101 -0
  42. package/commands/performance.md +288 -0
  43. package/commands/refactor.md +105 -0
  44. package/commands/security-review.md +288 -0
  45. package/commands/tdd.md +183 -0
  46. package/commands/testing-strategy.md +265 -0
  47. package/dist/cli.d.ts +2 -0
  48. package/dist/cli.js +295 -0
  49. package/dist/core/auto-compound-runner.d.ts +12 -0
  50. package/dist/core/auto-compound-runner.js +460 -0
  51. package/dist/core/config-hooks.d.ts +10 -0
  52. package/dist/core/config-hooks.js +112 -0
  53. package/dist/core/config-injector.d.ts +50 -0
  54. package/dist/core/config-injector.js +455 -0
  55. package/dist/core/doctor.d.ts +1 -0
  56. package/dist/core/doctor.js +163 -0
  57. package/dist/core/errors.d.ts +81 -0
  58. package/dist/core/errors.js +133 -0
  59. package/dist/core/global-config.d.ts +43 -0
  60. package/dist/core/global-config.js +25 -0
  61. package/dist/core/harness.d.ts +24 -0
  62. package/dist/core/harness.js +621 -0
  63. package/dist/core/init.d.ts +7 -0
  64. package/dist/core/init.js +37 -0
  65. package/dist/core/inspect-cli.d.ts +7 -0
  66. package/dist/core/inspect-cli.js +47 -0
  67. package/dist/core/legacy-detector.d.ts +33 -0
  68. package/dist/core/legacy-detector.js +66 -0
  69. package/dist/core/logger.d.ts +34 -0
  70. package/dist/core/logger.js +121 -0
  71. package/dist/core/mcp-config.d.ts +44 -0
  72. package/dist/core/mcp-config.js +177 -0
  73. package/dist/core/notepad.d.ts +31 -0
  74. package/dist/core/notepad.js +88 -0
  75. package/dist/core/paths.d.ts +85 -0
  76. package/dist/core/paths.js +101 -0
  77. package/dist/core/plugin-detector.d.ts +44 -0
  78. package/dist/core/plugin-detector.js +226 -0
  79. package/dist/core/runtime-detector.d.ts +8 -0
  80. package/dist/core/runtime-detector.js +49 -0
  81. package/dist/core/scope-resolver.d.ts +8 -0
  82. package/dist/core/scope-resolver.js +45 -0
  83. package/dist/core/session-logger.d.ts +6 -0
  84. package/dist/core/session-logger.js +111 -0
  85. package/dist/core/session-store.d.ts +28 -0
  86. package/dist/core/session-store.js +218 -0
  87. package/dist/core/settings-lock.d.ts +18 -0
  88. package/dist/core/settings-lock.js +125 -0
  89. package/dist/core/spawn.d.ts +3 -0
  90. package/dist/core/spawn.js +135 -0
  91. package/dist/core/types.d.ts +108 -0
  92. package/dist/core/types.js +1 -0
  93. package/dist/core/uninstall.d.ts +4 -0
  94. package/dist/core/uninstall.js +307 -0
  95. package/dist/core/v1-bootstrap.d.ts +26 -0
  96. package/dist/core/v1-bootstrap.js +155 -0
  97. package/dist/engine/compound-cli.d.ts +24 -0
  98. package/dist/engine/compound-cli.js +250 -0
  99. package/dist/engine/compound-extractor.d.ts +68 -0
  100. package/dist/engine/compound-extractor.js +860 -0
  101. package/dist/engine/compound-lifecycle.d.ts +32 -0
  102. package/dist/engine/compound-lifecycle.js +305 -0
  103. package/dist/engine/compound-loop.d.ts +32 -0
  104. package/dist/engine/compound-loop.js +511 -0
  105. package/dist/engine/match-eval-log.d.ts +139 -0
  106. package/dist/engine/match-eval-log.js +270 -0
  107. package/dist/engine/phrase-blocklist.d.ts +119 -0
  108. package/dist/engine/phrase-blocklist.js +208 -0
  109. package/dist/engine/skill-promoter.d.ts +20 -0
  110. package/dist/engine/skill-promoter.js +115 -0
  111. package/dist/engine/solution-format.d.ts +160 -0
  112. package/dist/engine/solution-format.js +432 -0
  113. package/dist/engine/solution-index.d.ts +13 -0
  114. package/dist/engine/solution-index.js +252 -0
  115. package/dist/engine/solution-matcher.d.ts +364 -0
  116. package/dist/engine/solution-matcher.js +656 -0
  117. package/dist/engine/solution-writer.d.ts +76 -0
  118. package/dist/engine/solution-writer.js +157 -0
  119. package/dist/engine/term-matcher.d.ts +81 -0
  120. package/dist/engine/term-matcher.js +268 -0
  121. package/dist/engine/term-normalizer.d.ts +116 -0
  122. package/dist/engine/term-normalizer.js +171 -0
  123. package/dist/fgx.d.ts +6 -0
  124. package/dist/fgx.js +42 -0
  125. package/dist/forge/cli.d.ts +11 -0
  126. package/dist/forge/cli.js +100 -0
  127. package/dist/forge/evidence-processor.d.ts +21 -0
  128. package/dist/forge/evidence-processor.js +87 -0
  129. package/dist/forge/mismatch-detector.d.ts +44 -0
  130. package/dist/forge/mismatch-detector.js +83 -0
  131. package/dist/forge/onboarding-cli.d.ts +6 -0
  132. package/dist/forge/onboarding-cli.js +89 -0
  133. package/dist/forge/onboarding.d.ts +25 -0
  134. package/dist/forge/onboarding.js +122 -0
  135. package/dist/hooks/compound-reflection.d.ts +45 -0
  136. package/dist/hooks/compound-reflection.js +82 -0
  137. package/dist/hooks/context-guard.d.ts +24 -0
  138. package/dist/hooks/context-guard.js +156 -0
  139. package/dist/hooks/dangerous-patterns.json +18 -0
  140. package/dist/hooks/db-guard.d.ts +17 -0
  141. package/dist/hooks/db-guard.js +105 -0
  142. package/dist/hooks/hook-config.d.ts +29 -0
  143. package/dist/hooks/hook-config.js +92 -0
  144. package/dist/hooks/hook-registry.d.ts +43 -0
  145. package/dist/hooks/hook-registry.js +31 -0
  146. package/dist/hooks/hooks-generator.d.ts +49 -0
  147. package/dist/hooks/hooks-generator.js +99 -0
  148. package/dist/hooks/intent-classifier.d.ts +12 -0
  149. package/dist/hooks/intent-classifier.js +62 -0
  150. package/dist/hooks/keyword-detector.d.ts +25 -0
  151. package/dist/hooks/keyword-detector.js +389 -0
  152. package/dist/hooks/notepad-injector.d.ts +18 -0
  153. package/dist/hooks/notepad-injector.js +51 -0
  154. package/dist/hooks/permission-handler.d.ts +14 -0
  155. package/dist/hooks/permission-handler.js +114 -0
  156. package/dist/hooks/post-tool-failure.d.ts +11 -0
  157. package/dist/hooks/post-tool-failure.js +118 -0
  158. package/dist/hooks/post-tool-handlers.d.ts +17 -0
  159. package/dist/hooks/post-tool-handlers.js +115 -0
  160. package/dist/hooks/post-tool-use.d.ts +29 -0
  161. package/dist/hooks/post-tool-use.js +151 -0
  162. package/dist/hooks/pre-compact.d.ts +10 -0
  163. package/dist/hooks/pre-compact.js +165 -0
  164. package/dist/hooks/pre-tool-use.d.ts +31 -0
  165. package/dist/hooks/pre-tool-use.js +325 -0
  166. package/dist/hooks/prompt-injection-filter.d.ts +56 -0
  167. package/dist/hooks/prompt-injection-filter.js +287 -0
  168. package/dist/hooks/rate-limiter.d.ts +21 -0
  169. package/dist/hooks/rate-limiter.js +86 -0
  170. package/dist/hooks/secret-filter.d.ts +14 -0
  171. package/dist/hooks/secret-filter.js +65 -0
  172. package/dist/hooks/session-recovery.d.ts +27 -0
  173. package/dist/hooks/session-recovery.js +406 -0
  174. package/dist/hooks/shared/atomic-write.d.ts +41 -0
  175. package/dist/hooks/shared/atomic-write.js +148 -0
  176. package/dist/hooks/shared/context-budget.d.ts +37 -0
  177. package/dist/hooks/shared/context-budget.js +45 -0
  178. package/dist/hooks/shared/file-lock.d.ts +56 -0
  179. package/dist/hooks/shared/file-lock.js +253 -0
  180. package/dist/hooks/shared/hook-response.d.ts +33 -0
  181. package/dist/hooks/shared/hook-response.js +62 -0
  182. package/dist/hooks/shared/injection-caps.d.ts +39 -0
  183. package/dist/hooks/shared/injection-caps.js +52 -0
  184. package/dist/hooks/shared/plugin-signal.d.ts +23 -0
  185. package/dist/hooks/shared/plugin-signal.js +104 -0
  186. package/dist/hooks/shared/read-stdin.d.ts +8 -0
  187. package/dist/hooks/shared/read-stdin.js +63 -0
  188. package/dist/hooks/shared/sanitize-id.d.ts +7 -0
  189. package/dist/hooks/shared/sanitize-id.js +9 -0
  190. package/dist/hooks/shared/sanitize.d.ts +7 -0
  191. package/dist/hooks/shared/sanitize.js +22 -0
  192. package/dist/hooks/skill-injector.d.ts +38 -0
  193. package/dist/hooks/skill-injector.js +285 -0
  194. package/dist/hooks/slop-detector.d.ts +18 -0
  195. package/dist/hooks/slop-detector.js +93 -0
  196. package/dist/hooks/solution-injector.d.ts +58 -0
  197. package/dist/hooks/solution-injector.js +436 -0
  198. package/dist/hooks/subagent-tracker.d.ts +10 -0
  199. package/dist/hooks/subagent-tracker.js +90 -0
  200. package/dist/i18n/index.d.ts +43 -0
  201. package/dist/i18n/index.js +224 -0
  202. package/dist/lib.d.ts +14 -0
  203. package/dist/lib.js +14 -0
  204. package/dist/mcp/server.d.ts +8 -0
  205. package/dist/mcp/server.js +40 -0
  206. package/dist/mcp/solution-reader.d.ts +90 -0
  207. package/dist/mcp/solution-reader.js +273 -0
  208. package/dist/mcp/tools.d.ts +16 -0
  209. package/dist/mcp/tools.js +302 -0
  210. package/dist/preset/facet-catalog.d.ts +17 -0
  211. package/dist/preset/facet-catalog.js +46 -0
  212. package/dist/preset/preset-manager.d.ts +31 -0
  213. package/dist/preset/preset-manager.js +111 -0
  214. package/dist/renderer/inspect-renderer.d.ts +11 -0
  215. package/dist/renderer/inspect-renderer.js +123 -0
  216. package/dist/renderer/rule-renderer.d.ts +18 -0
  217. package/dist/renderer/rule-renderer.js +159 -0
  218. package/dist/store/evidence-store.d.ts +23 -0
  219. package/dist/store/evidence-store.js +58 -0
  220. package/dist/store/profile-store.d.ts +12 -0
  221. package/dist/store/profile-store.js +53 -0
  222. package/dist/store/recommendation-store.d.ts +22 -0
  223. package/dist/store/recommendation-store.js +64 -0
  224. package/dist/store/rule-store.d.ts +22 -0
  225. package/dist/store/rule-store.js +62 -0
  226. package/dist/store/session-state-store.d.ts +11 -0
  227. package/dist/store/session-state-store.js +44 -0
  228. package/dist/store/types.d.ts +159 -0
  229. package/dist/store/types.js +7 -0
  230. package/hooks/hook-registry.json +21 -0
  231. package/hooks/hooks.json +185 -0
  232. package/package.json +89 -0
  233. package/plugin.json +20 -0
  234. package/scripts/postinstall.js +826 -0
  235. package/skills/api-design/SKILL.md +262 -0
  236. package/skills/architecture-decision/SKILL.md +309 -0
  237. package/skills/ci-cd/SKILL.md +264 -0
  238. package/skills/code-review/SKILL.md +228 -0
  239. package/skills/compound/SKILL.md +101 -0
  240. package/skills/database/SKILL.md +257 -0
  241. package/skills/debug-detective/SKILL.md +95 -0
  242. package/skills/docker/SKILL.md +268 -0
  243. package/skills/documentation/SKILL.md +270 -0
  244. package/skills/ecomode/SKILL.md +46 -0
  245. package/skills/frontend/SKILL.md +265 -0
  246. package/skills/git-master/SKILL.md +86 -0
  247. package/skills/incident-response/SKILL.md +286 -0
  248. package/skills/migrate/SKILL.md +96 -0
  249. package/skills/performance/SKILL.md +282 -0
  250. package/skills/refactor/SKILL.md +100 -0
  251. package/skills/security-review/SKILL.md +282 -0
  252. package/skills/tdd/SKILL.md +178 -0
  253. package/skills/testing-strategy/SKILL.md +260 -0
  254. package/starter-pack/solutions/starter-api-error-responses.md +37 -0
  255. package/starter-pack/solutions/starter-async-patterns.md +40 -0
  256. package/starter-pack/solutions/starter-caching-strategy.md +40 -0
  257. package/starter-pack/solutions/starter-code-review-checklist.md +39 -0
  258. package/starter-pack/solutions/starter-debugging-systematic.md +40 -0
  259. package/starter-pack/solutions/starter-dependency-injection.md +40 -0
  260. package/starter-pack/solutions/starter-error-handling-patterns.md +38 -0
  261. package/starter-pack/solutions/starter-git-atomic-commits.md +36 -0
  262. package/starter-pack/solutions/starter-input-validation.md +40 -0
  263. package/starter-pack/solutions/starter-n-plus-one-queries.md +37 -0
  264. package/starter-pack/solutions/starter-refactor-safely.md +38 -0
  265. package/starter-pack/solutions/starter-secret-management.md +37 -0
  266. package/starter-pack/solutions/starter-separation-of-concerns.md +36 -0
  267. package/starter-pack/solutions/starter-tdd-red-green-refactor.md +40 -0
  268. package/starter-pack/solutions/starter-typescript-strict-types.md +39 -0
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Forgen — SubagentStart/Stop Hook
4
+ *
5
+ * 에이전트 생성/종료 추적.
6
+ * - 활성 에이전트 수 모니터링
7
+ * - 에이전트 동시 실행 제한 (10개 초과 시 경고)
8
+ * - 에이전트 실행 이력 기록
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ import { readStdinJSON } from './shared/read-stdin.js';
13
+ import { isHookEnabled } from './hook-config.js';
14
+ import { sanitizeId } from './shared/sanitize-id.js';
15
+ import { atomicWriteJSON } from './shared/atomic-write.js';
16
+ import { approve, approveWithWarning, failOpen } from './shared/hook-response.js';
17
+ import { STATE_DIR } from '../core/paths.js';
18
+ const MAX_CONCURRENT_AGENTS = 10;
19
+ const AGENT_GC_AGE_MS = 60 * 60 * 1000; // 1시간 이상 종료된 에이전트는 GC
20
+ function getAgentsStatePath(sessionId) {
21
+ return path.join(STATE_DIR, `active-agents-${sanitizeId(sessionId)}.json`);
22
+ }
23
+ function loadAgentsState(sessionId) {
24
+ try {
25
+ const filePath = getAgentsStatePath(sessionId);
26
+ if (fs.existsSync(filePath)) {
27
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
28
+ }
29
+ }
30
+ catch { /* agent state parse failure — starting fresh, active agent count history for this session is lost */ }
31
+ return { sessionId, agents: [] };
32
+ }
33
+ function saveAgentsState(state) {
34
+ // GC: 1시간 이상 종료된 에이전트 제거
35
+ const now = Date.now();
36
+ state.agents = state.agents.filter(a => {
37
+ if (!a.stoppedAt)
38
+ return true; // 활성 에이전트는 유지
39
+ return now - new Date(a.stoppedAt).getTime() < AGENT_GC_AGE_MS;
40
+ });
41
+ atomicWriteJSON(getAgentsStatePath(state.sessionId), state);
42
+ }
43
+ async function main() {
44
+ const data = await readStdinJSON();
45
+ // hook-registry에서는 subagent-tracker-start/stop으로 분리 등록됨
46
+ const suffix = process.argv[2] === 'stop' ? 'stop' : 'start';
47
+ if (!isHookEnabled(`subagent-tracker-${suffix}`)) {
48
+ console.log(approve());
49
+ return;
50
+ }
51
+ if (!data) {
52
+ console.log(approve());
53
+ return;
54
+ }
55
+ const sessionId = data.session_id ?? 'default';
56
+ // 이벤트 타입은 argv[2] 또는 data 필드에서 판별
57
+ const action = process.argv[2] ?? data.action ?? '';
58
+ const agentId = data.agent_id ?? data.agentId ?? `agent-${Date.now()}`;
59
+ const agentType = data.agent_type ?? data.agentType ?? data.subagent_type ?? '';
60
+ const state = loadAgentsState(sessionId);
61
+ if (action === 'start') {
62
+ const model = data.model ?? data.agentModel ?? undefined;
63
+ state.agents.push({
64
+ agentId,
65
+ agentType: agentType || undefined,
66
+ model,
67
+ startedAt: new Date().toISOString(),
68
+ });
69
+ saveAgentsState(state);
70
+ // 활성 에이전트 수 체크
71
+ const activeCount = state.agents.filter(a => !a.stoppedAt).length;
72
+ if (activeCount > MAX_CONCURRENT_AGENTS) {
73
+ console.log(approveWithWarning(`<compound-tool-warning>\n[Forgen] ⚠ ${activeCount} active agents — too many concurrent executions. Watch resource usage.\n</compound-tool-warning>`));
74
+ return;
75
+ }
76
+ }
77
+ else if (action === 'stop') {
78
+ // 해당 에이전트 종료 표시
79
+ const agent = state.agents.find(a => a.agentId === agentId && !a.stoppedAt);
80
+ if (agent) {
81
+ agent.stoppedAt = new Date().toISOString();
82
+ }
83
+ saveAgentsState(state);
84
+ }
85
+ console.log(approve());
86
+ }
87
+ main().catch((e) => {
88
+ process.stderr.write(`[ch-hook] ${e instanceof Error ? e.message : String(e)}\n`);
89
+ console.log(failOpen());
90
+ });
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Forgen — i18n (English / Korean)
3
+ *
4
+ * 내부 타입은 한글 유지 (QualityPack = '보수형' | ...).
5
+ * 사용자 대면 출력만 로케일에 따라 전환.
6
+ */
7
+ import type { QualityPack, AutonomyPack, JudgmentPack, CommunicationPack, TrustPolicy } from '../store/types.js';
8
+ export type Locale = 'en' | 'ko';
9
+ export declare function qualityName(pack: QualityPack, locale: Locale): string;
10
+ export declare function autonomyName(pack: AutonomyPack, locale: Locale): string;
11
+ export declare function judgmentName(pack: JudgmentPack, locale: Locale): string;
12
+ export declare function communicationName(pack: CommunicationPack, locale: Locale): string;
13
+ export declare function trustName(policy: TrustPolicy, locale: Locale): string;
14
+ export interface OnboardingStrings {
15
+ header: string;
16
+ subtitle: string;
17
+ q1: string;
18
+ q2: string;
19
+ q3: string;
20
+ q4: string;
21
+ resultHeader: string;
22
+ profileSaved: string;
23
+ invalidChoice: string;
24
+ }
25
+ export declare const ONBOARDING: Record<Locale, OnboardingStrings>;
26
+ export interface RuleRendererStrings {
27
+ trustGuardrails: string;
28
+ trustRelaxed: string;
29
+ trustFullTrust: string;
30
+ evidenceCollectionHeader: string;
31
+ evidenceCollectionRules: string[];
32
+ judgmentMinimalChange: string[];
33
+ judgmentBalanced: string[];
34
+ judgmentStructural: string[];
35
+ commConcise: string[];
36
+ commBalanced: string[];
37
+ commDetailed: string[];
38
+ }
39
+ export declare const RULE_RENDERER: Record<Locale, RuleRendererStrings>;
40
+ export declare function setLocale(locale: Locale): void;
41
+ export declare function getLocale(): Locale;
42
+ /** GlobalConfig에서 locale을 읽어 설정. 없으면 'en' 기본값. */
43
+ export declare function initLocaleFromConfig(): void;
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Forgen — i18n (English / Korean)
3
+ *
4
+ * 내부 타입은 한글 유지 (QualityPack = '보수형' | ...).
5
+ * 사용자 대면 출력만 로케일에 따라 전환.
6
+ */
7
+ // ── Pack Display Names ──
8
+ const QUALITY_NAMES = {
9
+ ko: { '보수형': '보수형', '균형형': '균형형', '속도형': '속도형' },
10
+ en: { '보수형': 'Conservative', '균형형': 'Balanced', '속도형': 'Speed-first' },
11
+ };
12
+ const AUTONOMY_NAMES = {
13
+ ko: { '확인 우선형': '확인 우선형', '균형형': '균형형', '자율 실행형': '자율 실행형' },
14
+ en: { '확인 우선형': 'Confirm-first', '균형형': 'Balanced', '자율 실행형': 'Autonomous' },
15
+ };
16
+ const JUDGMENT_NAMES = {
17
+ ko: { '최소변경형': '최소변경형', '균형형': '균형형', '구조적접근형': '구조적접근형' },
18
+ en: { '최소변경형': 'Minimal-change', '균형형': 'Balanced', '구조적접근형': 'Structural' },
19
+ };
20
+ const COMMUNICATION_NAMES = {
21
+ ko: { '간결형': '간결형', '균형형': '균형형', '상세형': '상세형' },
22
+ en: { '간결형': 'Concise', '균형형': 'Balanced', '상세형': 'Detailed' },
23
+ };
24
+ const TRUST_NAMES = {
25
+ ko: { '가드레일 우선': '가드레일 우선', '승인 완화': '승인 완화', '완전 신뢰 실행': '완전 신뢰 실행' },
26
+ en: { '가드레일 우선': 'Guardrails-first', '승인 완화': 'Relaxed-approval', '완전 신뢰 실행': 'Full-trust' },
27
+ };
28
+ export function qualityName(pack, locale) { return QUALITY_NAMES[locale][pack]; }
29
+ export function autonomyName(pack, locale) { return AUTONOMY_NAMES[locale][pack]; }
30
+ export function judgmentName(pack, locale) { return JUDGMENT_NAMES[locale][pack]; }
31
+ export function communicationName(pack, locale) { return COMMUNICATION_NAMES[locale][pack]; }
32
+ export function trustName(policy, locale) { return TRUST_NAMES[locale][policy]; }
33
+ export const ONBOARDING = {
34
+ ko: {
35
+ header: ' Forgen — 개인화 온보딩',
36
+ subtitle: ' 4개의 상황 질문으로 당신의 작업 스타일을 파악합니다.\n 이 결과는 임시 추천이며, 첫 세션 이후 확정됩니다.',
37
+ q1: `
38
+ ─────────────────────────────────────────
39
+ 질문 1: 애매한 구현 요청
40
+
41
+ "로그인 기능을 개선해줘"라는 요청을 받았습니다.
42
+ 요구사항이 명확하지 않고, 인접 모듈에 영향을 줄 수 있습니다.
43
+
44
+ A) 먼저 요구사항/범위를 확인하고, 범위 확대 가능성이 있으면 물어본다
45
+ B) 같은 흐름 안이면 진행하되, 큰 범위 확대가 보이면 확인한다
46
+ C) 합리적으로 가정하고 인접 파일까지 바로 수정한다
47
+
48
+ 선택 (A/B/C): `,
49
+ q2: `
50
+ ─────────────────────────────────────────
51
+ 질문 2: 검증 강도 vs 완료 속도
52
+
53
+ 수정이 거의 끝났습니다. 테스트와 타입 검사가 남아 있습니다.
54
+
55
+ A) 관련 테스트, 타입, 핵심 검증을 끝내기 전에는 완료라 하지 않는다
56
+ B) 핵심 검증 1개 이상 하고, 남은 리스크를 요약해서 끝낸다
57
+ C) 최소 smoke만 보고 빠르게 결과와 리스크만 보고한다
58
+
59
+ 선택 (A/B/C): `,
60
+ q3: `
61
+ ─────────────────────────────────────────
62
+ 질문 3: 코드 수정 접근법
63
+
64
+ 레거시 코드에서 반복 패턴을 발견했습니다. 동작은 하지만 구조가 좋지 않습니다.
65
+
66
+ A) 현재 동작을 깨뜨리지 않도록 최소한만 수정한다
67
+ B) 관련된 부분만 정리하되, 전체 구조 변경은 하지 않는다
68
+ C) 이왕 손대는 거 주변 코드까지 구조적으로 정리한다
69
+
70
+ 선택 (A/B/C): `,
71
+ q4: `
72
+ ─────────────────────────────────────────
73
+ 질문 4: 설명/보고 스타일
74
+
75
+ 복잡한 버그를 수정했습니다. 결과를 보고해야 합니다.
76
+
77
+ A) 무엇을 왜 바꿨는지, 영향 범위, 대안까지 상세하게 설명한다
78
+ B) 핵심 변경과 이유를 요약하고, 필요하면 추가 질문을 유도한다
79
+ C) 변경 사항만 간결하게 보고한다
80
+
81
+ 선택 (A/B/C): `,
82
+ resultHeader: ' 추천 결과 (임시)',
83
+ profileSaved: ' Profile 저장 완료. 첫 세션을 시작하면 이 추천이 적용됩니다.',
84
+ invalidChoice: ' A, B, C 중 하나를 입력해주세요.',
85
+ },
86
+ en: {
87
+ header: ' Forgen — Personalization Onboarding',
88
+ subtitle: ' 4 scenario questions to understand your work style.\n Results are provisional and confirmed after your first session.',
89
+ q1: `
90
+ ─────────────────────────────────────────
91
+ Q1: Ambiguous implementation request
92
+
93
+ You receive "improve the login feature." Requirements are
94
+ unclear and adjacent modules may be affected.
95
+
96
+ A) Clarify requirements/scope first. Ask if scope expansion is possible.
97
+ B) Proceed if within same flow. Check when major scope expansion appears.
98
+ C) Make reasonable assumptions and fix adjacent files directly.
99
+
100
+ Choice (A/B/C): `,
101
+ q2: `
102
+ ─────────────────────────────────────────
103
+ Q2: Verification depth vs completion speed
104
+
105
+ Your fix is almost done. Tests and type checks remain.
106
+
107
+ A) Don't call it done until all tests, types, and key checks pass.
108
+ B) Run at least one key check, then summarize remaining risks.
109
+ C) Quick smoke test, report results and risks.
110
+
111
+ Choice (A/B/C): `,
112
+ q3: `
113
+ ─────────────────────────────────────────
114
+ Q3: Code modification approach
115
+
116
+ You found a repeated pattern in legacy code. It works but
117
+ the structure is poor.
118
+
119
+ A) Make minimal changes. Don't break what works.
120
+ B) Clean up related parts only. No full restructuring.
121
+ C) Restructure surrounding code too. Reduce tech debt.
122
+
123
+ Choice (A/B/C): `,
124
+ q4: `
125
+ ─────────────────────────────────────────
126
+ Q4: Explanation/reporting style
127
+
128
+ You fixed a complex bug. Time to report.
129
+
130
+ A) Explain what, why, impact scope, and alternatives in detail.
131
+ B) Summarize key changes and reasons. Invite follow-up questions.
132
+ C) Report changes concisely. Explain only if asked.
133
+
134
+ Choice (A/B/C): `,
135
+ resultHeader: ' Recommendation (provisional)',
136
+ profileSaved: ' Profile saved. Personalization will apply from your next session.',
137
+ invalidChoice: ' Please enter A, B, or C.',
138
+ },
139
+ };
140
+ export const RULE_RENDERER = {
141
+ ko: {
142
+ trustGuardrails: '위험 우회 비활성. 파괴적 명령, 민감 경로 접근 시 항상 확인.',
143
+ trustRelaxed: '일반 파일 쓰기는 승인 없이 진행 가능. 위험 우회는 기본 제한.',
144
+ trustFullTrust: '런타임 마찰 최소화. 명시적 금지와 파괴적 명령 외에는 자유 실행.',
145
+ evidenceCollectionHeader: 'Evidence Collection',
146
+ evidenceCollectionRules: [
147
+ '사용자가 행동을 교정하면("하지마", "그렇게 말고", "앞으로는 이렇게") 반드시 correction-record MCP 도구를 호출하여 evidence로 기록하라.',
148
+ 'kind 선택: fix-now(즉시 수정), prefer-from-now(앞으로 이렇게), avoid-this(하지 마라)',
149
+ 'axis_hint: quality_safety(품질/검증), autonomy(자율/확인), judgment_philosophy(변경 접근법), communication_style(설명 스타일)',
150
+ '교정이 아닌 일반 피드백은 기록하지 않는다.',
151
+ ],
152
+ judgmentMinimalChange: [
153
+ '기존 코드 구조를 최대한 유지하라. 동작하는 코드를 불필요하게 리팩토링하지 마라.',
154
+ '수정 범위를 최소한으로 유지하라. 인접 파일 변경은 꼭 필요한 경우에만.',
155
+ '변경 전 근거(테스트, 에러 로그)를 먼저 확보하라.',
156
+ ],
157
+ judgmentBalanced: ['현재 작업 범위에 집중하되, 명확한 개선 기회가 보이면 제안하라.'],
158
+ judgmentStructural: [
159
+ '반복되는 패턴이나 기술 부채를 발견하면 적극적으로 구조 개선을 제안하라.',
160
+ '추상화와 재사용 가능한 설계를 선호하라. 단, 과도한 추상화는 피한다.',
161
+ '변경 시 전체 아키텍처 관점에서 일관성을 유지하라.',
162
+ ],
163
+ commConcise: [
164
+ '응답은 짧고 핵심만. 코드와 결과 위주로 보고하라.',
165
+ '부연 설명은 물어볼 때만. 선제적으로 길게 설명하지 마라.',
166
+ ],
167
+ commBalanced: ['핵심 변경과 이유를 요약하고, 필요하면 추가 설명을 유도하라.'],
168
+ commDetailed: [
169
+ '변경 이유, 대안 검토, 영향 범위를 함께 설명하라.',
170
+ '교육적 맥락을 제공하라 — 왜 이 접근이 좋은지, 다른 방법과 비교.',
171
+ '보고는 구조화하라 (변경 사항, 이유, 영향, 다음 단계).',
172
+ ],
173
+ },
174
+ en: {
175
+ trustGuardrails: 'Dangerous bypass disabled. Always confirm before destructive commands or sensitive path access.',
176
+ trustRelaxed: 'Regular file writes proceed without approval. Dangerous bypass restricted by default.',
177
+ trustFullTrust: 'Minimal runtime friction. Free execution except explicit bans and destructive commands.',
178
+ evidenceCollectionHeader: 'Evidence Collection',
179
+ evidenceCollectionRules: [
180
+ 'When the user corrects your behavior ("don\'t do that", "always do X", "stop doing Y"), call the correction-record MCP tool to record it as evidence.',
181
+ 'kind: fix-now (immediate fix), prefer-from-now (going forward), avoid-this (never do this)',
182
+ 'axis_hint: quality_safety, autonomy, judgment_philosophy, communication_style',
183
+ 'Do not record general feedback — only explicit behavioral corrections.',
184
+ ],
185
+ judgmentMinimalChange: [
186
+ 'Preserve existing code structure. Do not refactor working code unnecessarily.',
187
+ 'Keep modification scope minimal. Change adjacent files only when strictly necessary.',
188
+ 'Secure evidence (tests, error logs) before making changes.',
189
+ ],
190
+ judgmentBalanced: ['Focus on current task scope, but suggest improvements when clearly beneficial.'],
191
+ judgmentStructural: [
192
+ 'Proactively suggest structural improvements when you spot repeated patterns or tech debt.',
193
+ 'Prefer abstraction and reusable design, but avoid over-abstraction.',
194
+ 'Maintain architectural consistency across changes.',
195
+ ],
196
+ commConcise: [
197
+ 'Keep responses short and to the point. Focus on code and results.',
198
+ 'Only elaborate when asked. Do not proactively write long explanations.',
199
+ ],
200
+ commBalanced: ['Summarize key changes and reasons. Invite follow-up questions when needed.'],
201
+ commDetailed: [
202
+ 'Explain what changed, why, impact scope, and alternatives considered.',
203
+ 'Provide educational context — why this approach is better, compare with alternatives.',
204
+ 'Structure reports: changes, reasoning, impact, next steps.',
205
+ ],
206
+ },
207
+ };
208
+ // ── Locale Detection ──
209
+ let _currentLocale = 'en';
210
+ export function setLocale(locale) { _currentLocale = locale; }
211
+ export function getLocale() { return _currentLocale; }
212
+ /** GlobalConfig에서 locale을 읽어 설정. 없으면 'en' 기본값. */
213
+ export function initLocaleFromConfig() {
214
+ try {
215
+ const { loadGlobalConfig } = require('../core/global-config.js');
216
+ const config = loadGlobalConfig();
217
+ if (config.locale === 'ko' || config.locale === 'en') {
218
+ _currentLocale = config.locale;
219
+ }
220
+ }
221
+ catch {
222
+ // config 로드 실패 시 기본값 유지
223
+ }
224
+ }
package/dist/lib.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Forgen public library API.
3
+ * Import via `import { ... } from 'forgen'` or `import { ... } from 'forgen/lib'`
4
+ *
5
+ * Separates library exports from CLI entrypoint (cli.ts)
6
+ * so forgen can be used programmatically.
7
+ */
8
+ export type { Philosophy, Principle, HarnessContext, ScopeInfo, } from './core/types.js';
9
+ export type { Profile, Rule, Evidence, PackRecommendation, SessionEffectiveState, QualityPack, AutonomyPack, JudgmentPack, CommunicationPack, TrustPolicy, QualityFacets, AutonomyFacets, JudgmentFacets, CommunicationFacets, } from './store/types.js';
10
+ export { SECURITY_PATTERNS, PROMPT_INJECTION_PATTERNS, normalizeForInjectionCheck, containsPromptInjection, filterSolutionContent, } from './hooks/prompt-injection-filter.js';
11
+ export type { ScanFinding, ScanResult, } from './hooks/prompt-injection-filter.js';
12
+ export { loadProfile, saveProfile, createProfile } from './store/profile-store.js';
13
+ export { loadActiveRules } from './store/rule-store.js';
14
+ export { ForgenError, HookError, ConfigError, ForgeError, NonRetryableError } from './core/errors.js';
package/dist/lib.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Forgen public library API.
3
+ * Import via `import { ... } from 'forgen'` or `import { ... } from 'forgen/lib'`
4
+ *
5
+ * Separates library exports from CLI entrypoint (cli.ts)
6
+ * so forgen can be used programmatically.
7
+ */
8
+ // ── Hooks (utilities) ──
9
+ export { SECURITY_PATTERNS, PROMPT_INJECTION_PATTERNS, normalizeForInjectionCheck, containsPromptInjection, filterSolutionContent, } from './hooks/prompt-injection-filter.js';
10
+ // ── v1 stores ──
11
+ export { loadProfile, saveProfile, createProfile } from './store/profile-store.js';
12
+ export { loadActiveRules } from './store/rule-store.js';
13
+ // ── Errors ──
14
+ export { ForgenError, HookError, ConfigError, ForgeError, NonRetryableError } from './core/errors.js';
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Forgen — MCP Compound Knowledge Server
4
+ *
5
+ * Pull 모델: Claude가 필요할 때 compound-search/read를 직접 호출.
6
+ * instructions 필드로 Claude에게 compound 도구 사용법을 안내.
7
+ */
8
+ export {};
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Forgen — MCP Compound Knowledge Server
4
+ *
5
+ * Pull 모델: Claude가 필요할 때 compound-search/read를 직접 호출.
6
+ * instructions 필드로 Claude에게 compound 도구 사용법을 안내.
7
+ */
8
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import { registerTools } from './tools.js';
11
+ if (!process.env.FORGEN_CWD && !process.env.COMPOUND_CWD) {
12
+ process.env.FORGEN_CWD = process.cwd();
13
+ process.env.COMPOUND_CWD = process.cwd(); // legacy compat
14
+ }
15
+ const INSTRUCTIONS = [
16
+ 'Forgen compound knowledge — accumulated patterns and solutions from past sessions.',
17
+ '',
18
+ 'When to use:',
19
+ '- Before starting a task: search for similar past patterns with compound-search',
20
+ '- When encountering an error: search for troubleshooting solutions',
21
+ '- When making architectural decisions: check if a similar decision was documented',
22
+ '- After completing work: user may run /compound to extract new patterns',
23
+ '',
24
+ 'Usage flow: compound-search (find relevant) → compound-read (get full content)',
25
+ 'compound-stats gives an overview of accumulated knowledge.',
26
+ '',
27
+ 'Evidence collection:',
28
+ '- When the user corrects your behavior, use correction-record to record it as evidence',
29
+ '- This enables forgen to learn from corrections and adapt personalization over time',
30
+ ].join('\n');
31
+ const server = new McpServer({ name: 'forgen-compound', version: '1.0.0' }, { instructions: INSTRUCTIONS });
32
+ registerTools(server);
33
+ try {
34
+ const transport = new StdioServerTransport();
35
+ await server.connect(transport);
36
+ }
37
+ catch (err) {
38
+ process.stderr.write(`[forgen-mcp] Failed to start: ${err instanceof Error ? err.message : err}\n`);
39
+ process.exit(1);
40
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Forgen — MCP Solution Reader
3
+ *
4
+ * MCP 도구 핸들러를 위한 비즈니스 로직 파사드.
5
+ * 기존 solution-index, solution-matcher, solution-format 모듈을 조합하여
6
+ * 검색/목록/읽기/통계 기능을 제공합니다.
7
+ *
8
+ * 설계 결정:
9
+ * - MCP 도구 핸들러가 직접 fs/path를 다루지 않도록 격리
10
+ * - Hook injection(push)과 독립: 세션 캐시/버짓 적용 안 함
11
+ * - compound-read는 전문 반환 (축약 없음), compound-search는 요약만
12
+ * - prompt injection 필터는 동일하게 적용 (보안 일관성)
13
+ * - 인덱스 캐시는 isIndexStale()에 의존 (resetIndexCache 미사용)
14
+ * → 디렉토리 mtime이 변하지 않으면 캐시 재사용 (성능)
15
+ */
16
+ import type { SolutionDirConfig } from '../engine/solution-index.js';
17
+ import type { SolutionStatus, SolutionType } from '../engine/solution-format.js';
18
+ export interface SearchOptions {
19
+ dirs?: SolutionDirConfig[];
20
+ type?: SolutionType;
21
+ status?: SolutionStatus;
22
+ limit?: number;
23
+ }
24
+ export interface ListOptions {
25
+ dirs?: SolutionDirConfig[];
26
+ status?: SolutionStatus;
27
+ type?: SolutionType;
28
+ scope?: 'me' | 'team' | 'project';
29
+ sort?: 'confidence' | 'updated' | 'name';
30
+ }
31
+ export interface SolutionSummary {
32
+ name: string;
33
+ status: SolutionStatus;
34
+ confidence: number;
35
+ type: SolutionType;
36
+ scope: 'me' | 'team' | 'project';
37
+ tags: string[];
38
+ }
39
+ export interface SearchResult extends SolutionSummary {
40
+ relevance: number;
41
+ matchedTags: string[];
42
+ }
43
+ export interface SolutionDetail {
44
+ name: string;
45
+ status: SolutionStatus;
46
+ confidence: number;
47
+ type: SolutionType;
48
+ scope: 'me' | 'team' | 'project';
49
+ tags: string[];
50
+ identifiers: string[];
51
+ context: string;
52
+ content: string;
53
+ }
54
+ export interface SolutionStats {
55
+ total: number;
56
+ byStatus: Record<SolutionStatus, number>;
57
+ byType: Record<SolutionType, number>;
58
+ byScope: Record<'me' | 'team' | 'project', number>;
59
+ }
60
+ /**
61
+ * 기본 솔루션 디렉토리 목록 생성.
62
+ * MCP 서버에서 cwd를 전달받으면 project 스코프도 포함.
63
+ */
64
+ export declare function defaultSolutionDirs(cwd?: string): SolutionDirConfig[];
65
+ /**
66
+ * 쿼리 텍스트로 솔루션을 검색합니다.
67
+ * 태그 기반 Jaccard 매칭 + confidence 가중치.
68
+ * Hook injection과 달리 세션 캐시/버짓 없이 순수 검색.
69
+ *
70
+ * 인덱스 캐시: getOrBuildIndex() 내부의 isIndexStale()이
71
+ * 디렉토리 mtime을 비교하여 변경 시에만 재구축합니다.
72
+ */
73
+ export declare function searchSolutions(query: string, options?: SearchOptions): SearchResult[];
74
+ /** 솔루션 요약 목록을 반환합니다 (필터/정렬 지원). */
75
+ export declare function listSolutions(options?: ListOptions): SolutionSummary[];
76
+ /**
77
+ * 이름으로 솔루션 전문을 읽습니다.
78
+ *
79
+ * MCP는 온디맨드이므로 truncation 없이 전문을 반환합니다.
80
+ * 이것이 hook injection(1500자 캡)과의 핵심 차이입니다.
81
+ * Prompt injection 필터만 적용합니다.
82
+ */
83
+ export declare function readSolution(name: string, options?: {
84
+ dirs?: SolutionDirConfig[];
85
+ skipEvidence?: boolean;
86
+ }): SolutionDetail | null;
87
+ /** 솔루션 통계 (status별, type별, scope별 카운트). */
88
+ export declare function getSolutionStats(options?: {
89
+ dirs?: SolutionDirConfig[];
90
+ }): SolutionStats;