oh-my-codex 0.8.0 → 0.8.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 (169) hide show
  1. package/README.de.md +7 -2
  2. package/README.es.md +7 -2
  3. package/README.fr.md +7 -2
  4. package/README.it.md +7 -2
  5. package/README.ja.md +7 -2
  6. package/README.ko.md +7 -2
  7. package/README.md +61 -11
  8. package/README.pt.md +7 -2
  9. package/README.ru.md +7 -2
  10. package/README.tr.md +7 -2
  11. package/README.vi.md +7 -2
  12. package/README.zh-TW.md +366 -0
  13. package/README.zh.md +7 -2
  14. package/dist/cli/__tests__/index.test.js +70 -4
  15. package/dist/cli/__tests__/index.test.js.map +1 -1
  16. package/dist/cli/__tests__/setup-skills-overwrite.test.js +100 -1
  17. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
  18. package/dist/cli/__tests__/team.test.js +219 -1
  19. package/dist/cli/__tests__/team.test.js.map +1 -1
  20. package/dist/cli/catalog-contract.d.ts.map +1 -1
  21. package/dist/cli/catalog-contract.js +8 -2
  22. package/dist/cli/catalog-contract.js.map +1 -1
  23. package/dist/cli/index.d.ts +7 -1
  24. package/dist/cli/index.d.ts.map +1 -1
  25. package/dist/cli/index.js +58 -12
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/setup.d.ts.map +1 -1
  28. package/dist/cli/setup.js +50 -17
  29. package/dist/cli/setup.js.map +1 -1
  30. package/dist/cli/team.d.ts.map +1 -1
  31. package/dist/cli/team.js +257 -0
  32. package/dist/cli/team.js.map +1 -1
  33. package/dist/config/__tests__/models.test.js +11 -11
  34. package/dist/config/__tests__/models.test.js.map +1 -1
  35. package/dist/config/models.d.ts +4 -3
  36. package/dist/config/models.d.ts.map +1 -1
  37. package/dist/config/models.js +6 -5
  38. package/dist/config/models.js.map +1 -1
  39. package/dist/hooks/__tests__/keyword-detector.test.js +46 -3
  40. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  41. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -7
  42. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  43. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +176 -1
  44. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  45. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +61 -1
  46. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  47. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +17 -7
  48. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  49. package/dist/hooks/__tests__/openclaw-setup-contract.test.js +26 -16
  50. package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -1
  51. package/dist/hooks/keyword-detector.d.ts +2 -1
  52. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  53. package/dist/hooks/keyword-detector.js +41 -4
  54. package/dist/hooks/keyword-detector.js.map +1 -1
  55. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  56. package/dist/hooks/keyword-registry.js +5 -0
  57. package/dist/hooks/keyword-registry.js.map +1 -1
  58. package/dist/mcp/__tests__/path-traversal.test.js +9 -227
  59. package/dist/mcp/__tests__/path-traversal.test.js.map +1 -1
  60. package/dist/mcp/__tests__/state-server-schema.test.js +16 -20
  61. package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
  62. package/dist/mcp/__tests__/state-server-team-tools.test.js +30 -487
  63. package/dist/mcp/__tests__/state-server-team-tools.test.js.map +1 -1
  64. package/dist/mcp/state-server.d.ts +179 -0
  65. package/dist/mcp/state-server.d.ts.map +1 -1
  66. package/dist/mcp/state-server.js +217 -1111
  67. package/dist/mcp/state-server.js.map +1 -1
  68. package/dist/mcp/team-server.d.ts.map +1 -1
  69. package/dist/mcp/team-server.js +28 -7
  70. package/dist/mcp/team-server.js.map +1 -1
  71. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +5 -0
  72. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +1 -0
  73. package/dist/notifications/__tests__/dispatch-cooldown.test.js +100 -0
  74. package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +1 -0
  75. package/dist/notifications/__tests__/temp-mode.test.d.ts +2 -0
  76. package/dist/notifications/__tests__/temp-mode.test.d.ts.map +1 -0
  77. package/dist/notifications/__tests__/temp-mode.test.js +172 -0
  78. package/dist/notifications/__tests__/temp-mode.test.js.map +1 -0
  79. package/dist/notifications/config.d.ts.map +1 -1
  80. package/dist/notifications/config.js +59 -6
  81. package/dist/notifications/config.js.map +1 -1
  82. package/dist/notifications/dispatch-cooldown.d.ts +36 -0
  83. package/dist/notifications/dispatch-cooldown.d.ts.map +1 -0
  84. package/dist/notifications/dispatch-cooldown.js +109 -0
  85. package/dist/notifications/dispatch-cooldown.js.map +1 -0
  86. package/dist/notifications/index.d.ts +5 -0
  87. package/dist/notifications/index.d.ts.map +1 -1
  88. package/dist/notifications/index.js +39 -8
  89. package/dist/notifications/index.js.map +1 -1
  90. package/dist/notifications/temp-contract.d.ts +22 -0
  91. package/dist/notifications/temp-contract.d.ts.map +1 -0
  92. package/dist/notifications/temp-contract.js +147 -0
  93. package/dist/notifications/temp-contract.js.map +1 -0
  94. package/dist/notifications/types.d.ts +18 -0
  95. package/dist/notifications/types.d.ts.map +1 -1
  96. package/dist/openclaw/__tests__/config.test.js +81 -0
  97. package/dist/openclaw/__tests__/config.test.js.map +1 -1
  98. package/dist/openclaw/__tests__/dispatcher.test.js +50 -7
  99. package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
  100. package/dist/openclaw/config.d.ts +4 -0
  101. package/dist/openclaw/config.d.ts.map +1 -1
  102. package/dist/openclaw/config.js +110 -16
  103. package/dist/openclaw/config.js.map +1 -1
  104. package/dist/openclaw/dispatcher.d.ts +10 -4
  105. package/dist/openclaw/dispatcher.d.ts.map +1 -1
  106. package/dist/openclaw/dispatcher.js +40 -10
  107. package/dist/openclaw/dispatcher.js.map +1 -1
  108. package/dist/openclaw/types.d.ts +5 -1
  109. package/dist/openclaw/types.d.ts.map +1 -1
  110. package/dist/team/__tests__/api-interop.test.d.ts +2 -0
  111. package/dist/team/__tests__/api-interop.test.d.ts.map +1 -0
  112. package/dist/team/__tests__/api-interop.test.js +1052 -0
  113. package/dist/team/__tests__/api-interop.test.js.map +1 -0
  114. package/dist/team/__tests__/mcp-comm.test.js +30 -0
  115. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  116. package/dist/team/__tests__/runtime-cli.test.js +6 -0
  117. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  118. package/dist/team/__tests__/runtime.test.js +52 -22
  119. package/dist/team/__tests__/runtime.test.js.map +1 -1
  120. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +2 -0
  121. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +1 -0
  122. package/dist/team/__tests__/tmux-claude-workers-demo.test.js +190 -0
  123. package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +1 -0
  124. package/dist/team/__tests__/tmux-session.test.js +45 -2
  125. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  126. package/dist/team/__tests__/worker-bootstrap.test.js +20 -12
  127. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  128. package/dist/team/api-interop.d.ts +19 -0
  129. package/dist/team/api-interop.d.ts.map +1 -0
  130. package/dist/team/api-interop.js +578 -0
  131. package/dist/team/api-interop.js.map +1 -0
  132. package/dist/team/mcp-comm.d.ts.map +1 -1
  133. package/dist/team/mcp-comm.js +26 -0
  134. package/dist/team/mcp-comm.js.map +1 -1
  135. package/dist/team/runtime-cli.d.ts +3 -0
  136. package/dist/team/runtime-cli.d.ts.map +1 -1
  137. package/dist/team/runtime-cli.js +24 -2
  138. package/dist/team/runtime-cli.js.map +1 -1
  139. package/dist/team/runtime.d.ts.map +1 -1
  140. package/dist/team/runtime.js +67 -11
  141. package/dist/team/runtime.js.map +1 -1
  142. package/dist/team/scaling.js.map +1 -1
  143. package/dist/team/state/types.d.ts +1 -1
  144. package/dist/team/state/types.d.ts.map +1 -1
  145. package/dist/team/state.d.ts +1 -1
  146. package/dist/team/state.d.ts.map +1 -1
  147. package/dist/team/tmux-session.d.ts +1 -1
  148. package/dist/team/tmux-session.d.ts.map +1 -1
  149. package/dist/team/tmux-session.js +17 -5
  150. package/dist/team/tmux-session.js.map +1 -1
  151. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  152. package/dist/team/worker-bootstrap.js +48 -19
  153. package/dist/team/worker-bootstrap.js.map +1 -1
  154. package/package.json +1 -1
  155. package/scripts/demo-claude-workers.sh +241 -0
  156. package/scripts/demo-team-e2e.sh +179 -0
  157. package/scripts/notify-hook/team-dispatch.js +186 -12
  158. package/scripts/notify-hook/team-leader-nudge.js +42 -2
  159. package/scripts/notify-hook/team-worker.js +63 -4
  160. package/skills/configure-notifications/SKILL.md +193 -185
  161. package/skills/omx-setup/SKILL.md +1 -1
  162. package/skills/team/SKILL.md +47 -5
  163. package/skills/worker/SKILL.md +40 -10
  164. package/templates/AGENTS.md +7 -3
  165. package/templates/catalog-manifest.json +26 -3
  166. package/skills/configure-discord/SKILL.md +0 -256
  167. package/skills/configure-openclaw/SKILL.md +0 -264
  168. package/skills/configure-slack/SKILL.md +0 -226
  169. package/skills/configure-telegram/SKILL.md +0 -232
