oh-my-codex 0.3.10 → 0.4.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 (76) hide show
  1. package/README.md +25 -0
  2. package/dist/cli/__tests__/index.test.js +6 -0
  3. package/dist/cli/__tests__/index.test.js.map +1 -1
  4. package/dist/cli/hooks.d.ts +4 -0
  5. package/dist/cli/hooks.d.ts.map +1 -0
  6. package/dist/cli/hooks.js +201 -0
  7. package/dist/cli/hooks.js.map +1 -0
  8. package/dist/cli/index.d.ts +1 -1
  9. package/dist/cli/index.d.ts.map +1 -1
  10. package/dist/cli/index.js +141 -2
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/hooks/__tests__/notify-hook-linked-sync.test.js +6 -0
  13. package/dist/hooks/__tests__/notify-hook-linked-sync.test.js.map +1 -1
  14. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +6 -0
  15. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  16. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +3 -0
  17. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  18. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +4 -0
  19. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  20. package/dist/hooks/__tests__/tmux-hook-engine.test.js +1 -1
  21. package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
  22. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts +2 -0
  23. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts.map +1 -0
  24. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js +153 -0
  25. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js.map +1 -0
  26. package/dist/hooks/extensibility/dispatcher.d.ts +4 -0
  27. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -0
  28. package/dist/hooks/extensibility/dispatcher.js +223 -0
  29. package/dist/hooks/extensibility/dispatcher.js.map +1 -0
  30. package/dist/hooks/extensibility/events.d.ts +18 -0
  31. package/dist/hooks/extensibility/events.d.ts.map +1 -0
  32. package/dist/hooks/extensibility/events.js +53 -0
  33. package/dist/hooks/extensibility/events.js.map +1 -0
  34. package/dist/hooks/extensibility/index.d.ts +6 -0
  35. package/dist/hooks/extensibility/index.d.ts.map +1 -0
  36. package/dist/hooks/extensibility/index.js +6 -0
  37. package/dist/hooks/extensibility/index.js.map +1 -0
  38. package/dist/hooks/extensibility/loader.d.ts +14 -0
  39. package/dist/hooks/extensibility/loader.d.ts.map +1 -0
  40. package/dist/hooks/extensibility/loader.js +102 -0
  41. package/dist/hooks/extensibility/loader.js.map +1 -0
  42. package/dist/hooks/extensibility/logging.d.ts +4 -0
  43. package/dist/hooks/extensibility/logging.d.ts.map +1 -0
  44. package/dist/hooks/extensibility/logging.js +16 -0
  45. package/dist/hooks/extensibility/logging.js.map +1 -0
  46. package/dist/hooks/extensibility/plugin-runner.d.ts +2 -0
  47. package/dist/hooks/extensibility/plugin-runner.d.ts.map +1 -0
  48. package/dist/hooks/extensibility/plugin-runner.js +69 -0
  49. package/dist/hooks/extensibility/plugin-runner.js.map +1 -0
  50. package/dist/hooks/extensibility/runtime.d.ts +3 -0
  51. package/dist/hooks/extensibility/runtime.d.ts.map +1 -0
  52. package/dist/hooks/extensibility/runtime.js +29 -0
  53. package/dist/hooks/extensibility/runtime.js.map +1 -0
  54. package/dist/hooks/extensibility/sdk.d.ts +11 -0
  55. package/dist/hooks/extensibility/sdk.d.ts.map +1 -0
  56. package/dist/hooks/extensibility/sdk.js +240 -0
  57. package/dist/hooks/extensibility/sdk.js.map +1 -0
  58. package/dist/hooks/extensibility/types.d.ts +122 -0
  59. package/dist/hooks/extensibility/types.d.ts.map +1 -0
  60. package/dist/hooks/extensibility/types.js +2 -0
  61. package/dist/hooks/extensibility/types.js.map +1 -0
  62. package/dist/notifications/__tests__/tmux.test.js +10 -6
  63. package/dist/notifications/__tests__/tmux.test.js.map +1 -1
  64. package/dist/notifications/tmux-detector.d.ts.map +1 -1
  65. package/dist/notifications/tmux-detector.js +7 -2
  66. package/dist/notifications/tmux-detector.js.map +1 -1
  67. package/dist/notifications/tmux.d.ts.map +1 -1
  68. package/dist/notifications/tmux.js +8 -1
  69. package/dist/notifications/tmux.js.map +1 -1
  70. package/dist/team/tmux-session.d.ts.map +1 -1
  71. package/dist/team/tmux-session.js +8 -7
  72. package/dist/team/tmux-session.js.map +1 -1
  73. package/package.json +1 -1
  74. package/scripts/hook-derived-watcher.js +335 -0
  75. package/scripts/notify-hook.js +32 -1
  76. package/scripts/tmux-hook-engine.js +3 -2
