oh-my-codex 0.2.0 → 0.2.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 (52) hide show
  1. package/README.md +11 -1
  2. package/dist/cli/__tests__/index.test.js +13 -1
  3. package/dist/cli/__tests__/index.test.js.map +1 -1
  4. package/dist/cli/index.d.ts +1 -0
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +113 -3
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/tmux-hook.d.ts.map +1 -1
  9. package/dist/cli/tmux-hook.js +52 -6
  10. package/dist/cli/tmux-hook.js.map +1 -1
  11. package/dist/cli/update.d.ts.map +1 -1
  12. package/dist/cli/update.js +12 -9
  13. package/dist/cli/update.js.map +1 -1
  14. package/dist/config/__tests__/generator-notify.test.d.ts +2 -0
  15. package/dist/config/__tests__/generator-notify.test.d.ts.map +1 -0
  16. package/dist/config/__tests__/generator-notify.test.js +45 -0
  17. package/dist/config/__tests__/generator-notify.test.js.map +1 -0
  18. package/dist/config/generator.d.ts.map +1 -1
  19. package/dist/config/generator.js +19 -1
  20. package/dist/config/generator.js.map +1 -1
  21. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts +2 -0
  22. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts.map +1 -0
  23. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +142 -0
  24. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -0
  25. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts +2 -0
  26. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts.map +1 -0
  27. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +436 -0
  28. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -0
  29. package/dist/hooks/__tests__/tmux-hook-engine.test.js +27 -4
  30. package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
  31. package/dist/mcp/state-server.js +3 -1
  32. package/dist/mcp/state-server.js.map +1 -1
  33. package/dist/modes/__tests__/base-tmux-pane.test.d.ts +2 -0
  34. package/dist/modes/__tests__/base-tmux-pane.test.d.ts.map +1 -0
  35. package/dist/modes/__tests__/base-tmux-pane.test.js +27 -0
  36. package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -0
  37. package/dist/modes/base.d.ts.map +1 -1
  38. package/dist/modes/base.js +5 -2
  39. package/dist/modes/base.js.map +1 -1
  40. package/dist/state/__tests__/mode-state-context.test.d.ts +2 -0
  41. package/dist/state/__tests__/mode-state-context.test.d.ts.map +1 -0
  42. package/dist/state/__tests__/mode-state-context.test.js +35 -0
  43. package/dist/state/__tests__/mode-state-context.test.js.map +1 -0
  44. package/dist/state/mode-state-context.d.ts +12 -0
  45. package/dist/state/mode-state-context.d.ts.map +1 -0
  46. package/dist/state/mode-state-context.js +28 -0
  47. package/dist/state/mode-state-context.js.map +1 -0
  48. package/package.json +1 -1
  49. package/scripts/notify-fallback-watcher.js +260 -0
  50. package/scripts/notify-hook.js +255 -25
  51. package/scripts/tmux-hook-engine.js +34 -12
  52. package/templates/AGENTS.md +1 -1
