@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,64 @@
1
+ /**
2
+ * Forgen v1 — Pack Recommendation Store
3
+ *
4
+ * Authoritative schema: docs/plans/2026-04-03-forgen-data-model-storage-spec.md §6
5
+ */
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ import * as crypto from 'node:crypto';
9
+ import { V1_RECOMMENDATIONS_DIR } from '../core/paths.js';
10
+ import { atomicWriteJSON, safeReadJSON } from '../hooks/shared/atomic-write.js';
11
+ function recPath(id) {
12
+ return path.join(V1_RECOMMENDATIONS_DIR, `${id}.json`);
13
+ }
14
+ export function createRecommendation(params) {
15
+ return {
16
+ recommendation_id: crypto.randomUUID(),
17
+ source: params.source,
18
+ quality_pack: params.quality_pack,
19
+ autonomy_pack: params.autonomy_pack,
20
+ judgment_pack: params.judgment_pack ?? '균형형',
21
+ communication_pack: params.communication_pack ?? '균형형',
22
+ suggested_trust_policy: params.suggested_trust_policy,
23
+ confidence: params.confidence,
24
+ reason_summary: params.reason_summary,
25
+ status: 'proposed',
26
+ created_at: new Date().toISOString(),
27
+ };
28
+ }
29
+ export function saveRecommendation(rec) {
30
+ atomicWriteJSON(recPath(rec.recommendation_id), rec, { pretty: true });
31
+ }
32
+ export function loadRecommendation(id) {
33
+ return safeReadJSON(recPath(id), null);
34
+ }
35
+ export function loadAllRecommendations() {
36
+ if (!fs.existsSync(V1_RECOMMENDATIONS_DIR))
37
+ return [];
38
+ const items = [];
39
+ for (const file of fs.readdirSync(V1_RECOMMENDATIONS_DIR)) {
40
+ if (!file.endsWith('.json'))
41
+ continue;
42
+ const rec = safeReadJSON(path.join(V1_RECOMMENDATIONS_DIR, file), null);
43
+ if (rec)
44
+ items.push(rec);
45
+ }
46
+ return items;
47
+ }
48
+ export function updateRecommendationStatus(id, status) {
49
+ const rec = loadRecommendation(id);
50
+ if (!rec)
51
+ return false;
52
+ rec.status = status;
53
+ saveRecommendation(rec);
54
+ return true;
55
+ }
56
+ export function loadAcceptedRecommendation() {
57
+ return loadAllRecommendations().find(r => r.status === 'accepted') ?? null;
58
+ }
59
+ export function loadLatestRecommendation() {
60
+ const all = loadAllRecommendations();
61
+ if (all.length === 0)
62
+ return null;
63
+ return all.sort((a, b) => b.created_at.localeCompare(a.created_at))[0];
64
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Forgen v1 — Rule Store
3
+ *
4
+ * Structured Rule CRUD. render_key 기반 dedupe는 renderer 책임.
5
+ * Authoritative schema: docs/plans/2026-04-03-forgen-data-model-storage-spec.md §3
6
+ */
7
+ import type { Rule, RuleCategory, RuleScope, RuleStrength, RuleSource, RuleStatus } from './types.js';
8
+ export declare function createRule(params: {
9
+ category: RuleCategory;
10
+ scope: RuleScope;
11
+ trigger: string;
12
+ policy: string;
13
+ strength: RuleStrength;
14
+ source: RuleSource;
15
+ evidence_refs?: string[];
16
+ render_key: string;
17
+ }): Rule;
18
+ export declare function saveRule(rule: Rule): void;
19
+ export declare function loadRule(ruleId: string): Rule | null;
20
+ export declare function loadAllRules(): Rule[];
21
+ export declare function loadActiveRules(): Rule[];
22
+ export declare function updateRuleStatus(ruleId: string, status: RuleStatus): boolean;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Forgen v1 — Rule Store
3
+ *
4
+ * Structured Rule CRUD. render_key 기반 dedupe는 renderer 책임.
5
+ * Authoritative schema: docs/plans/2026-04-03-forgen-data-model-storage-spec.md §3
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import * as crypto from 'node:crypto';
10
+ import { V1_RULES_DIR } from '../core/paths.js';
11
+ import { atomicWriteJSON, safeReadJSON } from '../hooks/shared/atomic-write.js';
12
+ function rulePath(ruleId) {
13
+ return path.join(V1_RULES_DIR, `${ruleId}.json`);
14
+ }
15
+ export function createRule(params) {
16
+ const now = new Date().toISOString();
17
+ return {
18
+ rule_id: crypto.randomUUID(),
19
+ category: params.category,
20
+ scope: params.scope,
21
+ trigger: params.trigger,
22
+ policy: params.policy,
23
+ strength: params.strength,
24
+ source: params.source,
25
+ status: 'active',
26
+ evidence_refs: params.evidence_refs ?? [],
27
+ render_key: params.render_key,
28
+ created_at: now,
29
+ updated_at: now,
30
+ };
31
+ }
32
+ export function saveRule(rule) {
33
+ rule.updated_at = new Date().toISOString();
34
+ atomicWriteJSON(rulePath(rule.rule_id), rule, { pretty: true });
35
+ }
36
+ export function loadRule(ruleId) {
37
+ return safeReadJSON(rulePath(ruleId), null);
38
+ }
39
+ export function loadAllRules() {
40
+ if (!fs.existsSync(V1_RULES_DIR))
41
+ return [];
42
+ const rules = [];
43
+ for (const file of fs.readdirSync(V1_RULES_DIR)) {
44
+ if (!file.endsWith('.json'))
45
+ continue;
46
+ const rule = safeReadJSON(path.join(V1_RULES_DIR, file), null);
47
+ if (rule)
48
+ rules.push(rule);
49
+ }
50
+ return rules;
51
+ }
52
+ export function loadActiveRules() {
53
+ return loadAllRules().filter(r => r.status === 'active');
54
+ }
55
+ export function updateRuleStatus(ruleId, status) {
56
+ const rule = loadRule(ruleId);
57
+ if (!rule)
58
+ return false;
59
+ rule.status = status;
60
+ saveRule(rule);
61
+ return true;
62
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Forgen v1 — Session Effective State Store
3
+ *
4
+ * Authoritative schema: docs/plans/2026-04-03-forgen-data-model-storage-spec.md §7
5
+ */
6
+ import type { SessionEffectiveState } from './types.js';
7
+ export declare function saveSessionState(state: SessionEffectiveState): void;
8
+ export declare function loadSessionState(sessionId: string): SessionEffectiveState | null;
9
+ export declare function loadAllSessionStates(): SessionEffectiveState[];
10
+ export declare function loadRecentSessions(limit?: number): SessionEffectiveState[];
11
+ export declare function finalizeSession(sessionId: string): boolean;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Forgen v1 — Session Effective State Store
3
+ *
4
+ * Authoritative schema: docs/plans/2026-04-03-forgen-data-model-storage-spec.md §7
5
+ */
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ import { V1_SESSIONS_DIR } from '../core/paths.js';
9
+ import { atomicWriteJSON, safeReadJSON } from '../hooks/shared/atomic-write.js';
10
+ function sessionPath(sessionId) {
11
+ return path.join(V1_SESSIONS_DIR, `${sessionId}.json`);
12
+ }
13
+ export function saveSessionState(state) {
14
+ atomicWriteJSON(sessionPath(state.session_id), state, { pretty: true });
15
+ }
16
+ export function loadSessionState(sessionId) {
17
+ return safeReadJSON(sessionPath(sessionId), null);
18
+ }
19
+ export function loadAllSessionStates() {
20
+ if (!fs.existsSync(V1_SESSIONS_DIR))
21
+ return [];
22
+ const items = [];
23
+ for (const file of fs.readdirSync(V1_SESSIONS_DIR)) {
24
+ if (!file.endsWith('.json'))
25
+ continue;
26
+ const s = safeReadJSON(path.join(V1_SESSIONS_DIR, file), null);
27
+ if (s)
28
+ items.push(s);
29
+ }
30
+ return items;
31
+ }
32
+ export function loadRecentSessions(limit = 10) {
33
+ return loadAllSessionStates()
34
+ .sort((a, b) => b.started_at.localeCompare(a.started_at))
35
+ .slice(0, limit);
36
+ }
37
+ export function finalizeSession(sessionId) {
38
+ const state = loadSessionState(sessionId);
39
+ if (!state)
40
+ return false;
41
+ state.ended_at = new Date().toISOString();
42
+ saveSessionState(state);
43
+ return true;
44
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Forgen v1 — Data Model Types
3
+ *
4
+ * Authoritative source: docs/plans/2026-04-03-forgen-data-model-storage-spec.md
5
+ * Runtime contracts: docs/plans/2026-04-03-forgen-component-interface-design.md
6
+ */
7
+ export type QualityPack = '보수형' | '균형형' | '속도형';
8
+ export type AutonomyPack = '확인 우선형' | '균형형' | '자율 실행형';
9
+ export type JudgmentPack = '최소변경형' | '균형형' | '구조적접근형';
10
+ export type CommunicationPack = '간결형' | '균형형' | '상세형';
11
+ export type TrustPolicy = '가드레일 우선' | '승인 완화' | '완전 신뢰 실행';
12
+ export type RuleCategory = 'quality' | 'autonomy' | 'communication' | 'workflow' | 'safety';
13
+ export type RuleScope = 'me' | 'session';
14
+ export type RuleStrength = 'soft' | 'default' | 'strong' | 'hard';
15
+ export type RuleSource = 'onboarding' | 'explicit_correction' | 'behavior_inference' | 'pack_overlay';
16
+ export type RuleStatus = 'active' | 'suppressed' | 'removed' | 'superseded';
17
+ export interface Rule {
18
+ rule_id: string;
19
+ category: RuleCategory;
20
+ scope: RuleScope;
21
+ trigger: string;
22
+ policy: string;
23
+ strength: RuleStrength;
24
+ source: RuleSource;
25
+ status: RuleStatus;
26
+ evidence_refs: string[];
27
+ render_key: string;
28
+ created_at: string;
29
+ updated_at: string;
30
+ }
31
+ export type EvidenceType = 'explicit_correction' | 'behavior_observation' | 'session_summary';
32
+ export interface Evidence {
33
+ evidence_id: string;
34
+ type: EvidenceType;
35
+ session_id: string;
36
+ timestamp: string;
37
+ source_component: string;
38
+ summary: string;
39
+ axis_refs: string[];
40
+ candidate_rule_refs: string[];
41
+ confidence: number;
42
+ raw_payload: Record<string, unknown>;
43
+ }
44
+ export interface QualityFacets {
45
+ verification_depth: number;
46
+ stop_threshold: number;
47
+ change_conservatism: number;
48
+ }
49
+ export interface AutonomyFacets {
50
+ confirmation_independence: number;
51
+ assumption_tolerance: number;
52
+ scope_expansion_tolerance: number;
53
+ approval_threshold: number;
54
+ }
55
+ export interface JudgmentFacets {
56
+ minimal_change_bias: number;
57
+ abstraction_bias: number;
58
+ evidence_first_bias: number;
59
+ }
60
+ export interface CommunicationFacets {
61
+ verbosity: number;
62
+ structure: number;
63
+ teaching_bias: number;
64
+ }
65
+ export interface Axis<F> {
66
+ score: number;
67
+ facets: F;
68
+ confidence: number;
69
+ }
70
+ export interface Profile {
71
+ user_id: string;
72
+ model_version: string;
73
+ axes: {
74
+ quality_safety: Axis<QualityFacets>;
75
+ autonomy: Axis<AutonomyFacets>;
76
+ judgment_philosophy: Axis<JudgmentFacets>;
77
+ communication_style: Axis<CommunicationFacets>;
78
+ };
79
+ base_packs: {
80
+ quality_pack: QualityPack;
81
+ autonomy_pack: AutonomyPack;
82
+ judgment_pack: JudgmentPack;
83
+ communication_pack: CommunicationPack;
84
+ };
85
+ trust_preferences: {
86
+ desired_policy: TrustPolicy;
87
+ source: 'onboarding' | 'user_override' | 'mismatch_recommendation';
88
+ };
89
+ metadata: {
90
+ created_at: string;
91
+ updated_at: string;
92
+ last_onboarding_at: string;
93
+ last_reclassification_at: string | null;
94
+ };
95
+ }
96
+ export type RecommendationSource = 'onboarding' | 'mismatch_recommendation';
97
+ export type RecommendationStatus = 'proposed' | 'accepted' | 'archived';
98
+ export interface PackRecommendation {
99
+ recommendation_id: string;
100
+ source: RecommendationSource;
101
+ quality_pack: QualityPack;
102
+ autonomy_pack: AutonomyPack;
103
+ judgment_pack: JudgmentPack;
104
+ communication_pack: CommunicationPack;
105
+ suggested_trust_policy: TrustPolicy;
106
+ confidence: number;
107
+ reason_summary: string;
108
+ status: RecommendationStatus;
109
+ created_at: string;
110
+ }
111
+ export type PermissionMode = 'guarded' | 'relaxed' | 'bypassed';
112
+ export interface RuntimeCapabilityState {
113
+ permission_mode: PermissionMode;
114
+ dangerous_skip_permissions: boolean;
115
+ auto_accept_scope: string[];
116
+ detected_from: string;
117
+ }
118
+ export interface SessionEffectiveState {
119
+ session_id: string;
120
+ profile_version: string;
121
+ quality_pack: QualityPack;
122
+ autonomy_pack: AutonomyPack;
123
+ judgment_pack: JudgmentPack;
124
+ communication_pack: CommunicationPack;
125
+ effective_trust_policy: TrustPolicy;
126
+ active_rule_ids: string[];
127
+ temporary_overlays: Rule[];
128
+ runtime_capability_state: RuntimeCapabilityState;
129
+ warnings: string[];
130
+ started_at: string;
131
+ ended_at: string | null;
132
+ }
133
+ export type CorrectionKind = 'fix-now' | 'prefer-from-now' | 'avoid-this';
134
+ export interface CorrectionRequest {
135
+ session_id: string;
136
+ kind: CorrectionKind;
137
+ message: string;
138
+ target: string;
139
+ axis_hint: 'quality_safety' | 'autonomy' | 'judgment_philosophy' | 'communication_style' | null;
140
+ }
141
+ export interface CorrectionResult {
142
+ temporary_rule: Rule | null;
143
+ evidence_event_id: string;
144
+ recompose_required: boolean;
145
+ promotion_candidate: boolean;
146
+ }
147
+ export interface SessionLearningSummary {
148
+ session_id: string;
149
+ explicit_corrections: Evidence[];
150
+ behavior_observations: Evidence[];
151
+ session_summary_evidence: Evidence | null;
152
+ rule_candidates: string[];
153
+ knowledge_candidates: string[];
154
+ profile_delta_suggestion: Partial<{
155
+ quality_safety: Partial<QualityFacets>;
156
+ autonomy: Partial<AutonomyFacets>;
157
+ }> | null;
158
+ pack_mismatch_candidate: boolean;
159
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Forgen v1 — Data Model Types
3
+ *
4
+ * Authoritative source: docs/plans/2026-04-03-forgen-data-model-storage-spec.md
5
+ * Runtime contracts: docs/plans/2026-04-03-forgen-component-interface-design.md
6
+ */
7
+ export {};
@@ -0,0 +1,21 @@
1
+ [
2
+ { "name": "notepad-injector", "tier": "compound-core", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/notepad-injector.js", "timeout": 3, "compoundCritical": false },
3
+ { "name": "context-guard", "tier": "compound-core", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/context-guard.js", "timeout": 2, "compoundCritical": false },
4
+ { "name": "session-recovery", "tier": "compound-core", "event": "SessionStart", "matcher": "*", "script": "hooks/session-recovery.js", "timeout": 3, "compoundCritical": true },
5
+ { "name": "post-tool-use", "tier": "compound-core", "event": "PostToolUse", "matcher": "*", "script": "hooks/post-tool-use.js", "timeout": 3, "compoundCritical": true },
6
+ { "name": "pre-compact", "tier": "compound-core", "event": "PreCompact", "matcher": "*", "script": "hooks/pre-compact.js", "timeout": 3, "compoundCritical": false },
7
+ { "name": "context-guard-stop", "tier": "compound-core", "event": "Stop", "matcher": "*", "script": "hooks/context-guard.js", "timeout": 5, "compoundCritical": false },
8
+ { "name": "pre-tool-use", "tier": "compound-core", "event": "PreToolUse", "matcher": "*", "script": "hooks/pre-tool-use.js", "timeout": 3, "compoundCritical": true },
9
+ { "name": "secret-filter", "tier": "safety", "event": "PostToolUse", "matcher": "Write|Edit|Bash", "script": "hooks/secret-filter.js", "timeout": 3, "compoundCritical": false },
10
+ { "name": "slop-detector", "tier": "safety", "event": "PostToolUse", "matcher": "Write|Edit", "script": "hooks/slop-detector.js", "timeout": 3, "compoundCritical": false },
11
+ { "name": "db-guard", "tier": "safety", "event": "PreToolUse", "matcher": "Bash", "script": "hooks/db-guard.js", "timeout": 3, "compoundCritical": false },
12
+ { "name": "rate-limiter", "tier": "safety", "event": "PreToolUse", "matcher": "*", "script": "hooks/rate-limiter.js", "timeout": 2, "compoundCritical": false },
13
+ { "name": "intent-classifier", "tier": "workflow", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/intent-classifier.js", "timeout": 3, "compoundCritical": false },
14
+ { "name": "keyword-detector", "tier": "workflow", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/keyword-detector.js", "timeout": 5, "compoundCritical": false },
15
+ { "name": "permission-handler", "tier": "workflow", "event": "PermissionRequest", "matcher": "*", "script": "hooks/permission-handler.js", "timeout": 2, "compoundCritical": false },
16
+ { "name": "subagent-tracker-start", "tier": "workflow", "event": "SubagentStart", "matcher": "*", "script": "hooks/subagent-tracker.js start", "timeout": 2, "compoundCritical": false },
17
+ { "name": "subagent-tracker-stop", "tier": "workflow", "event": "SubagentStop", "matcher": "*", "script": "hooks/subagent-tracker.js stop", "timeout": 2, "compoundCritical": false },
18
+ { "name": "post-tool-failure", "tier": "workflow", "event": "PostToolUseFailure", "matcher": "*", "script": "hooks/post-tool-failure.js", "timeout": 3, "compoundCritical": false },
19
+ { "name": "solution-injector", "tier": "compound-core", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/solution-injector.js", "timeout": 5, "compoundCritical": true },
20
+ { "name": "skill-injector", "tier": "compound-core", "event": "UserPromptSubmit", "matcher": "*", "script": "hooks/skill-injector.js", "timeout": 5, "compoundCritical": true }
21
+ ]
@@ -0,0 +1,185 @@
1
+ {
2
+ "description": "Forgen harness hooks (auto-generated, 19/19 active)",
3
+ "hooks": {
4
+ "UserPromptSubmit": [
5
+ {
6
+ "matcher": "*",
7
+ "hooks": [
8
+ {
9
+ "type": "command",
10
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/notepad-injector.js\"",
11
+ "timeout": 3
12
+ },
13
+ {
14
+ "type": "command",
15
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/context-guard.js\"",
16
+ "timeout": 2
17
+ },
18
+ {
19
+ "type": "command",
20
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/intent-classifier.js\"",
21
+ "timeout": 3
22
+ },
23
+ {
24
+ "type": "command",
25
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/keyword-detector.js\"",
26
+ "timeout": 5
27
+ },
28
+ {
29
+ "type": "command",
30
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/solution-injector.js\"",
31
+ "timeout": 5
32
+ },
33
+ {
34
+ "type": "command",
35
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/skill-injector.js\"",
36
+ "timeout": 5
37
+ }
38
+ ]
39
+ }
40
+ ],
41
+ "SessionStart": [
42
+ {
43
+ "matcher": "*",
44
+ "hooks": [
45
+ {
46
+ "type": "command",
47
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/session-recovery.js\"",
48
+ "timeout": 3
49
+ }
50
+ ]
51
+ }
52
+ ],
53
+ "PostToolUse": [
54
+ {
55
+ "matcher": "*",
56
+ "hooks": [
57
+ {
58
+ "type": "command",
59
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/post-tool-use.js\"",
60
+ "timeout": 3
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "matcher": "Write|Edit|Bash",
66
+ "hooks": [
67
+ {
68
+ "type": "command",
69
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/secret-filter.js\"",
70
+ "timeout": 3
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ "matcher": "Write|Edit",
76
+ "hooks": [
77
+ {
78
+ "type": "command",
79
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/slop-detector.js\"",
80
+ "timeout": 3
81
+ }
82
+ ]
83
+ }
84
+ ],
85
+ "PreCompact": [
86
+ {
87
+ "matcher": "*",
88
+ "hooks": [
89
+ {
90
+ "type": "command",
91
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/pre-compact.js\"",
92
+ "timeout": 3
93
+ }
94
+ ]
95
+ }
96
+ ],
97
+ "Stop": [
98
+ {
99
+ "matcher": "*",
100
+ "hooks": [
101
+ {
102
+ "type": "command",
103
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/context-guard.js\"",
104
+ "timeout": 5
105
+ }
106
+ ]
107
+ }
108
+ ],
109
+ "PreToolUse": [
110
+ {
111
+ "matcher": "*",
112
+ "hooks": [
113
+ {
114
+ "type": "command",
115
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/pre-tool-use.js\"",
116
+ "timeout": 3
117
+ },
118
+ {
119
+ "type": "command",
120
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/rate-limiter.js\"",
121
+ "timeout": 2
122
+ }
123
+ ]
124
+ },
125
+ {
126
+ "matcher": "Bash",
127
+ "hooks": [
128
+ {
129
+ "type": "command",
130
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/db-guard.js\"",
131
+ "timeout": 3
132
+ }
133
+ ]
134
+ }
135
+ ],
136
+ "PermissionRequest": [
137
+ {
138
+ "matcher": "*",
139
+ "hooks": [
140
+ {
141
+ "type": "command",
142
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/permission-handler.js\"",
143
+ "timeout": 2
144
+ }
145
+ ]
146
+ }
147
+ ],
148
+ "SubagentStart": [
149
+ {
150
+ "matcher": "*",
151
+ "hooks": [
152
+ {
153
+ "type": "command",
154
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/subagent-tracker.js\" start",
155
+ "timeout": 2
156
+ }
157
+ ]
158
+ }
159
+ ],
160
+ "SubagentStop": [
161
+ {
162
+ "matcher": "*",
163
+ "hooks": [
164
+ {
165
+ "type": "command",
166
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/subagent-tracker.js\" stop",
167
+ "timeout": 2
168
+ }
169
+ ]
170
+ }
171
+ ],
172
+ "PostToolUseFailure": [
173
+ {
174
+ "matcher": "*",
175
+ "hooks": [
176
+ {
177
+ "type": "command",
178
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/post-tool-failure.js\"",
179
+ "timeout": 3
180
+ }
181
+ ]
182
+ }
183
+ ]
184
+ }
185
+ }
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@wooojin/forgen",
3
+ "version": "0.1.0",
4
+ "main": "dist/lib.js",
5
+ "types": "./dist/lib.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/lib.d.ts",
9
+ "import": "./dist/lib.js"
10
+ },
11
+ "./lib": {
12
+ "types": "./dist/lib.d.ts",
13
+ "import": "./dist/lib.js"
14
+ },
15
+ "./cli": {
16
+ "types": "./dist/cli.d.ts",
17
+ "import": "./dist/cli.js"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "node scripts/clean-dist.cjs clean && tsc && node scripts/copy-assets.js && node scripts/clean-dist.cjs chmod",
22
+ "dev": "tsc --watch",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "link": "npm run build && npm link",
26
+ "lint": "biome lint src/",
27
+ "lint:fix": "biome lint --write src/",
28
+ "format": "biome format --write src/",
29
+ "postinstall": "node scripts/postinstall.js",
30
+ "prepare": "npm run build",
31
+ "prepublishOnly": "npm test",
32
+ "prepack": "node scripts/prepack-hooks.cjs"
33
+ },
34
+ "author": "jang-ujin",
35
+ "license": "MIT",
36
+ "description": "Code, forged for you — personalized Claude Code harness",
37
+ "keywords": [
38
+ "claude-code",
39
+ "forgen",
40
+ "personalization",
41
+ "ai-harness",
42
+ "workflow",
43
+ "ai-agent",
44
+ "forge",
45
+ "compound-engineering"
46
+ ],
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/wooo-jin/forgen.git"
50
+ },
51
+ "engines": {
52
+ "node": ">=20.0.0"
53
+ },
54
+ "type": "module",
55
+ "bin": {
56
+ "forgen": "./dist/cli.js",
57
+ "fgx": "./dist/fgx.js",
58
+ "forgen-mcp": "./dist/mcp/server.js"
59
+ },
60
+ "files": [
61
+ "dist/",
62
+ "agents/",
63
+ "commands/",
64
+ "skills/",
65
+ "starter-pack/",
66
+ "scripts/postinstall.js",
67
+ ".claude-plugin/",
68
+ "hooks/",
69
+ "plugin.json",
70
+ "README.md",
71
+ "README.ko.md",
72
+ "LICENSE",
73
+ "CHANGELOG.md",
74
+ "CONTRIBUTING.md"
75
+ ],
76
+ "devDependencies": {
77
+ "@biomejs/biome": "^2.4.8",
78
+ "@types/js-yaml": "^4.0.9",
79
+ "@types/node": "^25.5.0",
80
+ "@vitest/coverage-v8": "^4.1.0",
81
+ "typescript": "^5.9.3",
82
+ "vitest": "^4.0.18"
83
+ },
84
+ "dependencies": {
85
+ "@modelcontextprotocol/sdk": "^1.28.0",
86
+ "js-yaml": "^4.1.1",
87
+ "zod": "^4.3.6"
88
+ }
89
+ }