package/README.md CHANGED
@@ -51,6 +51,18 @@ Recommended trusted-environment launch profile:
51
51
  omx --xhigh --madmax
52
52
  ```
53
53
 
54
+ ## New in v0.4.0
55
+
56
+ - **Hook extension workflow** with `omx hooks` (`init|status|validate|test`) for additive plugin-based automation.
57
+ - **Native hook runtime integration** for `session-start`, `session-end`, `session-idle`, and `turn-complete` event dispatch.
58
+ - **tmux reliability hardening** by standardizing submit key behavior to `C-m` across the codebase.
59
+
60
+ Try it:
61
+
62
+ ```bash
63
+ OMX_HOOK_PLUGINS=1 omx hooks test
64
+ ```
65
+
54
66
  ## First Session
55
67
 
56
68
  Inside Codex:
@@ -96,10 +108,22 @@ omx status # Show active modes
96
108
  omx cancel # Cancel active execution modes
97
109
  omx reasoning <mode> # low|medium|high|xhigh
98
110
  omx tmux-hook ... # init|status|validate|test
111
+ omx hooks ... # init|status|validate|test (plugin extension workflow)
99
112
  omx hud ... # --watch|--json|--preset
100
113
  omx help
101
114
  ```
102
115
 
116
+ ## Hooks Extension (Additive Surface)
117
+
118
+ OMX now includes `omx hooks` for plugin scaffolding and validation.
119
+
120
+ - `omx tmux-hook` remains supported and unchanged.
121
+ - `omx hooks` is additive and does not replace tmux-hook workflows.
122
+ - Plugin files live at `.omx/hooks/*.mjs`.
123
+ - Plugins are off by default; enable with `OMX_HOOK_PLUGINS=1`.
124
+
125
+ See `docs/hooks-extension.md` for the full extension workflow and event model.
126
+
103
127
  ## Launch Flags
104
128
 