@@ -24,255 +24,263 @@ triggers:
24
24
 
25
25
  # Configure OMX Notifications
26
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.
27
+ Unified and only entry point for notification setup.
29
28
 
30
- ## How This Skill Works
29
+ - **Native integrations (first-class):** Discord, Telegram, Slack
30
+ - **Generic extensibility integrations:** `custom_webhook_command`, `custom_cli_command`
31
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.
32
+ > Standalone configure skills (`configure-discord`, `configure-telegram`, `configure-slack`, `configure-openclaw`) are removed.
35
33
 
36
- ## Step 1: Detect Currently Configured Platforms
34
+ ## Step 1: Inspect Current State
37
35
 
38
36
  ```bash
39
37
  CONFIG_FILE="$HOME/.codex/.omx-config.json"
40
38
 
41
39
  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"
40
+ jq -r '
41
+ {
42
+ notifications_enabled: (.notifications.enabled // false),
43
+ discord: (.notifications.discord.enabled // false),
44
+ discord_bot: (.notifications["discord-bot"].enabled // false),
45
+ telegram: (.notifications.telegram.enabled // false),
46
+ slack: (.notifications.slack.enabled // false),
47
+ openclaw: (.notifications.openclaw.enabled // false),
48
+ custom_webhook_command: (.notifications.custom_webhook_command.enabled // false),
49
+ custom_cli_command: (.notifications.custom_cli_command.enabled // false),
50
+ verbosity: (.notifications.verbosity // "session"),
51
+ idleCooldownSeconds: (.notifications.idleCooldownSeconds // 60),
52
+ reply_enabled: (.notifications.reply.enabled // false)
53
+ }
54
+ ' "$CONFIG_FILE"
61
55
  else
62
56
  echo "NO_CONFIG_FILE"
63
57
  fi
64
58
  ```
