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,74 @@
1
+ const { buildNotifyEvent } = require('./extensibility/events');
2
+ const { dispatchNotifyEvent } = require('./extensibility/dispatcher');
3
+ const { applyTeamAutoAdvance } = require('../team/auto-advance');
4
+
5
+ function pickString(payload, keys) {
6
+ for (const key of keys) {
7
+ const value = payload ? payload[key] : undefined;
8
+ if (typeof value === 'string' && value.trim() !== '') return value;
9
+ }
10
+ return undefined;
11
+ }
12
+
13
+ function normalizeNotifyEventName(rawType) {
14
+ const type = typeof rawType === 'string' ? rawType.trim().toLowerCase() : '';
15
+ if (!type) return null;
16
+
17
+ if (type === 'agent-turn-complete' || type === 'turn-complete' || type === 'turn_complete') {
18
+ return 'turn-complete';
19
+ }
20
+ if (type === 'session-start' || type === 'session_start' || type === 'start') {
21
+ return 'session-start';
22
+ }
23
+ if (type === 'session-end' || type === 'session_end' || type === 'session-stop' || type === 'stop' || type === 'end') {
24
+ return 'session-end';
25
+ }
26
+ if (type === 'session-idle' || type === 'session_idle' || type === 'idle') {
27
+ return 'session-idle';
28
+ }
29
+ if (type === 'needs-input' || type === 'needs_input') {
30
+ return 'needs-input';
31
+ }
32
+ if (type === 'pre-tool-use' || type === 'pre_tool_use') {
33
+ return 'pre-tool-use';
34
+ }
35
+ if (type === 'post-tool-use' || type === 'post_tool_use') {
36
+ return 'post-tool-use';
37
+ }
38
+ return null;
39
+ }
40
+
41
+ function toNotifyEvent(payload) {
42
+ const normalizedEvent = normalizeNotifyEventName(
43
+ pickString(payload, ['type', 'event', 'event_type', 'event-type']),
44
+ );
45
+ if (!normalizedEvent) return null;
46
+
47
+ return buildNotifyEvent(normalizedEvent, {
48
+ source: 'native',
49
+ session_id: pickString(payload, ['session_id', 'session-id', 'sessionId']),
50
+ thread_id: pickString(payload, ['thread_id', 'thread-id', 'threadId']),
51
+ turn_id: pickString(payload, ['turn_id', 'turn-id', 'turnId']),
52
+ mode: pickString(payload, ['mode']),
53
+ context: {
54
+ cwd: payload ? payload.cwd : undefined,
55
+ payload_type: pickString(payload, ['type']),
56
+ last_assistant_message: pickString(payload, ['last-assistant-message', 'last_assistant_message']),
57
+ },
58
+ });
59
+ }
60
+
61
+ async function dispatchFromNotifyPayload(payload, options = {}) {
62
+ const event = toNotifyEvent(payload);
63
+ if (!event) return { enabled: false, event: 'unsupported', plugin_count: 0, results: [] };
64
+ const dispatch = await dispatchNotifyEvent(event, options);
65
+ const teamAutoAdvance = await applyTeamAutoAdvance(event, { cwd: options.cwd || process.cwd() });
66
+ return {
67
+ ...dispatch,
68
+ team_auto_advance: teamAutoAdvance,
69
+ };
70
+ }
71
+
72
+ module.exports = {
73
+ dispatchFromNotifyPayload,
74
+ };
@@ -0,0 +1,113 @@
1
+ const fs = require('fs/promises');
2
+ const path = require('path');
3
+ const { pathToFileURL } = require('url');
4
+ const {
5
+ discoverNotifyPlugins,
6
+ isNotifyPluginsEnabled,
7
+ resolveNotifyPluginTimeoutMs,
8
+ } = require('./loader');
9
+
10
+ function notifyLogPath(cwd) {
11
+ const day = new Date().toISOString().slice(0, 10);
12
+ return path.join(cwd, '.omcodex', 'logs', `notify-${day}.jsonl`);
13
+ }
14
+
15
+ async function appendLog(cwd, payload) {
16
+ const file = notifyLogPath(cwd);
17
+ await fs.mkdir(path.dirname(file), { recursive: true });
18
+ await fs.appendFile(file, `${JSON.stringify({ timestamp: new Date().toISOString(), ...payload })}\n`, 'utf8');
19
+ }
20
+
21
+ function withTimeout(promise, timeoutMs) {
22
+ let timer;
23
+ const timeout = new Promise((_, reject) => {
24
+ timer = setTimeout(() => reject(new Error('timeout')), timeoutMs);
25
+ });
26
+ return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
27
+ }
28
+
29
+ function buildSdk(cwd, pluginId) {
30
+ const pluginStateDir = path.join(cwd, '.omcodex', 'state', 'notify-plugins', pluginId);
31
+
32
+ async function readState(key) {
33
+ const file = path.join(pluginStateDir, `${key}.json`);
34
+ try {
35
+ const raw = await fs.readFile(file, 'utf8');
36
+ return JSON.parse(raw);
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ async function writeState(key, value) {
43
+ const file = path.join(pluginStateDir, `${key}.json`);
44
+ await fs.mkdir(path.dirname(file), { recursive: true });
45
+ await fs.writeFile(file, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
46
+ }
47
+
48
+ async function deleteState(key) {
49
+ const file = path.join(pluginStateDir, `${key}.json`);
50
+ try { await fs.unlink(file); } catch {}
51
+ }
52
+
53
+ return {
54
+ log: {
55
+ info: async (message, meta) => appendLog(cwd, { type: 'notify_plugin_log', level: 'info', plugin: pluginId, message, meta }),
56
+ warn: async (message, meta) => appendLog(cwd, { type: 'notify_plugin_log', level: 'warn', plugin: pluginId, message, meta }),
57
+ error: async (message, meta) => appendLog(cwd, { type: 'notify_plugin_log', level: 'error', plugin: pluginId, message, meta }),
58
+ },
59
+ state: {
60
+ read: readState,
61
+ write: writeState,
62
+ delete: deleteState,
63
+ },
64
+ };
65
+ }
66
+
67
+ async function dispatchNotifyEvent(event, options = {}) {
68
+ const cwd = options.cwd || process.cwd();
69
+ const enabled = options.enabled !== false && isNotifyPluginsEnabled(options.env || process.env);
70
+ const plugins = discoverNotifyPlugins(cwd);
71
+
72
+ const summary = {
73
+ enabled,
74
+ event: event.event,
75
+ plugin_count: plugins.length,
76
+ results: [],
77
+ };
78
+
79
+ if (!enabled) {
80
+ await appendLog(cwd, { type: 'notify_dispatch', enabled: false, reason: 'plugins_disabled', event: event.event });
81
+ return summary;
82
+ }
83
+
84
+ const timeoutMs = resolveNotifyPluginTimeoutMs(options.env || process.env);
85
+
86
+ for (const plugin of plugins) {
87
+ const started = Date.now();
88
+ try {
89
+ const mod = await import(`${pathToFileURL(plugin.filePath).href}?t=${Date.now()}`);
90
+ if (typeof mod.onNotifyEvent !== 'function') {
91
+ summary.results.push({ plugin: plugin.id, ok: false, status: 'invalid_export', duration_ms: Date.now() - started });
92
+ await appendLog(cwd, { type: 'notify_plugin_dispatch', plugin: plugin.id, event: event.event, ok: false, status: 'invalid_export' });
93
+ continue;
94
+ }
95
+
96
+ const sdk = buildSdk(cwd, plugin.id);
97
+ await withTimeout(Promise.resolve(mod.onNotifyEvent(event, sdk)), timeoutMs);
98
+ summary.results.push({ plugin: plugin.id, ok: true, status: 'ok', duration_ms: Date.now() - started });
99
+ await appendLog(cwd, { type: 'notify_plugin_dispatch', plugin: plugin.id, event: event.event, ok: true, status: 'ok' });
100
+ } catch (error) {
101
+ const message = error instanceof Error ? error.message : String(error);
102
+ const status = message === 'timeout' ? 'timeout' : 'error';
103
+ summary.results.push({ plugin: plugin.id, ok: false, status, error: message, duration_ms: Date.now() - started });
104
+ await appendLog(cwd, { type: 'notify_plugin_dispatch', plugin: plugin.id, event: event.event, ok: false, status, error: message });
105
+ }
106
+ }
107
+
108
+ return summary;
109
+ }
110
+
111
+ module.exports = {
112
+ dispatchNotifyEvent,
113
+ };
@@ -0,0 +1,15 @@
1
+ function buildNotifyEvent(event, payload = {}) {
2
+ return {
3
+ schema_version: '1',
4
+ event,
5
+ timestamp: new Date().toISOString(),
6
+ source: payload.source || 'native',
7
+ context: payload.context || {},
8
+ session_id: payload.session_id,
9
+ thread_id: payload.thread_id,
10
+ turn_id: payload.turn_id,
11
+ mode: payload.mode,
12
+ };
13
+ }
14
+
15
+ module.exports = { buildNotifyEvent };
@@ -0,0 +1,54 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function notifyPluginsDir(cwd) {
5
+ return path.join(cwd, '.omcodex', 'notify');
6
+ }
7
+
8
+ function legacyNotifyPluginsDir(cwd) {
9
+ return path.join(cwd, '.omcodex', 'notify-plugins');
10
+ }
11
+
12
+ function discoverNotifyPlugins(cwd = process.cwd()) {
13
+ const primaryDir = notifyPluginsDir(cwd);
14
+ const legacyDir = legacyNotifyPluginsDir(cwd);
15
+ const candidates = [primaryDir, legacyDir];
16
+ const seen = new Set();
17
+ const plugins = [];
18
+
19
+ for (const dir of candidates) {
20
+ if (!fs.existsSync(dir)) continue;
21
+ for (const file of fs.readdirSync(dir)) {
22
+ if (!file.endsWith('.mjs') && !file.endsWith('.js')) continue;
23
+ const key = `${dir}/${file}`;
24
+ if (seen.has(key)) continue;
25
+ seen.add(key);
26
+ plugins.push({
27
+ id: file.replace(/\.(mjs|js)$/i, ''),
28
+ fileName: file,
29
+ filePath: path.join(dir, file),
30
+ legacy: dir === legacyDir,
31
+ });
32
+ }
33
+ }
34
+
35
+ return plugins.sort((a, b) => a.fileName.localeCompare(b.fileName));
36
+ }
37
+
38
+ function isNotifyPluginsEnabled(env = process.env) {
39
+ return env.OMX_NOTIFY_PLUGINS === '1';
40
+ }
41
+
42
+ function resolveNotifyPluginTimeoutMs(env = process.env) {
43
+ const raw = Number.parseInt(String(env.OMX_NOTIFY_PLUGIN_TIMEOUT_MS || ''), 10);
44
+ if (Number.isFinite(raw) && raw >= 100 && raw <= 60000) return raw;
45
+ return 1500;
46
+ }
47
+
48
+ module.exports = {
49
+ notifyPluginsDir,
50
+ legacyNotifyPluginsDir,
51
+ discoverNotifyPlugins,
52
+ isNotifyPluginsEnabled,
53
+ resolveNotifyPluginTimeoutMs,
54
+ };
@@ -0,0 +1,90 @@
1
+ const { tryReadCatalogManifest } = require('../catalog/reader');
2
+
3
+ const ROUTE_RULES = [
4
+ { skill: 'plan', weight: 3, keywords: ['plan', '规划', '设计', 'architecture', '架构', '方案', 'roadmap'] },
5
+ { skill: 'research', weight: 3, keywords: ['research', '调研', 'compare', '对比', 'benchmark'] },
6
+ { skill: 'code-review', weight: 4, keywords: ['review', 'code review', '审查', '评审'] },
7
+ { skill: 'security-review', weight: 4, keywords: ['security', 'auth', '鉴权', '漏洞', '安全'] },
8
+ { skill: 'build-fix', weight: 4, keywords: ['build error', 'compile', 'type error', 'lint', '失败', '报错'] },
9
+ { skill: 'verify', weight: 3, keywords: ['verify', '验证', 'check', '检查'] },
10
+ { skill: 'tdd', weight: 3, keywords: ['tdd', 'test first', '测试先行'] },
11
+ { skill: 'tdd-workflow', weight: 2, keywords: ['unit test', 'integration test', 'e2e', 'coverage'] },
12
+ { skill: 'ultraqa', weight: 3, keywords: ['qa', '回归', 'quality loop', '质量闭环'] },
13
+ { skill: 'autopilot', weight: 3, keywords: ['implement', '实现', '开发', 'build feature', '交付'] },
14
+ { skill: 'start-dev', weight: 3, keywords: ['start', 'kickoff', '开始开发', '新功能'] },
15
+ { skill: 'swarm', weight: 2, keywords: ['parallel', '并行', 'multi-agent', '多代理'] },
16
+ { skill: 'ultrawork', weight: 2, keywords: ['batch', '批量', 'high throughput', '大量'] },
17
+ { skill: 'backend-patterns', weight: 2, keywords: ['api', 'backend', '数据库', 'service'] },
18
+ { skill: 'frontend-patterns', weight: 2, keywords: ['frontend', 'ui', '组件', '页面'] },
19
+ { skill: 'frontend-ui-ux', weight: 2, keywords: ['ux', '视觉', '交互', '界面设计'] },
20
+ { skill: 'debug-analysis', weight: 3, keywords: ['debug', '定位问题', '根因', 'trace'] },
21
+ ];
22
+
23
+ function normalizeText(input) {
24
+ return String(input || '').toLowerCase().replace(/\s+/g, ' ').trim();
25
+ }
26
+
27
+ function countHits(text, keywords) {
28
+ let hits = 0;
29
+ for (const keyword of keywords) {
30
+ const token = normalizeText(keyword);
31
+ if (!token) continue;
32
+ if (text.includes(token)) hits += 1;
33
+ }
34
+ return hits;
35
+ }
36
+
37
+ function catalogSkills(root) {
38
+ const manifest = tryReadCatalogManifest(root);
39
+ if (!manifest) return null;
40
+ return new Set(manifest.skills.filter((skill) => skill.status === 'active').map((skill) => skill.name));
41
+ }
42
+
43
+ function routeTaskToSkills(taskDescription, options = {}) {
44
+ const text = normalizeText(taskDescription);
45
+ const limit = Math.max(1, Number(options.limit) || 5);
46
+ const root = options.root;
47
+ const available = catalogSkills(root);
48
+
49
+ const scored = [];
50
+ for (const rule of ROUTE_RULES) {
51
+ if (available && !available.has(rule.skill)) continue;
52
+ const hits = countHits(text, rule.keywords);
53
+ if (hits === 0) continue;
54
+ scored.push({
55
+ skill: rule.skill,
56
+ score: hits * rule.weight,
57
+ hits,
58
+ rationale: `matched ${hits} keyword(s)`,
59
+ });
60
+ }
61
+
62
+ scored.sort((a, b) => b.score - a.score || a.skill.localeCompare(b.skill));
63
+
64
+ const unique = [];
65
+ const seen = new Set();
66
+ for (const item of scored) {
67
+ if (seen.has(item.skill)) continue;
68
+ seen.add(item.skill);
69
+ unique.push(item);
70
+ }
71
+
72
+ if (unique.length === 0) {
73
+ if (!available || available.has('autopilot')) unique.push({ skill: 'autopilot', score: 1, hits: 0, rationale: 'default execution fallback' });
74
+ if (!available || available.has('plan')) unique.push({ skill: 'plan', score: 1, hits: 0, rationale: 'default planning fallback' });
75
+ }
76
+
77
+ const top = unique.slice(0, limit);
78
+ const totalScore = top.reduce((sum, item) => sum + item.score, 0);
79
+ const confidence = Math.min(1, totalScore / 12);
80
+
81
+ return {
82
+ task: String(taskDescription || ''),
83
+ confidence,
84
+ recommendations: top,
85
+ };
86
+ }
87
+
88
+ module.exports = {
89
+ routeTaskToSkills,
90
+ };
@@ -0,0 +1,72 @@
1
+ const fs = require('fs/promises');
2
+ const path = require('path');
3
+ const { readTeamState, writeTeamState } = require('./state-store');
4
+ const { transitionPhase } = require('./orchestrator');
5
+
6
+ const FAILURE_HINT = /\b(fail(?:ed|ure)?|error|exception|timeout|lint|type\s*error|test(?:s)?\s+failed)\b/i;
7
+
8
+ function isFailureSignal(event) {
9
+ const context = event && typeof event.context === 'object' ? event.context : {};
10
+ const message = String(context.last_assistant_message || '');
11
+ return FAILURE_HINT.test(message);
12
+ }
13
+
14
+ function nextPhaseFor(state, event, failed) {
15
+ const name = event ? event.event : '';
16
+ if (state.phase === 'team-plan' && name === 'turn-complete') return 'team-prd';
17
+ if (state.phase === 'team-prd' && name === 'turn-complete') return 'team-exec';
18
+
19
+ if (state.phase === 'team-exec') {
20
+ if (failed) return 'team-fix';
21
+ if (name === 'post-tool-use' || name === 'turn-complete') return 'team-verify';
22
+ }
23
+
24
+ if (state.phase === 'team-verify') {
25
+ if (failed) return 'team-fix';
26
+ if (name === 'turn-complete') return 'complete';
27
+ }
28
+
29
+ if (state.phase === 'team-fix' && name === 'turn-complete') {
30
+ return failed ? 'failed' : 'team-exec';
31
+ }
32
+
33
+ return null;
34
+ }
35
+
36
+ function teamAutoLogPath(cwd) {
37
+ const day = new Date().toISOString().slice(0, 10);
38
+ return path.join(cwd, '.omcodex', 'logs', `team-auto-${day}.jsonl`);
39
+ }
40
+
41
+ async function appendTeamAutoLog(cwd, payload) {
42
+ const file = teamAutoLogPath(cwd);
43
+ await fs.mkdir(path.dirname(file), { recursive: true });
44
+ await fs.appendFile(file, `${JSON.stringify({ timestamp: new Date().toISOString(), ...payload })}\n`, 'utf8');
45
+ }
46
+
47
+ async function applyTeamAutoAdvance(event, options = {}) {
48
+ const cwd = options.cwd || process.cwd();
49
+ const state = readTeamState(cwd);
50
+ if (!state || !state.active) return { applied: false, reason: 'inactive_or_missing' };
51
+ if (state.auto_advance !== true) return { applied: false, reason: 'auto_advance_disabled' };
52
+
53
+ const failed = isFailureSignal(event);
54
+ const nextPhase = nextPhaseFor(state, event, failed);
55
+ if (!nextPhase) return { applied: false, reason: 'no_transition' };
56
+
57
+ try {
58
+ const next = transitionPhase(state, nextPhase, `notify:${event.event}${failed ? ':failure' : ''}`);
59
+ writeTeamState(cwd, next);
60
+ const result = { applied: true, from: state.phase, to: next.phase, event: event.event, failed_signal: failed };
61
+ await appendTeamAutoLog(cwd, { type: 'team_auto_advance', ...result });
62
+ return result;
63
+ } catch (error) {
64
+ const message = error instanceof Error ? error.message : String(error);
65
+ await appendTeamAutoLog(cwd, { type: 'team_auto_advance', applied: false, event: event.event, error: message });
66
+ return { applied: false, reason: 'transition_error', error: message };
67
+ }
68
+ }
69
+
70
+ module.exports = {
71
+ applyTeamAutoAdvance,
72
+ };
@@ -0,0 +1,82 @@
1
+ const TEAM_PHASES = ['team-plan', 'team-prd', 'team-exec', 'team-verify', 'team-fix'];
2
+ const TERMINAL_PHASES = ['complete', 'failed', 'cancelled'];
3
+
4
+ const TRANSITIONS = {
5
+ 'team-plan': ['team-prd'],
6
+ 'team-prd': ['team-exec'],
7
+ 'team-exec': ['team-verify', 'team-fix'],
8
+ 'team-verify': ['team-fix', 'complete', 'failed'],
9
+ 'team-fix': ['team-exec', 'team-verify', 'complete', 'failed'],
10
+ };
11
+
12
+ function isTerminal(phase) {
13
+ return TERMINAL_PHASES.includes(phase);
14
+ }
15
+
16
+ function createTeamState(taskDescription, maxFixAttempts = 3, options = {}) {
17
+ return {
18
+ active: true,
19
+ phase: 'team-plan',
20
+ task_description: taskDescription,
21
+ auto_advance: options.autoAdvance === true,
22
+ created_at: new Date().toISOString(),
23
+ phase_transitions: [],
24
+ tasks: [],
25
+ max_fix_attempts: maxFixAttempts,
26
+ current_fix_attempt: 0,
27
+ };
28
+ }
29
+
30
+ function transitionPhase(state, to, reason) {
31
+ if (isTerminal(state.phase)) {
32
+ throw new Error(`Cannot transition from terminal phase: ${state.phase}`);
33
+ }
34
+
35
+ const allowed = TRANSITIONS[state.phase] || [];
36
+ if (!allowed.includes(to)) {
37
+ throw new Error(`Invalid transition: ${state.phase} -> ${to}`);
38
+ }
39
+
40
+ const nextFixAttempt = to === 'team-fix' ? state.current_fix_attempt + 1 : state.current_fix_attempt;
41
+
42
+ if (to === 'team-fix' && nextFixAttempt > state.max_fix_attempts) {
43
+ return {
44
+ ...state,
45
+ active: false,
46
+ phase: 'failed',
47
+ phase_transitions: [
48
+ ...state.phase_transitions,
49
+ {
50
+ from: state.phase,
51
+ to: 'failed',
52
+ at: new Date().toISOString(),
53
+ reason: `team-fix loop limit reached (${state.max_fix_attempts})`,
54
+ },
55
+ ],
56
+ };
57
+ }
58
+
59
+ return {
60
+ ...state,
61
+ active: !isTerminal(to),
62
+ phase: to,
63
+ current_fix_attempt: nextFixAttempt,
64
+ phase_transitions: [
65
+ ...state.phase_transitions,
66
+ {
67
+ from: state.phase,
68
+ to,
69
+ at: new Date().toISOString(),
70
+ reason,
71
+ },
72
+ ],
73
+ };
74
+ }
75
+
76
+ module.exports = {
77
+ TEAM_PHASES,
78
+ TERMINAL_PHASES,
79
+ createTeamState,
80
+ transitionPhase,
81
+ isTerminal,
82
+ };
@@ -0,0 +1,33 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function teamStatePath(cwd) {
5
+ return path.join(cwd, '.omcodex', 'state', 'team-state.json');
6
+ }
7
+
8
+ function readTeamState(cwd) {
9
+ const file = teamStatePath(cwd);
10
+ if (!fs.existsSync(file)) return null;
11
+ try {
12
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+
18
+ function writeTeamState(cwd, state) {
19
+ const file = teamStatePath(cwd);
20
+ fs.mkdirSync(path.dirname(file), { recursive: true });
21
+ fs.writeFileSync(file, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
22
+ }
23
+
24
+ function clearTeamState(cwd) {
25
+ const file = teamStatePath(cwd);
26
+ if (fs.existsSync(file)) fs.unlinkSync(file);
27
+ }
28
+
29
+ module.exports = {
30
+ readTeamState,
31
+ writeTeamState,
32
+ clearTeamState,
33
+ };
@@ -0,0 +1,33 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+
4
+ function codexHome(scope, cwd) {
5
+ if (scope === 'user') return path.join(os.homedir(), '.codex');
6
+ return path.join(cwd, '.codex');
7
+ }
8
+
9
+ function codexConfigPath(scope, cwd) {
10
+ return path.join(codexHome(scope, cwd), 'config.toml');
11
+ }
12
+
13
+ function codexPromptsPath(scope, cwd) {
14
+ return path.join(codexHome(scope, cwd), 'prompts');
15
+ }
16
+
17
+ function skillsSource(root) {
18
+ const agentSkills = path.join(root, '.agent', 'skills');
19
+ const codexSkills = path.join(root, '.codex', 'skills');
20
+ return { agentSkills, codexSkills };
21
+ }
22
+
23
+ function promptsSource(root) {
24
+ return path.join(root, 'prompts');
25
+ }
26
+
27
+ module.exports = {
28
+ codexHome,
29
+ codexConfigPath,
30
+ codexPromptsPath,
31
+ skillsSource,
32
+ promptsSource,
33
+ };
@@ -0,0 +1,15 @@
1
+ # oh-my-codex
2
+
3
+ Skill pack and workflow orchestration for OpenAI Codex CLI.
4
+
5
+ ## Guidance
6
+
7
+ - Prefer skills for reusable workflows (`$skill` or explicit skill name in prompt).
8
+ - Use Codex native multi-agent tools when a task benefits from delegation.
9
+ - Verify outcomes with concrete evidence before claiming completion.
10
+ - Keep instructions concise and implementation-focused.
11
+
12
+ ## Notify Compatibility
13
+
14
+ Codex does not expose Claude Code style pre/post tool interception lifecycle.
15
+ This project uses event-driven extensions built on top of Codex notifications (`notify`), not execution interception.