105
129
  ```bash
@@ -212,6 +236,7 @@ npm test
212
236
  ## Notes
213
237
 
214
238
  - Coverage and parity notes: `COVERAGE.md`
239
+ - Hook extension workflow: `docs/hooks-extension.md`
215
240
  - Setup and contribution details: `CONTRIBUTING.md`
216
241
 
217
242
  ## Acknowledgments
@@ -39,6 +39,12 @@ describe('normalizeCodexLaunchArgs', () => {
39
39
  });
40
40
  });
41
41
  describe('resolveCliInvocation', () => {
42
+ it('resolves hooks to hooks command', () => {
43
+ assert.deepEqual(resolveCliInvocation(['hooks']), {
44
+ command: 'hooks',
45
+ launchArgs: [],
46
+ });
47
+ });
42
48
  it('resolves --help to the help command instead of launch', () => {
43
49
  assert.deepEqual(resolveCliInvocation(['--help']), {
44
50
  command: 'help',
@@ -1 +1 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/index.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { HookPluginDescriptor } from '../hooks/extensibility/types.js';
2
+ export declare function hooksCommand(args: string[]): Promise<void>;
3
+ export declare function formatHooksStatusLine(plugin: HookPluginDescriptor): string;
4
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/cli/hooks.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAyD5E,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhE;AA0ID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAE1E"}
@@ -0,0 +1,201 @@
1
+ import { existsSync } from 'fs';
2
+ import { mkdir, readFile, writeFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+ import { pathToFileURL } from 'url';
5
+ import { buildHookEvent } from '../hooks/extensibility/events.js';
6
+ import { dispatchHookEvent } from '../hooks/extensibility/dispatcher.js';
7
+ import { discoverHookPlugins, isHookPluginsEnabled } from '../hooks/extensibility/loader.js';
8
+ const HELP = `
9
+ Usage:
10
+ omx hooks init Create .omx/hooks/sample-plugin.mjs scaffold
11
+ omx hooks status Show plugin directory + discovered plugins
12
+ omx hooks validate Validate plugin exports/signatures
13
+ omx hooks test Dispatch synthetic turn-complete event to plugins
14
+
15
+ Notes:
16
+ - This command is additive. Existing \`omx tmux-hook\` behavior is unchanged.
17
+ - Plugins are disabled by default. Enable with OMX_HOOK_PLUGINS=1.
18
+ `;
19
+ const SAMPLE_PLUGIN = `export async function onHookEvent(event, sdk) {
20
+ if (event.event !== 'turn-complete') return;
21
+
22
+ const current = Number((await sdk.state.read('sample-seen-count')) ?? 0);
23
+ const next = Number.isFinite(current) ? current + 1 : 1;
24
+ await sdk.state.write('sample-seen-count', next);
25
+
26
+ await sdk.log.info('sample-plugin observed turn-complete', {
27
+ turn_id: event.turn_id,
28
+ seen_count: next,
29
+ });
30
+ }
31
+ `;
32
+ function hooksDir(cwd = process.cwd()) {
33
+ return join(cwd, '.omx', 'hooks');
34
+ }
35
+ function samplePluginPath(cwd = process.cwd()) {
36
+ return join(hooksDir(cwd), 'sample-plugin.mjs');
37
+ }
38
+ async function validateHookPluginExport(filePath) {
39
+ try {
40
+ const moduleUrl = `${pathToFileURL(filePath).href}?t=${Date.now()}`;
41
+ const mod = await import(moduleUrl);
42
+ if (typeof mod.onHookEvent !== 'function') {
43
+ return { valid: false, reason: 'missing export `onHookEvent(event, sdk)`' };
44
+ }
45
+ return { valid: true };
46
+ }
47
+ catch (error) {
48
+ return {
49
+ valid: false,
50
+ reason: error instanceof Error ? error.message : 'failed to import plugin',
51
+ };
52
+ }
53
+ }
54
+ export async function hooksCommand(args) {
55
+ const subcommand = args[0] || 'status';
56
+ switch (subcommand) {
57
+ case 'init':
58
+ await initHooks();
59
+ return;
60
+ case 'status':
61
+ await statusHooks();
62
+ return;
63
+ case 'validate':
64
+ await validateHooks();
65
+ return;
66
+ case 'test':
67
+ await testHooks();
68
+ return;
69
+ case 'help':
70
+ case '--help':
71
+ case '-h':
72
+ console.log(HELP);
73
+ return;
74
+ default:
75
+ throw new Error(`Unknown hooks subcommand: ${subcommand}`);
76
+ }
77
+ }
78
+ async function initHooks() {
79
+ const cwd = process.cwd();
80
+ const dir = hooksDir(cwd);
81
+ const samplePath = samplePluginPath(cwd);
82
+ await mkdir(dir, { recursive: true });
83
+ if (existsSync(samplePath)) {
84
+ console.log(`hooks scaffold already exists: ${samplePath}`);
85
+ return;
86
+ }
87
+ await writeFile(samplePath, SAMPLE_PLUGIN);
88
+ console.log(`Created ${samplePath}`);
89
+ console.log('Enable plugins with: OMX_HOOK_PLUGINS=1');
90
+ }
91
+ async function statusHooks() {
92
+ const cwd = process.cwd();
93
+ const dir = hooksDir(cwd);
94
+ const plugins = await discoverHookPlugins(cwd);
95
+ console.log('hooks status');
96
+ console.log('-----------');
97
+ console.log(`Directory: ${dir}`);
98
+ console.log(`Plugins enabled: ${isHookPluginsEnabled(process.env) ? 'yes' : 'no (set OMX_HOOK_PLUGINS=1)'}`);
99
+ console.log(`Discovered plugins: ${plugins.length}`);
100
+ for (const plugin of plugins) {
101
+ console.log(`- ${plugin.fileName}`);
102
+ }
103
+ }
104
+ async function validateHooks() {
105
+ const cwd = process.cwd();
106
+ const plugins = await discoverHookPlugins(cwd);
107
+ if (plugins.length === 0) {
108
+ console.log('No plugins found. Run: omx hooks init');
109
+ return;
110
+ }
111
+ let failed = 0;
112
+ for (const plugin of plugins) {
113
+ const result = await validateHookPluginExport(plugin.filePath);
114
+ if (result.valid) {
115
+ console.log(`✓ ${plugin.fileName}`);
116
+ }
117
+ else {
118
+ failed += 1;
119
+ console.log(`✗ ${plugin.fileName}: ${result.reason || 'invalid export'}`);
120
+ }
121
+ }
122
+ if (failed > 0) {
123
+ throw new Error(`hooks validation failed (${failed} plugin${failed === 1 ? '' : 's'})`);
124
+ }
125
+ }
126
+ function normalizeDispatchResult(result) {
127
+ if (!result || typeof result !== 'object') {
128
+ return { enabled: false, reason: 'invalid_result', results: [] };
129
+ }
130
+ const obj = result;
131
+ const results = Array.isArray(obj.results)
132
+ ? obj.results.filter((item) => !!item && typeof item === 'object')
133
+ : [];
134
+ return {
135
+ enabled: obj.enabled !== false,
136
+ reason: typeof obj.reason === 'string' ? obj.reason : 'ok',
137
+ results,
138
+ };
139
+ }
140
+ function pluginLabelFromResult(result) {
141
+ if (typeof result.plugin_id === 'string' && result.plugin_id)
142
+ return result.plugin_id;
143
+ if (typeof result.plugin === 'string' && result.plugin)
144
+ return result.plugin;
145
+ if (typeof result.file === 'string' && result.file)
146
+ return result.file;
147
+ return 'unknown-plugin';
148
+ }
149
+ function pluginStatusFromResult(result) {
150
+ if (typeof result.status === 'string' && result.status)
151
+ return result.status;
152
+ if (typeof result.reason === 'string' && result.reason)
153
+ return result.reason;
154
+ if (typeof result.ok === 'boolean')
155
+ return result.ok ? 'ok' : 'error';
156
+ return 'unknown';
157
+ }
158
+ async function testHooks() {
159
+ const cwd = process.cwd();
160
+ const discovered = await discoverHookPlugins(cwd);
161
+ const event = buildHookEvent('turn-complete', {
162
+ source: 'native',
163
+ context: {
164
+ reason: 'omx-hooks-test',
165
+ },
166
+ session_id: 'omx-hooks-test',
167
+ thread_id: `thread-${Date.now()}`,
168
+ turn_id: `turn-${Date.now()}`,
169
+ });
170
+ const rawResult = await dispatchHookEvent(event, {
171
+ cwd,
172
+ event,
173
+ env: {
174
+ ...process.env,
175
+ OMX_HOOK_PLUGINS: '1',
176
+ },
177
+ allowInTeamWorker: false,
178
+ });
179
+ const result = normalizeDispatchResult(rawResult);
180
+ console.log('hooks test dispatch complete');
181
+ console.log(`plugins discovered: ${discovered.length}`);
182
+ console.log(`plugins enabled: ${result.enabled ? 'yes' : 'no'}`);
183
+ console.log(`dispatch reason: ${result.reason}`);
184
+ for (const pluginResult of result.results) {
185
+ const label = pluginLabelFromResult(pluginResult);
186
+ const status = pluginStatusFromResult(pluginResult);
187
+ const error = typeof pluginResult.error === 'string' ? pluginResult.error : '';
188
+ console.log(error ? `${label}: ${status} (${error})` : `${label}: ${status}`);
189
+ }
190
+ const logPath = join(cwd, '.omx', 'logs', `hooks-${new Date().toISOString().split('T')[0]}.jsonl`);
191
+ if (existsSync(logPath)) {
192
+ const content = await readFile(logPath, 'utf-8').catch(() => '');
193
+ if (content.trim()) {
194
+ console.log(`log file: ${logPath}`);
195
+ }
196
+ }
197
+ }
198
+ export function formatHooksStatusLine(plugin) {
199
+ return plugin.fileName;
200
+ }
201
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/cli/hooks.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * oh-my-codex CLI
3
3
  * Multi-agent orchestration for OpenAI Codex CLI
