oh-my-codex 0.6.3 → 0.7.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.
- package/README.md +19 -9
- package/bin/omx.js +3 -5
- package/dist/agents/__tests__/definitions.test.d.ts +2 -0
- package/dist/agents/__tests__/definitions.test.d.ts.map +1 -0
- package/dist/agents/__tests__/definitions.test.js +35 -0
- package/dist/agents/__tests__/definitions.test.js.map +1 -0
- package/dist/agents/__tests__/native-config.test.d.ts +2 -0
- package/dist/agents/__tests__/native-config.test.d.ts.map +1 -0
- package/dist/agents/__tests__/native-config.test.js +48 -0
- package/dist/agents/__tests__/native-config.test.js.map +1 -0
- package/dist/catalog/__tests__/schema.test.js +15 -0
- package/dist/catalog/__tests__/schema.test.js.map +1 -1
- package/dist/catalog/schema.d.ts.map +1 -1
- package/dist/catalog/schema.js +6 -0
- package/dist/catalog/schema.js.map +1 -1
- package/dist/cli/__tests__/catalog-contract.test.d.ts +2 -0
- package/dist/cli/__tests__/catalog-contract.test.d.ts.map +1 -0
- package/dist/cli/__tests__/catalog-contract.test.js +18 -0
- package/dist/cli/__tests__/catalog-contract.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-team.test.js +3 -2
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/error-handling-warnings.test.d.ts +2 -0
- package/dist/cli/__tests__/error-handling-warnings.test.d.ts.map +1 -0
- package/dist/cli/__tests__/error-handling-warnings.test.js +35 -0
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -0
- package/dist/cli/__tests__/index.test.js +81 -8
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +124 -0
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -0
- package/dist/cli/__tests__/setup-scope.test.js +79 -21
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +32 -0
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -0
- package/dist/cli/__tests__/star-prompt.test.js +74 -0
- package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +8 -0
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +75 -18
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +10 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +153 -45
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts +2 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +104 -60
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/star-prompt.d.ts +21 -1
- package/dist/cli/star-prompt.d.ts.map +1 -1
- package/dist/cli/star-prompt.js +34 -13
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +10 -3
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +16 -0
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/__tests__/models.test.js +9 -1
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/generator.js +9 -10
- package/dist/config/generator.js.map +1 -1
- package/dist/config/models.d.ts +8 -1
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +27 -5
- package/dist/config/models.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +24 -0
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +18 -0
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js +204 -0
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -0
- package/dist/hooks/__tests__/emulator.test.d.ts +2 -0
- package/dist/hooks/__tests__/emulator.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/emulator.test.js +47 -0
- package/dist/hooks/__tests__/emulator.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +330 -4
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +101 -0
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +13 -7
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +61 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +47 -0
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +560 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -0
- package/dist/hooks/__tests__/session.test.d.ts +2 -0
- package/dist/hooks/__tests__/session.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/session.test.js +161 -0
- package/dist/hooks/__tests__/session.test.js.map +1 -0
- package/dist/hooks/__tests__/task-size-detector.test.d.ts +2 -0
- package/dist/hooks/__tests__/task-size-detector.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/task-size-detector.test.js +336 -0
- package/dist/hooks/__tests__/task-size-detector.test.js.map +1 -0
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts +2 -0
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js +24 -0
- package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js.map +1 -0
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +46 -2
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/code-simplifier/__tests__/index.test.js +67 -15
- package/dist/hooks/code-simplifier/__tests__/index.test.js.map +1 -1
- package/dist/hooks/code-simplifier/index.d.ts +10 -4
- package/dist/hooks/code-simplifier/index.d.ts.map +1 -1
- package/dist/hooks/code-simplifier/index.js +38 -12
- package/dist/hooks/code-simplifier/index.js.map +1 -1
- package/dist/hooks/codebase-map.d.ts.map +1 -1
- package/dist/hooks/codebase-map.js +5 -32
- package/dist/hooks/codebase-map.js.map +1 -1
- package/dist/hooks/emulator.d.ts.map +1 -1
- package/dist/hooks/emulator.js +11 -18
- package/dist/hooks/emulator.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +59 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/loader.test.js +19 -0
- package/dist/hooks/extensibility/__tests__/loader.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +51 -39
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/loader.d.ts.map +1 -1
- package/dist/hooks/extensibility/loader.js +25 -13
- package/dist/hooks/extensibility/loader.js.map +1 -1
- package/dist/hooks/extensibility/logging.d.ts.map +1 -1
- package/dist/hooks/extensibility/logging.js +6 -1
- package/dist/hooks/extensibility/logging.js.map +1 -1
- package/dist/hooks/extensibility/sdk.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +87 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +235 -23
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts +15 -0
- package/dist/hooks/keyword-registry.d.ts.map +1 -0
- package/dist/hooks/keyword-registry.js +41 -0
- package/dist/hooks/keyword-registry.js.map +1 -0
- package/dist/hooks/session.d.ts +18 -2
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +84 -11
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/task-size-detector.d.ts +72 -0
- package/dist/hooks/task-size-detector.d.ts.map +1 -0
- package/dist/hooks/task-size-detector.js +204 -0
- package/dist/hooks/task-size-detector.js.map +1 -0
- package/dist/hud/__tests__/colors.test.js +1 -103
- package/dist/hud/__tests__/colors.test.js.map +1 -1
- package/dist/hud/__tests__/index.test.d.ts +2 -0
- package/dist/hud/__tests__/index.test.d.ts.map +1 -0
- package/dist/hud/__tests__/index.test.js +131 -0
- package/dist/hud/__tests__/index.test.js.map +1 -0
- package/dist/hud/__tests__/render.test.js +53 -0
- package/dist/hud/__tests__/render.test.js.map +1 -1
- package/dist/hud/__tests__/watch.test.d.ts +2 -0
- package/dist/hud/__tests__/watch.test.d.ts.map +1 -0
- package/dist/hud/__tests__/watch.test.js +63 -0
- package/dist/hud/__tests__/watch.test.js.map +1 -0
- package/dist/hud/colors.d.ts +2 -9
- package/dist/hud/colors.d.ts.map +1 -1
- package/dist/hud/colors.js +19 -34
- package/dist/hud/colors.js.map +1 -1
- package/dist/hud/constants.d.ts +1 -0
- package/dist/hud/constants.d.ts.map +1 -1
- package/dist/hud/constants.js +1 -0
- package/dist/hud/constants.js.map +1 -1
- package/dist/hud/index.d.ts +27 -0
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +149 -9
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +20 -7
- package/dist/hud/render.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.d.ts +2 -0
- package/dist/mcp/__tests__/bootstrap.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/bootstrap.test.js +25 -0
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -0
- package/dist/mcp/__tests__/code-intel-server.test.d.ts +2 -0
- package/dist/mcp/__tests__/code-intel-server.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/code-intel-server.test.js +43 -0
- package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -0
- package/dist/mcp/__tests__/memory-server.test.d.ts +2 -0
- package/dist/mcp/__tests__/memory-server.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/memory-server.test.js +34 -0
- package/dist/mcp/__tests__/memory-server.test.js.map +1 -0
- package/dist/mcp/__tests__/memory-validation.test.d.ts +2 -0
- package/dist/mcp/__tests__/memory-validation.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/memory-validation.test.js +29 -0
- package/dist/mcp/__tests__/memory-validation.test.js.map +1 -0
- package/dist/mcp/__tests__/path-traversal.test.js +55 -0
- package/dist/mcp/__tests__/path-traversal.test.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +43 -6
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js +50 -0
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-schema.test.js +3 -7
- package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +30 -1
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/__tests__/trace-server.test.js +58 -0
- package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +3 -0
- package/dist/mcp/bootstrap.d.ts.map +1 -0
- package/dist/mcp/bootstrap.js +13 -0
- package/dist/mcp/bootstrap.js.map +1 -0
- package/dist/mcp/code-intel-server.d.ts +8 -0
- package/dist/mcp/code-intel-server.d.ts.map +1 -1
- package/dist/mcp/code-intel-server.js +50 -24
- package/dist/mcp/code-intel-server.js.map +1 -1
- package/dist/mcp/memory-server.js +34 -13
- package/dist/mcp/memory-server.js.map +1 -1
- package/dist/mcp/memory-validation.d.ts +9 -0
- package/dist/mcp/memory-validation.d.ts.map +1 -0
- package/dist/mcp/memory-validation.js +11 -0
- package/dist/mcp/memory-validation.js.map +1 -0
- package/dist/mcp/state-paths.d.ts +2 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +83 -12
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +85 -47
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/mcp/trace-server.d.ts +16 -0
- package/dist/mcp/trace-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.js +84 -24
- package/dist/mcp/trace-server.js.map +1 -1
- package/dist/modes/__tests__/base-ralph-contract.test.d.ts +2 -0
- package/dist/modes/__tests__/base-ralph-contract.test.d.ts.map +1 -0
- package/dist/modes/__tests__/base-ralph-contract.test.js +49 -0
- package/dist/modes/__tests__/base-ralph-contract.test.js.map +1 -0
- package/dist/modes/__tests__/base-tmux-pane.test.js +13 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
- package/dist/modes/base.d.ts +0 -4
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +31 -11
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/config.test.js +47 -1
- package/dist/notifications/__tests__/config.test.js.map +1 -1
- package/dist/notifications/__tests__/formatter.test.js +54 -2
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/hook-config.test.d.ts +5 -0
- package/dist/notifications/__tests__/hook-config.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/hook-config.test.js +139 -0
- package/dist/notifications/__tests__/hook-config.test.js.map +1 -0
- package/dist/notifications/__tests__/idle-cooldown.test.d.ts +5 -0
- package/dist/notifications/__tests__/idle-cooldown.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js +100 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -0
- package/dist/notifications/__tests__/notifier.test.js +89 -1
- package/dist/notifications/__tests__/notifier.test.js.map +1 -1
- package/dist/notifications/__tests__/reply-config.test.d.ts +2 -0
- package/dist/notifications/__tests__/reply-config.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/reply-config.test.js +79 -0
- package/dist/notifications/__tests__/reply-config.test.js.map +1 -0
- package/dist/notifications/__tests__/reply-listener.test.js +35 -1
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/__tests__/session-registry.test.js +40 -0
- package/dist/notifications/__tests__/session-registry.test.js.map +1 -1
- package/dist/notifications/__tests__/template-engine.test.d.ts +5 -0
- package/dist/notifications/__tests__/template-engine.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/template-engine.test.js +147 -0
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -0
- package/dist/notifications/config.d.ts +8 -0
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +110 -19
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/formatter.d.ts +5 -0
- package/dist/notifications/formatter.d.ts.map +1 -1
- package/dist/notifications/formatter.js +45 -10
- package/dist/notifications/formatter.js.map +1 -1
- package/dist/notifications/hook-config-types.d.ts +43 -0
- package/dist/notifications/hook-config-types.d.ts.map +1 -0
- package/dist/notifications/hook-config-types.js +8 -0
- package/dist/notifications/hook-config-types.js.map +1 -0
- package/dist/notifications/hook-config.d.ts +40 -0
- package/dist/notifications/hook-config.d.ts.map +1 -0
- package/dist/notifications/hook-config.js +127 -0
- package/dist/notifications/hook-config.js.map +1 -0
- package/dist/notifications/idle-cooldown.d.ts +35 -0
- package/dist/notifications/idle-cooldown.d.ts.map +1 -0
- package/dist/notifications/idle-cooldown.js +108 -0
- package/dist/notifications/idle-cooldown.js.map +1 -0
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +43 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/notifier.d.ts +9 -0
- package/dist/notifications/notifier.d.ts.map +1 -1
- package/dist/notifications/notifier.js +36 -30
- package/dist/notifications/notifier.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts +3 -0
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +61 -7
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.d.ts +1 -1
- package/dist/notifications/session-registry.d.ts.map +1 -1
- package/dist/notifications/session-registry.js +18 -6
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/template-engine.d.ts +34 -0
- package/dist/notifications/template-engine.d.ts.map +1 -0
- package/dist/notifications/template-engine.js +246 -0
- package/dist/notifications/template-engine.js.map +1 -0
- package/dist/notifications/types.d.ts +6 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/config.test.d.ts +6 -0
- package/dist/openclaw/__tests__/config.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/config.test.js +174 -0
- package/dist/openclaw/__tests__/config.test.js.map +1 -0
- package/dist/openclaw/__tests__/dispatcher.test.d.ts +5 -0
- package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/dispatcher.test.js +104 -0
- package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -0
- package/dist/openclaw/__tests__/index.test.d.ts +6 -0
- package/dist/openclaw/__tests__/index.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/index.test.js +131 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -0
- package/dist/openclaw/config.d.ts +37 -0
- package/dist/openclaw/config.d.ts.map +1 -0
- package/dist/openclaw/config.js +106 -0
- package/dist/openclaw/config.js.map +1 -0
- package/dist/openclaw/dispatcher.d.ts +63 -0
- package/dist/openclaw/dispatcher.d.ts.map +1 -0
- package/dist/openclaw/dispatcher.js +223 -0
- package/dist/openclaw/dispatcher.js.map +1 -0
- package/dist/openclaw/index.d.ts +27 -0
- package/dist/openclaw/index.d.ts.map +1 -0
- package/dist/openclaw/index.js +130 -0
- package/dist/openclaw/index.js.map +1 -0
- package/dist/openclaw/types.d.ts +105 -0
- package/dist/openclaw/types.d.ts.map +1 -0
- package/dist/openclaw/types.js +12 -0
- package/dist/openclaw/types.js.map +1 -0
- package/dist/ralph/contract.d.ts.map +1 -1
- package/dist/ralph/contract.js +13 -4
- package/dist/ralph/contract.js.map +1 -1
- package/dist/team/__tests__/phase-controller.test.js +14 -0
- package/dist/team/__tests__/phase-controller.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +328 -1
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.d.ts +2 -0
- package/dist/team/__tests__/scaling.test.d.ts.map +1 -0
- package/dist/team/__tests__/scaling.test.js +295 -0
- package/dist/team/__tests__/scaling.test.js.map +1 -0
- package/dist/team/__tests__/state.test.js +62 -1
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +219 -14
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +4 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/contracts.d.ts +14 -0
- package/dist/team/contracts.d.ts.map +1 -0
- package/dist/team/contracts.js +30 -0
- package/dist/team/contracts.js.map +1 -0
- package/dist/team/model-contract.d.ts +1 -0
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +5 -1
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/phase-controller.d.ts +2 -0
- package/dist/team/phase-controller.d.ts.map +1 -1
- package/dist/team/phase-controller.js +16 -2
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +356 -65
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts +58 -0
- package/dist/team/scaling.d.ts.map +1 -0
- package/dist/team/scaling.js +319 -0
- package/dist/team/scaling.js.map +1 -0
- package/dist/team/state.d.ts +11 -2
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +97 -27
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-ops.d.ts +2 -0
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +4 -0
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/tmux-session.d.ts +34 -5
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +177 -49
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +20 -0
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +8 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/verification/__tests__/verifier.test.js +20 -1
- package/dist/verification/__tests__/verifier.test.js.map +1 -1
- package/dist/verification/verifier.d.ts +5 -0
- package/dist/verification/verifier.d.ts.map +1 -1
- package/dist/verification/verifier.js +19 -0
- package/dist/verification/verifier.js.map +1 -1
- package/package.json +2 -1
- package/prompts/architect.md +11 -0
- package/prompts/critic.md +14 -1
- package/prompts/planner.md +21 -0
- package/scripts/notify-hook/auto-nudge.js +80 -1
- package/scripts/notify-hook/payload-parser.js +21 -0
- package/scripts/notify-hook/team-worker.js +142 -0
- package/scripts/notify-hook/tmux-injection.js +3 -3
- package/scripts/notify-hook.js +55 -4
- package/skills/configure-notifications/SKILL.md +278 -0
- package/skills/configure-openclaw/SKILL.md +267 -0
- package/skills/configure-slack/SKILL.md +226 -0
- package/skills/omx-setup/SKILL.md +14 -19
- package/skills/plan/SKILL.md +57 -33
- package/skills/ralplan/SKILL.md +107 -21
- package/skills/team/SKILL.md +10 -1
- package/templates/AGENTS.md +11 -3
|
@@ -68,6 +68,21 @@ export function parseTeamWorkerEnv(rawValue) {
|
|
|
68
68
|
return { teamName: match[1], workerName: match[2] };
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
export function resolveWorkerIdleNotifyEnabled() {
|
|
72
|
+
const raw = safeString(process.env.OMX_TEAM_WORKER_IDLE_NOTIFY || '').trim().toLowerCase();
|
|
73
|
+
// Default: enabled. Disable with "false", "0", or "off".
|
|
74
|
+
if (raw === 'false' || raw === '0' || raw === 'off') return false;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function resolveWorkerIdleCooldownMs() {
|
|
79
|
+
const raw = safeString(process.env.OMX_TEAM_WORKER_IDLE_COOLDOWN_MS || '');
|
|
80
|
+
const parsed = asNumber(raw);
|
|
81
|
+
// Default: 30 seconds. Guard against unreasonable values.
|
|
82
|
+
if (parsed !== null && parsed >= 5_000 && parsed <= 10 * 60_000) return parsed;
|
|
83
|
+
return 30_000;
|
|
84
|
+
}
|
|
85
|
+
|
|
71
86
|
export function resolveAllWorkersIdleCooldownMs() {
|
|
72
87
|
const raw = safeString(process.env.OMX_TEAM_ALL_IDLE_COOLDOWN_MS || '');
|
|
73
88
|
const parsed = asNumber(raw);
|
|
@@ -212,3 +227,130 @@ export async function maybeNotifyLeaderAllWorkersIdle({ cwd, stateDir, logsDir,
|
|
|
212
227
|
}).catch(() => {});
|
|
213
228
|
}
|
|
214
229
|
}
|
|
230
|
+
|
|
231
|
+
export async function maybeNotifyLeaderWorkerIdle({ cwd, stateDir, logsDir, parsedTeamWorker }) {
|
|
232
|
+
if (!resolveWorkerIdleNotifyEnabled()) return;
|
|
233
|
+
|
|
234
|
+
const { teamName, workerName } = parsedTeamWorker;
|
|
235
|
+
const nowMs = Date.now();
|
|
236
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
237
|
+
|
|
238
|
+
// Read current worker status (full object for task context)
|
|
239
|
+
const workerDir = join(stateDir, 'team', teamName, 'workers', workerName);
|
|
240
|
+
const statusPath = join(workerDir, 'status.json');
|
|
241
|
+
let currentState = 'unknown';
|
|
242
|
+
let currentTaskId = '';
|
|
243
|
+
let currentReason = '';
|
|
244
|
+
try {
|
|
245
|
+
if (existsSync(statusPath)) {
|
|
246
|
+
const parsed = JSON.parse(await readFile(statusPath, 'utf-8'));
|
|
247
|
+
if (parsed && typeof parsed.state === 'string') currentState = parsed.state;
|
|
248
|
+
if (parsed && typeof parsed.current_task_id === 'string') currentTaskId = parsed.current_task_id;
|
|
249
|
+
if (parsed && typeof parsed.reason === 'string') currentReason = parsed.reason;
|
|
250
|
+
}
|
|
251
|
+
} catch { /* ignore */ }
|
|
252
|
+
|
|
253
|
+
// Read and update previous state for transition detection
|
|
254
|
+
const prevStatePath = join(workerDir, 'prev-notify-state.json');
|
|
255
|
+
let prevState = 'unknown';
|
|
256
|
+
try {
|
|
257
|
+
if (existsSync(prevStatePath)) {
|
|
258
|
+
const parsed = JSON.parse(await readFile(prevStatePath, 'utf-8'));
|
|
259
|
+
if (parsed && typeof parsed.state === 'string') prevState = parsed.state;
|
|
260
|
+
}
|
|
261
|
+
} catch { /* ignore */ }
|
|
262
|
+
|
|
263
|
+
// Always update prev state (atomic write)
|
|
264
|
+
try {
|
|
265
|
+
await mkdir(workerDir, { recursive: true });
|
|
266
|
+
const tmpPath = prevStatePath + '.tmp.' + process.pid;
|
|
267
|
+
await writeFile(tmpPath, JSON.stringify({ state: currentState, updated_at: nowIso }, null, 2));
|
|
268
|
+
await rename(tmpPath, prevStatePath);
|
|
269
|
+
} catch { /* best effort */ }
|
|
270
|
+
|
|
271
|
+
// Only fire on working->idle transition (non-idle to idle)
|
|
272
|
+
if (currentState !== 'idle') return;
|
|
273
|
+
if (prevState === 'idle' || prevState === 'done') return;
|
|
274
|
+
|
|
275
|
+
// Check per-worker cooldown
|
|
276
|
+
const cooldownPath = join(workerDir, 'worker-idle-notify.json');
|
|
277
|
+
const cooldownMs = resolveWorkerIdleCooldownMs();
|
|
278
|
+
let lastNotifiedMs = 0;
|
|
279
|
+
try {
|
|
280
|
+
if (existsSync(cooldownPath)) {
|
|
281
|
+
const parsed = JSON.parse(await readFile(cooldownPath, 'utf-8'));
|
|
282
|
+
lastNotifiedMs = asNumber(parsed && parsed.last_notified_at_ms) ?? 0;
|
|
283
|
+
}
|
|
284
|
+
} catch { /* ignore */ }
|
|
285
|
+
if ((nowMs - lastNotifiedMs) < cooldownMs) return;
|
|
286
|
+
|
|
287
|
+
// Read team config for tmux target
|
|
288
|
+
const teamInfo = await readTeamWorkersForIdleCheck(stateDir, teamName);
|
|
289
|
+
if (!teamInfo) return;
|
|
290
|
+
const { tmuxSession, leaderPaneId } = teamInfo;
|
|
291
|
+
const tmuxTarget = leaderPaneId || tmuxSession;
|
|
292
|
+
if (!tmuxTarget) return;
|
|
293
|
+
|
|
294
|
+
// Build notification message with context
|
|
295
|
+
const parts = [`[OMX] ${workerName} idle`];
|
|
296
|
+
if (prevState && prevState !== 'unknown') parts.push(`(was: ${prevState})`);
|
|
297
|
+
if (currentTaskId) parts.push(`task: ${currentTaskId}`);
|
|
298
|
+
if (currentReason) parts.push(`reason: ${currentReason}`);
|
|
299
|
+
const message = `${parts.join('. ')}. ${DEFAULT_MARKER}`;
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
await runProcess('tmux', ['send-keys', '-t', tmuxTarget, '-l', message], 3000);
|
|
303
|
+
await new Promise(r => setTimeout(r, 100));
|
|
304
|
+
await runProcess('tmux', ['send-keys', '-t', tmuxTarget, 'C-m'], 3000);
|
|
305
|
+
await new Promise(r => setTimeout(r, 100));
|
|
306
|
+
await runProcess('tmux', ['send-keys', '-t', tmuxTarget, 'C-m'], 3000);
|
|
307
|
+
|
|
308
|
+
// Update cooldown state
|
|
309
|
+
try {
|
|
310
|
+
const tmpPath = cooldownPath + '.tmp.' + process.pid;
|
|
311
|
+
await writeFile(tmpPath, JSON.stringify({
|
|
312
|
+
last_notified_at_ms: nowMs,
|
|
313
|
+
last_notified_at: nowIso,
|
|
314
|
+
prev_state: prevState,
|
|
315
|
+
}, null, 2));
|
|
316
|
+
await rename(tmpPath, cooldownPath);
|
|
317
|
+
} catch { /* best effort */ }
|
|
318
|
+
|
|
319
|
+
// Write event to events.ndjson
|
|
320
|
+
const eventsDir = join(stateDir, 'team', teamName, 'events');
|
|
321
|
+
const eventsPath = join(eventsDir, 'events.ndjson');
|
|
322
|
+
try {
|
|
323
|
+
await mkdir(eventsDir, { recursive: true });
|
|
324
|
+
const event = {
|
|
325
|
+
event_id: `worker-idle-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`,
|
|
326
|
+
team: teamName,
|
|
327
|
+
type: 'worker_idle',
|
|
328
|
+
worker: workerName,
|
|
329
|
+
prev_state: prevState,
|
|
330
|
+
task_id: currentTaskId || null,
|
|
331
|
+
reason: currentReason || null,
|
|
332
|
+
created_at: nowIso,
|
|
333
|
+
};
|
|
334
|
+
await appendFile(eventsPath, JSON.stringify(event) + '\n');
|
|
335
|
+
} catch { /* best effort */ }
|
|
336
|
+
|
|
337
|
+
await logTmuxHookEvent(logsDir, {
|
|
338
|
+
timestamp: nowIso,
|
|
339
|
+
type: 'worker_idle_notification',
|
|
340
|
+
team: teamName,
|
|
341
|
+
tmux_target: tmuxTarget,
|
|
342
|
+
worker: workerName,
|
|
343
|
+
prev_state: prevState,
|
|
344
|
+
task_id: currentTaskId || null,
|
|
345
|
+
});
|
|
346
|
+
} catch (err) {
|
|
347
|
+
await logTmuxHookEvent(logsDir, {
|
|
348
|
+
timestamp: nowIso,
|
|
349
|
+
type: 'worker_idle_notification',
|
|
350
|
+
team: teamName,
|
|
351
|
+
tmux_target: tmuxTarget,
|
|
352
|
+
worker: workerName,
|
|
353
|
+
error: err instanceof Error ? err.message : safeString(err),
|
|
354
|
+
}).catch(() => {});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -245,13 +245,13 @@ export async function handleTmuxInjection({
|
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
const { renderPrompt } = await import('./payload-parser.js');
|
|
249
|
-
const prompt = renderPrompt(config.prompt_template, {
|
|
248
|
+
const { renderPrompt, injectLanguageReminder } = await import('./payload-parser.js');
|
|
249
|
+
const prompt = injectLanguageReminder(renderPrompt(config.prompt_template, {
|
|
250
250
|
mode: mode || 'unknown',
|
|
251
251
|
threadId,
|
|
252
252
|
turnId,
|
|
253
253
|
timestamp: nowIso,
|
|
254
|
-
});
|
|
254
|
+
}), sourceText);
|
|
255
255
|
const fallbackPane = safeString(process.env.TMUX_PANE || '');
|
|
256
256
|
const resolution = await resolvePaneTarget(config.target, fallbackPane, cwd, modePane);
|
|
257
257
|
if (!resolution.paneTarget) {
|
package/scripts/notify-hook.js
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
resolveTeamStateDirForWorker,
|
|
45
45
|
updateWorkerHeartbeat,
|
|
46
46
|
maybeNotifyLeaderAllWorkersIdle,
|
|
47
|
+
maybeNotifyLeaderWorkerIdle,
|
|
47
48
|
} from './notify-hook/team-worker.js';
|
|
48
49
|
import { DEFAULT_MARKER } from './tmux-hook-engine.js';
|
|
49
50
|
|
|
@@ -129,8 +130,27 @@ async function main() {
|
|
|
129
130
|
const statePath = join(scopedDir, f);
|
|
130
131
|
const state = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
131
132
|
if (state.active) {
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
const nowIso = new Date().toISOString();
|
|
134
|
+
const nextIteration = (state.iteration || 0) + 1;
|
|
135
|
+
state.iteration = nextIteration;
|
|
136
|
+
state.last_turn_at = nowIso;
|
|
137
|
+
|
|
138
|
+
const maxIterations = asNumber(state.max_iterations);
|
|
139
|
+
if (maxIterations !== null && maxIterations > 0 && nextIteration >= maxIterations) {
|
|
140
|
+
state.active = false;
|
|
141
|
+
if (typeof state.current_phase !== 'string' || !state.current_phase.trim()) {
|
|
142
|
+
state.current_phase = 'complete';
|
|
143
|
+
} else if (!['cancelled', 'failed', 'complete'].includes(state.current_phase)) {
|
|
144
|
+
state.current_phase = 'complete';
|
|
145
|
+
}
|
|
146
|
+
if (typeof state.completed_at !== 'string' || !state.completed_at) {
|
|
147
|
+
state.completed_at = nowIso;
|
|
148
|
+
}
|
|
149
|
+
if (typeof state.stop_reason !== 'string' || !state.stop_reason) {
|
|
150
|
+
state.stop_reason = 'max_iterations_reached';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
134
154
|
await writeFile(statePath, JSON.stringify(state, null, 2));
|
|
135
155
|
}
|
|
136
156
|
}
|
|
@@ -248,6 +268,15 @@ async function main() {
|
|
|
248
268
|
}
|
|
249
269
|
}
|
|
250
270
|
|
|
271
|
+
// 4.55. Notify leader when individual worker transitions to idle (worker session only)
|
|
272
|
+
if (isTeamWorker && parsedTeamWorker) {
|
|
273
|
+
try {
|
|
274
|
+
await maybeNotifyLeaderWorkerIdle({ cwd, stateDir, logsDir, parsedTeamWorker });
|
|
275
|
+
} catch {
|
|
276
|
+
// Non-critical
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
251
280
|
// 4.6. Notify leader when all workers are idle (worker session only)
|
|
252
281
|
if (isTeamWorker && parsedTeamWorker) {
|
|
253
282
|
try {
|
|
@@ -300,6 +329,7 @@ async function main() {
|
|
|
300
329
|
if (!isTeamWorker) {
|
|
301
330
|
try {
|
|
302
331
|
const { notifyLifecycle } = await import('../dist/notifications/index.js');
|
|
332
|
+
const { shouldSendIdleNotification, recordIdleNotificationSent } = await import('../dist/notifications/idle-cooldown.js');
|
|
303
333
|
const sessionJsonPath = join(stateDir, 'session.json');
|
|
304
334
|
let notifySessionId = '';
|
|
305
335
|
try {
|
|
@@ -307,11 +337,14 @@ async function main() {
|
|
|
307
337
|
notifySessionId = safeString(sessionData && sessionData.session_id ? sessionData.session_id : '');
|
|
308
338
|
} catch { /* no session file */ }
|
|
309
339
|
|
|
310
|
-
if (notifySessionId) {
|
|
311
|
-
await notifyLifecycle('session-idle', {
|
|
340
|
+
if (notifySessionId && shouldSendIdleNotification(stateDir, notifySessionId)) {
|
|
341
|
+
const idleResult = await notifyLifecycle('session-idle', {
|
|
312
342
|
sessionId: notifySessionId,
|
|
313
343
|
projectPath: cwd,
|
|
314
344
|
});
|
|
345
|
+
if (idleResult && idleResult.anySuccess) {
|
|
346
|
+
recordIdleNotificationSent(stateDir, notifySessionId);
|
|
347
|
+
}
|
|
315
348
|
try {
|
|
316
349
|
const { buildNativeHookEvent } = await import('../dist/hooks/extensibility/events.js');
|
|
317
350
|
const { dispatchHookEvent } = await import('../dist/hooks/extensibility/dispatcher.js');
|
|
@@ -334,6 +367,24 @@ async function main() {
|
|
|
334
367
|
}
|
|
335
368
|
}
|
|
336
369
|
|
|
370
|
+
// 8.5. Skill activation tracking: update skill-active-state.json when a keyword is detected.
|
|
371
|
+
try {
|
|
372
|
+
const { recordSkillActivation } = await import('../dist/hooks/keyword-detector.js');
|
|
373
|
+
const inputMessages = normalizeInputMessages(payload);
|
|
374
|
+
const latestUserInput = safeString(inputMessages.length > 0 ? inputMessages[inputMessages.length - 1] : '');
|
|
375
|
+
if (latestUserInput) {
|
|
376
|
+
await recordSkillActivation({
|
|
377
|
+
stateDir,
|
|
378
|
+
text: latestUserInput,
|
|
379
|
+
sessionId: payloadSessionId,
|
|
380
|
+
threadId: safeString(payload['thread-id'] || payload.thread_id || ''),
|
|
381
|
+
turnId: safeString(payload['turn-id'] || payload.turn_id || ''),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
} catch {
|
|
385
|
+
// Non-fatal: keyword detector module may not be built yet
|
|
386
|
+
}
|
|
387
|
+
|
|
337
388
|
// 9. Auto-nudge: detect Codex stall patterns and automatically send a continuation prompt.
|
|
338
389
|
// Works for both leader and worker contexts.
|
|
339
390
|
try {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-notifications
|
|
3
|
+
description: Configure OMX notifications - unified entry point for all platforms
|
|
4
|
+
triggers:
|
|
5
|
+
- "configure notifications"
|
|
6
|
+
- "setup notifications"
|
|
7
|
+
- "notification settings"
|
|
8
|
+
- "configure discord"
|
|
9
|
+
- "configure telegram"
|
|
10
|
+
- "configure slack"
|
|
11
|
+
- "configure openclaw"
|
|
12
|
+
- "setup discord"
|
|
13
|
+
- "setup telegram"
|
|
14
|
+
- "setup slack"
|
|
15
|
+
- "setup openclaw"
|
|
16
|
+
- "discord notifications"
|
|
17
|
+
- "telegram notifications"
|
|
18
|
+
- "slack notifications"
|
|
19
|
+
- "openclaw notifications"
|
|
20
|
+
- "discord webhook"
|
|
21
|
+
- "telegram bot"
|
|
22
|
+
- "slack webhook"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Configure OMX Notifications
|
|
26
|
+
|
|
27
|
+
Unified entry point for setting up notifications across all supported platforms.
|
|
28
|
+
OMX can notify you on Discord, Telegram, Slack, or your own OpenClaw gateway.
|
|
29
|
+
|
|
30
|
+
## How This Skill Works
|
|
31
|
+
|
|
32
|
+
This skill detects what's already configured, presents a menu, and delegates to the
|
|
33
|
+
appropriate platform skill. It also handles cross-cutting settings like verbosity,
|
|
34
|
+
notification profiles, reply listener, and idle cooldown.
|
|
35
|
+
|
|
36
|
+
## Step 1: Detect Currently Configured Platforms
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
CONFIG_FILE="$HOME/.codex/.omx-config.json"
|
|
40
|
+
|
|
41
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
42
|
+
DISCORD_ENABLED=$(jq -r '.notifications.discord.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
43
|
+
DISCORD_BOT_ENABLED=$(jq -r '.notifications["discord-bot"].enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
44
|
+
TELEGRAM_ENABLED=$(jq -r '.notifications.telegram.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
45
|
+
SLACK_ENABLED=$(jq -r '.notifications.slack.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
46
|
+
OPENCLAW_ENABLED=$(jq -r '.notifications.openclaw.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
47
|
+
NOTIF_ENABLED=$(jq -r '.notifications.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
48
|
+
VERBOSITY=$(jq -r '.notifications.verbosity // "session"' "$CONFIG_FILE" 2>/dev/null)
|
|
49
|
+
COOLDOWN=$(jq -r '.notifications.idleCooldownSeconds // 60' "$CONFIG_FILE" 2>/dev/null)
|
|
50
|
+
REPLY_ENABLED=$(jq -r '.notifications.reply.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
51
|
+
|
|
52
|
+
echo "NOTIF_ENABLED=$NOTIF_ENABLED"
|
|
53
|
+
echo "DISCORD_ENABLED=$DISCORD_ENABLED"
|
|
54
|
+
echo "DISCORD_BOT_ENABLED=$DISCORD_BOT_ENABLED"
|
|
55
|
+
echo "TELEGRAM_ENABLED=$TELEGRAM_ENABLED"
|
|
56
|
+
echo "SLACK_ENABLED=$SLACK_ENABLED"
|
|
57
|
+
echo "OPENCLAW_ENABLED=$OPENCLAW_ENABLED"
|
|
58
|
+
echo "VERBOSITY=$VERBOSITY"
|
|
59
|
+
echo "COOLDOWN=$COOLDOWN"
|
|
60
|
+
echo "REPLY_ENABLED=$REPLY_ENABLED"
|
|
61
|
+
else
|
|
62
|
+
echo "NO_CONFIG_FILE"
|
|
63
|
+
fi
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Step 2: Show Current Status and Main Menu
|
|
67
|
+
|
|
68
|
+
Display a summary of what's configured:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
OMX Notification Status
|
|
72
|
+
───────────────────────
|
|
73
|
+
Discord webhook: enabled / not configured
|
|
74
|
+
Discord bot: enabled / not configured
|
|
75
|
+
Telegram: enabled / not configured
|
|
76
|
+
Slack: enabled / not configured
|
|
77
|
+
OpenClaw: enabled / not configured
|
|
78
|
+
|
|
79
|
+
Verbosity: session (default)
|
|
80
|
+
Idle cooldown: 60s
|
|
81
|
+
Reply listener: disabled
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then use AskUserQuestion:
|
|
85
|
+
|
|
86
|
+
**Question:** "What would you like to configure?"
|
|
87
|
+
|
|
88
|
+
**Options:**
|
|
89
|
+
1. **Discord** - Webhook or bot notifications to Discord channels
|
|
90
|
+
2. **Telegram** - Bot notifications to personal or group chats
|
|
91
|
+
3. **Slack** - Incoming webhook notifications to Slack channels
|
|
92
|
+
4. **OpenClaw** - Self-hosted HTTP or CLI command gateway
|
|
93
|
+
5. **Cross-cutting settings** - Verbosity, idle cooldown, profiles, reply listener
|
|
94
|
+
6. **Disable all notifications** - Turn off all notification dispatching
|
|
95
|
+
|
|
96
|
+
## Step 3: Delegate to Platform Skill
|
|
97
|
+
|
|
98
|
+
Based on the user's choice, invoke the appropriate platform skill:
|
|
99
|
+
|
|
100
|
+
- **Discord** → invoke `/configure-discord`
|
|
101
|
+
- **Telegram** → invoke `/configure-telegram`
|
|
102
|
+
- **Slack** → invoke `/configure-slack`
|
|
103
|
+
- **OpenClaw** → invoke `/configure-openclaw`
|
|
104
|
+
- **Cross-cutting settings** → continue with Step 4 below
|
|
105
|
+
- **Disable all** → continue with Step 5 below
|
|
106
|
+
|
|
107
|
+
When delegating, say: "Starting the [Platform] configuration wizard..." and invoke the skill.
|
|
108
|
+
|
|
109
|
+
## Step 4: Cross-Cutting Settings
|
|
110
|
+
|
|
111
|
+
If the user chose "Cross-cutting settings":
|
|
112
|
+
|
|
113
|
+
### 4a. Verbosity
|
|
114
|
+
|
|
115
|
+
Use AskUserQuestion:
|
|
116
|
+
|
|
117
|
+
**Question:** "How verbose should notifications be?"
|
|
118
|
+
|
|
119
|
+
**Options:**
|
|
120
|
+
1. **session (Recommended)** - Start, idle, stop, end events + tmux snippet
|
|
121
|
+
2. **minimal** - Start, stop, end only (no idle events, no tmux tail)
|
|
122
|
+
3. **agent** - All session events plus ask-user-question prompts
|
|
123
|
+
4. **verbose** - Everything including tool call output
|
|
124
|
+
|
|
125
|
+
Write verbosity to config:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
echo "$(cat "$CONFIG_FILE")" | jq \
|
|
129
|
+
--arg verbosity "$VERBOSITY" \
|
|
130
|
+
'.notifications.verbosity = $verbosity' > "$CONFIG_FILE"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Env var alternative: `OMX_NOTIFY_VERBOSITY=session`
|
|
134
|
+
|
|
135
|
+
### 4b. Idle Notification Cooldown
|
|
136
|
+
|
|
137
|
+
Use AskUserQuestion:
|
|
138
|
+
|
|
139
|
+
**Question:** "How often should idle notifications fire at most? (in seconds)"
|
|
140
|
+
|
|
141
|
+
**Options:**
|
|
142
|
+
1. **60 seconds (default)** - At most once per minute
|
|
143
|
+
2. **300 seconds** - At most once per 5 minutes
|
|
144
|
+
3. **0 (disabled)** - Send every turn with no throttling
|
|
145
|
+
4. **Custom** - Enter a number of seconds
|
|
146
|
+
|
|
147
|
+
Write the cooldown to config:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
echo "$(cat "$CONFIG_FILE")" | jq \
|
|
151
|
+
--argjson cooldown "$COOLDOWN_SECONDS" \
|
|
152
|
+
'.notifications.idleCooldownSeconds = $cooldown' > "$CONFIG_FILE"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Env var alternative: `OMX_IDLE_COOLDOWN_SECONDS=60`
|
|
156
|
+
|
|
157
|
+
### 4c. Notification Profiles
|
|
158
|
+
|
|
159
|
+
Explain that profiles let the user have different notification configs per context:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Notification Profiles
|
|
163
|
+
─────────────────────
|
|
164
|
+
Profiles let you switch notification targets based on context.
|
|
165
|
+
For example: a "work" profile for your work Slack, a "personal"
|
|
166
|
+
profile for your personal Telegram.
|
|
167
|
+
|
|
168
|
+
Activate a profile with: OMX_NOTIFY_PROFILE=work
|
|
169
|
+
or set a default: .omx-config.json > notifications.defaultProfile
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Use AskUserQuestion:
|
|
173
|
+
|
|
174
|
+
**Question:** "Would you like to configure notification profiles?"
|
|
175
|
+
|
|
176
|
+
**Options:**
|
|
177
|
+
1. **Yes** - Set up named profiles
|
|
178
|
+
2. **No, use flat config** - Keep the current single-config setup
|
|
179
|
+
|
|
180
|
+
If yes, guide the user to manually add profiles under `notifications.profiles` in `.omx-config.json`, and set `defaultProfile`.
|
|
181
|
+
|
|
182
|
+
### 4d. Reply Listener
|
|
183
|
+
|
|
184
|
+
Explain the reply listener:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
Reply Listener
|
|
188
|
+
──────────────
|
|
189
|
+
The reply listener lets you send messages back to Codex from
|
|
190
|
+
Discord (bot) or Telegram. When OMX asks for input, you can
|
|
191
|
+
reply directly from your phone or messaging app.
|
|
192
|
+
|
|
193
|
+
Requires:
|
|
194
|
+
- Discord Bot or Telegram platform configured
|
|
195
|
+
- OMX_REPLY_ENABLED=true in your shell profile
|
|
196
|
+
- For Discord: OMX_REPLY_DISCORD_USER_IDS=<your user ID>
|
|
197
|
+
(only messages from these IDs are accepted for security)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Use AskUserQuestion:
|
|
201
|
+
|
|
202
|
+
**Question:** "Would you like to enable the reply listener?"
|
|
203
|
+
|
|
204
|
+
**Options:**
|
|
205
|
+
1. **Yes** - Enable two-way communication from Discord/Telegram
|
|
206
|
+
2. **No** - Keep notifications one-way only
|
|
207
|
+
|
|
208
|
+
If yes, write to config:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
echo "$(cat "$CONFIG_FILE")" | jq \
|
|
212
|
+
'.notifications.reply = (.notifications.reply // {}) |
|
|
213
|
+
.notifications.reply.enabled = true' > "$CONFIG_FILE"
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
And remind them to set `OMX_REPLY_ENABLED=true` and (for Discord) `OMX_REPLY_DISCORD_USER_IDS`.
|
|
217
|
+
|
|
218
|
+
## Step 5: Disable All Notifications
|
|
219
|
+
|
|
220
|
+
If the user chose "Disable all notifications":
|
|
221
|
+
|
|
222
|
+
Use AskUserQuestion:
|
|
223
|
+
|
|
224
|
+
**Question:** "Are you sure you want to disable all notifications?"
|
|
225
|
+
|
|
226
|
+
**Options:**
|
|
227
|
+
1. **Yes, disable all** - Set notifications.enabled = false
|
|
228
|
+
2. **No, go back** - Return to the main menu
|
|
229
|
+
|
|
230
|
+
If confirmed:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
echo "$(cat "$CONFIG_FILE")" | jq \
|
|
234
|
+
'.notifications.enabled = false' > "$CONFIG_FILE"
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Confirm: "Notifications disabled. Re-enable anytime by running /configure-notifications."
|
|
238
|
+
|
|
239
|
+
## Step 6: After Configuration
|
|
240
|
+
|
|
241
|
+
After completing any platform or setting configuration, offer to configure another:
|
|
242
|
+
|
|
243
|
+
Use AskUserQuestion:
|
|
244
|
+
|
|
245
|
+
**Question:** "Would you like to configure another platform or setting?"
|
|
246
|
+
|
|
247
|
+
**Options:**
|
|
248
|
+
1. **Yes** - Return to the main menu (Step 2)
|
|
249
|
+
2. **No, I'm done** - Show final summary and exit
|
|
250
|
+
|
|
251
|
+
## Final Summary
|
|
252
|
+
|
|
253
|
+
Display a summary of all active notification platforms:
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
OMX Notification Configuration Complete!
|
|
257
|
+
─────────────────────────────────────────
|
|
258
|
+
Active platforms:
|
|
259
|
+
Discord webhook: enabled
|
|
260
|
+
Telegram: enabled
|
|
261
|
+
|
|
262
|
+
Verbosity: session
|
|
263
|
+
Idle cooldown: 60s
|
|
264
|
+
Reply listener: disabled
|
|
265
|
+
|
|
266
|
+
Config saved to: ~/.codex/.omx-config.json
|
|
267
|
+
|
|
268
|
+
Quick reference — env vars:
|
|
269
|
+
OMX_DISCORD_WEBHOOK_URL=...
|
|
270
|
+
OMX_TELEGRAM_BOT_TOKEN=...
|
|
271
|
+
OMX_TELEGRAM_CHAT_ID=...
|
|
272
|
+
OMX_SLACK_WEBHOOK_URL=...
|
|
273
|
+
OMX_NOTIFY_VERBOSITY=session
|
|
274
|
+
OMX_IDLE_COOLDOWN_SECONDS=60
|
|
275
|
+
OMX_OPENCLAW=1
|
|
276
|
+
|
|
277
|
+
Run /configure-notifications again to update any settings.
|
|
278
|
+
```
|