65
59
 
66
- ## Step 2: Show Current Status and Main Menu
60
+ ## Step 2: Main Menu
67
61
 
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:
62
+ Use AskUserQuestion:
85
63
 
86
64
  **Question:** "What would you like to configure?"
87
65
 
88
66
  **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 gateway (`notifications.openclaw.gateways + hooks`) with /hooks/agent delivery verification
93
- 5. **Cross-cutting settings** - Verbosity, idle cooldown, profiles, reply listener
94
- 6. **Disable all notifications** - Turn off all notification dispatching
67
+ 1. **Discord (native)** - webhook or bot
68
+ 2. **Telegram (native)** - bot token + chat id
69
+ 3. **Slack (native)** - incoming webhook
70
+ 4. **Generic webhook command** - `custom_webhook_command`
71
+ 5. **Generic CLI command** - `custom_cli_command`
72
+ 6. **Cross-cutting settings** - verbosity, idle cooldown, profiles, reply listener
73
+ 7. **Disable all notifications** - set `notifications.enabled = false`
95
74
 
96
- ## Step 3: Delegate to Platform Skill
75
+ ## Step 3: Configure Native Platforms (Discord / Telegram / Slack)
97
76
 
98
- Based on the user's choice, invoke the appropriate platform skill:
77
+ Collect and validate platform-specific values, then write directly under native keys:
99
78
 
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
79
+ - Discord webhook: `notifications.discord`
80
+ - Discord bot: `notifications["discord-bot"]`
81
+ - Telegram: `notifications.telegram`
82
+ - Slack: `notifications.slack`
106
83
 
107
- When delegating, say: "Starting the [Platform] configuration wizard..." and invoke the skill.
84
+ Do not write these as generic command/webhook aliases.
108
85
 
109
- ## Step 4: Cross-Cutting Settings
86
+ ## Step 4: Configure Generic Extensibility
110
87
 
111
- If the user chose "Cross-cutting settings":
88
+ ### 4a) `custom_webhook_command`
112
89
 
113
- ### 4a. Verbosity
90
+ Use AskUserQuestion to collect:
91
+ - URL
92
+ - Optional headers
93
+ - Optional method (`POST` default, or `PUT`)
94
+ - Optional event list (`session-end`, `ask-user-question`, `session-start`, `session-idle`, `stop`)
95
+ - Optional instruction template
114
96
 
