oh-my-codex-cli 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 (292) hide show
  1. package/.agent/skills/agent-kb/HOW_TO_USE.md +428 -0
  2. package/.agent/skills/agent-kb/README.md +46 -0
  3. package/.agent/skills/agent-kb/SKILL.md +128 -0
  4. package/.agent/skills/agent-kb/references/intelligent-analysis-explained.md +333 -0
  5. package/.agent/skills/agent-kb/references/query-optimization.md +225 -0
  6. package/.agent/skills/aireview/SKILL.md +704 -0
  7. package/.agent/skills/analyze/SKILL.md +81 -0
  8. package/.agent/skills/architect-planner/HOW_TO_USE.md +238 -0
  9. package/.agent/skills/architect-planner/README.md +41 -0
  10. package/.agent/skills/architect-planner/SKILL.md +539 -0
  11. package/.agent/skills/auto-mbti/SKILL.md +291 -0
  12. package/.agent/skills/autopilot/SKILL.md +222 -0
  13. package/.agent/skills/backend-patterns/SKILL.md +602 -0
  14. package/.agent/skills/bdd-generator/README.md +78 -0
  15. package/.agent/skills/bdd-generator/SKILL.md +436 -0
  16. package/.agent/skills/brainstorming/HOW_TO_USE.md +289 -0
  17. package/.agent/skills/brainstorming/README.md +41 -0
  18. package/.agent/skills/brainstorming/SKILL.md +165 -0
  19. package/.agent/skills/build-fix/SKILL.md +190 -0
  20. package/.agent/skills/cancel/SKILL.md +658 -0
  21. package/.agent/skills/checkpoint/SKILL.md +94 -0
  22. package/.agent/skills/code-review/SKILL.md +273 -0
  23. package/.agent/skills/coding-standards/SKILL.md +535 -0
  24. package/.agent/skills/conductor/SKILL.md +128 -0
  25. package/.agent/skills/conductor/commands/conductor/implement.toml +358 -0
  26. package/.agent/skills/conductor/commands/conductor/newTrack.toml +142 -0
  27. package/.agent/skills/conductor/commands/conductor/revert.toml +123 -0
  28. package/.agent/skills/conductor/commands/conductor/setup.toml +429 -0
  29. package/.agent/skills/conductor/commands/conductor/status.toml +57 -0
  30. package/.agent/skills/conductor/scripts/install.sh +89 -0
  31. package/.agent/skills/conductor/templates/code_styleguides/csharp.md +115 -0
  32. package/.agent/skills/conductor/templates/code_styleguides/dart.md +238 -0
  33. package/.agent/skills/conductor/templates/code_styleguides/general.md +23 -0
  34. package/.agent/skills/conductor/templates/code_styleguides/go.md +48 -0
  35. package/.agent/skills/conductor/templates/code_styleguides/html-css.md +49 -0
  36. package/.agent/skills/conductor/templates/code_styleguides/javascript.md +51 -0
  37. package/.agent/skills/conductor/templates/code_styleguides/python.md +37 -0
  38. package/.agent/skills/conductor/templates/code_styleguides/typescript.md +43 -0
  39. package/.agent/skills/conductor/templates/rules/README.md +23 -0
  40. package/.agent/skills/conductor/templates/rules/agents.md +49 -0
  41. package/.agent/skills/conductor/templates/rules/coding-style.md +70 -0
  42. package/.agent/skills/conductor/templates/rules/dev.md +20 -0
  43. package/.agent/skills/conductor/templates/rules/git-workflow.md +45 -0
  44. package/.agent/skills/conductor/templates/rules/hooks.md +6 -0
  45. package/.agent/skills/conductor/templates/rules/patterns.md +55 -0
  46. package/.agent/skills/conductor/templates/rules/performance.md +47 -0
  47. package/.agent/skills/conductor/templates/rules/research.md +26 -0
  48. package/.agent/skills/conductor/templates/rules/review.md +22 -0
  49. package/.agent/skills/conductor/templates/rules/security.md +36 -0
  50. package/.agent/skills/conductor/templates/rules/testing.md +30 -0
  51. package/.agent/skills/conductor/templates/workflow.md +333 -0
  52. package/.agent/skills/consensus/HOW_TO_USE.md +191 -0
  53. package/.agent/skills/consensus/README.md +41 -0
  54. package/.agent/skills/consensus/SKILL.md +317 -0
  55. package/.agent/skills/content-research-writer/SKILL.md +537 -0
  56. package/.agent/skills/debug-analysis/SKILL.md +331 -0
  57. package/.agent/skills/deepinit/SKILL.md +347 -0
  58. package/.agent/skills/deepsearch/SKILL.md +56 -0
  59. package/.agent/skills/doctor/SKILL.md +158 -0
  60. package/.agent/skills/drawio/EXAMPLES.md +382 -0
  61. package/.agent/skills/drawio/QUICK_START.md +237 -0
  62. package/.agent/skills/drawio/README.md +315 -0
  63. package/.agent/skills/drawio/SETUP_GUIDE.md +254 -0
  64. package/.agent/skills/drawio/SKILL.md +1176 -0
  65. package/.agent/skills/e2e/SKILL.md +396 -0
  66. package/.agent/skills/ecomode/SKILL.md +160 -0
  67. package/.agent/skills/electron-driver/SKILL.md +144 -0
  68. package/.agent/skills/electron-driver/scripts/driver-template.js +71 -0
  69. package/.agent/skills/eval/SKILL.md +140 -0
  70. package/.agent/skills/eval-harness/SKILL.md +242 -0
  71. package/.agent/skills/evolve/SKILL.md +213 -0
  72. package/.agent/skills/frontend-design/SKILL.md +42 -0
  73. package/.agent/skills/frontend-patterns/SKILL.md +646 -0
  74. package/.agent/skills/frontend-ui-ux/SKILL.md +70 -0
  75. package/.agent/skills/git-master/SKILL.md +75 -0
  76. package/.agent/skills/help/SKILL.md +89 -0
  77. package/.agent/skills/iterative-retrieval/SKILL.md +217 -0
  78. package/.agent/skills/local-skills-setup/SKILL.md +483 -0
  79. package/.agent/skills/log-analyzer/SKILL.md +187 -0
  80. package/.agent/skills/mcp-setup/SKILL.md +226 -0
  81. package/.agent/skills/multi-model-research/HOW_TO_USE.md +614 -0
  82. package/.agent/skills/multi-model-research/README.md +233 -0
  83. package/.agent/skills/multi-model-research/SKILL.md +541 -0
  84. package/.agent/skills/multi-model-research/references/troubleshooting.md +415 -0
  85. package/.agent/skills/note/SKILL.md +80 -0
  86. package/.agent/skills/omc-setup/SKILL.md +219 -0
  87. package/.agent/skills/orchestrate/SKILL.md +620 -0
  88. package/.agent/skills/patent-workflow/IMPLEMENTATION_SUMMARY.md +500 -0
  89. package/.agent/skills/patent-workflow/README.md +455 -0
  90. package/.agent/skills/patent-workflow/SKILL.md +1036 -0
  91. package/.agent/skills/patent-workflow/tools/irr_checker.py +260 -0
  92. package/.agent/skills/patent-workflow/tools/sample_terminology.json +49 -0
  93. package/.agent/skills/patent-workflow/tools/term_checker.py +355 -0
  94. package/.agent/skills/pattern-recognition/SKILL.md +792 -0
  95. package/.agent/skills/pipeline/SKILL.md +448 -0
  96. package/.agent/skills/plan/SKILL.md +309 -0
  97. package/.agent/skills/planning-methodology/SKILL.md +370 -0
  98. package/.agent/skills/planning-with-files/SKILL.md +210 -0
  99. package/.agent/skills/planning-with-files/examples.md +202 -0
  100. package/.agent/skills/planning-with-files/reference.md +218 -0
  101. package/.agent/skills/planning-with-files/scripts/check-complete.ps1 +42 -0
  102. package/.agent/skills/planning-with-files/scripts/check-complete.sh +44 -0
  103. package/.agent/skills/planning-with-files/scripts/init-session.ps1 +120 -0
  104. package/.agent/skills/planning-with-files/scripts/init-session.sh +120 -0
  105. package/.agent/skills/planning-with-files/scripts/session-catchup.py +208 -0
  106. package/.agent/skills/planning-with-files/templates/findings.md +95 -0
  107. package/.agent/skills/planning-with-files/templates/progress.md +114 -0
  108. package/.agent/skills/planning-with-files/templates/task_plan.md +132 -0
  109. package/.agent/skills/project-analyze/CLAUDE.md +18 -0
  110. package/.agent/skills/project-analyze/HOW_TO_USE.md +145 -0
  111. package/.agent/skills/project-analyze/README.md +42 -0
  112. package/.agent/skills/project-analyze/SKILL.md +289 -0
  113. package/.agent/skills/project-analyze/SKILL.md.backup +287 -0
  114. package/.agent/skills/project-analyze/SKILL.md.backup_20260105_093646 +287 -0
  115. package/.agent/skills/project-analyze/assets/analysis-report-template.md +433 -0
  116. package/.agent/skills/project-analyze/references/analysis-patterns.md +422 -0
  117. package/.agent/skills/project-analyze/references/projectmind-explained.md +535 -0
  118. package/.agent/skills/project-session-manager/SKILL.md +428 -0
  119. package/.agent/skills/project-session-manager/lib/config.sh +86 -0
  120. package/.agent/skills/project-session-manager/lib/parse.sh +121 -0
  121. package/.agent/skills/project-session-manager/lib/session.sh +132 -0
  122. package/.agent/skills/project-session-manager/lib/tmux.sh +103 -0
  123. package/.agent/skills/project-session-manager/lib/worktree.sh +171 -0
  124. package/.agent/skills/project-session-manager/psm.sh +629 -0
  125. package/.agent/skills/project-session-manager/templates/feature.md +56 -0
  126. package/.agent/skills/project-session-manager/templates/issue-fix.md +57 -0
  127. package/.agent/skills/project-session-manager/templates/pr-review.md +65 -0
  128. package/.agent/skills/project-session-manager/templates/projects.json +19 -0
  129. package/.agent/skills/quality-check/HOW_TO_USE.md +171 -0
  130. package/.agent/skills/quality-check/README.md +50 -0
  131. package/.agent/skills/quality-check/SKILL.md +240 -0
  132. package/.agent/skills/quality-check/SKILL.md.backup +238 -0
  133. package/.agent/skills/quality-check/SKILL.md.backup_20260105_093646 +238 -0
  134. package/.agent/skills/quality-check/assets/quality-report-template.md +437 -0
  135. package/.agent/skills/quality-check/references/refactoring-patterns.md +550 -0
  136. package/.agent/skills/quality-check/references/scoring-criteria.md +454 -0
  137. package/.agent/skills/quality-validation/SKILL.md +519 -0
  138. package/.agent/skills/quality-validation/SKILL.md.backup +573 -0
  139. package/.agent/skills/quality-validation/SKILL.md.backup_20260105_093646 +573 -0
  140. package/.agent/skills/ralph/SKILL.md +236 -0
  141. package/.agent/skills/ralph-init/SKILL.md +78 -0
  142. package/.agent/skills/ralplan/SKILL.md +58 -0
  143. package/.agent/skills/refactor-clean/SKILL.md +49 -0
  144. package/.agent/skills/release/SKILL.md +84 -0
  145. package/.agent/skills/research/SKILL.md +526 -0
  146. package/.agent/skills/research-methodology/SKILL.md +268 -0
  147. package/.agent/skills/review/SKILL.md +53 -0
  148. package/.agent/skills/security-review/SKILL.md +509 -0
  149. package/.agent/skills/security-review/cloud-infrastructure-security.md +361 -0
  150. package/.agent/skills/setup-pm/SKILL.md +102 -0
  151. package/.agent/skills/skill/SKILL.md +424 -0
  152. package/.agent/skills/skill-create/SKILL.md +209 -0
  153. package/.agent/skills/skill-debugger/HOW_TO_USE.md +244 -0
  154. package/.agent/skills/skill-debugger/README.md +44 -0
  155. package/.agent/skills/skill-debugger/SKILL.md +326 -0
  156. package/.agent/skills/skill-debugger/diagnostic_checklist.md +115 -0
  157. package/.agent/skills/skill-development/SKILL.md +661 -0
  158. package/.agent/skills/skill-development/references/skill-creator-original.md +209 -0
  159. package/.agent/skills/skill-doc-generator/README.md +37 -0
  160. package/.agent/skills/skill-doc-generator/SKILL.md +331 -0
  161. package/.agent/skills/skill-quality-analyzer/HOW_TO_USE.md +243 -0
  162. package/.agent/skills/skill-quality-analyzer/README.md +61 -0
  163. package/.agent/skills/skill-quality-analyzer/SKILL.md +247 -0
  164. package/.agent/skills/skill-quality-analyzer/analyzer.py +209 -0
  165. package/.agent/skills/skill-quality-analyzer/expected_output.json +81 -0
  166. package/.agent/skills/skill-quality-analyzer/sample_input.json +9 -0
  167. package/.agent/skills/skill-tester/README.md +46 -0
  168. package/.agent/skills/skill-tester/SKILL.md +345 -0
  169. package/.agent/skills/start-dev/SKILL.md +701 -0
  170. package/.agent/skills/swarm/SKILL.md +691 -0
  171. package/.agent/skills/task-kb-lookup/SKILL.md +211 -0
  172. package/.agent/skills/task-kb-record/SKILL.md +417 -0
  173. package/.agent/skills/tdd/SKILL.md +446 -0
  174. package/.agent/skills/tdd-generator/DEMO.md +516 -0
  175. package/.agent/skills/tdd-generator/README.md +89 -0
  176. package/.agent/skills/tdd-generator/SKILL.md +278 -0
  177. package/.agent/skills/tdd-workflow/SKILL.md +424 -0
  178. package/.agent/skills/test-coverage/SKILL.md +48 -0
  179. package/.agent/skills/thinkdeep/HOW_TO_USE.md +183 -0
  180. package/.agent/skills/thinkdeep/README.md +41 -0
  181. package/.agent/skills/thinkdeep/SKILL.md +343 -0
  182. package/.agent/skills/ui-ux-pro-max/SKILL.md +228 -0
  183. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  184. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  185. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  186. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  187. package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  188. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  189. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  190. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  191. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  192. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  193. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  194. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  195. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  196. package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
  197. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  198. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  199. package/.agent/skills/ui-ux-pro-max/scripts/core.py +236 -0
  200. package/.agent/skills/ui-ux-pro-max/scripts/search.py +61 -0
  201. package/.agent/skills/ultrapilot/SKILL.md +647 -0
  202. package/.agent/skills/ultraqa/SKILL.md +152 -0
  203. package/.agent/skills/ultrawork/SKILL.md +123 -0
  204. package/.agent/skills/update-codemaps/SKILL.md +38 -0
  205. package/.agent/skills/update-docs/SKILL.md +52 -0
  206. package/.agent/skills/verification-loop/SKILL.md +140 -0
  207. package/.agent/skills/verify/SKILL.md +80 -0
  208. package/.agent/skills/writer-memory/SKILL.md +459 -0
  209. package/.agent/skills/writer-memory/lib/character-tracker.ts +338 -0
  210. package/.agent/skills/writer-memory/lib/memory-manager.ts +804 -0
  211. package/.agent/skills/writer-memory/lib/relationship-graph.ts +400 -0
  212. package/.agent/skills/writer-memory/lib/scene-organizer.ts +544 -0
  213. package/.agent/skills/writer-memory/lib/synopsis-builder.ts +339 -0
  214. package/.agent/skills/writer-memory/templates/synopsis-template.md +46 -0
  215. package/.governance/skill-lint.allowlist +4 -0
  216. package/.governance/skill-llm.allowlist +4 -0
  217. package/AGENTS.md +59 -0
  218. package/LICENSE +21 -0
  219. package/README.md +169 -0
  220. package/README.zh.md +145 -0
  221. package/bin/omcodex.js +8 -0
  222. package/commands/conductor/implement.toml +358 -0
  223. package/commands/conductor/newTrack.toml +142 -0
  224. package/commands/conductor/revert.toml +123 -0
  225. package/commands/conductor/setup.toml +429 -0
  226. package/commands/conductor/status.toml +57 -0
  227. package/docs/ALIGNMENT.md +40 -0
  228. package/docs/CODEX.md +133 -0
  229. package/docs/NOTIFY.md +81 -0
  230. package/docs/SKILL_GOVERNANCE.md +72 -0
  231. package/docs/SKILL_GOVERNANCE_FRAMEWORK.md +182 -0
  232. package/docs/SKILL_GOVERNANCE_FRAMEWORK.zh.md +170 -0
  233. package/package.json +50 -0
  234. package/prompts/architect.md +105 -0
  235. package/prompts/executor.md +134 -0
  236. package/prompts/planner.md +113 -0
  237. package/scripts/check-skill-governance.sh +84 -0
  238. package/scripts/check-skill-llm-governance.js +302 -0
  239. package/scripts/eval-skills.js +217 -0
  240. package/scripts/generate-catalog-docs.js +95 -0
  241. package/scripts/generate-codex-mcp-config.sh +22 -0
  242. package/scripts/install-codex-force.sh +5 -0
  243. package/scripts/install-codex-incremental.sh +5 -0
  244. package/scripts/install-codex.sh +79 -0
  245. package/scripts/notify-dispatch.js +15 -0
  246. package/scripts/setup-package-manager.js +137 -0
  247. package/src/catalog/generated/public-catalog.json +547 -0
  248. package/src/catalog/manifest.json +542 -0
  249. package/src/catalog/reader.js +43 -0
  250. package/src/catalog/schema.js +79 -0
  251. package/src/cli/doctor.js +62 -0
  252. package/src/cli/index.js +85 -0
  253. package/src/cli/notify.js +127 -0
  254. package/src/cli/route.js +43 -0
  255. package/src/cli/setup.js +155 -0
  256. package/src/cli/team.js +125 -0
  257. package/src/config/generator.js +119 -0
  258. package/src/mcp/memory-server.js +241 -0
  259. package/src/mcp/state-server.js +112 -0
  260. package/src/mcp/trace-server.js +168 -0
  261. package/src/notify/dispatch.js +74 -0
  262. package/src/notify/extensibility/dispatcher.js +113 -0
  263. package/src/notify/extensibility/events.js +15 -0
  264. package/src/notify/extensibility/loader.js +54 -0
  265. package/src/router/skill-router.js +90 -0
  266. package/src/team/auto-advance.js +72 -0
  267. package/src/team/orchestrator.js +82 -0
  268. package/src/team/state-store.js +33 -0
  269. package/src/utils/paths.js +33 -0
  270. package/templates/AGENTS.md +15 -0
  271. package/templates/catalog-manifest.json +542 -0
  272. package/templates/code_styleguides/csharp.md +115 -0
  273. package/templates/code_styleguides/dart.md +238 -0
  274. package/templates/code_styleguides/general.md +23 -0
  275. package/templates/code_styleguides/go.md +48 -0
  276. package/templates/code_styleguides/html-css.md +49 -0
  277. package/templates/code_styleguides/javascript.md +51 -0
  278. package/templates/code_styleguides/python.md +37 -0
  279. package/templates/code_styleguides/typescript.md +43 -0
  280. package/templates/rules/README.md +23 -0
  281. package/templates/rules/agents.md +49 -0
  282. package/templates/rules/coding-style.md +70 -0
  283. package/templates/rules/dev.md +20 -0
  284. package/templates/rules/git-workflow.md +45 -0
  285. package/templates/rules/notify.md +6 -0
  286. package/templates/rules/patterns.md +55 -0
  287. package/templates/rules/performance.md +47 -0
  288. package/templates/rules/research.md +26 -0
  289. package/templates/rules/review.md +22 -0
  290. package/templates/rules/security.md +36 -0
  291. package/templates/rules/testing.md +30 -0
  292. package/templates/workflow.md +333 -0
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Character Tracking Module
3
+ * 캐릭터 추적 및 검증 시스템
4
+ */
5
+
6
+ import { loadMemory, saveMemory, generateId, now } from './memory-manager';
7
+ import type { Character, EmotionPoint, SpeechLevel, WriterMemory } from './memory-manager';
8
+
9
+ // === Helper to find character ===
10
+ function findCharacter(memory: WriterMemory, nameOrAlias: string): Character | null {
11
+ // Direct lookup
12
+ if (memory.characters[nameOrAlias]) {
13
+ return memory.characters[nameOrAlias];
14
+ }
15
+ // Alias lookup
16
+ for (const char of Object.values(memory.characters)) {
17
+ if (char.aliases?.includes(nameOrAlias)) {
18
+ return char;
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+
24
+ // === Character CRUD ===
25
+
26
+ export function addCharacter(name: string, options?: {
27
+ arc?: string;
28
+ tone?: string;
29
+ speechLevel?: SpeechLevel;
30
+ attitude?: string;
31
+ keywords?: string[];
32
+ notes?: string;
33
+ }): Character | null {
34
+ const memory = loadMemory();
35
+ if (!memory) return null;
36
+
37
+ if (memory.characters[name]) {
38
+ return null; // Already exists
39
+ }
40
+
41
+ const character: Character = {
42
+ id: generateId('char'),
43
+ name,
44
+ aliases: [],
45
+ arc: options?.arc || '',
46
+ tone: options?.tone || '',
47
+ speechLevel: options?.speechLevel || '반말',
48
+ attitude: options?.attitude || '',
49
+ keywords: options?.keywords || [],
50
+ timeline: [],
51
+ notes: options?.notes || '',
52
+ created: now(),
53
+ updated: now()
54
+ };
55
+
56
+ memory.characters[name] = character;
57
+ saveMemory(memory);
58
+ return character;
59
+ }
60
+
61
+ export function updateCharacter(name: string, updates: Partial<Character>): Character | null {
62
+ const memory = loadMemory();
63
+ if (!memory) return null;
64
+
65
+ const character = findCharacter(memory, name);
66
+ if (!character) return null;
67
+
68
+ // Apply updates (excluding id, name, created)
69
+ const { id, name: _, created, ...allowedUpdates } = updates as any;
70
+ Object.assign(character, allowedUpdates, { updated: now() });
71
+
72
+ saveMemory(memory);
73
+ return character;
74
+ }
75
+
76
+ export function removeCharacter(name: string): boolean {
77
+ const memory = loadMemory();
78
+ if (!memory) return false;
79
+
80
+ const character = findCharacter(memory, name);
81
+ if (!character) return false;
82
+
83
+ delete memory.characters[character.name];
84
+ saveMemory(memory);
85
+ return true;
86
+ }
87
+
88
+ export interface CharacterSummary {
89
+ id: string;
90
+ name: string;
91
+ arc: string;
92
+ tone: string;
93
+ emotionCount: number;
94
+ lastUpdated: string;
95
+ }
96
+
97
+ export function listCharacters(): CharacterSummary[] {
98
+ const memory = loadMemory();
99
+ if (!memory) return [];
100
+
101
+ return Object.values(memory.characters).map(c => ({
102
+ id: c.id,
103
+ name: c.name,
104
+ arc: c.arc,
105
+ tone: c.tone,
106
+ emotionCount: c.timeline?.length || 0,
107
+ lastUpdated: c.updated
108
+ }));
109
+ }
110
+
111
+ // === Alias Management ===
112
+
113
+ export function addAlias(characterName: string, alias: string): boolean {
114
+ const memory = loadMemory();
115
+ if (!memory) return false;
116
+
117
+ const character = findCharacter(memory, characterName);
118
+ if (!character) return false;
119
+
120
+ if (!character.aliases.includes(alias)) {
121
+ character.aliases.push(alias);
122
+ character.updated = now();
123
+ saveMemory(memory);
124
+ }
125
+ return true;
126
+ }
127
+
128
+ export function removeAlias(characterName: string, alias: string): boolean {
129
+ const memory = loadMemory();
130
+ if (!memory) return false;
131
+
132
+ const character = findCharacter(memory, characterName);
133
+ if (!character) return false;
134
+
135
+ const idx = character.aliases.indexOf(alias);
136
+ if (idx !== -1) {
137
+ character.aliases.splice(idx, 1);
138
+ character.updated = now();
139
+ saveMemory(memory);
140
+ return true;
141
+ }
142
+ return false;
143
+ }
144
+
145
+ export function resolveCharacter(nameOrAlias: string): Character | null {
146
+ const memory = loadMemory();
147
+ if (!memory) return null;
148
+ return findCharacter(memory, nameOrAlias);
149
+ }
150
+
151
+ // === Emotion Timeline ===
152
+
153
+ export function addEmotionPoint(characterName: string, emotion: string, trigger: string, options?: {
154
+ sceneId?: string;
155
+ intensity?: 1 | 2 | 3 | 4 | 5;
156
+ }): boolean {
157
+ const memory = loadMemory();
158
+ if (!memory) return false;
159
+
160
+ const character = findCharacter(memory, characterName);
161
+ if (!character) return false;
162
+
163
+ const point: EmotionPoint = {
164
+ timestamp: now(),
165
+ sceneId: options?.sceneId,
166
+ emotion,
167
+ trigger,
168
+ intensity: options?.intensity || 3
169
+ };
170
+
171
+ character.timeline.push(point);
172
+ character.updated = now();
173
+ saveMemory(memory);
174
+ return true;
175
+ }
176
+
177
+ export function getEmotionTimeline(characterName: string): EmotionPoint[] {
178
+ const character = resolveCharacter(characterName);
179
+ return character?.timeline || [];
180
+ }
181
+
182
+ export function getLatestEmotion(characterName: string): EmotionPoint | null {
183
+ const timeline = getEmotionTimeline(characterName);
184
+ return timeline.length > 0 ? timeline[timeline.length - 1] : null;
185
+ }
186
+
187
+ export function getEmotionArc(characterName: string): string {
188
+ const timeline = getEmotionTimeline(characterName);
189
+ if (timeline.length === 0) return '';
190
+ return timeline.map(e => e.emotion).join(' → ');
191
+ }
192
+
193
+ // === Dialogue Validation ===
194
+
195
+ export interface ValidationResult {
196
+ status: 'PASS' | 'WARN' | 'FAIL';
197
+ character: string;
198
+ checks: {
199
+ toneMatch: { passed: boolean; detail: string };
200
+ speechLevelMatch: { passed: boolean; detail: string };
201
+ keywordConsistency: { passed: boolean; detail: string };
202
+ };
203
+ suggestion: string;
204
+ }
205
+
206
+ export function detectSpeechLevel(text: string): SpeechLevel {
207
+ // 존댓말 patterns
208
+ const formal = /요$|습니다$|세요$|십시오$/;
209
+ // 반말 patterns
210
+ const informal = /야$|아$|어$|지$|는데$/;
211
+ // 해체 patterns
212
+ const casual = /임$|음$|ㅋ|ㅎ$/;
213
+
214
+ const sentences = text.split(/[.!?]/).filter(s => s.trim());
215
+ let formalCnt = 0, informalCnt = 0, casualCnt = 0;
216
+
217
+ for (const s of sentences) {
218
+ const t = s.trim();
219
+ if (formal.test(t)) formalCnt++;
220
+ if (informal.test(t)) informalCnt++;
221
+ if (casual.test(t)) casualCnt++;
222
+ }
223
+
224
+ if (formalCnt > informalCnt && formalCnt > casualCnt) return '존댓말';
225
+ if (casualCnt > informalCnt) return '해체';
226
+ if (informalCnt > 0) return '반말';
227
+ return '혼합';
228
+ }
229
+
230
+ export function validateDialogue(characterName: string, dialogue: string): ValidationResult {
231
+ const character = resolveCharacter(characterName);
232
+
233
+ if (!character) {
234
+ return {
235
+ status: 'FAIL',
236
+ character: characterName,
237
+ checks: {
238
+ toneMatch: { passed: false, detail: '캐릭터를 찾을 수 없음' },
239
+ speechLevelMatch: { passed: false, detail: '캐릭터를 찾을 수 없음' },
240
+ keywordConsistency: { passed: false, detail: '캐릭터를 찾을 수 없음' }
241
+ },
242
+ suggestion: `"${characterName}" 캐릭터가 메모리에 없습니다.`
243
+ };
244
+ }
245
+
246
+ // Check tone
247
+ const exclamations = (dialogue.match(/!/g) || []).length;
248
+ const toneCheck = { passed: true, detail: '톤 일치' };
249
+ if (character.tone.includes('담백') && exclamations > 1) {
250
+ toneCheck.passed = false;
251
+ toneCheck.detail = `담백한 톤에 느낌표 ${exclamations}개는 과함`;
252
+ }
253
+
254
+ // Check speech level
255
+ const detected = detectSpeechLevel(dialogue);
256
+ const speechCheck = {
257
+ passed: detected === character.speechLevel || detected === '혼합',
258
+ detail: detected === character.speechLevel ? '말투 일치' : `기대: ${character.speechLevel}, 감지: ${detected}`
259
+ };
260
+
261
+ // Check keywords
262
+ const keywordCheck = { passed: true, detail: '키워드 없음 (검사 생략)' };
263
+ if (character.keywords.length > 0) {
264
+ const hasKeyword = character.keywords.some(kw => dialogue.includes(kw));
265
+ keywordCheck.passed = hasKeyword;
266
+ keywordCheck.detail = hasKeyword ? '특징 키워드 포함' : `키워드 미포함: ${character.keywords.slice(0, 2).join(', ')}`;
267
+ }
268
+
269
+ const failCount = [toneCheck, speechCheck, keywordCheck].filter(c => !c.passed).length;
270
+ const status: 'PASS' | 'WARN' | 'FAIL' = failCount === 0 ? 'PASS' : failCount >= 2 ? 'FAIL' : 'WARN';
271
+
272
+ const suggestions: string[] = [];
273
+ if (!toneCheck.passed) suggestions.push(`톤 조정 필요`);
274
+ if (!speechCheck.passed) suggestions.push(`${character.speechLevel}로 말투 수정`);
275
+ if (!keywordCheck.passed) suggestions.push(`특징 키워드 사용 고려`);
276
+
277
+ return {
278
+ status,
279
+ character: character.name,
280
+ checks: {
281
+ toneMatch: toneCheck,
282
+ speechLevelMatch: speechCheck,
283
+ keywordConsistency: keywordCheck
284
+ },
285
+ suggestion: suggestions.length > 0 ? suggestions.join('. ') : '대사가 캐릭터와 잘 어울립니다.'
286
+ };
287
+ }
288
+
289
+ // === Profile Generation ===
290
+
291
+ export function generateCharacterProfile(characterName: string): string {
292
+ const character = resolveCharacter(characterName);
293
+
294
+ if (!character) {
295
+ return `# "${characterName}" 캐릭터를 찾을 수 없습니다`;
296
+ }
297
+
298
+ const latest = getLatestEmotion(characterName);
299
+ const arc = getEmotionArc(characterName);
300
+
301
+ let profile = `# ${character.name}\n\n`;
302
+
303
+ if (character.aliases.length > 0) {
304
+ profile += `**별칭**: ${character.aliases.join(', ')}\n\n`;
305
+ }
306
+
307
+ if (character.arc) {
308
+ profile += `**캐릭터 아크**: ${character.arc}\n\n`;
309
+ }
310
+
311
+ if (character.tone) {
312
+ profile += `**대사 톤**: ${character.tone}\n\n`;
313
+ }
314
+
315
+ profile += `**말투**: ${character.speechLevel}\n\n`;
316
+
317
+ if (character.keywords.length > 0) {
318
+ profile += `**핵심 키워드**: ${character.keywords.join(', ')}\n\n`;
319
+ }
320
+
321
+ if (latest) {
322
+ profile += `**현재 감정**: ${latest.emotion} (강도: ${latest.intensity}/5)\n\n`;
323
+ }
324
+
325
+ if (character.attitude) {
326
+ profile += `**태도**: ${character.attitude}\n\n`;
327
+ }
328
+
329
+ if (arc) {
330
+ profile += `**감정 궤도**: ${arc}\n\n`;
331
+ }
332
+
333
+ if (character.notes) {
334
+ profile += `**메모**: ${character.notes}\n\n`;
335
+ }
336
+
337
+ return profile.trim();
338
+ }