oh-my-codex 0.4.0 → 0.4.2

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 (93) hide show
  1. package/README.es.md +36 -0
  2. package/README.ja.md +36 -0
  3. package/README.ko.md +36 -0
  4. package/README.md +13 -1
  5. package/README.pt.md +36 -0
  6. package/README.ru.md +36 -0
  7. package/README.vi.md +36 -0
  8. package/README.zh.md +39 -0
  9. package/bin/omx.js +2 -1
  10. package/dist/config/__tests__/generator-notify.test.js +3 -3
  11. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  12. package/dist/config/generator.d.ts +1 -1
  13. package/dist/config/generator.js +8 -8
  14. package/dist/config/generator.js.map +1 -1
  15. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts +2 -0
  16. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts.map +1 -0
  17. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +427 -0
  18. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -0
  19. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts +2 -0
  20. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts.map +1 -0
  21. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +432 -0
  22. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -0
  23. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +3 -0
  24. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  25. package/dist/hooks/emulator.d.ts +1 -1
  26. package/dist/hooks/emulator.js +5 -5
  27. package/dist/hooks/emulator.js.map +1 -1
  28. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts +2 -0
  29. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts.map +1 -0
  30. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +152 -0
  31. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -0
  32. package/dist/hooks/extensibility/__tests__/events.test.d.ts +2 -0
  33. package/dist/hooks/extensibility/__tests__/events.test.d.ts.map +1 -0
  34. package/dist/hooks/extensibility/__tests__/events.test.js +117 -0
  35. package/dist/hooks/extensibility/__tests__/events.test.js.map +1 -0
  36. package/dist/hooks/extensibility/__tests__/loader.test.d.ts +2 -0
  37. package/dist/hooks/extensibility/__tests__/loader.test.d.ts.map +1 -0
  38. package/dist/hooks/extensibility/__tests__/loader.test.js +229 -0
  39. package/dist/hooks/extensibility/__tests__/loader.test.js.map +1 -0
  40. package/dist/hooks/extensibility/__tests__/logging.test.d.ts +2 -0
  41. package/dist/hooks/extensibility/__tests__/logging.test.d.ts.map +1 -0
  42. package/dist/hooks/extensibility/__tests__/logging.test.js +74 -0
  43. package/dist/hooks/extensibility/__tests__/logging.test.js.map +1 -0
  44. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts +2 -0
  45. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts.map +1 -0
  46. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +202 -0
  47. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +1 -0
  48. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts +2 -0
  49. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts.map +1 -0
  50. package/dist/hooks/extensibility/__tests__/runtime.test.js +117 -0
  51. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -0
  52. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts +2 -0
  53. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts.map +1 -0
  54. package/dist/hooks/extensibility/__tests__/sdk.test.js +277 -0
  55. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -0
  56. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  57. package/dist/hooks/extensibility/sdk.js +10 -2
  58. package/dist/hooks/extensibility/sdk.js.map +1 -1
  59. package/dist/hud/__tests__/colors.test.d.ts +2 -0
  60. package/dist/hud/__tests__/colors.test.d.ts.map +1 -0
  61. package/dist/hud/__tests__/colors.test.js +194 -0
  62. package/dist/hud/__tests__/colors.test.js.map +1 -0
  63. package/dist/hud/__tests__/render.test.d.ts +2 -0
  64. package/dist/hud/__tests__/render.test.d.ts.map +1 -0
  65. package/dist/hud/__tests__/render.test.js +449 -0
  66. package/dist/hud/__tests__/render.test.js.map +1 -0
  67. package/dist/hud/__tests__/types.test.d.ts +2 -0
  68. package/dist/hud/__tests__/types.test.d.ts.map +1 -0
  69. package/dist/hud/__tests__/types.test.js +17 -0
  70. package/dist/hud/__tests__/types.test.js.map +1 -0
  71. package/dist/team/__tests__/tmux-session.test.js +15 -1
  72. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  73. package/dist/team/orchestrator.d.ts +1 -1
  74. package/dist/team/orchestrator.js +1 -1
  75. package/dist/team/tmux-session.d.ts +8 -0
  76. package/dist/team/tmux-session.d.ts.map +1 -1
  77. package/dist/team/tmux-session.js +28 -7
  78. package/dist/team/tmux-session.js.map +1 -1
  79. package/dist/utils/__tests__/package.test.d.ts +2 -0
  80. package/dist/utils/__tests__/package.test.d.ts.map +1 -0
  81. package/dist/utils/__tests__/package.test.js +21 -0
  82. package/dist/utils/__tests__/package.test.js.map +1 -0
  83. package/dist/utils/__tests__/paths.test.d.ts +2 -0
  84. package/dist/utils/__tests__/paths.test.d.ts.map +1 -0
  85. package/dist/utils/__tests__/paths.test.js +117 -0
  86. package/dist/utils/__tests__/paths.test.js.map +1 -0
  87. package/dist/verification/__tests__/verifier.test.d.ts +2 -0
  88. package/dist/verification/__tests__/verifier.test.d.ts.map +1 -0
  89. package/dist/verification/__tests__/verifier.test.js +94 -0
  90. package/dist/verification/__tests__/verifier.test.js.map +1 -0
  91. package/package.json +1 -1
  92. package/scripts/notify-hook.js +346 -1
  93. package/templates/AGENTS.md +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/logging.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-runner.test.d.ts","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/plugin-runner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ import assert from 'node:assert/strict';