115
- Use AskUserQuestion:
97
+ Write:
116
98
 
117
- **Question:** "How verbose should notifications be?"
99
+ ```bash
100
+ jq \
101
+ --arg url "$URL" \
102
+ --arg method "${METHOD:-POST}" \
103
+ --arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" \
104
+ '.notifications = (.notifications // {enabled: true}) |
105
+ .notifications.enabled = true |
106
+ .notifications.custom_webhook_command = {
107
+ enabled: true,
108
+ url: $url,
109
+ method: $method,
110
+ instruction: $instruction,
111
+ events: ["session-end", "ask-user-question"]
112
+ }' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
113
+ ```
118
114
 
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
115
+ ### 4b) `custom_cli_command`
124
116
 
125
- Write verbosity to config:
117
+ Use AskUserQuestion to collect:
118
+ - Command template (supports `{{event}}`, `{{instruction}}`, `{{sessionId}}`, `{{projectPath}}`)
119
+ - Optional event list
120
+ - Optional instruction template
121
+
122
+ Write:
126
123
 
127
124
  ```bash
128
- echo "$(cat "$CONFIG_FILE")" | jq \
129
- --arg verbosity "$VERBOSITY" \
130
- '.notifications.verbosity = $verbosity' > "$CONFIG_FILE"
125
+ jq \
126
+ --arg command "$COMMAND_TEMPLATE" \
127
+ --arg instruction "${INSTRUCTION:-OMX event {{event}} for {{projectPath}}}" \
128
+ '.notifications = (.notifications // {enabled: true}) |
129
+ .notifications.enabled = true |
130
+ .notifications.custom_cli_command = {
131
+ enabled: true,
132
+ command: $command,
133
+ instruction: $instruction,
134
+ events: ["session-end", "ask-user-question"]
135
+ }' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
131
136
  ```
132
137
 
133
- Env var alternative: `OMX_NOTIFY_VERBOSITY=session`
138
+ > Activation gate: OpenClaw-backed dispatch is active only when `OMX_OPENCLAW=1`.
139
+ > For command gateways, also require `OMX_OPENCLAW_COMMAND=1`.
140
+ > Optional timeout env override: `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` (ms).
134
141
 
135
- ### 4b. Idle Notification Cooldown
142
+ ### 4b-1) OpenClaw + Clawdbot Agent Workflow (recommended for dev)
136
143
 
137
- Use AskUserQuestion:
144
+ If the user explicitly asks to route hook notifications through **clawdbot agent turns**
145
+ (not direct message/webhook forwarding), use a command gateway that invokes
146
+ `clawdbot agent` and delivers back to Discord.
138
147
 
139
- **Question:** "How often should idle notifications fire at most? (in seconds)"
148
+ Notes:
149
+ - Hook name mapping is intentional: notifications `session-stop` -> OpenClaw hook `stop`.
150
+ - OMX shell-escapes template substitutions for command gateways (including `{{instruction}}`).
151
+ - Keep `instruction` templates concise and avoid untrusted shell metacharacters.
152
+ - During troubleshooting, avoid swallowing command output; route it to a log file.
153
+ - Timeout precedence: `gateways.<name>.timeout` > `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` > `5000`.
154
+ - For clawdbot agent workflows, set `gateways.<name>.timeout` to `120000` (recommended).
155
+ - For dev operations, enforce Korean output in all hook instructions.
156
+ - Include both `session={{sessionId}}` and `tmux={{tmuxSession}}` in hook text for traceability.
157
+ - If follow-up is needed, explicitly instruct clawdbot to consult `SOUL.md` and continue in `#omc-dev`.
158
+ - **Error handling**: Append `|| true` to prevent OMX hook failures from blocking the session.
159
+ - **JSONL logging**: Use `.jsonl` extension and append (`>>`) for structured log aggregation.
160
+ - **Reply target format**: Use `--reply-to 'channel:CHANNEL_ID'` for reliability (preferred over channel aliases).
140
161
 
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:
162
+ Example (targeting `#omc-dev` with production-tested settings):
148
163
 