4
4
  */
5
- type CliCommand = 'launch' | 'setup' | 'doctor' | 'team' | 'version' | 'tmux-hook' | 'hud' | 'status' | 'cancel' | 'help' | 'reasoning' | string;
5
+ type CliCommand = 'launch' | 'setup' | 'doctor' | 'team' | 'version' | 'tmux-hook' | 'hooks' | 'hud' | 'status' | 'cancel' | 'help' | 'reasoning' | string;
6
6
  export interface ResolvedCliInvocation {
7
7
  command: CliCommand;
8
8
  launchArgs: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0EH,KAAK,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAEjJ,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAY1E;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEzD,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CAEhG;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAcxE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAK9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/F;AAED,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAM5G;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgExD;AAgGD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA2CjE;AAsCD,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,EAAE,CAIV;AA2ED,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ9E;AAeD,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,kBAAkB,UAAO,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBlF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAyC5F;AAsBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAgB3E;AAkKD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAE7E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8EH,KAAK,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAE3J,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAY1E;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEzD,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CAEhG;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAcxE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAK9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/F;AAED,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAM5G;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmExD;AAgGD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA2CjE;AAsCD,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,EAAE,CAIV;AA2ED,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ9E;AAeD,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,kBAAkB,UAAO,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBlF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAyC5F;AAsBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAgB3E;AAsLD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAE7E"}
package/dist/cli/index.js CHANGED
@@ -9,6 +9,7 @@ import { setup } from './setup.js';
9
9
  import { doctor } from './doctor.js';
10
10
  import { version } from './version.js';
11
11
  import { tmuxHookCommand } from './tmux-hook.js';
12
+ import { hooksCommand } from './hooks.js';
12
13
  import { hudCommand } from '../hud/index.js';
13
14
  import { teamCommand } from './team.js';
14
15
  import { getAllScopedStateDirs, getBaseStateDir, getStateDir } from '../mcp/state-paths.js';
@@ -18,6 +19,8 @@ import { readSessionState, isSessionStale, writeSessionStart, writeSessionEnd, r
18
19
  import { getPackageRoot } from '../utils/package.js';
19
20
  import { codexConfigPath } from '../utils/paths.js';
20
21
  import { getModelForMode } from '../config/models.js';
22
+ import { buildHookEvent } from '../hooks/extensibility/events.js';
23
+ import { dispatchHookEvent } from '../hooks/extensibility/dispatcher.js';
21
24
  const HELP = `
22
25
  oh-my-codex (omx) - Multi-agent orchestration for Codex CLI
23
26
 
@@ -29,6 +32,7 @@ Usage:
29
32
  omx team Spawn parallel worker panes in tmux and bootstrap inbox/task state
30
33
  omx version Show version information
31
34
  omx tmux-hook Manage tmux prompt injection workaround (init|status|validate|test)
35
+ omx hooks Manage hook plugins (init|status|validate|test)
32
36
  omx hud Show HUD statusline (--watch, --json, --preset=NAME)
33
37
  omx help Show this help message
34
38
  omx status Show active modes and state
@@ -115,7 +119,7 @@ export function buildHudPaneCleanupTargets(existingPaneIds, createdPaneId) {
115
119
  }
116
120
  export async function main(args) {
117
121
  const knownCommands = new Set([
118
- 'launch', 'setup', 'doctor', 'team', 'version', 'tmux-hook', 'hud', 'status', 'cancel', 'help', '--help', '-h',
122
+ 'launch', 'setup', 'doctor', 'team', 'version', 'tmux-hook', 'hooks', 'hud', 'status', 'cancel', 'help', '--help', '-h',
119
123
  ]);
120
124
  const firstArg = args[0];
121
125
  const { command, launchArgs } = resolveCliInvocation(args);
@@ -149,6 +153,9 @@ export async function main(args) {
149
153
  case 'tmux-hook':
150
154
  await tmuxHookCommand(args.slice(1));
151
155
  break;
156
+ case 'hooks':
157
+ await hooksCommand(args.slice(1));
158
+ break;
152
159
  case 'status':
153
160
  await showStatus();
154
161
  break;
@@ -565,7 +572,14 @@ async function preLaunch(cwd, sessionId) {
565
572
  catch {
566
573
  // Non-fatal
567
574
  }
568
- // 5. Send session-start lifecycle notification (best effort)
575
+ // 5. Start derived watcher (best effort, opt-in)
576
+ try {
577
+ await startHookDerivedWatcher(cwd);
578
+ }
579
+ catch {
580
+ // Non-fatal
581
+ }
582
+ // 6. Send session-start lifecycle notification (best effort)
569
583
  try {
570
584
  const { notifyLifecycle } = await import('../notifications/index.js');
571
585
  await notifyLifecycle('session-start', {
@@ -577,6 +591,19 @@ async function preLaunch(cwd, sessionId) {
577
591
  catch {
578
592
  // Non-fatal: notification failures must never block launch
579
593
  }
594
+ // 7. Dispatch native hook event (best effort)
595
+ try {
596
+ await emitNativeHookEvent(cwd, 'session-start', {
597
+ session_id: sessionId,
598
+ context: {
599
+ project_path: cwd,
600
+ project_name: basename(cwd),
601
+ },
602
+ });
603
+ }
604
+ catch {
605
+ // Non-fatal
606
+ }
580
607
  }
581
608
  /**
582
609
  * runCodex: Launch Codex CLI (blocks until exit).
@@ -706,6 +733,20 @@ async function postLaunch(cwd, sessionId) {
706
733
  catch {
707
734
  // Non-fatal
708
735
  }
736
+ // 0. Flush derived watcher once on shutdown (opt-in, best effort).
737
+ try {
738
+ await flushHookDerivedWatcherOnce(cwd);
739
+ }
740
+ catch {
741
+ // Non-fatal
742
+ }
743
+ // 0.1 Stop derived watcher first (opt-in, best effort).
744
+ try {
745
+ await stopHookDerivedWatcher(cwd);
746
+ }
747
+ catch {
748
+ // Non-fatal
749
+ }
709
750
  // 1. Remove session-scoped model instructions file
710
751
  try {
711
752
  await removeSessionModelInstructionsFile(cwd, sessionId);
@@ -760,10 +801,44 @@ async function postLaunch(cwd, sessionId) {
760
801
  catch {
761
802
  // Non-fatal: notification failures must never block session cleanup
762
803
  }
804
+ // 5. Dispatch native hook event (best effort)
805
+ try {
806
+ const durationMs = sessionStartedAt
807
+ ? Date.now() - new Date(sessionStartedAt).getTime()
808
+ : undefined;
809
+ await emitNativeHookEvent(cwd, 'session-end', {
810
+ session_id: sessionId,
811
+ context: {
812
+ project_path: cwd,
813
+ project_name: basename(cwd),
814
+ duration_ms: durationMs,
815
+ reason: 'session_exit',
816
+ },
817
+ });
818
+ }
819
+ catch {
820
+ // Non-fatal
821
+ }
822
+ }
823
+ async function emitNativeHookEvent(cwd, event, opts = {}) {
824
+ const payload = buildHookEvent(event, {
825
+ source: 'native',
826
+ context: opts.context || {},
827
+ session_id: opts.session_id,
828
+ thread_id: opts.thread_id,
829
+ turn_id: opts.turn_id,
830
+ mode: opts.mode,
831
+ });
832
+ await dispatchHookEvent(payload, {
833
+ cwd,
834
+ });
763
835
  }
764
836
  function notifyFallbackPidPath(cwd) {
765
837
  return join(cwd, '.omx', 'state', 'notify-fallback.pid');
766
838
  }
839
+ function hookDerivedWatcherPidPath(cwd) {
840
+ return join(cwd, '.omx', 'state', 'hook-derived-watcher.pid');
841
+ }
767
842
  async function startNotifyFallbackWatcher(cwd) {
768
843
  if (process.env.OMX_NOTIFY_FALLBACK === '0')
769
844
  return;
@@ -795,6 +870,36 @@ async function startNotifyFallbackWatcher(cwd) {
795
870
  child.unref();
796
871
  await writeFile(pidPath, JSON.stringify({ pid: child.pid, started_at: new Date().toISOString() }, null, 2)).catch(() => { });
797
872
  }
873
+ async function startHookDerivedWatcher(cwd) {
874
+ if (process.env.OMX_HOOK_DERIVED_SIGNALS !== '1')
875
+ return;
876
+ const { mkdir, writeFile, readFile } = await import('fs/promises');
877
+ const pidPath = hookDerivedWatcherPidPath(cwd);
878
+ const pkgRoot = getPackageRoot();
879
+ const watcherScript = join(pkgRoot, 'scripts', 'hook-derived-watcher.js');
880
+ if (!existsSync(watcherScript))
881
+ return;
882
+ if (existsSync(pidPath)) {
883
+ try {
884
+ const prev = JSON.parse(await readFile(pidPath, 'utf-8'));
885
+ if (prev && typeof prev.pid === 'number') {
886
+ process.kill(prev.pid, 'SIGTERM');
887
+ }
888
+ }
889
+ catch {
890
+ // Ignore stale PID parse/kill errors.
891
+ }
892
+ }
893
+ await mkdir(join(cwd, '.omx', 'state'), { recursive: true }).catch(() => { });
894
+ const child = spawn(process.execPath, [watcherScript, '--cwd', cwd], {
895
+ cwd,
896
+ detached: true,
897
+ stdio: 'ignore',
898
+ env: process.env,
899
+ });
900
+ child.unref();
901
+ await writeFile(pidPath, JSON.stringify({ pid: child.pid, started_at: new Date().toISOString() }, null, 2)).catch(() => { });
902
+ }
798
903
  async function stopNotifyFallbackWatcher(cwd) {
799
904
  const { readFile, unlink } = await import('fs/promises');
800
905
  const pidPath = notifyFallbackPidPath(cwd);
@@ -811,6 +916,22 @@ async function stopNotifyFallbackWatcher(cwd) {
811
916
  }
812
917
  await unlink(pidPath).catch(() => { });
813
918
  }
919
+ async function stopHookDerivedWatcher(cwd) {
920
+ const { readFile, unlink } = await import('fs/promises');
921
+ const pidPath = hookDerivedWatcherPidPath(cwd);
922
+ if (!existsSync(pidPath))
923
+ return;
924
+ try {
925
+ const parsed = JSON.parse(await readFile(pidPath, 'utf-8'));
926
+ if (parsed && typeof parsed.pid === 'number') {
927
+ process.kill(parsed.pid, 'SIGTERM');
928
+ }
929
+ }
930
+ catch {
931
+ // Ignore stop errors.
932
+ }
933
+ await unlink(pidPath).catch(() => { });
934
+ }
814
935
  async function flushNotifyFallbackOnce(cwd) {
815
936
  const { spawnSync } = await import('child_process');
816
937
  const pkgRoot = getPackageRoot();
@@ -824,6 +945,24 @@ async function flushNotifyFallbackOnce(cwd) {
824
945
  timeout: 3000,
825
946
  });
826
947
  }
948
+ async function flushHookDerivedWatcherOnce(cwd) {
949
+ if (process.env.OMX_HOOK_DERIVED_SIGNALS !== '1')
950
+ return;
951
+ const { spawnSync } = await import('child_process');
952
+ const pkgRoot = getPackageRoot();
953
+ const watcherScript = join(pkgRoot, 'scripts', 'hook-derived-watcher.js');
954
+ if (!existsSync(watcherScript))
955
+ return;
956
+ spawnSync(process.execPath, [watcherScript, '--once', '--cwd', cwd], {
957
+ cwd,
958
+ stdio: 'ignore',
959
+ timeout: 3000,
960
+ env: {
961
+ ...process.env,
962
+ OMX_HOOK_DERIVED_SIGNALS: '1',
963
+ },
964
+ });
965
+ }
827
966
  async function cancelModes() {
828
967
  const { readdir, writeFile, readFile } = await import('fs/promises');
829
968
  const cwd = process.cwd();