2
+ import { spawn } from 'node:child_process';
3
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { describe, it } from 'node:test';
7
+ const RESULT_PREFIX = '__OMX_PLUGIN_RESULT__ ';
8
+ function getRunnerPath() {
9
+ // Resolve from dist after build
10
+ return join(process.cwd(), 'dist', 'hooks', 'extensibility', 'plugin-runner.js');
11
+ }
12
+ function runRunner(input) {
13
+ return new Promise((resolve) => {
14
+ const child = spawn(process.execPath, [getRunnerPath()], {
15
+ stdio: ['pipe', 'pipe', 'pipe'],
16
+ });
17
+ let stdout = '';
18
+ let stderr = '';
19
+ child.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
20
+ child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
21
+ child.on('close', (code) => {
22
+ const lines = stdout.split('\n').filter(Boolean);
23
+ const resultLine = [...lines].reverse().find((l) => l.startsWith(RESULT_PREFIX));
24
+ let result = null;
25
+ if (resultLine) {
26
+ try {
27
+ result = JSON.parse(resultLine.slice(RESULT_PREFIX.length));
28
+ }
29
+ catch {
30
+ result = null;
31
+ }
32
+ }
33
+ resolve({ stdout, stderr, code, result });
34
+ });
35
+ child.stdin.write(JSON.stringify(input));
36
+ child.stdin.end();
37
+ });
38
+ }
39
+ describe('plugin-runner', () => {
40
+ it('emits error for empty stdin', async () => {
41
+ const { result, code } = await new Promise((resolve) => {
42
+ const child = spawn(process.execPath, [getRunnerPath()], {
43
+ stdio: ['pipe', 'pipe', 'pipe'],
44
+ });
45
+ let stdout = '';
46
+ child.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
47
+ child.on('close', (exitCode) => {
48
+ const lines = stdout.split('\n').filter(Boolean);
49
+ const resultLine = [...lines].reverse().find((l) => l.startsWith(RESULT_PREFIX));
50
+ let parsed = null;
51
+ if (resultLine) {
52
+ try {
53
+ parsed = JSON.parse(resultLine.slice(RESULT_PREFIX.length));
54
+ }
55
+ catch {
56
+ parsed = null;
57
+ }
58
+ }
59
+ resolve({ result: parsed, code: exitCode });
60
+ });
61
+ child.stdin.end('');
62
+ });
63
+ assert.ok(result);
64
+ assert.equal(result.ok, false);
65
+ assert.equal(result.reason, 'empty_request');
66
+ assert.equal(code, 1);
67
+ });
68
+ it('emits error for invalid JSON', async () => {
69
+ const { result, code } = await new Promise((resolve) => {
70
+ const child = spawn(process.execPath, [getRunnerPath()], {
71
+ stdio: ['pipe', 'pipe', 'pipe'],
72
+ });
73
+ let stdout = '';
74
+ child.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
75
+ child.on('close', (exitCode) => {
76
+ const lines = stdout.split('\n').filter(Boolean);
77
+ const resultLine = [...lines].reverse().find((l) => l.startsWith(RESULT_PREFIX));
78
+ let parsed = null;
79
+ if (resultLine) {
80
+ try {
81
+ parsed = JSON.parse(resultLine.slice(RESULT_PREFIX.length));
82
+ }
83
+ catch {
84
+ parsed = null;
85
+ }
86
+ }
87
+ resolve({ result: parsed, code: exitCode });
88
+ });
89
+ child.stdin.write('not json at all');
90
+ child.stdin.end();
91
+ });
92
+ assert.ok(result);
93
+ assert.equal(result.ok, false);
94
+ assert.equal(result.reason, 'invalid_json');
95
+ assert.equal(code, 1);
96
+ });
97
+ it('emits invalid_export for plugin without onHookEvent', async () => {
98
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runner-'));
99
+ try {
100
+ const pluginPath = join(cwd, 'no-export.mjs');
101
+ await writeFile(pluginPath, 'export const x = 1;');
102
+ const { result, code } = await runRunner({
103
+ cwd,
104
+ pluginId: 'no-export',
105
+ pluginPath,
106
+ event: {
107
+ schema_version: '1',
108
+ event: 'session-start',
109
+ timestamp: new Date().toISOString(),
110
+ source: 'native',
111
+ context: {},
112
+ },
113
+ });
114
+ assert.ok(result);
115
+ assert.equal(result.ok, false);
116
+ assert.equal(result.reason, 'invalid_export');
117
+ assert.equal(code, 1);
118
+ }
119
+ finally {
120
+ await rm(cwd, { recursive: true, force: true });
121
+ }
122
+ });
123
+ it('emits ok for valid plugin', async () => {
124
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runner-'));
125
+ try {
126
+ const pluginPath = join(cwd, 'valid.mjs');
127
+ await writeFile(pluginPath, 'export async function onHookEvent(event, sdk) {}');
128
+ const { result, code } = await runRunner({
129
+ cwd,
130
+ pluginId: 'valid',
131
+ pluginPath,
132
+ event: {
133
+ schema_version: '1',
134
+ event: 'session-start',
135
+ timestamp: new Date().toISOString(),
136
+ source: 'native',
137
+ context: {},
138
+ },
139
+ });
140
+ assert.ok(result);
141
+ assert.equal(result.ok, true);
142
+ assert.equal(result.reason, 'ok');
143
+ assert.equal(result.plugin, 'valid');
144
+ assert.equal(code, 0);
145
+ }
146
+ finally {
147
+ await rm(cwd, { recursive: true, force: true });
148
+ }
149
+ });
150
+ it('emits runner_error when plugin throws', async () => {
151
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runner-'));
152
+ try {
153
+ const pluginPath = join(cwd, 'throws.mjs');
154
+ await writeFile(pluginPath, 'export function onHookEvent() { throw new Error("boom"); }');
155
+ const { result, code } = await runRunner({
156
+ cwd,
157
+ pluginId: 'throws',
158
+ pluginPath,
159
+ event: {
160
+ schema_version: '1',
161
+ event: 'session-start',
162
+ timestamp: new Date().toISOString(),
163
+ source: 'native',
164
+ context: {},
165
+ },
166
+ });
167
+ assert.ok(result);
168
+ assert.equal(result.ok, false);
169
+ assert.equal(result.reason, 'runner_error');
170
+ assert.match(String(result.error), /boom/);
171
+ assert.equal(code, 1);
172
+ }
173
+ finally {
174
+ await rm(cwd, { recursive: true, force: true });
175
+ }
176
+ });
177
+ it('derives pluginId from path when not provided', async () => {
178
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runner-'));
179
+ try {
180
+ const pluginPath = join(cwd, 'derived-name.mjs');
181
+ await writeFile(pluginPath, 'export async function onHookEvent() {}');
182
+ const { result } = await runRunner({
183
+ cwd,
184
+ pluginPath,
185
+ event: {
186
+ schema_version: '1',
187
+ event: 'session-start',
188
+ timestamp: new Date().toISOString(),
189
+ source: 'native',
190
+ context: {},
191
+ },
192
+ });
193
+ assert.ok(result);
194
+ assert.equal(result.ok, true);
195
+ assert.equal(result.plugin, 'derived-name.mjs');
196
+ }
197
+ finally {
198
+ await rm(cwd, { recursive: true, force: true });
199
+ }
200
+ });
201
+ });
202
+ //# sourceMappingURL=plugin-runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-runner.test.js","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/plugin-runner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.test.d.ts","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/runtime.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,117 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { describe, it } from 'node:test';
6
+ import { dispatchHookEventRuntime } from '../runtime.js';
7
+ import { buildHookEvent } from '../events.js';
8
+ describe('dispatchHookEventRuntime', () => {
9
+ it('returns disabled when plugins env var is not set', async () => {
10
+ const originalEnv = process.env.OMX_HOOK_PLUGINS;
11
+ try {
12
+ delete process.env.OMX_HOOK_PLUGINS;
13
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-'));
14
+ try {
15
+ const event = buildHookEvent('session-start');
16
+ const result = await dispatchHookEventRuntime({ cwd, event });
17
+ assert.equal(result.dispatched, false);
18
+ assert.equal(result.reason, 'plugins_disabled');
19
+ assert.equal(result.result.enabled, false);
20
+ assert.equal(result.result.plugin_count, 0);
21
+ }
22
+ finally {
23
+ await rm(cwd, { recursive: true, force: true });
24
+ }
25
+ }
26
+ finally {
27
+ if (originalEnv !== undefined) {
28
+ process.env.OMX_HOOK_PLUGINS = originalEnv;
29
+ }
30
+ else {
31
+ delete process.env.OMX_HOOK_PLUGINS;
32
+ }
33
+ }
34
+ });
35
+ it('dispatches when plugins are enabled', async () => {
36
+ const originalEnv = process.env.OMX_HOOK_PLUGINS;
37
+ try {
38
+ process.env.OMX_HOOK_PLUGINS = '1';
39
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-'));
40
+ try {
41
+ const dir = join(cwd, '.omx', 'hooks');
42
+ await mkdir(dir, { recursive: true });
43
+ await writeFile(join(dir, 'rt-test.mjs'), 'export async function onHookEvent() {}');
44
+ const event = buildHookEvent('session-start');
45
+ const result = await dispatchHookEventRuntime({ cwd, event });
46
+ assert.equal(result.dispatched, true);
47
+ assert.equal(result.reason, 'ok');
48
+ assert.equal(result.result.enabled, true);
49
+ assert.equal(result.result.plugin_count, 1);
50
+ }
51
+ finally {
52
+ await rm(cwd, { recursive: true, force: true });
53
+ }
54
+ }
55
+ finally {
56
+ if (originalEnv !== undefined) {
57
+ process.env.OMX_HOOK_PLUGINS = originalEnv;
58
+ }
59
+ else {
60
+ delete process.env.OMX_HOOK_PLUGINS;
61
+ }
62
+ }
63
+ });
64
+ it('passes allowTeamWorkerSideEffects through to dispatcher', async () => {
65
+ const originalEnv = process.env.OMX_HOOK_PLUGINS;
66
+ try {
67
+ process.env.OMX_HOOK_PLUGINS = '1';
68
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-'));
69
+ try {
70
+ const event = buildHookEvent('turn-complete');
71
+ const result = await dispatchHookEventRuntime({
72
+ cwd,
73
+ event,
74
+ allowTeamWorkerSideEffects: true,
75
+ });
76
+ assert.equal(result.dispatched, true);
77
+ assert.equal(result.result.enabled, true);
78
+ }
79
+ finally {
80
+ await rm(cwd, { recursive: true, force: true });
81
+ }
82
+ }
83
+ finally {
84
+ if (originalEnv !== undefined) {
85
+ process.env.OMX_HOOK_PLUGINS = originalEnv;
86
+ }
87
+ else {
88
+ delete process.env.OMX_HOOK_PLUGINS;
89
+ }
90
+ }
91
+ });
92
+ it('returns event name and source in result', async () => {
93
+ const originalEnv = process.env.OMX_HOOK_PLUGINS;
94
+ try {
95
+ delete process.env.OMX_HOOK_PLUGINS;
96
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-'));
97
+ try {
98
+ const event = buildHookEvent('needs-input');
99
+ const result = await dispatchHookEventRuntime({ cwd, event });
100
+ assert.equal(result.result.event, 'needs-input');
101
+ assert.equal(result.result.source, 'derived');
102
+ }
103
+ finally {
104
+ await rm(cwd, { recursive: true, force: true });
105
+ }
106
+ }
107
+ finally {
108
+ if (originalEnv !== undefined) {
109
+ process.env.OMX_HOOK_PLUGINS = originalEnv;
110
+ }
111
+ else {
112
+ delete process.env.OMX_HOOK_PLUGINS;
113
+ }
114
+ }
115
+ });
116
+ });
117
+ //# sourceMappingURL=runtime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.test.js","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/runtime.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sdk.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.test.d.ts","sourceRoot":"","sources":["../../../../src/hooks/extensibility/__tests__/sdk.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,277 @@
1
+ import assert from 'node:assert/strict';
2
+ import { existsSync } from 'node:fs';
3
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { describe, it } from 'node:test';
7
+ import { createHookPluginSdk, clearHookPluginState } from '../sdk.js';
8
+ function makeEvent(event = 'session-start') {
9
+ return {
10
+ schema_version: '1',
11
+ event,
12
+ timestamp: '2026-01-01T00:00:00.000Z',
13
+ source: 'native',
14
+ context: {},
15
+ };
16
+ }
17
+ describe('createHookPluginSdk', () => {
18
+ describe('state', () => {
19
+ it('reads undefined for missing key', async () => {
20
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
21
+ try {
22
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
23
+ const val = await sdk.state.read('nonexistent');
24
+ assert.equal(val, undefined);
25
+ }
26
+ finally {
27
+ await rm(cwd, { recursive: true, force: true });
28
+ }
29
+ });
30
+ it('returns fallback for missing key', async () => {
31
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
32
+ try {
33
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
34
+ const val = await sdk.state.read('missing', 42);
35
+ assert.equal(val, 42);
36
+ }
37
+ finally {
38
+ await rm(cwd, { recursive: true, force: true });
39
+ }
40
+ });
41
+ it('writes and reads state', async () => {
42
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
43
+ try {
44
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
45
+ await sdk.state.write('counter', 5);
46
+ const val = await sdk.state.read('counter');
47
+ assert.equal(val, 5);
48
+ }
49
+ finally {
50
+ await rm(cwd, { recursive: true, force: true });
51
+ }
52
+ });
53
+ it('deletes state key', async () => {
54
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
55
+ try {
56
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
57
+ await sdk.state.write('key', 'value');
58
+ await sdk.state.delete('key');
59
+ const val = await sdk.state.read('key');
60
+ assert.equal(val, undefined);
61
+ }
62
+ finally {
63
+ await rm(cwd, { recursive: true, force: true });
64
+ }
65
+ });
66
+ it('delete is a no-op for nonexistent key', async () => {
67
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
68
+ try {
69
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
70
+ await sdk.state.write('keep', 'yes');
71
+ await sdk.state.delete('nonexistent');
72
+ const val = await sdk.state.read('keep');
73
+ assert.equal(val, 'yes');
74
+ }
75
+ finally {
76
+ await rm(cwd, { recursive: true, force: true });
77
+ }
78
+ });
79
+ it('reads all state', async () => {
80
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
81
+ try {
82
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
83
+ await sdk.state.write('a', 1);
84
+ await sdk.state.write('b', 'two');
85
+ const all = await sdk.state.all();
86
+ assert.deepEqual(all, { a: 1, b: 'two' });
87
+ }
88
+ finally {
89
+ await rm(cwd, { recursive: true, force: true });
90
+ }
91
+ });
92
+ it('returns empty object for all() with no state', async () => {
93
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
94
+ try {
95
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
96
+ const all = await sdk.state.all();
97
+ assert.deepEqual(all, {});
98
+ }
99
+ finally {
100
+ await rm(cwd, { recursive: true, force: true });
101
+ }
102
+ });
103
+ it('rejects empty state key', async () => {
104
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
105
+ try {
106
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
107
+ await assert.rejects(() => sdk.state.read(''), /state key is required/);
108
+ }
109
+ finally {
110
+ await rm(cwd, { recursive: true, force: true });
111
+ }
112
+ });
113
+ it('rejects state key with path traversal', async () => {
114
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
115
+ try {
116
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
117
+ await assert.rejects(() => sdk.state.read('../escape'), /invalid state key/);
118
+ }
119
+ finally {
120
+ await rm(cwd, { recursive: true, force: true });
121
+ }
122
+ });
123
+ it('rejects state key starting with /', async () => {
124
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
125
+ try {
126
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
127
+ await assert.rejects(() => sdk.state.write('/absolute', 1), /invalid state key/);
128
+ }
129
+ finally {
130
+ await rm(cwd, { recursive: true, force: true });
131
+ }
132
+ });
133
+ });
134
+ describe('log', () => {
135
+ it('exposes info, warn, error methods', async () => {
136
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
137
+ try {
138
+ const sdk = createHookPluginSdk({ cwd, pluginName: 'test', event: makeEvent() });
139
+ // These should not throw
140
+ await sdk.log.info('test info');
141
+ await sdk.log.warn('test warn');
142
+ await sdk.log.error('test error');
143
+ }
144
+ finally {
145
+ await rm(cwd, { recursive: true, force: true });
146
+ }
147
+ });
148
+ });
149
+ describe('tmux.sendKeys', () => {
150
+ it('returns side_effects_disabled when sideEffectsEnabled is false', async () => {
151
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
152
+ try {
153
+ const sdk = createHookPluginSdk({
154
+ cwd,
155
+ pluginName: 'test',
156
+ event: makeEvent(),
157
+ sideEffectsEnabled: false,
158
+ });
159
+ const result = await sdk.tmux.sendKeys({ text: 'hello' });
160
+ assert.equal(result.ok, false);
161
+ assert.equal(result.reason, 'side_effects_disabled');
162
+ }
163
+ finally {
164
+ await rm(cwd, { recursive: true, force: true });
165
+ }
166
+ });
167
+ it('returns invalid_text for empty text', async () => {
168
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
169
+ try {
170
+ const sdk = createHookPluginSdk({
171
+ cwd,
172
+ pluginName: 'test',
173
+ event: makeEvent(),
174
+ sideEffectsEnabled: true,
175
+ });
176
+ const result = await sdk.tmux.sendKeys({ text: ' ' });
177
+ assert.equal(result.ok, false);
178
+ assert.equal(result.reason, 'invalid_text');
179
+ }
180
+ finally {
181
+ await rm(cwd, { recursive: true, force: true });
182
+ }
183
+ });
184
+ it('returns loop_guard_input_marker when text contains loop marker', async () => {
185
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
186
+ const originalMarker = process.env.OMX_HOOK_PLUGIN_LOOP_MARKER;
187
+ try {
188
+ process.env.OMX_HOOK_PLUGIN_LOOP_MARKER = '[TESTMARK]';
189
+ const sdk = createHookPluginSdk({
190
+ cwd,
191
+ pluginName: 'test',
192
+ event: makeEvent(),
193
+ sideEffectsEnabled: true,
194
+ });
195
+ const result = await sdk.tmux.sendKeys({ text: 'hello [TESTMARK] world' });
196
+ assert.equal(result.ok, false);
197
+ assert.equal(result.reason, 'loop_guard_input_marker');
198
+ }
199
+ finally {
200
+ if (originalMarker === undefined) {
201
+ delete process.env.OMX_HOOK_PLUGIN_LOOP_MARKER;
202
+ }
203
+ else {
204
+ process.env.OMX_HOOK_PLUGIN_LOOP_MARKER = originalMarker;
205
+ }
206
+ await rm(cwd, { recursive: true, force: true });
207
+ }
208
+ });
209
+ it('returns target_missing when no pane is resolvable', async () => {
210
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
211
+ const originalPane = process.env.TMUX_PANE;
212
+ try {
213
+ delete process.env.TMUX_PANE;
214
+ const sdk = createHookPluginSdk({
215
+ cwd,
216
+ pluginName: 'test',
217
+ event: makeEvent(),
218
+ sideEffectsEnabled: true,
219
+ });
220
+ const result = await sdk.tmux.sendKeys({ text: 'hello' });
221
+ assert.equal(result.ok, false);
222
+ assert.equal(result.reason, 'target_missing');
223
+ }
224
+ finally {
225
+ if (originalPane !== undefined) {
226
+ process.env.TMUX_PANE = originalPane;
227
+ }
228
+ await rm(cwd, { recursive: true, force: true });
229
+ }
230
+ });
231
+ });
232
+ describe('plugin name sanitization', () => {
233
+ it('sanitizes special characters in plugin name', async () => {
234
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-sdk-'));
235
+ try {
236
+ const sdk = createHookPluginSdk({
237
+ cwd,
238
+ pluginName: 'my plugin!@#',
239
+ event: makeEvent(),
240
+ });
241
+ await sdk.state.write('test', 'value');
242
+ const val = await sdk.state.read('test');
243
+ assert.equal(val, 'value');
244
+ }
245
+ finally {
246
+ await rm(cwd, { recursive: true, force: true });
247
+ }
248
+ });
249
+ });
250
+ });
251
+ describe('clearHookPluginState', () => {
252
+ it('removes data.json and tmux.json for plugin', async () => {
253
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-clear-'));
254
+ try {
255
+ const pluginDir = join(cwd, '.omx', 'state', 'hooks', 'plugins', 'my-plugin');
256
+ await mkdir(pluginDir, { recursive: true });
257
+ await writeFile(join(pluginDir, 'data.json'), '{}');
258
+ await writeFile(join(pluginDir, 'tmux.json'), '{}');
259
+ await clearHookPluginState(cwd, 'my-plugin');
260
+ assert.equal(existsSync(join(pluginDir, 'data.json')), false);
261
+ assert.equal(existsSync(join(pluginDir, 'tmux.json')), false);
262
+ }
263
+ finally {
264
+ await rm(cwd, { recursive: true, force: true });
265
+ }
266
+ });
267
+ it('does not throw when files do not exist', async () => {
268
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-clear-'));
269
+ try {
270
+ await clearHookPluginState(cwd, 'nonexistent');
271
+ }
272
+ finally {
273
+ await rm(cwd, { recursive: true, force: true });
274
+ }
275
+ });
276
+ });
277
+ //# sourceMappingURL=sdk.test.js.map