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.
- package/README.de.md +7 -2
- package/README.es.md +7 -2
- package/README.fr.md +7 -2
- package/README.it.md +7 -2
- package/README.ja.md +7 -2
- package/README.ko.md +7 -2
- package/README.md +61 -11
- package/README.pt.md +7 -2
- package/README.ru.md +7 -2
- package/README.tr.md +7 -2
- package/README.vi.md +7 -2
- package/README.zh-TW.md +366 -0
- package/README.zh.md +7 -2
- package/dist/cli/__tests__/index.test.js +70 -4
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +100 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +219 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/catalog-contract.d.ts.map +1 -1
- package/dist/cli/catalog-contract.js +8 -2
- package/dist/cli/catalog-contract.js.map +1 -1
- package/dist/cli/index.d.ts +7 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +58 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +50 -17
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +257 -0
- package/dist/cli/team.js.map +1 -1
- package/dist/config/__tests__/models.test.js +11 -11
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/models.d.ts +4 -3
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +6 -5
- package/dist/config/models.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +46 -3
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -7
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +176 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +61 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +17 -7
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js +26 -16
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +2 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +41 -4
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +5 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/mcp/__tests__/path-traversal.test.js +9 -227
- package/dist/mcp/__tests__/path-traversal.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-schema.test.js +16 -20
- package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-team-tools.test.js +30 -487
- package/dist/mcp/__tests__/state-server-team-tools.test.js.map +1 -1
- package/dist/mcp/state-server.d.ts +179 -0
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +217 -1111
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/mcp/team-server.d.ts.map +1 -1
- package/dist/mcp/team-server.js +28 -7
- package/dist/mcp/team-server.js.map +1 -1
- package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +5 -0
- package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/dispatch-cooldown.test.js +100 -0
- package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +1 -0
- package/dist/notifications/__tests__/temp-mode.test.d.ts +2 -0
- package/dist/notifications/__tests__/temp-mode.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/temp-mode.test.js +172 -0
- package/dist/notifications/__tests__/temp-mode.test.js.map +1 -0
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +59 -6
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/dispatch-cooldown.d.ts +36 -0
- package/dist/notifications/dispatch-cooldown.d.ts.map +1 -0
- package/dist/notifications/dispatch-cooldown.js +109 -0
- package/dist/notifications/dispatch-cooldown.js.map +1 -0
- package/dist/notifications/index.d.ts +5 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +39 -8
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/temp-contract.d.ts +22 -0
- package/dist/notifications/temp-contract.d.ts.map +1 -0
- package/dist/notifications/temp-contract.js +147 -0
- package/dist/notifications/temp-contract.js.map +1 -0
- package/dist/notifications/types.d.ts +18 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/config.test.js +81 -0
- package/dist/openclaw/__tests__/config.test.js.map +1 -1
- package/dist/openclaw/__tests__/dispatcher.test.js +50 -7
- package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
- package/dist/openclaw/config.d.ts +4 -0
- package/dist/openclaw/config.d.ts.map +1 -1
- package/dist/openclaw/config.js +110 -16
- package/dist/openclaw/config.js.map +1 -1
- package/dist/openclaw/dispatcher.d.ts +10 -4
- package/dist/openclaw/dispatcher.d.ts.map +1 -1
- package/dist/openclaw/dispatcher.js +40 -10
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/openclaw/types.d.ts +5 -1
- package/dist/openclaw/types.d.ts.map +1 -1
- package/dist/team/__tests__/api-interop.test.d.ts +2 -0
- package/dist/team/__tests__/api-interop.test.d.ts.map +1 -0
- package/dist/team/__tests__/api-interop.test.js +1052 -0
- package/dist/team/__tests__/api-interop.test.js.map +1 -0
- package/dist/team/__tests__/mcp-comm.test.js +30 -0
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/runtime-cli.test.js +6 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +52 -22
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-claude-workers-demo.test.js +190 -0
- package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +1 -0
- package/dist/team/__tests__/tmux-session.test.js +45 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +20 -12
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/api-interop.d.ts +19 -0
- package/dist/team/api-interop.d.ts.map +1 -0
- package/dist/team/api-interop.js +578 -0
- package/dist/team/api-interop.js.map +1 -0
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +26 -0
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/runtime-cli.d.ts +3 -0
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +24 -2
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +67 -11
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/types.d.ts +1 -1
- package/dist/team/state/types.d.ts.map +1 -1
- package/dist/team/state.d.ts +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +17 -5
- 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 +48 -19
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/package.json +1 -1
- package/scripts/demo-claude-workers.sh +241 -0
- package/scripts/demo-team-e2e.sh +179 -0
- package/scripts/notify-hook/team-dispatch.js +186 -12
- package/scripts/notify-hook/team-leader-nudge.js +42 -2
- package/scripts/notify-hook/team-worker.js +63 -4
- package/skills/configure-notifications/SKILL.md +193 -185
- package/skills/omx-setup/SKILL.md +1 -1
- package/skills/team/SKILL.md +47 -5
- package/skills/worker/SKILL.md +40 -10
- package/templates/AGENTS.md +7 -3
- package/templates/catalog-manifest.json +26 -3
- package/skills/configure-discord/SKILL.md +0 -256
- package/skills/configure-openclaw/SKILL.md +0 -264
- package/skills/configure-slack/SKILL.md +0 -226
- 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
|
|
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
|
-
|
|
29
|
+
- **Native integrations (first-class):** Discord, Telegram, Slack
|
|
30
|
+
- **Generic extensibility integrations:** `custom_webhook_command`, `custom_cli_command`
|
|
31
31
|
|
|
32
|
-
|
|
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:
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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:
|
|
60
|
+
## Step 2: Main Menu
|
|
67
61
|
|
|
68
|
-
|
|
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** -
|
|
90
|
-
2. **Telegram** -
|
|
91
|
-
3. **Slack** -
|
|
92
|
-
4. **
|
|
93
|
-
5. **
|
|
94
|
-
6. **
|
|
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:
|
|
75
|
+
## Step 3: Configure Native Platforms (Discord / Telegram / Slack)
|
|
97
76
|
|
|
98
|
-
|
|
77
|
+
Collect and validate platform-specific values, then write directly under native keys:
|
|
99
78
|
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
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
|
-
|
|
84
|
+
Do not write these as generic command/webhook aliases.
|
|
108
85
|
|
|
109
|
-
## Step 4:
|
|
86
|
+
## Step 4: Configure Generic Extensibility
|
|
110
87
|
|
|
111
|
-
|
|
88
|
+
### 4a) `custom_webhook_command`
|
|
112
89
|
|
|
113
|
-
|
|
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
|
-
|
|
97
|
+
Write:
|
|
116
98
|
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
129
|
-
--arg
|
|
130
|
-
|
|
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
|
-
|
|
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
|
|
142
|
+
### 4b-1) OpenClaw + Clawdbot Agent Workflow (recommended for dev)
|
|
136
143
|
|
|
137
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
151
|
-
--
|
|
152
|
-
'.notifications
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
### 4c. Notification Profiles
|
|
212
|
+
Verification for this mode:
|
|
158
213
|
|
|
159
|
-
|
|
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
|
-
|
|
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
|
-
|
|
221
|
+
```bash
|
|
222
|
+
# 1) identify active OMX tmux sessions
|
|
223
|
+
tmux list-sessions -F '#{session_name}' | rg '^omx-' || true
|
|
181
224
|
|
|
182
|
-
|
|
225
|
+
# 2) confirm hook templates include session/tmux context
|
|
226
|
+
jq '.notifications.openclaw.hooks' "$CONFIG_FILE"
|
|
183
227
|
|
|
184
|
-
|
|
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
|
-
|
|
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
|
-
|
|
237
|
+
OMX accepts both:
|
|
238
|
+
- explicit `notifications.openclaw` schema (legacy/runtime shape)
|
|
239
|
+
- generic aliases (`custom_webhook_command`, `custom_cli_command`)
|
|
209
240
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
245
|
+
## Step 5: Cross-Cutting Settings
|
|
217
246
|
|
|
218
|
-
|
|
247
|
+
### Verbosity
|
|
248
|
+
- minimal / session (recommended) / agent / verbose
|
|
219
249
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
Use AskUserQuestion:
|
|
250
|
+
### Idle cooldown
|
|
251
|
+
- `notifications.idleCooldownSeconds`
|
|
223
252
|
|
|
224
|
-
|
|
253
|
+
### Profiles
|
|
254
|
+
- `notifications.profiles`
|
|
255
|
+
- `notifications.defaultProfile`
|
|
225
256
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
261
|
+
## Step 6: Disable All Notifications
|
|
231
262
|
|
|
232
263
|
```bash
|
|
233
|
-
|
|
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
|
-
|
|
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
|
-
|
|
269
|
+
After writing config, run a smoke check:
|
|
246
270
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
271
|
+
```bash
|
|
272
|
+
npm run build
|
|
273
|
+
```
|
|
250
274
|
|
|
251
|
-
|
|
275
|
+
For OpenClaw-like HTTP integrations, verify both:
|
|
276
|
+
- `/hooks/wake` smoke test
|
|
277
|
+
- `/hooks/agent` delivery verification
|
|
252
278
|
|
|
253
|
-
|
|
279
|
+
## Final Summary Template
|
|
254
280
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
|
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
|
|
package/skills/team/SKILL.md
CHANGED
|
@@ -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
|
|
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 `
|
|
219
|
-
- Claim task via
|
|
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 `
|
|
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.
|
package/skills/worker/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
33
|
-
- `
|
|
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
|
|
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
|
|
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 `
|
|
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
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
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
|
|