openclaw-code-agent 2.3.0 → 3.0.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 +164 -7
- package/dist/index.js +110 -53
- package/openclaw.plugin.json +17 -3
- package/package.json +21 -8
- package/skills/code-agent-orchestration/SKILL.md +151 -14
- package/workflows/plan-approval.lobster +0 -15
package/README.md
CHANGED
|
@@ -43,24 +43,45 @@ For the current version-pinned breakdown, see [docs/ACP-COMPARISON.md](docs/ACP-
|
|
|
43
43
|
|
|
44
44
|
- **Multi-session management** — Run multiple concurrent coding agent sessions, each with a unique ID and human-readable name
|
|
45
45
|
- **Plan → Execute workflow** — Claude Code sessions expose plan mode; Codex uses a soft first-turn planning prompt while staying externally in implement mode
|
|
46
|
+
- **Plan approval modes** — Three configurable modes (`ask` / `delegate` / `approve`) control how the orchestrator handles plan-approval events before execution
|
|
46
47
|
- **Real Codex approval policy support** — Codex sessions default to the real Codex SDK/CLI `approvalPolicy: "on-request"` and can be pinned back to `"never"` via `harnesses.codex.approvalPolicy`
|
|
48
|
+
- **Git worktree isolation** — Opt-in worktree support keeps main checkout clean; configurable strategies: `manual`, `ask`, `delegate`, `auto-merge`, `auto-pr`
|
|
49
|
+
- **Telegram inline buttons** — `ask` strategy sends inline keyboard buttons (Merge locally / Create PR) directly in chat; button taps route back to the plugin
|
|
50
|
+
- **PR lifecycle management** — `agent_pr` detects existing open/merged/closed PRs and updates instead of duplicating; full lifecycle handling via `gh` CLI
|
|
51
|
+
- **Conflict resolution** — Auto-merge conflicts spawn Claude Code conflict-resolver sessions automatically
|
|
47
52
|
- **Thread-based routing** — Notifications go to the Telegram thread/topic where the session was launched
|
|
48
53
|
- **Pause + auto-resume** — Non-question turn completion pauses sessions (`done`) and next `agent_respond` auto-resumes with context intact
|
|
49
54
|
- **Turn-end wake signaling** — Every turn end emits a deterministic wake signal with output preview and waiting hint
|
|
50
55
|
- **Smart waiting detection** — Heuristic waiting detector reduces false-positive wake escalations
|
|
51
56
|
- **Multi-turn conversations** — Send follow-up messages, interrupt, or iterate with a running agent
|
|
52
57
|
- **Session resume & fork** — Resume any completed session or fork it into a new conversation branch
|
|
58
|
+
- **Deliverable mode** — `output_mode: "deliverable"` switches from `✅ Completed` to `📄 Deliverable ready` for document/report generation tasks
|
|
53
59
|
- **Merged session listing** — `agent_sessions` shows active + persisted sessions in one view (deduped by internal session ID)
|
|
54
60
|
- **Pending MessageStream safety** — queued follow-ups are preserved across turn completion so messages are not dropped
|
|
55
61
|
- **Codex SDK streaming harness** — uses `@openai/codex-sdk` thread streaming with soft first-turn planning, waiting detection, and activity heartbeats
|
|
56
62
|
- **Multi-agent support** — Route notifications to the correct agent/chat via workspace-based channel mapping
|
|
57
63
|
- **Auto-respond rules** — Orchestrator auto-handles permission requests and confirmations; forwards real decisions to you
|
|
58
64
|
- **Anti-cascade protection** — Orchestrator never launches new sessions from wake events
|
|
65
|
+
- **Startup recovery** — Orphaned worktrees and crashed running-state sessions are automatically cleaned up on gateway restart
|
|
59
66
|
- **Automatic cleanup** — Completed sessions are garbage-collected after a configurable TTL (`sessionGcAgeMinutes`, default 24h); IDs persist for resume
|
|
60
67
|
- **Harness-agnostic architecture** — Pluggable `AgentHarness` interface allows adding new coding agent backends
|
|
61
68
|
|
|
62
69
|
---
|
|
63
70
|
|
|
71
|
+
## Compatibility
|
|
72
|
+
|
|
73
|
+
| Plugin version | OpenClaw version |
|
|
74
|
+
|---|---|
|
|
75
|
+
| 2.3.x | >=2026.3.13 |
|
|
76
|
+
| 2.4.x | >=2026.3.22 |
|
|
77
|
+
| 3.0.x | >=2026.3.22 |
|
|
78
|
+
|
|
79
|
+
Tested against OpenClaw v2026.3.23. The plugin uses CLI-based integration and is unaffected by OpenClaw plugin SDK surface changes.
|
|
80
|
+
|
|
81
|
+
**Codex model options (v2026.3.22+):** In addition to the default `gpt-5.4`, you can configure `gpt-5.4-mini` or `gpt-5.4-nano` in `harnesses.codex.allowedModels` for lower-cost Codex sessions.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
64
85
|
## Quick Start
|
|
65
86
|
|
|
66
87
|
### 1. Install the plugin
|
|
@@ -129,12 +150,16 @@ Put that in `~/.codex/config.toml`. This keeps Codex on the ChatGPT auth path an
|
|
|
129
150
|
|
|
130
151
|
| Tool | Description | Key Parameters |
|
|
131
152
|
|------|-------------|----------------|
|
|
132
|
-
| `agent_launch` | Start a new coding agent session in background | `prompt`, `name`, `workdir`, `model`, `resume_session_id`, `fork_session`, `permission_mode`, `harness` |
|
|
153
|
+
| `agent_launch` | Start a new coding agent session in background | `prompt`, `name`, `workdir`, `model`, `resume_session_id`, `fork_session`, `permission_mode`, `harness`, `worktree_strategy`, `output_mode` |
|
|
133
154
|
| `agent_respond` | Send a follow-up message to a running session | `session`, `message`, `interrupt`, `approve`, `userInitiated` |
|
|
134
155
|
| `agent_kill` | Terminate or complete a running session | `session`, `reason` |
|
|
135
156
|
| `agent_output` | Read buffered output from a session | `session`, `lines`, `full` |
|
|
136
157
|
| `agent_sessions` | List recent sessions (5 by default, `full` for 24h view) | `status`, `full` |
|
|
137
158
|
| `agent_stats` | Show usage metrics (counts, durations, costs) | *(none)* |
|
|
159
|
+
| `agent_merge` | Merge a worktree branch back to base branch | `session`, `base_branch`, `strategy`, `push`, `delete_branch` |
|
|
160
|
+
| `agent_pr` | Create or update a GitHub PR for a worktree branch (full lifecycle) | `session`, `title`, `body`, `base_branch`, `force_new` |
|
|
161
|
+
| `agent_worktree_status` | Show worktree status for sessions | `session` (optional) |
|
|
162
|
+
| `agent_worktree_cleanup` | Clean up merged agent/* branches | `workdir`, `base_branch`, `skip_session_check`, `dry_run`, `session` |
|
|
138
163
|
|
|
139
164
|
Core orchestration workflows use `agent_launch`, `agent_respond`, `agent_output`, `agent_sessions`, and `agent_kill`.
|
|
140
165
|
|
|
@@ -179,11 +204,16 @@ The plugin sends targeted notifications to the originating Telegram thread:
|
|
|
179
204
|
| ❓ | Waiting for input | Session is waiting for user input |
|
|
180
205
|
| 📋 | Plan ready | Plan approval requested — reply "go" to approve |
|
|
181
206
|
| ⏸️ | Paused after turn | Turn completed, session paused (auto-resumable) |
|
|
207
|
+
| ↪️ | Responded / Redirected | `agent_respond` sent a message; also fires when `interrupt: true` redirects active work |
|
|
208
|
+
| 👍 | Plan approved | Plan was approved via `agent_respond(..., approve: true)` |
|
|
182
209
|
| ▶️ | Auto-resumed | Session resumed on the next `agent_respond` |
|
|
183
210
|
| ✅ | Completed | Completion summary with cost and duration |
|
|
184
|
-
|
|
|
211
|
+
| 📄 | Deliverable ready | Session finished with `output_mode: "deliverable"` |
|
|
212
|
+
| ❌ | Failed | Error notification with `harnessSessionId` and resume guidance |
|
|
185
213
|
| 💤 | Idle timeout | Session timed out while waiting; auto-resumes on next respond |
|
|
186
214
|
| ⛔ | Stopped | Session was stopped by user, shutdown, or another forced stop |
|
|
215
|
+
| 🔀 | Worktree decision (`ask`) | Telegram inline buttons sent: Merge locally / Create PR |
|
|
216
|
+
| 🤖 | Worktree decision (`delegate`) | Wake sent to orchestrator with diff context for autonomous decision |
|
|
187
217
|
|
|
188
218
|
---
|
|
189
219
|
|
|
@@ -227,33 +257,40 @@ Set values in `~/.openclaw/openclaw.json` under `plugins.entries["openclaw-code-
|
|
|
227
257
|
| `fallbackChannel` | `string` | — | Default notification channel when no workspace match found |
|
|
228
258
|
| `maxSessions` | `number` | `20` | Maximum concurrent sessions |
|
|
229
259
|
| `maxAutoResponds` | `number` | `10` | Max consecutive auto-responds before requiring user input |
|
|
230
|
-
| `permissionMode` | `string` | `"plan"` | Plugin orchestration mode: `"default"` / `"plan"`
|
|
260
|
+
| `permissionMode` | `string` | `"plan"` | Plugin orchestration mode: `"default"` (standard prompts) / `"plan"` (present plan first) / `"bypassPermissions"` (fully autonomous) |
|
|
231
261
|
| `idleTimeoutMinutes` | `number` | `15` | Idle timeout before auto-kill |
|
|
232
262
|
| `sessionGcAgeMinutes` | `number` | `1440` | TTL for completed/failed/killed runtime sessions before GC eviction |
|
|
233
263
|
| `maxPersistedSessions` | `number` | `10000` | Max completed sessions kept for resume; the 24h GC TTL (`sessionGcAgeMinutes`) is the primary retention control |
|
|
234
|
-
| `planApproval` | `string` | `"
|
|
264
|
+
| `planApproval` | `string` | `"ask"` | `"ask"` (always forward to user) / `"delegate"` (orchestrator decides) / `"approve"` (orchestrator can auto-approve) |
|
|
235
265
|
| `defaultHarness` | `string` | `"claude-code"` | Default harness for new sessions (`"claude-code"` / `"codex"`) |
|
|
236
266
|
| `harnesses` | `object` | built-in defaults | Per-harness defaults and restrictions. Built-in defaults: `claude-code.defaultModel = "sonnet"`, `claude-code.allowedModels = ["sonnet","opus"]`, `codex.defaultModel = "gpt-5.4"`, `codex.allowedModels = ["gpt-5.4"]`, `codex.reasoningEffort = "medium"`, `codex.approvalPolicy = "on-request"` |
|
|
237
267
|
| `defaultWorkdir` | `string` | — | Default working directory for new sessions |
|
|
268
|
+
| `defaultWorktreeStrategy` | `string` | `"ask"` | Default worktree strategy for new sessions when `worktree_strategy` is omitted from `agent_launch`. Accepts any `WorktreeStrategy` value including `"delegate"` |
|
|
269
|
+
| `worktreeDir` | `string` | `<repoRoot>/.worktrees` | Override base directory for agent worktrees |
|
|
270
|
+
|
|
271
|
+
Out of the box (with no custom config), the plugin delivers the full interactive experience: `planApproval: "ask"` ensures every plan is forwarded to the user for review before execution, and `defaultWorktreeStrategy: "ask"` means every session runs in an isolated git worktree and presents inline Telegram buttons (Merge locally / Create PR) on completion. Set either to `"delegate"` to hand those decisions to the orchestrator autonomously.
|
|
238
272
|
|
|
239
273
|
### Permission Mode Mapping By Harness
|
|
240
274
|
|
|
241
275
|
Permission modes are shared at the plugin API, but each harness maps them differently:
|
|
242
276
|
|
|
243
277
|
- **Claude Code harness**
|
|
244
|
-
- `default`, `plan`, `
|
|
278
|
+
- `default`, `plan`, `bypassPermissions` are passed through the SDK
|
|
245
279
|
- **Codex harness**
|
|
246
280
|
- Always runs with SDK thread option `sandboxMode: "danger-full-access"`
|
|
247
281
|
- Uses Codex SDK/CLI `approvalPolicy: "on-request"` by default, or `"never"` when `harnesses.codex.approvalPolicy` is set
|
|
248
282
|
- Supports `harnesses.codex.defaultModel`, `harnesses.codex.allowedModels`, `harnesses.codex.reasoningEffort`, and `harnesses.codex.approvalPolicy`
|
|
249
283
|
- In `bypassPermissions`, the harness adds filesystem root (`/` on POSIX) to Codex `additionalDirectories`, plus optional extras from `OPENCLAW_CODEX_BYPASS_ADDITIONAL_DIRS` (comma-separated)
|
|
250
284
|
- `setPermissionMode()` is applied by recreating the thread on the next turn via `resumeThread` (same thread ID)
|
|
251
|
-
- `plan`
|
|
285
|
+
- `plan` remains a plugin behavioral orchestration constraint (planning/approval flow), not a Codex sandbox or SDK approval setting
|
|
252
286
|
|
|
253
287
|
### Runtime Environment Overrides
|
|
254
288
|
|
|
255
289
|
- `OPENCLAW_CODE_AGENT_SESSIONS_PATH` — explicit persisted session index path
|
|
256
290
|
- `OPENCLAW_HOME` — base dir for persisted session index when explicit path is unset (`$OPENCLAW_HOME/code-agent-sessions.json`)
|
|
291
|
+
- `OPENCLAW_WORKTREE_DIR` — base directory for worktrees (default: system tmpdir)
|
|
292
|
+
- `OPENCLAW_WORKTREE_BASE_BRANCH` — global base branch override (default: auto-detected from repo)
|
|
293
|
+
- `OPENCLAW_WORKTREE_CLEANUP_AGE_HOURS` — age threshold for orphan worktree cleanup (default: 1 hour)
|
|
257
294
|
- `OPENCLAW_CODEX_BYPASS_ADDITIONAL_DIRS` — comma-separated extra directories for Codex bypass mode
|
|
258
295
|
- `OPENCLAW_CODEX_HEARTBEAT_MS` — Codex activity heartbeat interval in milliseconds (default `10000`)
|
|
259
296
|
|
|
@@ -264,6 +301,124 @@ Permission modes are shared at the plugin API, but each harness maps them differ
|
|
|
264
301
|
- Runtime records are evicted after `sessionGcAgeMinutes` (default 1440 / 24h)
|
|
265
302
|
- Eviction means **removed from runtime cache**, not deleted permanently; persisted session records remain resumable
|
|
266
303
|
|
|
304
|
+
### Discord Notifications
|
|
305
|
+
|
|
306
|
+
To route notifications to a Discord channel or user, set `originChannel` (or `fallbackChannel`) using the Discord format:
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
discord|channel:CHANNEL_ID
|
|
310
|
+
discord|accountId|channel:CHANNEL_ID
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
- Use `channel:CHANNEL_ID` for a server channel, or `user:USER_ID` for a DM.
|
|
314
|
+
- The `accountId` segment is optional and selects a specific Discord bot account when you have multiple Discord integrations.
|
|
315
|
+
- Discord session keys (`agent:*:discord:channel:ID`) are auto-parsed — no explicit `originChannel` is required when a session is launched from a Discord thread.
|
|
316
|
+
- If using bot notifications, set `allowBots: "mentions"` in your OpenClaw Discord integration config so the bot is permitted to receive and forward mention events.
|
|
317
|
+
|
|
318
|
+
Example `fallbackChannel` for Discord:
|
|
319
|
+
|
|
320
|
+
```json
|
|
321
|
+
"fallbackChannel": "discord|channel:1234567890123456789"
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
With an explicit account:
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
"fallbackChannel": "discord|my-discord-bot|channel:1234567890123456789"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Git Worktree Support
|
|
331
|
+
|
|
332
|
+
When `worktree_strategy` is set to anything other than `"off"` (via `agent_launch` or plugin config `defaultWorktreeStrategy`), the agent will automatically create a git worktree for the session if the `workdir` is a git repository. This keeps the main checkout clean while the agent works in an isolated branch.
|
|
333
|
+
|
|
334
|
+
**Behavior:**
|
|
335
|
+
- Worktree path: `<OPENCLAW_WORKTREE_DIR>/openclaw-worktree-<session-name>` (default: system tmpdir)
|
|
336
|
+
- Branch name: `agent/<session-name>` (sanitized, with random suffix if needed)
|
|
337
|
+
- Worktrees are automatically cleaned up when the session terminates
|
|
338
|
+
- **Branches are kept** — `agent/<name>` branches persist after session cleanup to allow pushing commits
|
|
339
|
+
- Base branch auto-detection: `OPENCLAW_WORKTREE_BASE_BRANCH` env var → origin/HEAD → main → master
|
|
340
|
+
|
|
341
|
+
**Worktree Strategies:**
|
|
342
|
+
|
|
343
|
+
Control what happens to worktree branches when a session completes via `worktree_strategy`. Set it per-launch in `agent_launch`, or set a default for all sessions via `defaultWorktreeStrategy` in plugin config.
|
|
344
|
+
|
|
345
|
+
- **`off`** — No worktree. Session runs in the main checkout.
|
|
346
|
+
- **`ask`** (plugin config default) — Push branch and send a Telegram notification with inline buttons (Merge locally / Create PR). Also wakes the orchestrator with full decision context (diff summary, original prompt, decision guidance) to present the choice to the user.
|
|
347
|
+
- **`delegate`** — Push branch and wake the orchestrator to decide autonomously (merge, create PR, or leave for later). Always sends a brief one-line notification to the user. **Available via `defaultWorktreeStrategy` plugin config; not exposed as a `worktree_strategy` tool parameter.**
|
|
348
|
+
- **`auto-merge`** — Automatically merge back to the base branch on session completion. On conflicts, spawns a Claude Code conflict-resolver session.
|
|
349
|
+
- **`auto-pr`** — Automatically open a GitHub PR on session completion (requires `gh` CLI). If `gh` is unavailable, falls back to `ask` strategy.
|
|
350
|
+
- **`manual`** — Push the branch but take no further action; user handles merge/PR manually via `agent_merge` or `agent_pr`.
|
|
351
|
+
|
|
352
|
+
Example with auto-pr:
|
|
353
|
+
```javascript
|
|
354
|
+
agent_launch({
|
|
355
|
+
prompt: "Fix the auth bug",
|
|
356
|
+
worktree_strategy: "auto-pr"
|
|
357
|
+
})
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**`output_mode: "deliverable"`:**
|
|
361
|
+
|
|
362
|
+
Use this when the session is producing a document, report, or artifact rather than a code change. Instead of the default `✅ Completed` notification, the session emits `📄 Deliverable ready`:
|
|
363
|
+
|
|
364
|
+
```javascript
|
|
365
|
+
agent_launch({
|
|
366
|
+
prompt: "Write a technical spec for the new auth system",
|
|
367
|
+
output_mode: "deliverable"
|
|
368
|
+
})
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Merge-Back Tools:**
|
|
372
|
+
|
|
373
|
+
Four tools are available for manual worktree management:
|
|
374
|
+
|
|
375
|
+
- `agent_merge` — Merge a worktree branch to base branch. On conflicts, spawns conflict-resolver session.
|
|
376
|
+
- `agent_pr` — Create or update a GitHub PR for a worktree branch (requires `gh` CLI). Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, detects merged/closed PRs.
|
|
377
|
+
- `agent_worktree_status` — Show worktree status for sessions (branch name, commits ahead, merge/PR status).
|
|
378
|
+
- `agent_worktree_cleanup` — List and delete merged `agent/*` branches. Use `dry_run: true` to preview, `force: true` to delete all agent branches regardless of merge status.
|
|
379
|
+
|
|
380
|
+
**PR Lifecycle Management:**
|
|
381
|
+
|
|
382
|
+
When using `auto-pr` strategy or calling `agent_pr` manually:
|
|
383
|
+
|
|
384
|
+
- **No PR exists**: Creates a new PR with auto-generated title and commit summary
|
|
385
|
+
- **Open PR exists**: Pushes new commits and adds a detailed comment with diff stats
|
|
386
|
+
- **Merged PR**: Notifies that the PR was already merged
|
|
387
|
+
- **Closed PR**: Prompts user to choose: reopen manually, delete branch, or recreate PR
|
|
388
|
+
|
|
389
|
+
**Conflict Resolution:**
|
|
390
|
+
|
|
391
|
+
When auto-merge encounters conflicts, a Claude Code session is automatically spawned with `bypassPermissions` to resolve conflicts and commit the resolution. You'll receive a notification when this happens.
|
|
392
|
+
|
|
393
|
+
**Cleanup:**
|
|
394
|
+
Users can manually prune accumulated agent branches with `agent_worktree_cleanup`. Three categories are always protected from deletion: branches with active sessions, branches with unmerged commits, and branches with open PRs.
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
// Preview what would be deleted
|
|
398
|
+
agent_worktree_cleanup({ workdir: "/path/to/repo", dry_run: true })
|
|
399
|
+
|
|
400
|
+
// Delete fully merged branches (unmerged and open-PR branches are always kept)
|
|
401
|
+
agent_worktree_cleanup({ workdir: "/path/to/repo" })
|
|
402
|
+
|
|
403
|
+
// Skip the active-session check (e.g. session crashed and left a stale branch)
|
|
404
|
+
// NOTE: unmerged-commit and open-PR protections still apply
|
|
405
|
+
agent_worktree_cleanup({ workdir: "/path/to/repo", skip_session_check: true })
|
|
406
|
+
|
|
407
|
+
// Dismiss a pending worktree decision for a session without merging
|
|
408
|
+
agent_worktree_cleanup({ session: "fix-auth-bug" })
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Environment Variables:**
|
|
412
|
+
- `OPENCLAW_WORKTREE_DIR` — Base directory for worktrees (default: system tmpdir)
|
|
413
|
+
- `OPENCLAW_WORKTREE_BASE_BRANCH` — Global base branch override (default: auto-detected)
|
|
414
|
+
- `OPENCLAW_WORKTREE_CLEANUP_AGE_HOURS` — Age threshold for orphan worktree cleanup (default: 1 hour)
|
|
415
|
+
|
|
416
|
+
**Limitations:**
|
|
417
|
+
- Worktree creation requires the workdir to be a git repository
|
|
418
|
+
- Only works with committed changes — uncommitted changes in the main checkout are not transferred to the worktree
|
|
419
|
+
- Worktree creation is enabled by default via `defaultWorktreeStrategy: "ask"`. Pass `worktree_strategy: "off"` to `agent_launch` (or set `defaultWorktreeStrategy: "off"` in plugin config) to disable
|
|
420
|
+
- Push and PR operations (`ask`, `auto-pr`, `delegate`) require a configured remote
|
|
421
|
+
|
|
267
422
|
### Example
|
|
268
423
|
|
|
269
424
|
```json
|
|
@@ -287,6 +442,8 @@ Permission modes are shared at the plugin API, but each harness maps them differ
|
|
|
287
442
|
}
|
|
288
443
|
},
|
|
289
444
|
"permissionMode": "plan",
|
|
445
|
+
"planApproval": "ask", // "ask" = always forward plans to user (default); "delegate" = orchestrator decides autonomously
|
|
446
|
+
"defaultWorktreeStrategy": "ask", // "ask" = isolated worktree + inline Merge/PR buttons (default); "off" = no worktree
|
|
290
447
|
"fallbackChannel": "telegram|my-bot|123456789",
|
|
291
448
|
"agentChannels": {
|
|
292
449
|
"/home/user/project-alpha": "telegram|my-bot|123456789",
|
|
@@ -403,7 +560,7 @@ openclaw-code-agent/
|
|
|
403
560
|
│ ├── notifications.ts # Notification service
|
|
404
561
|
│ ├── actions/respond.ts # Shared respond logic (tool + command)
|
|
405
562
|
│ ├── application/ # Shared app-layer logic used by tools + commands
|
|
406
|
-
│ ├── tools/ # Tool implementations (
|
|
563
|
+
│ ├── tools/ # Tool implementations (9 tools)
|
|
407
564
|
│ └── commands/ # Chat command implementations (7 commands)
|
|
408
565
|
├── tests/ # Unit tests (node:test + tsx)
|
|
409
566
|
├── skills/ # Orchestration skill definitions
|