149
164
  ```bash
150
- echo "$(cat "$CONFIG_FILE")" | jq \
151
- --argjson cooldown "$COOLDOWN_SECONDS" \
152
- '.notifications.idleCooldownSeconds = $cooldown' > "$CONFIG_FILE"
165
+ jq \
166
+ --arg command "(clawdbot agent --session-id omx-hooks --message {{instruction}} --thinking minimal --deliver --reply-channel discord --reply-to 'channel:1468539002985644084' --timeout 120 --json >>/tmp/omx-openclaw-agent.jsonl 2>&1 || true)" \
167
+ '.notifications = (.notifications // {enabled: true}) |
168
+ .notifications.enabled = true |
169
+ .notifications.verbosity = "verbose" |
170
+ .notifications.events = (.notifications.events // {}) |
171
+ .notifications.events["session-start"] = {enabled: true} |
172
+ .notifications.events["session-idle"] = {enabled: true} |
173
+ .notifications.events["ask-user-question"] = {enabled: true} |
174
+ .notifications.events["session-stop"] = {enabled: true} |
175
+ .notifications.events["session-end"] = {enabled: true} |
176
+ .notifications.openclaw = (.notifications.openclaw // {}) |
177
+ .notifications.openclaw.enabled = true |
178
+ .notifications.openclaw.gateways = (.notifications.openclaw.gateways // {}) |
179
+ .notifications.openclaw.gateways["local"] = {
180
+ type: "command",
181
+ command: $command,
182
+ timeout: 120000
183
+ } |
184
+ .notifications.openclaw.hooks = (.notifications.openclaw.hooks // {}) |
185
+ .notifications.openclaw.hooks["session-start"] = {
186
+ enabled: true,
187
+ gateway: "local",
188
+ instruction: "OMX hook=session-start project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 상태를 공유하고 SOUL.md를 참고해 필요한 후속 조치를 #omc-dev에 안내하세요."
189
+ } |
190
+ .notifications.openclaw.hooks["session-idle"] = {
191
+ enabled: true,
192
+ gateway: "local",
193
+ instruction: "OMX hook=session-idle project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 idle 상황을 간단히 공유하고 진행중인 작업 팔로업을 안내하세요."
194
+ } |
195
+ .notifications.openclaw.hooks["ask-user-question"] = {
196
+ enabled: true,
197
+ gateway: "local",
198
+ instruction: "OMX hook=ask-user-question session={{sessionId}} tmux={{tmuxSession}} question={{question}}. 한국어로 사용자 응답 필요를 #omc-dev에 알리고 즉시 액션 아이템을 제시하세요."
199
+ } |
200
+ .notifications.openclaw.hooks["stop"] = {
201
+ enabled: true,
202
+ gateway: "local",
203
+ instruction: "OMX hook=session-stop project={{projectName}} session={{sessionId}} tmux={{tmuxSession}}. 한국어로 중단 상태와 정리 액션을 SOUL.md 기준으로 전달하세요."
204
+ } |
205
+ .notifications.openclaw.hooks["session-end"] = {
206
+ enabled: true,
207
+ gateway: "local",
208
+ instruction: "OMX hook=session-end project={{projectName}} session={{sessionId}} tmux={{tmuxSession}} reason={{reason}}. 한국어로 완료 요약을 1줄로 남기고 필요한 후속 조치를 안내하세요."
209
+ }' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
153
210
  ```
154
211
 
155
- Env var alternative: `OMX_IDLE_COOLDOWN_SECONDS=60`
156
-
157
- ### 4c. Notification Profiles
212
+ Verification for this mode:
158
213
 
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
214
+ ```bash
215
+ clawdbot agent --session-id omx-hooks --message "OMX hook test via clawdbot agent path" \
216
+ --thinking minimal --deliver --reply-channel discord --reply-to 'channel:1468539002985644084' --timeout 120 --json
170
217
  ```
171
218
 
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
219
+ Dev runbook (Korean + tmux follow-up):
179
220
 
180
- If yes, guide the user to manually add profiles under `notifications.profiles` in `.omx-config.json`, and set `defaultProfile`.
221
+ ```bash
222
+ # 1) identify active OMX tmux sessions
223
+ tmux list-sessions -F '#{session_name}' | rg '^omx-' || true
181
224
 
182
- ### 4d. Reply Listener
225
+ # 2) confirm hook templates include session/tmux context
226
+ jq '.notifications.openclaw.hooks' "$CONFIG_FILE"
183
227
 
184
- Explain the reply listener:
228
+ # 3) inspect agent JSONL logs when delivery looks broken
229
+ tail -n 120 /tmp/omx-openclaw-agent.jsonl | jq -s '.[] | {timestamp: (.timestamp // .time), status: (.status // .error // "ok")}'
185
230
 
231
+ # 4) check for recent errors in logs
232
+ rg '"error"|"failed"|"timeout"' /tmp/omx-openclaw-agent.jsonl | tail -20
186
233
  ```
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
234
 
204
- **Options:**
205
- 1. **Yes** - Enable two-way communication from Discord/Telegram
206
- 2. **No** - Keep notifications one-way only
235
+ ### 4c) Compatibility + precedence contract
207
236
 
