oh-my-codex 0.4.1 → 0.4.3

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 (121) 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/cli/__tests__/index.test.js +11 -0
  11. package/dist/cli/__tests__/index.test.js.map +1 -1
  12. package/dist/cli/__tests__/star-prompt.test.d.ts +2 -0
  13. package/dist/cli/__tests__/star-prompt.test.d.ts.map +1 -0
  14. package/dist/cli/__tests__/star-prompt.test.js +82 -0
  15. package/dist/cli/__tests__/star-prompt.test.js.map +1 -0
  16. package/dist/cli/__tests__/update.test.d.ts +2 -0
  17. package/dist/cli/__tests__/update.test.d.ts.map +1 -0
  18. package/dist/cli/__tests__/update.test.js +66 -0
  19. package/dist/cli/__tests__/update.test.js.map +1 -0
  20. package/dist/cli/index.d.ts +1 -1
  21. package/dist/cli/index.d.ts.map +1 -1
  22. package/dist/cli/index.js +13 -2
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/cli/star-prompt.d.ts +11 -0
  25. package/dist/cli/star-prompt.d.ts.map +1 -0
  26. package/dist/cli/star-prompt.js +74 -0
  27. package/dist/cli/star-prompt.js.map +1 -0
  28. package/dist/cli/update.d.ts.map +1 -1
  29. package/dist/cli/update.js +7 -29
  30. package/dist/cli/update.js.map +1 -1
  31. package/dist/config/__tests__/generator-notify.test.js +3 -3
  32. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  33. package/dist/config/generator.d.ts +1 -1
  34. package/dist/config/generator.js +8 -8
  35. package/dist/config/generator.js.map +1 -1
  36. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts +2 -0
  37. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts.map +1 -0
  38. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +427 -0
  39. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -0
  40. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +17 -0
  41. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  42. package/dist/hooks/emulator.d.ts +1 -1
  43. package/dist/hooks/emulator.js +5 -5
  44. package/dist/hooks/emulator.js.map +1 -1
  45. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts +2 -0
  46. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts.map +1 -0
  47. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +152 -0
  48. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -0
  49. package/dist/hooks/extensibility/__tests__/events.test.d.ts +2 -0
  50. package/dist/hooks/extensibility/__tests__/events.test.d.ts.map +1 -0
  51. package/dist/hooks/extensibility/__tests__/events.test.js +117 -0
  52. package/dist/hooks/extensibility/__tests__/events.test.js.map +1 -0
  53. package/dist/hooks/extensibility/__tests__/loader.test.d.ts +2 -0
  54. package/dist/hooks/extensibility/__tests__/loader.test.d.ts.map +1 -0
  55. package/dist/hooks/extensibility/__tests__/loader.test.js +229 -0
  56. package/dist/hooks/extensibility/__tests__/loader.test.js.map +1 -0
  57. package/dist/hooks/extensibility/__tests__/logging.test.d.ts +2 -0
  58. package/dist/hooks/extensibility/__tests__/logging.test.d.ts.map +1 -0
  59. package/dist/hooks/extensibility/__tests__/logging.test.js +74 -0
  60. package/dist/hooks/extensibility/__tests__/logging.test.js.map +1 -0
  61. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts +2 -0
  62. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts.map +1 -0
  63. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +202 -0
  64. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +1 -0
  65. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts +2 -0
  66. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts.map +1 -0
  67. package/dist/hooks/extensibility/__tests__/runtime.test.js +117 -0
  68. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -0
  69. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts +2 -0
  70. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts.map +1 -0
  71. package/dist/hooks/extensibility/__tests__/sdk.test.js +277 -0
  72. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -0
  73. package/dist/hud/__tests__/colors.test.d.ts +2 -0
  74. package/dist/hud/__tests__/colors.test.d.ts.map +1 -0
  75. package/dist/hud/__tests__/colors.test.js +194 -0
  76. package/dist/hud/__tests__/colors.test.js.map +1 -0
  77. package/dist/hud/__tests__/render.test.d.ts +2 -0
  78. package/dist/hud/__tests__/render.test.d.ts.map +1 -0
  79. package/dist/hud/__tests__/render.test.js +449 -0
  80. package/dist/hud/__tests__/render.test.js.map +1 -0
  81. package/dist/hud/__tests__/types.test.d.ts +2 -0
  82. package/dist/hud/__tests__/types.test.d.ts.map +1 -0
  83. package/dist/hud/__tests__/types.test.js +17 -0
  84. package/dist/hud/__tests__/types.test.js.map +1 -0
  85. package/dist/notifications/__tests__/tmux-detector.test.js +69 -1
  86. package/dist/notifications/__tests__/tmux-detector.test.js.map +1 -1
  87. package/dist/notifications/reply-listener.d.ts +1 -1
  88. package/dist/notifications/reply-listener.js +1 -1
  89. package/dist/notifications/tmux-detector.d.ts +16 -0
  90. package/dist/notifications/tmux-detector.d.ts.map +1 -1
  91. package/dist/notifications/tmux-detector.js +37 -22
  92. package/dist/notifications/tmux-detector.js.map +1 -1
  93. package/dist/team/__tests__/tmux-session.test.js +61 -1
  94. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  95. package/dist/team/orchestrator.d.ts +1 -1
  96. package/dist/team/orchestrator.js +1 -1
  97. package/dist/team/runtime.d.ts.map +1 -1
  98. package/dist/team/runtime.js +14 -2
  99. package/dist/team/runtime.js.map +1 -1
  100. package/dist/team/state.d.ts +4 -0
  101. package/dist/team/state.d.ts.map +1 -1
  102. package/dist/team/state.js.map +1 -1
  103. package/dist/team/tmux-session.d.ts +14 -2
  104. package/dist/team/tmux-session.d.ts.map +1 -1
  105. package/dist/team/tmux-session.js +42 -6
  106. package/dist/team/tmux-session.js.map +1 -1
  107. package/dist/utils/__tests__/package.test.d.ts +2 -0
  108. package/dist/utils/__tests__/package.test.d.ts.map +1 -0
  109. package/dist/utils/__tests__/package.test.js +21 -0
  110. package/dist/utils/__tests__/package.test.js.map +1 -0
  111. package/dist/utils/__tests__/paths.test.d.ts +2 -0
  112. package/dist/utils/__tests__/paths.test.d.ts.map +1 -0
  113. package/dist/utils/__tests__/paths.test.js +117 -0
  114. package/dist/utils/__tests__/paths.test.js.map +1 -0
  115. package/dist/verification/__tests__/verifier.test.d.ts +2 -0
  116. package/dist/verification/__tests__/verifier.test.d.ts.map +1 -0
  117. package/dist/verification/__tests__/verifier.test.js +94 -0
  118. package/dist/verification/__tests__/verifier.test.js.map +1 -0
  119. package/package.json +1 -1
  120. package/scripts/notify-hook.js +164 -3
  121. package/templates/AGENTS.md +1 -1