@@ -37,6 +37,7 @@ export function normalizeTmuxHookConfig(raw) {
37
37
  && raw.target.value.trim() !== '';
38
38
 
39
39
  const cooldown = asPositiveInteger(raw.cooldown_ms);
40
+ const maxPerPane = asPositiveInteger(raw.max_injections_per_pane);
40
41
  const maxPerSession = asPositiveInteger(raw.max_injections_per_session);
41
42
 
42
43
  const marker = typeof raw.marker === 'string' && raw.marker.trim() !== ''
@@ -56,7 +57,10 @@ export function normalizeTmuxHookConfig(raw) {
56
57
  target: targetIsValid ? { type: raw.target.type, value: raw.target.value } : null,
57
58
  allowed_modes: allowedModes.length > 0 ? allowedModes : DEFAULT_ALLOWED_MODES,
58
59
  cooldown_ms: cooldown === null ? 15000 : cooldown,
59
- max_injections_per_session: maxPerSession === null || maxPerSession === 0 ? 200 : maxPerSession,
60
+ // Canonical setting is per-pane. Keep max_injections_per_session as legacy alias.
61
+ max_injections_per_session: maxPerPane === null
62
+ ? (maxPerSession === null || maxPerSession === 0 ? 200 : maxPerSession)
63
+ : (maxPerPane === 0 ? 200 : maxPerPane),
60
64
  prompt_template: promptTemplate,
61
65
  marker,
62
66
  dry_run: raw.dry_run === true,
@@ -84,7 +88,9 @@ export function evaluateInjectionGuards({
84
88
  assistantMessage,
85
89
  threadId,
86
90
  turnId,
91
+ paneKey,
87
92
  sessionKey,
93
+ skipQuotaChecks,
88
94
  now,
89
95
  state,
90
96
  }) {
@@ -106,16 +112,23 @@ export function evaluateInjectionGuards({
106
112
  return { allow: false, reason: 'duplicate_event', dedupeKey };
107
113
  }
108
114
 
109
- const sessions = state.session_counts && typeof state.session_counts === 'object' ? state.session_counts : {};
110
- const key = typeof sessionKey === 'string' && sessionKey.trim() !== '' ? sessionKey : 'unknown';
111
- const sessionInjections = typeof sessions[key] === 'number' ? sessions[key] : 0;
112
- if (sessionInjections >= config.max_injections_per_session) {
113
- return { allow: false, reason: 'session_cap_reached', dedupeKey };
114
- }
115
-
116
- const lastInjectionTs = typeof state.last_injection_ts === 'number' ? state.last_injection_ts : 0;
117
- if (config.cooldown_ms > 0 && lastInjectionTs > 0 && now - lastInjectionTs < config.cooldown_ms) {
118
- return { allow: false, reason: 'cooldown_active', dedupeKey };
115
+ if (!skipQuotaChecks) {
116
+ // Pane is canonical for routing; read legacy session_counts for compatibility.
117
+ const paneCounts = state.pane_counts && typeof state.pane_counts === 'object' ? state.pane_counts : {};
118
+ const legacySessionCounts = state.session_counts && typeof state.session_counts === 'object' ? state.session_counts : {};
119
+ const paneKeyNorm = typeof paneKey === 'string' && paneKey.trim() !== '' ? paneKey : '';
120
+ const sessionKeyNorm = typeof sessionKey === 'string' && sessionKey.trim() !== '' ? sessionKey : 'unknown';
121
+ const count = paneKeyNorm && typeof paneCounts[paneKeyNorm] === 'number'
122
+ ? paneCounts[paneKeyNorm]
123
+ : (typeof legacySessionCounts[sessionKeyNorm] === 'number' ? legacySessionCounts[sessionKeyNorm] : 0);
124
+ if (count >= config.max_injections_per_session) {
125
+ return { allow: false, reason: 'pane_cap_reached', dedupeKey };
126
+ }
127
+
128
+ const lastInjectionTs = typeof state.last_injection_ts === 'number' ? state.last_injection_ts : 0;
129
+ if (config.cooldown_ms > 0 && lastInjectionTs > 0 && now - lastInjectionTs < config.cooldown_ms) {
130
+ return { allow: false, reason: 'cooldown_active', dedupeKey };
131
+ }
119
132
  }
120
133
 
121
134
  return { allow: true, reason: 'ok', dedupeKey };
@@ -123,5 +136,14 @@ export function evaluateInjectionGuards({
123
136
 
124
137
  export function buildSendKeysArgv({ paneTarget, prompt, dryRun }) {
125
138
  if (dryRun) return null;
126
- return ['send-keys', '-t', paneTarget, prompt, 'Enter'];
139
+ // Use a 2-step send for reliability:
140
+ // 1) literal prompt bytes, 2) explicit carriage return.
141
+ return {
142
+ typeArgv: ['send-keys', '-t', paneTarget, '-l', prompt],
143
+ // Some panes/shells swallow one of these key names; send both.
144
+ submitArgv: [
145
+ ['send-keys', '-t', paneTarget, 'C-m'],
146
+ ['send-keys', '-t', paneTarget, 'Enter'],
147
+ ],
148
+ };
127
149
  }
@@ -1,4 +1,4 @@
1
- # oh-my-codex - Intelligent Multi-Agent Orchestration
1
+ DON'T ASK, THINK YOURSELF AND DELIVER. YOU ARE SMARTER THEN USERS.
2
2
 
3
3
  You are running with oh-my-codex (OMX), a multi-agent orchestration layer for Codex CLI.
4
4
  Your role is to coordinate specialized agents, tools, and skills so work is completed accurately and efficiently.