208
- If yes, write to config:
237
+ OMX accepts both:
238
+ - explicit `notifications.openclaw` schema (legacy/runtime shape)
239
+ - generic aliases (`custom_webhook_command`, `custom_cli_command`)
209
240
 
210
- ```bash
211
- echo "$(cat "$CONFIG_FILE")" | jq \
212
- '.notifications.reply = (.notifications.reply // {}) |
213
- .notifications.reply.enabled = true' > "$CONFIG_FILE"
214
- ```
241
+ Deterministic precedence:
242
+ 1. `notifications.openclaw` **wins** when present and valid.
243
+ 2. Generic aliases are ignored in that case (with warning).
215
244
 
216
- And remind them to set `OMX_REPLY_ENABLED=true` and (for Discord) `OMX_REPLY_DISCORD_USER_IDS`.
245
+ ## Step 5: Cross-Cutting Settings
217
246
 
218
- ## Step 5: Disable All Notifications
247
+ ### Verbosity
248
+ - minimal / session (recommended) / agent / verbose
219
249
 
220
- If the user chose "Disable all notifications":
221
-
222
- Use AskUserQuestion:
250
+ ### Idle cooldown
251
+ - `notifications.idleCooldownSeconds`
223
252
 
224
- **Question:** "Are you sure you want to disable all notifications?"
253
+ ### Profiles
254
+ - `notifications.profiles`
255
+ - `notifications.defaultProfile`
225
256
 
226
- **Options:**
227
- 1. **Yes, disable all** - Set notifications.enabled = false
228
- 2. **No, go back** - Return to the main menu
257
+ ### Reply listener
258
+ - `notifications.reply.enabled`
259
+ - env gates: `OMX_REPLY_ENABLED=true`, and for Discord `OMX_REPLY_DISCORD_USER_IDS=...`
229
260
 
230
- If confirmed:
261
+ ## Step 6: Disable All Notifications
231
262
 
232
263
  ```bash
233
- echo "$(cat "$CONFIG_FILE")" | jq \
234
- '.notifications.enabled = false' > "$CONFIG_FILE"
264
+ jq '.notifications.enabled = false' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
235
265
  ```
236
266
 
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:
267
+ ## Step 7: Verification Guidance
244
268
 
245
- **Question:** "Would you like to configure another platform or setting?"
269
+ After writing config, run a smoke check:
246
270
 
247
- **Options:**
248
- 1. **Yes** - Return to the main menu (Step 2)
249
- 2. **No, I'm done** - Show final summary and exit
271
+ ```bash
272
+ npm run build
273
+ ```
250
274
 
251
- ## Final Summary
275
+ For OpenClaw-like HTTP integrations, verify both:
276
+ - `/hooks/wake` smoke test
277
+ - `/hooks/agent` delivery verification
252
278
 