@@ -0,0 +1,449 @@
1
+ import { describe, it, mock, afterEach } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { renderHud } from '../render.js';
4
+ const RESET = '\x1b[0m';
5
+ const DIM = '\x1b[2m';
6
+ const GREEN = '\x1b[32m';
7
+ const YELLOW = '\x1b[33m';
8
+ const CYAN = '\x1b[36m';
9
+ afterEach(() => {
10
+ mock.restoreAll();
11
+ });
12
+ function emptyCtx() {
13
+ return {
14
+ version: null,
15
+ gitBranch: null,
16
+ ralph: null,
17
+ ultrawork: null,
18
+ autopilot: null,
19
+ team: null,
20
+ ecomode: null,
21
+ pipeline: null,
22
+ metrics: null,
23
+ hudNotify: null,
24
+ session: null,
25
+ };
26
+ }
27
+ // ── Empty context ─────────────────────────────────────────────────────────────
28
+ describe('renderHud – empty context', () => {
29
+ it('shows "No active modes." when nothing is active', () => {
30
+ const result = renderHud(emptyCtx(), 'focused');
31
+ assert.ok(result.includes('No active modes.'));
32
+ });
33
+ it('includes the [OMX] label', () => {
34
+ const result = renderHud(emptyCtx(), 'focused');
35
+ assert.ok(result.includes('[OMX]'));
36
+ });
37
+ });
38
+ // ── Version ───────────────────────────────────────────────────────────────────
39
+ describe('renderHud – version', () => {
40
+ it('strips the "v" prefix from a semver version', () => {
41
+ const ctx = { ...emptyCtx(), version: 'v1.2.3' };
42
+ const result = renderHud(ctx, 'focused');
43
+ assert.ok(result.includes('[OMX#1.2.3]'));
44
+ });
45
+ it('keeps a plain version number as-is', () => {
46
+ const ctx = { ...emptyCtx(), version: '2.0.0' };
47
+ const result = renderHud(ctx, 'focused');
48
+ assert.ok(result.includes('[OMX#2.0.0]'));
49
+ });
50
+ it('omits hash suffix when version is null', () => {
51
+ const result = renderHud(emptyCtx(), 'focused');
52
+ assert.ok(result.includes('[OMX]'));
53
+ assert.ok(!result.includes('[OMX#'));
54
+ });
55
+ });
56
+ // ── Git branch ────────────────────────────────────────────────────────────────
57
+ describe('renderHud – gitBranch', () => {
58
+ it('renders the branch name wrapped in cyan', () => {
59
+ const ctx = { ...emptyCtx(), gitBranch: 'main' };
60
+ const result = renderHud(ctx, 'focused');
61
+ assert.ok(result.includes(`${CYAN}main${RESET}`));
62
+ });
63
+ it('omits the branch element when null', () => {
64
+ const result = renderHud(emptyCtx(), 'focused');
65
+ assert.ok(!result.includes('main'));
66
+ });
67
+ });
68
+ // ── Ralph ─────────────────────────────────────────────────────────────────────
69
+ describe('renderHud – ralph', () => {
70
+ it('renders ralph iteration info', () => {
71
+ const ctx = { ...emptyCtx(), ralph: { active: true, iteration: 3, max_iterations: 10 } };
72
+ const result = renderHud(ctx, 'focused');
73
+ assert.ok(result.includes('ralph:3/10'));
74
+ });
75
+ it('omits ralph when null', () => {
76
+ const result = renderHud(emptyCtx(), 'focused');
77
+ assert.ok(!result.includes('ralph'));
78
+ });
79
+ });
80
+ // ── Ultrawork ─────────────────────────────────────────────────────────────────
81
+ describe('renderHud – ultrawork', () => {
82
+ it('renders "ultrawork" in cyan', () => {
83
+ const ctx = { ...emptyCtx(), ultrawork: { active: true } };
84
+ const result = renderHud(ctx, 'focused');
85
+ assert.ok(result.includes(`${CYAN}ultrawork${RESET}`));
86
+ });
87
+ it('omits ultrawork when null', () => {
88
+ const result = renderHud(emptyCtx(), 'focused');
89
+ assert.ok(!result.includes('ultrawork'));
90
+ });
91
+ });
92
+ // ── Autopilot ─────────────────────────────────────────────────────────────────
93
+ describe('renderHud – autopilot', () => {
94
+ it('renders autopilot with the current phase', () => {
95
+ const ctx = { ...emptyCtx(), autopilot: { active: true, current_phase: 'planning' } };
96
+ const result = renderHud(ctx, 'focused');
97
+ assert.ok(result.includes(`${YELLOW}autopilot:planning${RESET}`));
98
+ });
99
+ it('defaults phase to "active" when not set', () => {
100
+ const ctx = { ...emptyCtx(), autopilot: { active: true } };
101
+ const result = renderHud(ctx, 'focused');
102
+ assert.ok(result.includes('autopilot:active'));
103
+ });
104
+ it('omits autopilot when null', () => {
105
+ const result = renderHud(emptyCtx(), 'focused');
106
+ assert.ok(!result.includes('autopilot'));
107
+ });
108
+ });
109
+ // ── Team ──────────────────────────────────────────────────────────────────────
110
+ describe('renderHud – team', () => {
111
+ it('renders agent count when count > 0', () => {
112
+ const ctx = { ...emptyCtx(), team: { active: true, agent_count: 3 } };
113
+ const result = renderHud(ctx, 'focused');
114
+ assert.ok(result.includes(`${GREEN}team:3 workers${RESET}`));
115
+ });
116
+ it('renders team name when count is absent', () => {
117
+ const ctx = { ...emptyCtx(), team: { active: true, team_name: 'my-team' } };
118
+ const result = renderHud(ctx, 'focused');
119
+ assert.ok(result.includes(`${GREEN}team:my-team${RESET}`));
120
+ });
121
+ it('renders bare "team" when neither count nor name is set', () => {
122
+ const ctx = { ...emptyCtx(), team: { active: true } };
123
+ const result = renderHud(ctx, 'focused');
124
+ assert.ok(result.includes(`${GREEN}team${RESET}`));
125
+ });
126
+ it('skips the count branch when agent_count is 0', () => {
127
+ const ctx = { ...emptyCtx(), team: { active: true, agent_count: 0 } };
128
+ const result = renderHud(ctx, 'focused');
129
+ assert.ok(!result.includes('workers'));
130
+ // Falls through to bare "team"
131
+ assert.ok(result.includes(`${GREEN}team${RESET}`));
132
+ });
133
+ it('omits team when null', () => {
134
+ const result = renderHud(emptyCtx(), 'focused');
135
+ assert.ok(!result.includes('team'));
136
+ });
137
+ });
138
+ // ── Ecomode ───────────────────────────────────────────────────────────────────
139
+ describe('renderHud – ecomode', () => {
140
+ it('renders "ecomode" as dim text', () => {
141
+ const ctx = { ...emptyCtx(), ecomode: { active: true } };
142
+ const result = renderHud(ctx, 'focused');
143
+ assert.ok(result.includes(`${DIM}ecomode${RESET}`));
144
+ });
145
+ it('omits ecomode when null', () => {
146
+ const result = renderHud(emptyCtx(), 'focused');
147
+ assert.ok(!result.includes('ecomode'));
148
+ });
149
+ });
150
+ // ── Pipeline ──────────────────────────────────────────────────────────────────
151
+ describe('renderHud – pipeline', () => {
152
+ it('renders pipeline with the current phase', () => {
153
+ const ctx = { ...emptyCtx(), pipeline: { active: true, current_phase: 'exec' } };
154
+ const result = renderHud(ctx, 'focused');
155
+ assert.ok(result.includes(`${CYAN}pipeline:exec${RESET}`));
156
+ });
157
+ it('defaults phase to "active" when not set', () => {
158
+ const ctx = { ...emptyCtx(), pipeline: { active: true } };
159
+ const result = renderHud(ctx, 'focused');
160
+ assert.ok(result.includes('pipeline:active'));
161
+ });
162
+ it('omits pipeline when null', () => {
163
+ const result = renderHud(emptyCtx(), 'focused');
164
+ assert.ok(!result.includes('pipeline'));
165
+ });
166
+ });
167
+ // ── Metrics – turns ───────────────────────────────────────────────────────────
168
+ describe('renderHud – metrics (turns)', () => {
169
+ it('renders session turn count', () => {
170
+ const ctx = {
171
+ ...emptyCtx(),
172
+ metrics: { total_turns: 100, session_turns: 5, last_activity: '' },
173
+ };
174
+ const result = renderHud(ctx, 'focused');
175
+ assert.ok(result.includes('turns:5'));
176
+ });
177
+ it('omits turns when metrics is null', () => {
178
+ const result = renderHud(emptyCtx(), 'focused');
179
+ assert.ok(!result.includes('turns'));
180
+ });
181
+ it('does not render stale metrics (last_activity before session start)', () => {
182
+ const ctx = {
183
+ ...emptyCtx(),
184
+ session: { session_id: 's1', started_at: '2024-06-01T10:00:00Z' },
185
+ metrics: {
186
+ total_turns: 50,
187
+ session_turns: 3,
188
+ last_activity: '2024-06-01T09:00:00Z', // before session start
189
+ },
190
+ };
191
+ const result = renderHud(ctx, 'focused');
192
+ assert.ok(!result.includes('turns:3'));
193
+ });
194
+ });
195
+ // ── Metrics – tokens ──────────────────────────────────────────────────────────
196
+ describe('renderHud – metrics (tokens)', () => {
197
+ it('renders session_total_tokens formatted as "k"', () => {
198
+ const ctx = {
199
+ ...emptyCtx(),
200
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '', session_total_tokens: 5000 },
201
+ };
202
+ const result = renderHud(ctx, 'focused');
203
+ assert.ok(result.includes('tokens:5.0k'));
204
+ });
205
+ it('sums input and output tokens when session_total_tokens is absent', () => {
206
+ const ctx = {
207
+ ...emptyCtx(),
208
+ metrics: {
209
+ total_turns: 10,
210
+ session_turns: 3,
211
+ last_activity: '',
212
+ session_input_tokens: 2000,
213
+ session_output_tokens: 3000,
214
+ },
215
+ };
216
+ const result = renderHud(ctx, 'focused');
217
+ assert.ok(result.includes('tokens:5.0k'));
218
+ });
219
+ it('formats values in millions', () => {
220
+ const ctx = {
221
+ ...emptyCtx(),
222
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '', session_total_tokens: 2_500_000 },
223
+ };
224
+ const result = renderHud(ctx, 'focused');
225
+ assert.ok(result.includes('tokens:2.5M'));
226
+ });
227
+ it('formats small values without suffix', () => {
228
+ const ctx = {
229
+ ...emptyCtx(),
230
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '', session_total_tokens: 500 },
231
+ };
232
+ const result = renderHud(ctx, 'focused');
233
+ assert.ok(result.includes('tokens:500'));
234
+ });
235
+ it('omits tokens when total is 0', () => {
236
+ const ctx = {
237
+ ...emptyCtx(),
238
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '', session_total_tokens: 0 },
239
+ };
240
+ const result = renderHud(ctx, 'focused');
241
+ assert.ok(!result.includes('tokens'));
242
+ });
243
+ });
244
+ // ── Metrics – quota ───────────────────────────────────────────────────────────
245
+ describe('renderHud – metrics (quota)', () => {
246
+ it('renders both 5-hour and weekly limits', () => {
247
+ const ctx = {
248
+ ...emptyCtx(),
249
+ metrics: {
250
+ total_turns: 10,
251
+ session_turns: 3,
252
+ last_activity: '',
253
+ five_hour_limit_pct: 42.7,
254
+ weekly_limit_pct: 15.3,
255
+ },
256
+ };
257
+ const result = renderHud(ctx, 'focused');
258
+ assert.ok(result.includes('quota:5h:43%,wk:15%'));
259
+ });
260
+ it('renders only 5-hour limit when weekly is absent', () => {
261
+ const ctx = {
262
+ ...emptyCtx(),
263
+ metrics: {
264
+ total_turns: 10,
265
+ session_turns: 3,
266
+ last_activity: '',
267
+ five_hour_limit_pct: 60,
268
+ },
269
+ };
270
+ const result = renderHud(ctx, 'focused');
271
+ assert.ok(result.includes('quota:5h:60%'));
272
+ assert.ok(!result.includes('wk:'));
273
+ });
274
+ it('omits quota when both limits are absent', () => {
275
+ const ctx = {
276
+ ...emptyCtx(),
277
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '' },
278
+ };
279
+ const result = renderHud(ctx, 'focused');
280
+ assert.ok(!result.includes('quota'));
281
+ });
282
+ it('omits quota when both limits are 0', () => {
283
+ const ctx = {
284
+ ...emptyCtx(),
285
+ metrics: {
286
+ total_turns: 10,
287
+ session_turns: 3,
288
+ last_activity: '',
289
+ five_hour_limit_pct: 0,
290
+ weekly_limit_pct: 0,
291
+ },
292
+ };
293
+ const result = renderHud(ctx, 'focused');
294
+ assert.ok(!result.includes('quota'));
295
+ });
296
+ });
297
+ // ── HudNotify – last activity ─────────────────────────────────────────────────
298
+ describe('renderHud – hudNotify (last activity)', () => {
299
+ it('renders last activity in seconds', () => {
300
+ const fixedNow = 1_700_000_030_000;
301
+ const lastTurnAt = new Date(fixedNow - 30_000).toISOString();
302
+ mock.method(Date, 'now', () => fixedNow);
303
+ const ctx = { ...emptyCtx(), hudNotify: { last_turn_at: lastTurnAt, turn_count: 5 } };
304
+ const result = renderHud(ctx, 'focused');
305
+ assert.ok(result.includes('last:30s ago'));
306
+ });
307
+ it('renders last activity in minutes', () => {
308
+ const fixedNow = 1_700_000_120_000;
309
+ const lastTurnAt = new Date(fixedNow - 120_000).toISOString();
310
+ mock.method(Date, 'now', () => fixedNow);
311
+ const ctx = { ...emptyCtx(), hudNotify: { last_turn_at: lastTurnAt, turn_count: 5 } };
312
+ const result = renderHud(ctx, 'focused');
313
+ assert.ok(result.includes('last:2m ago'));
314
+ });
315
+ it('omits last activity when hudNotify is null', () => {
316
+ const result = renderHud(emptyCtx(), 'focused');
317
+ assert.ok(!result.includes('last:'));
318
+ });
319
+ });
320
+ // ── Session duration ──────────────────────────────────────────────────────────
321
+ describe('renderHud – session duration', () => {
322
+ it('renders session duration in seconds', () => {
323
+ const fixedNow = 1_700_000_030_000;
324
+ const startedAt = new Date(fixedNow - 30_000).toISOString();
325
+ mock.method(Date, 'now', () => fixedNow);
326
+ const ctx = { ...emptyCtx(), session: { session_id: 's1', started_at: startedAt } };
327
+ const result = renderHud(ctx, 'focused');
328
+ assert.ok(result.includes('session:30s'));
329
+ });
330
+ it('renders session duration in minutes', () => {
331
+ const fixedNow = 1_700_000_300_000;
332
+ const startedAt = new Date(fixedNow - 300_000).toISOString(); // 5 minutes
333
+ mock.method(Date, 'now', () => fixedNow);
334
+ const ctx = { ...emptyCtx(), session: { session_id: 's1', started_at: startedAt } };
335
+ const result = renderHud(ctx, 'focused');
336
+ assert.ok(result.includes('session:5m'));
337
+ });
338
+ it('renders session duration in hours and minutes', () => {
339
+ const fixedNow = 1_700_010_920_000;
340
+ const startedAt = new Date(fixedNow - 7_320_000).toISOString(); // 2h 2m
341
+ mock.method(Date, 'now', () => fixedNow);
342
+ const ctx = { ...emptyCtx(), session: { session_id: 's1', started_at: startedAt } };
343
+ const result = renderHud(ctx, 'focused');
344
+ assert.ok(result.includes('session:2h2m'));
345
+ });
346
+ it('omits session duration when session is null', () => {
347
+ const result = renderHud(emptyCtx(), 'focused');
348
+ assert.ok(!result.includes('session:'));
349
+ });
350
+ });
351
+ // ── Total turns ───────────────────────────────────────────────────────────────
352
+ describe('renderHud – total turns (full preset)', () => {
353
+ it('renders total-turns in full preset', () => {
354
+ const ctx = {
355
+ ...emptyCtx(),
356
+ metrics: { total_turns: 200, session_turns: 5, last_activity: '' },
357
+ };
358
+ const result = renderHud(ctx, 'full');
359
+ assert.ok(result.includes('total-turns:200'));
360
+ });
361
+ it('omits total-turns in focused preset', () => {
362
+ const ctx = {
363
+ ...emptyCtx(),
364
+ metrics: { total_turns: 200, session_turns: 5, last_activity: '' },
365
+ };
366
+ const result = renderHud(ctx, 'focused');
367
+ assert.ok(!result.includes('total-turns'));
368
+ });
369
+ it('omits total-turns when total_turns is 0', () => {
370
+ const ctx = {
371
+ ...emptyCtx(),
372
+ metrics: { total_turns: 0, session_turns: 5, last_activity: '' },
373
+ };
374
+ const result = renderHud(ctx, 'full');
375
+ assert.ok(!result.includes('total-turns'));
376
+ });
377
+ });
378
+ // ── Presets ───────────────────────────────────────────────────────────────────
379
+ describe('renderHud – presets', () => {
380
+ it('minimal preset includes gitBranch, ralph, ultrawork, team, turns', () => {
381
+ const ctx = {
382
+ ...emptyCtx(),
383
+ gitBranch: 'feat/x',
384
+ ralph: { active: true, iteration: 1, max_iterations: 5 },
385
+ ultrawork: { active: true },
386
+ team: { active: true, agent_count: 2 },
387
+ metrics: { total_turns: 10, session_turns: 3, last_activity: '' },
388
+ };
389
+ const result = renderHud(ctx, 'minimal');
390
+ assert.ok(result.includes('feat/x'));
391
+ assert.ok(result.includes('ralph:1/5'));
392
+ assert.ok(result.includes('ultrawork'));
393
+ assert.ok(result.includes('workers'));
394
+ assert.ok(result.includes('turns:3'));
395
+ });
396
+ it('minimal preset excludes autopilot, ecomode, pipeline, quota', () => {
397
+ const ctx = {
398
+ ...emptyCtx(),
399
+ autopilot: { active: true, current_phase: 'exec' },
400
+ ecomode: { active: true },
401
+ pipeline: { active: true, current_phase: 'run' },
402
+ metrics: {
403
+ total_turns: 10,
404
+ session_turns: 3,
405
+ last_activity: '',
406
+ five_hour_limit_pct: 50,
407
+ },
408
+ };
409
+ const result = renderHud(ctx, 'minimal');
410
+ assert.ok(!result.includes('autopilot'));
411
+ assert.ok(!result.includes('ecomode'));
412
+ assert.ok(!result.includes('pipeline'));
413
+ assert.ok(!result.includes('quota'));
414
+ });
415
+ it('full preset includes all elements including total-turns', () => {
416
+ const ctx = {
417
+ ...emptyCtx(),
418
+ metrics: { total_turns: 99, session_turns: 5, last_activity: '' },
419
+ };
420
+ const result = renderHud(ctx, 'full');
421
+ assert.ok(result.includes('total-turns:99'));
422
+ });
423
+ it('focused preset is the default for unrecognised preset values', () => {
424
+ // TypeScript prevents invalid values, but we can test the focused default
425
+ const ctx = { ...emptyCtx(), ecomode: { active: true } };
426
+ // focused includes ecomode; minimal does not
427
+ assert.ok(renderHud(ctx, 'focused').includes('ecomode'));
428
+ assert.ok(!renderHud(ctx, 'minimal').includes('ecomode'));
429
+ });
430
+ });
431
+ // ── Separator ─────────────────────────────────────────────────────────────────
432
+ describe('renderHud – separator', () => {
433
+ it('joins multiple elements with a dim pipe separator', () => {
434
+ const ctx = {
435
+ ...emptyCtx(),
436
+ gitBranch: 'main',
437
+ ralph: { active: true, iteration: 2, max_iterations: 10 },
438
+ };
439
+ const result = renderHud(ctx, 'focused');
440
+ // SEP = dim(' | ') = '\x1b[2m | \x1b[0m'
441
+ assert.ok(result.includes(`${DIM} | ${RESET}`));
442
+ });
443
+ it('does not include the separator when only one element is present', () => {
444
+ const ctx = { ...emptyCtx(), gitBranch: 'solo' };
445
+ const result = renderHud(ctx, 'focused');
446
+ assert.ok(!result.includes(' | '));
447
+ });
448
+ });
449
+ //# sourceMappingURL=render.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.test.js","sourceRoot":"","sources":["../../../src/hud/__tests__/render.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../../src/hud/__tests__/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { DEFAULT_HUD_CONFIG } from '../types.js';
4
+ describe('DEFAULT_HUD_CONFIG', () => {
5
+ it('has preset set to "focused"', () => {
6
+ assert.equal(DEFAULT_HUD_CONFIG.preset, 'focused');
7
+ });
8
+ it('is an object with a preset property', () => {
9
+ assert.equal(typeof DEFAULT_HUD_CONFIG, 'object');
10
+ assert.ok('preset' in DEFAULT_HUD_CONFIG);
11
+ });
12
+ it('preset is a valid HudPreset value', () => {
13
+ const validPresets = ['minimal', 'focused', 'full'];
14
+ assert.ok(validPresets.includes(DEFAULT_HUD_CONFIG.preset));
15
+ });
16
+ });
17
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../../src/hud/__tests__/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,kBAAkB,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,kBAAkB,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- import { analyzePaneContent } from '../tmux-detector.js';
3
+ import { analyzePaneContent, buildSendPaneArgvs } from '../tmux-detector.js';
4
4
  describe('analyzePaneContent', () => {
5
5
  it('returns zero confidence for empty content', () => {
6
6
  const result = analyzePaneContent('');
@@ -74,4 +74,72 @@ describe('analyzePaneContent', () => {
74
74
  assert.ok(result.confidence > 0);
75
75
  });
76
76
  });
77
+ // issue #107: Enter/C-m must be sent in an isolated, separate send-keys call —
78
+ // never bundled with text — to prevent Shift+Enter injection.
79
+ describe('buildSendPaneArgvs', () => {
80
+ it('sends text with -l (literal) flag so key names in text are not interpreted', () => {
81
+ const argvs = buildSendPaneArgvs('%3', 'hello world', false);
82
+ const textArgv = argvs[0];
83
+ assert.ok(textArgv.includes('-l'), 'text argv must include -l flag');
84
+ assert.ok(textArgv.includes('hello world'), 'text argv must include the text');
85
+ });
86
+ it('uses -- separator so text starting with - is not parsed as a flag', () => {
87
+ const argvs = buildSendPaneArgvs('%3', '-flag-like', false);
88
+ const textArgv = argvs[0];
89
+ const sepIdx = textArgv.indexOf('--');
90
+ assert.ok(sepIdx !== -1, '-- separator must be present');
91
+ assert.equal(textArgv[sepIdx + 1], '-flag-like', 'text must come immediately after --');
92
+ });
93
+ it('sends Enter as an isolated separate argv — never bundled with text', () => {
94
+ const argvs = buildSendPaneArgvs('%3', 'hello', true);
95
+ assert.ok(argvs.length >= 2, 'must have at least text argv + one C-m argv');
96
+ // The text argv must NOT contain C-m
97
+ const textArgv = argvs[0];
98
+ assert.ok(!textArgv.includes('C-m'), 'text argv must not contain C-m');
99
+ // Submit argvs must NOT use -l (they are key names, not literal text)
100
+ for (const submitArgv of argvs.slice(1)) {
101
+ assert.ok(!submitArgv.includes('-l'), 'C-m argv must not use -l flag');
102
+ assert.ok(submitArgv.includes('C-m'), 'C-m argv must include C-m');
103
+ }
104
+ });
105
+ it('sends C-m twice when pressEnter is true', () => {
106
+ const argvs = buildSendPaneArgvs('%3', 'hello', true);
107
+ const submitArgvs = argvs.slice(1);
108
+ assert.equal(submitArgvs.length, 2, 'must send C-m exactly twice');
109
+ for (const argv of submitArgvs) {
110
+ assert.equal(argv[argv.length - 1], 'C-m');
111
+ }
112
+ });
113
+ it('omits C-m entirely when pressEnter is false', () => {
114
+ const argvs = buildSendPaneArgvs('%3', 'hello', false);
115
+ assert.equal(argvs.length, 1, 'must have only the text argv when pressEnter=false');
116
+ assert.ok(!argvs[0].includes('C-m'), 'no C-m when pressEnter=false');
117
+ });
118
+ it('strips newlines from text to prevent literal Enter injection via -l', () => {
119
+ const argvs = buildSendPaneArgvs('%3', 'line1\nline2\r\nline3', false);
120
+ const textArgv = argvs[0];
121
+ const text = textArgv[textArgv.length - 1];
122
+ assert.ok(!text.includes('\n'), 'newline must be stripped');
123
+ assert.ok(!text.includes('\r'), 'carriage return must be stripped');
124
+ assert.ok(text.includes('line1'), 'text content must be preserved');
125
+ });
126
+ it('targets the correct pane in every argv', () => {
127
+ const argvs = buildSendPaneArgvs('%42', 'hello', true);
128
+ for (const argv of argvs) {
129
+ const tIdx = argv.indexOf('-t');
130
+ assert.ok(tIdx !== -1, 'every argv must have -t flag');
131
+ assert.equal(argv[tIdx + 1], '%42', 'pane target must be %42');
132
+ }
133
+ });
134
+ it('matches the two-step pattern of buildSendKeysArgv from tmux-hook-engine', () => {
135
+ // Regression guard: the structure must be [typeArgv, submitArgv, submitArgv]
136
+ // consistent with the established pattern across the codebase.
137
+ const argvs = buildSendPaneArgvs('%5', 'continue', true);
138
+ assert.deepEqual(argvs, [
139
+ ['send-keys', '-t', '%5', '-l', '--', 'continue'],
140
+ ['send-keys', '-t', '%5', 'C-m'],
141
+ ['send-keys', '-t', '%5', 'C-m'],
142
+ ]);
143
+ });
144
+ });
77
145
  //# sourceMappingURL=tmux-detector.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tmux-detector.test.js","sourceRoot":"","sources":["../../../src/notifications/__tests__/tmux-detector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;QAC5D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACrD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,MAAM,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,kBAAkB,CAAC,4BAA4B,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,kBAAkB,CAAC,4BAA4B,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,2BAA2B,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,kBAAkB,CAAC,6BAA6B,CAAC,CAAC;QACjE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;QAC1D,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,kBAAkB,CAAC,+BAA+B,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,wDAAwD;QACxD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,EAAE,mCAAmC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,MAAM,GAAG,kBAAkB,CAAC,kCAAkC,CAAC,CAAC;QACtE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"tmux-detector.test.js","sourceRoot":"","sources":["../../../src/notifications/__tests__/tmux-detector.test.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  * Security considerations:
8
8
  * - State/PID/log files use restrictive permissions (0600)
9
9
  * - Bot tokens stored in state file, NOT in environment variables
10
- * - Two-layer input sanitization (sanitizeReplyInput + sanitizeForTmux)
10
+ * - Two-layer input sanitization (sanitizeReplyInput + newline stripping in buildSendPaneArgvs)
11
11
  * - Pane verification via analyzePaneContent before every injection
12
12
  * - Authorization: only configured user IDs (Discord) / chat ID (Telegram) can inject
13
13
  * - Rate limiting to prevent spam/abuse
@@ -7,7 +7,7 @@
7
7
  * Security considerations:
8
8
  * - State/PID/log files use restrictive permissions (0600)
9
9
  * - Bot tokens stored in state file, NOT in environment variables
10
- * - Two-layer input sanitization (sanitizeReplyInput + sanitizeForTmux)
10
+ * - Two-layer input sanitization (sanitizeReplyInput + newline stripping in buildSendPaneArgvs)
11
11
  * - Pane verification via analyzePaneContent before every injection
12
12
  * - Authorization: only configured user IDs (Discord) / chat ID (Telegram) can inject
13
13
  * - Rate limiting to prevent spam/abuse