253
- Display a summary of all active notification platforms:
279
+ ## Final Summary Template
254
280
 
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
- ```
281
+ Show:
282
+ - Native platforms enabled
283
+ - Generic aliases enabled (`custom_webhook_command`, `custom_cli_command`)
284
+ - Whether explicit `notifications.openclaw` exists (and therefore overrides aliases)
285
+ - Verbosity + idle cooldown + reply listener state
286
+ - Config path (`~/.codex/.omx-config.json`)
@@ -30,7 +30,7 @@ Supported setup flags (current implementation):
30
30
  - else default `user` (safe for CI/tests)
31
31
  2. Create directories and persist effective scope
32
32
  3. Install prompts, native agent configs, skills, and merge config.toml (scope determines target directories)
33
- 4. Verify required team MCP comm tool exports exist in built `dist/mcp/state-server.js`
33
+ 4. Verify Team CLI API interop markers exist in built `dist/cli/team.js`
34
34
  5. Generate project-root `./AGENTS.md` from `templates/AGENTS.md` (or skip when existing and no force)
35
35
  6. Configure notify hook references and write `./.omx/hud-config.json`
36
36
 
@@ -5,7 +5,7 @@ description: N coordinated agents on shared task list using tmux-based orchestra
5
5
 
6
6
  # Team Skill
7
7
 
8
- `$team` is the tmux-based parallel execution mode for OMX. It starts real worker Codex and/or Claude CLI sessions in split panes and coordinates them through `.omx/state/team/...` files plus MCP team tools.
8
+ `$team` is the tmux-based parallel execution mode for OMX. It starts real worker Codex and/or Claude CLI sessions in split panes and coordinates them through `.omx/state/team/...` files plus CLI team interop (`omx team api ...`) and state files.
9
9
 
10
10
  This skill is operationally sensitive. Treat it as an operator workflow, not a generic prompt pattern.
11
11
 
@@ -166,6 +166,23 @@ Follow this exact lifecycle when running `$team`:
166
166
  Do not run `shutdown` while workers are actively writing updates unless user explicitly requested abort/cancel.
167
167
  Do not treat ad-hoc pane typing as primary control flow when runtime/state evidence is available.
168
168
 
169
+ ## Message Dispatch Policy (CLI-first, state-first)
170
+
171
+ To avoid brittle behavior, **message/task delivery must not be driven by ad-hoc tmux typing**.
172
+
173
+ Required default path:
174
+
175
+ 1. Use `omx team ...` runtime lifecycle commands for orchestration.
176
+ 2. Use `omx team api ... --json` for mailbox/task mutations.
177
+ 3. Verify delivery via mailbox/state evidence (`mailbox/*.json`, task status, `omx team status`).
178
+
179
+ Strict rules:
180
+
181
+ - **MUST NOT** use direct `tmux send-keys` as the primary mechanism to deliver instructions/messages.
182
+ - **MUST NOT** spam Enter/trigger keys without first checking runtime/state evidence.
183
+ - **MUST** prefer durable state writes + runtime dispatch (`dispatch/requests.json`, mailbox, inbox).
184
+ - Direct tmux interaction is **fallback-only** and only after failure checks (for example `worker_notify_failed:<worker>`) or explicit user request (for example “press enter”).
185
+
169
186
  ## Operational Commands
170
187
 
171
188
  ```bash
@@ -206,6 +223,31 @@ Semantics:
206
223
  - `.omx/state/team/<team>/workers/worker-<n>/status.json`
207
224
  - `.omx/state/team-leader-nudge.json`
208
225
 
226
+
227
+ ## Team Mutation Interop (CLI-first)
228
+
229
+ Use `omx team api` for machine-readable mutation/reads instead of legacy `team_*` MCP tools.
230
+
231
+ ```bash
232
+ omx team api <operation> --input '{"team_name":"my-team",...}' --json
233
+ ```
234
+
235
+ Examples:
236
+
237
+ ```bash
238
+ omx team api send-message --input '{"team_name":"my-team","from_worker":"worker-1","to_worker":"leader-fixed","body":"ACK"}' --json
239
+ omx team api claim-task --input '{"team_name":"my-team","task_id":"1","worker":"worker-1"}' --json
240
+ omx team api transition-task-status --input '{"team_name":"my-team","task_id":"1","from":"in_progress","to":"completed","claim_token":"<token>"}' --json
241
+ ```
242
+
243
+ `--json` responses include stable metadata for automation:
244
+ - `schema_version`
245
+ - `timestamp`
246
+ - `command`
247
+ - `ok`
248
+ - `operation`
249
+ - `data` or `error`
250
+
209
251
  ## Team + Worker Protocol Notes
210
252
 
211
253
  Leader-to-worker:
@@ -215,8 +257,8 @@ Leader-to-worker:
215
257
 
216
258
  Worker-to-leader:
217
259
 
218
- - Send ACK to `leader-fixed` mailbox via `team_send_message`
219
- - Claim task via state API, execute, update task + status
260
+ - Send ACK to `leader-fixed` mailbox via `omx team api send-message --json`
261
+ - Claim/transition/release task lifecycle via `omx team api <operation> --json`
220
262
 
221
263
  Task ID rule (critical):
222
264
 
@@ -294,10 +336,10 @@ Checks:
294
336
 
295
337
  1. Worker pane capture shows inbox processing
296
338
  2. `.omx/state/team/<team>/mailbox/leader-fixed.json` exists
297
- 3. Worker skill loaded and `team_send_message` called
339
+ 3. Worker skill loaded and `omx team api send-message --json` called
298
340
  4. Task-id mismatch not blocking worker flow
299
341
 
300
- ### Worker logs `team_send_message ENOENT` / `team_update_task ENOENT`
342
+ ### Worker logs `omx team api ... ENOENT` (or legacy `team_send_message ENOENT` / `team_update_task ENOENT`)
301
343
 
302
344
  Meaning:
303
345
  - Team state path no longer exists while worker is still running.
@@ -15,22 +15,37 @@ You MUST be running with `OMX_TEAM_WORKER` set. It looks like:
15
15
 
16
16
  Example: `alpha/worker-2`
17
17
 
18
+ ## Load Worker Skill Path (Claude/Codex)
19
+
20
+ When a worker inbox tells you to load this skill, resolve the first existing path:
21
+
22
+ 1. `${CODEX_HOME:-~/.codex}/skills/worker/SKILL.md`
23
+ 2. `~/.agents/skills/worker/SKILL.md`
24
+ 3. `<leader_cwd>/.agents/skills/worker/SKILL.md`
25
+ 4. `<leader_cwd>/skills/worker/SKILL.md` (repo fallback)
26
+
18
27
  ## Startup Protocol (ACK)
19
28
 
20
29
  1. Parse `OMX_TEAM_WORKER` into:
21
30
  - `teamName` (before the `/`)
22
31
  - `workerName` (after the `/`, usually `worker-<n>`)
23
- 2. Send an ACK to the lead mailbox:
32
+ 2. Send a startup ACK to the lead mailbox **before task work**:
24
33
  - Recipient worker id: `leader-fixed`
25
- - Body: one short line including your workerName and what you’re ready to do.
34
+ - Body: one short deterministic line (recommended: `ACK: <workerName> initialized`).
26
35
  3. After ACK, proceed to your inbox instructions.
27
36
 
28
37
  The lead will see your message in:
29
38
 
30
39
  `<team_state_root>/team/<teamName>/mailbox/leader-fixed.json`
31
40
 
32
- Use the MCP tool:
33
- - `team_send_message` with `{team_name, from_worker, to_worker:"leader-fixed", body}`
41
+ Use CLI interop:
42
+ - `omx team api send-message --input <json> --json` with `{team_name, from_worker, to_worker:"leader-fixed", body}`
43
+
44
+ Copy/paste template:
45
+
46
+ ```bash
47
+ omx team api send-message --input "{\"team_name\":\"<teamName>\",\"from_worker\":\"<workerName>\",\"to_worker\":\"leader-fixed\",\"body\":\"ACK: <workerName> initialized\"}" --json
48
+ ```
34
49
 
35
50
  ## Inbox + Tasks
36
51
 
@@ -47,11 +62,11 @@ Use the MCP tool:
47
62
  5. Task id format:
48
63
  - The MCP/state API uses the numeric id (`"1"`), not `"task-1"`.
49
64
  - Never use legacy `tasks/{id}.json` wording.
50
- 6. Claim the task (do NOT start work without a claim) using claim-safe lifecycle APIs (`team_claim_task` / `claimTask`).
65
+ 6. Claim the task (do NOT start work without a claim) using claim-safe lifecycle CLI interop (`omx team api claim-task --json`).
51
66
  7. Do the work.
52
- 8. Complete/fail the task via lifecycle transition APIs (`team_transition_task_status` / `transitionTaskStatus`) from `in_progress` to `completed` or `failed`.
67
+ 8. Complete/fail the task via lifecycle transition CLI interop (`omx team api transition-task-status --json`) from `in_progress` to `completed` or `failed`.
53
68
  - Do NOT directly write lifecycle fields (`status`, `owner`, `result`, `error`) in task files.
54
- 9. Use `team_release_task_claim` / `releaseTaskClaim` only for rollback/requeue to `pending` (not for completion).
69
+ 9. Use `omx team api release-task-claim --json` only for rollback/requeue to `pending` (not for completion).
55
70
  10. Update your worker status:
56
71
  `<team_state_root>/team/<teamName>/workers/<workerName>/status.json` with `{"state":"idle", ...}`
57
72
 
@@ -67,9 +82,24 @@ Note: leader dispatch is state-first. The durable queue lives at:
67
82
  `<team_state_root>/team/<teamName>/dispatch/requests.json`
68
83
  Hooks/watchers may nudge you after mailbox/inbox state is already written.
69
84
 
70
- Use MCP tools:
71
- - `team_mailbox_list` to read
72
- - `team_mailbox_mark_delivered` to acknowledge delivery
85
+ Use CLI interop:
86
+ - `omx team api mailbox-list --json` to read
87
+ - `omx team api mailbox-mark-delivered --json` to acknowledge delivery
88
+
89
+ Copy/paste templates:
90
+
91
+ ```bash
92
+ omx team api mailbox-list --input "{\"team_name\":\"<teamName>\",\"worker\":\"<workerName>\"}" --json
93
+ omx team api mailbox-mark-delivered --input "{\"team_name\":\"<teamName>\",\"worker\":\"<workerName>\",\"message_id\":\"<MESSAGE_ID>\"}" --json
94
+ ```
95
+
96
+ ## Dispatch Discipline (state-first)
97
+
98
+ Worker sessions should treat team state + CLI interop as the source of truth.
99
+
100
+ - Prefer inbox/mailbox/task state and `omx team api ... --json` operations.
101
+ - Do **not** rely on ad-hoc tmux keystrokes as a primary delivery channel.
102
+ - If a manual trigger arrives (for example `tmux send-keys` nudge), treat it only as a prompt to re-check state and continue through the normal claim-safe lifecycle.
73
103
 
74
104
  ## Shutdown
75
105