overlord-cli 0.2608200954.0 → 0.2608210851.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/dist/connectors/HARNESS-MATRIX.md +1 -1
- package/dist/connectors/VERSION +1 -1
- package/dist/connectors/adapters/antigravity/plugin.json +1 -1
- package/dist/connectors/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/dist/connectors/adapters/codex/.codex-plugin/hooks.json +11 -0
- package/dist/connectors/adapters/codex/.codex-plugin/plugin.json +1 -1
- package/dist/connectors/adapters/codex/CAPABILITIES.md +3 -2
- package/dist/connectors/adapters/codex/README.md +2 -1
- package/dist/connectors/adapters/codex/conformance-manifest.yaml +4 -1
- package/dist/connectors/adapters/codex/fixtures/agent-session-hooks.json +2 -3
- package/dist/connectors/adapters/codex/fixtures/post-tool-use-hook.json +13 -0
- package/dist/connectors/adapters/codex/harness-capabilities.yaml +12 -2
- package/dist/connectors/adapters/codex/scripts/post-tool-use-hook.sh +30 -0
- package/dist/connectors/adapters/cursor/.cursor-plugin/plugin.json +1 -1
- package/dist/connectors/core/overlord-mission/reference/cli.md +1 -1
- package/dist/connectors/core/overlord-mission/reference/mcp.md +2 -2
- package/dist/connectors/core/scripts/overlord-mcp.mjs +215 -2
- package/dist/index.js +127 -11
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ Legend: ✅ supported (fixture-proven) · ⛔ unsupported (harness cannot) ·
|
|
|
28
28
|
| `observe.prompt` | ⛔ unsupported | ✅ supported | ✅ supported | ✅ supported | 🚧 not-implemented | ✅ supported |
|
|
29
29
|
| `observe.toolCall` | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented |
|
|
30
30
|
| `observe.toolResult` | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | ✅ supported | ✅ supported | 🚧 not-implemented |
|
|
31
|
-
| `observe.fileEdit` | 🚧 not-implemented | ✅ supported |
|
|
31
|
+
| `observe.fileEdit` | 🚧 not-implemented | ✅ supported | ✅ supported | ✅ supported | ✅ supported | 🚧 not-implemented |
|
|
32
32
|
| `observe.sessionLifecycle` | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | ✅ supported | 🚧 not-implemented |
|
|
33
33
|
| `decide.shell` | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | ✅ supported | 🚧 not-implemented |
|
|
34
34
|
| `decide.mcp` | ❓ unverified | 🚧 not-implemented | 🚧 not-implemented | 🚧 not-implemented | ✅ supported | 🚧 not-implemented |
|
package/dist/connectors/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.32
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://antigravity.google/schemas/v1/plugin.json",
|
|
3
3
|
"name": "overlord",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.32",
|
|
5
5
|
"description": "Chat-driven access to Overlord mission protocol workflows through skills and MCP.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Cooperativ",
|
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
}
|
|
11
11
|
]
|
|
12
12
|
}
|
|
13
|
+
],
|
|
14
|
+
"PostToolUse": [
|
|
15
|
+
{
|
|
16
|
+
"matcher": ".*",
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "/bin/sh -c 'exec \"${CODEX_PLUGIN_ROOT:-$HOME/.codex/plugins/overlord}/scripts/post-tool-use-hook.sh\"'"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
13
24
|
]
|
|
14
25
|
}
|
|
15
26
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
**Harness version verified** `0.147.0` · **range** `>=0.124.0` · **scheme** `semver`
|
|
8
8
|
|
|
9
|
-
**Descriptor digest** `
|
|
9
|
+
**Descriptor digest** `ede31118a90f1afc3d8e934b7fd921759faac4afca1a08e4214a1104ee487b1d`
|
|
10
10
|
|
|
11
11
|
> The tier is derived from passing fixtures, never authored. `unsupported` means the harness
|
|
12
12
|
> cannot do it — do not attempt it. `not-implemented` means it is buildable and unbuilt: that is
|
|
@@ -47,7 +47,7 @@ Per-hook timeouts in seconds; the documentation gives a 600-second default. The
|
|
|
47
47
|
| `observe.prompt` | ✅ supported | `UserPromptSubmit` | fixtures: `fixtures/normalize-user-prompt.json` |
|
|
48
48
|
| `observe.toolCall` | 🚧 not-implemented | `PreToolUse` | tracked as `latch-engine` |
|
|
49
49
|
| `observe.toolResult` | 🚧 not-implemented | `PostToolUse` | tracked as `latch-engine` |
|
|
50
|
-
| `observe.fileEdit` |
|
|
50
|
+
| `observe.fileEdit` | ✅ supported | `PostToolUse` | fixtures: `fixtures/normalize-post-tool-use.json`, `fixtures/agent-session-hooks.json`, `fixtures/post-tool-use-hook.json` |
|
|
51
51
|
| `observe.sessionLifecycle` | 🚧 not-implemented | `SessionStart` | tracked as `latch-engine` |
|
|
52
52
|
| `decide.shell` | 🚧 not-implemented | `PermissionRequest` | tracked as `latch-engine` |
|
|
53
53
|
| `decide.mcp` | 🚧 not-implemented | `PermissionRequest` | tracked as `latch-engine` |
|
|
@@ -65,6 +65,7 @@ Per-hook timeouts in seconds; the documentation gives a 600-second default. The
|
|
|
65
65
|
### Capability notes
|
|
66
66
|
|
|
67
67
|
- **`observe.toolCall`** — Mechanical PreToolUse observation moved to Latch `events`.
|
|
68
|
+
- **`observe.fileEdit`** — The lifecycle PostToolUse registration pipes Codex's native payload to `ovld protocol record-touched`, which appends normalized changed paths to the per-session attribution log read by `deliver`. It is intentionally separate from mechanical agent-session observation, which remains owned by Latch.
|
|
68
69
|
- **`decide.universal`** — Remote permission decisions moved to Latch `awaiting_input` / `latch send --resolve`.
|
|
69
70
|
- **`answer.structuredQuestion`** — `codex app-server` exposes ToolRequestUserInput with per-option label/description and an autoResolutionMs — an ACP-shaped structured question in everything but name. It is unreachable until the single-subscriber question is settled.
|
|
70
71
|
- **`inject.midTurn`** — ThreadInjectItems/TurnSteer exist on the experimental app-server surface only. The binary carries "expected exactly one client subscribed to the thread, found {}", so if the TUI is that one client Overlord cannot also subscribe and this path is closed.
|
|
@@ -70,7 +70,8 @@ This connector is intentionally reviewable against the four connector layers in
|
|
|
70
70
|
|
|
71
71
|
- `skills/overlord-mission/SKILL.md` — Codex adapter template with a `<!-- @connector-core -->` marker; setup interpolates shared core content at install time.
|
|
72
72
|
- `.codex-plugin/hooks.json` — Channel 1 `UserPromptSubmit` follow-up capture through
|
|
73
|
-
`ovld protocol hook-event
|
|
73
|
+
`ovld protocol hook-event` and `PostToolUse` delivery attribution through
|
|
74
|
+
`ovld protocol record-touched`. Mechanical harness observation, permission, and injection
|
|
74
75
|
are Latch's (`latch events` / PTY), not Overlord connector registrations.
|
|
75
76
|
- `.mcp.json` + `scripts/overlord-mcp.mjs` — MCP bridge to common `ovld protocol` operations. The shim is **generated**: it is rendered from `connectors/core/scripts/overlord-mcp.mjs` at setup time with the adapter key substituted, and there is no copy in this directory to edit.
|
|
76
77
|
- `assets/` — branded plugin assets for Codex install surfaces.
|
|
@@ -15,10 +15,11 @@ connector:
|
|
|
15
15
|
harnessCapabilities:
|
|
16
16
|
path: connectors/adapters/codex/harness-capabilities.yaml
|
|
17
17
|
schemaVersion: 1
|
|
18
|
-
digest: "
|
|
18
|
+
digest: "ede31118a90f1afc3d8e934b7fd921759faac4afca1a08e4214a1104ee487b1d"
|
|
19
19
|
capabilities:
|
|
20
20
|
- followUpHook
|
|
21
21
|
- permissionHook
|
|
22
|
+
- editHook
|
|
22
23
|
- nativeResume
|
|
23
24
|
- modelFlag
|
|
24
25
|
- effortFlag
|
|
@@ -27,6 +28,7 @@ connector:
|
|
|
27
28
|
hookTypes:
|
|
28
29
|
- UserPromptSubmit
|
|
29
30
|
- PermissionRequest
|
|
31
|
+
- PostToolUse
|
|
30
32
|
# ── END GENERATED ────────────────────────────────────────────────────────────
|
|
31
33
|
installPath: "~/.codex/plugins/overlord"
|
|
32
34
|
managedFiles:
|
|
@@ -42,6 +44,7 @@ connector:
|
|
|
42
44
|
- "prompt-wrapper.md"
|
|
43
45
|
- "scripts/overlord-mcp.mjs"
|
|
44
46
|
- "scripts/permission-hook.sh"
|
|
47
|
+
- "scripts/post-tool-use-hook.sh"
|
|
45
48
|
- "scripts/user-prompt-submit-hook.sh"
|
|
46
49
|
- "skills/overlord-mission/SKILL.md"
|
|
47
50
|
- "skills/overlord-mission/reference/cli.md"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"fixtureVersion": 1,
|
|
3
3
|
"kind": "source-guard",
|
|
4
|
-
"description": "Codex Channel 1 keeps the protocol follow-up hook. Mechanical agent-session observe/decide/inject is no longer registered.",
|
|
4
|
+
"description": "Codex Channel 1 keeps the protocol follow-up hook and the lifecycle PostToolUse attribution hook. Mechanical agent-session observe/decide/inject is no longer registered.",
|
|
5
5
|
"path": "connectors/adapters/codex/.codex-plugin/hooks.json",
|
|
6
6
|
"assert": {
|
|
7
|
-
"mustContain": ["user-prompt-submit-hook.sh"],
|
|
7
|
+
"mustContain": ["user-prompt-submit-hook.sh", "post-tool-use-hook.sh", "\"PostToolUse\""],
|
|
8
8
|
"mustNotContain": [
|
|
9
9
|
"agent-session-event.sh",
|
|
10
10
|
"agent-session-request.sh",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"permission-hook.sh",
|
|
13
13
|
"\"PermissionRequest\"",
|
|
14
14
|
"\"PreToolUse\"",
|
|
15
|
-
"\"PostToolUse\"",
|
|
16
15
|
"\"SessionStart\"",
|
|
17
16
|
"\"Stop\""
|
|
18
17
|
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fixtureVersion": 1,
|
|
3
|
+
"kind": "source-guard",
|
|
4
|
+
"description": "Codex's lifecycle PostToolUse hook must create its log directory before redirecting stderr, then forward the native payload to record-touched for delivery attribution.",
|
|
5
|
+
"path": "connectors/adapters/codex/scripts/post-tool-use-hook.sh",
|
|
6
|
+
"assert": {
|
|
7
|
+
"mustContain": [
|
|
8
|
+
"mkdir -p \"$LOG_DIR\" 2>/dev/null || true",
|
|
9
|
+
"ovld protocol record-touched",
|
|
10
|
+
"codex-post-tool-use-hook.log"
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -62,9 +62,17 @@ capabilities:
|
|
|
62
62
|
native: PostToolUse
|
|
63
63
|
trackedAs: latch-engine
|
|
64
64
|
observe.fileEdit:
|
|
65
|
-
status:
|
|
65
|
+
status: supported
|
|
66
66
|
native: PostToolUse
|
|
67
|
-
|
|
67
|
+
fixtures:
|
|
68
|
+
- fixtures/normalize-post-tool-use.json
|
|
69
|
+
- fixtures/agent-session-hooks.json
|
|
70
|
+
- fixtures/post-tool-use-hook.json
|
|
71
|
+
notes: >-
|
|
72
|
+
The lifecycle PostToolUse registration pipes Codex's native payload to
|
|
73
|
+
`ovld protocol record-touched`, which appends normalized changed paths to the
|
|
74
|
+
per-session attribution log read by `deliver`. It is intentionally separate
|
|
75
|
+
from mechanical agent-session observation, which remains owned by Latch.
|
|
68
76
|
observe.sessionLifecycle:
|
|
69
77
|
status: not-implemented
|
|
70
78
|
native: SessionStart
|
|
@@ -192,6 +200,7 @@ legacy:
|
|
|
192
200
|
capabilities:
|
|
193
201
|
- followUpHook
|
|
194
202
|
- permissionHook
|
|
203
|
+
- editHook
|
|
195
204
|
- nativeResume
|
|
196
205
|
- modelFlag
|
|
197
206
|
- effortFlag
|
|
@@ -200,3 +209,4 @@ legacy:
|
|
|
200
209
|
hookTypes:
|
|
201
210
|
- UserPromptSubmit
|
|
202
211
|
- PermissionRequest
|
|
212
|
+
- PostToolUse
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Overlord Codex PostToolUse hook. Records exact file and shell-mediated changes
|
|
3
|
+
# in the per-session touched-files log used by `ovld protocol deliver` for
|
|
4
|
+
# concurrent-work attribution. The CLI owns mission resolution and path
|
|
5
|
+
# normalization, so this adapter only forwards Codex's native hook payload.
|
|
6
|
+
|
|
7
|
+
BODY=$(cat -)
|
|
8
|
+
HOOK_NAME="codex-post-tool-use"
|
|
9
|
+
LOG_DIR="${HOME:-}/.ovld/logs"
|
|
10
|
+
LOG_FILE="${LOG_DIR}/codex-post-tool-use-hook.log"
|
|
11
|
+
|
|
12
|
+
log_hook() {
|
|
13
|
+
mkdir -p "$LOG_DIR" 2>/dev/null || return 0
|
|
14
|
+
printf '%s [%s] %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$HOOK_NAME" "$1" >>"$LOG_FILE" 2>/dev/null || true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# The stderr redirect below prevents a hook failure from writing into Codex's
|
|
18
|
+
# conversation, but Bash resolves it before invoking `ovld`; create the parent
|
|
19
|
+
# directory first so first-run installations can still record attribution.
|
|
20
|
+
mkdir -p "$LOG_DIR" 2>/dev/null || true
|
|
21
|
+
|
|
22
|
+
if ! command -v ovld >/dev/null 2>&1; then
|
|
23
|
+
log_hook "ovld not on PATH; skipping"
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
RESULT=$(printf '%s' "$BODY" | ovld protocol record-touched 2>>"$LOG_FILE")
|
|
28
|
+
log_hook "record-touched: ${RESULT:-<no output>}"
|
|
29
|
+
|
|
30
|
+
exit 0
|
|
@@ -181,7 +181,7 @@ When creating missions from within a repository:
|
|
|
181
181
|
- Add objectives to the same mission when each prompt is a sequential step toward the same feature or goal; use `ovld protocol add-objectives --mission-id <mission_id> --objectives-json '[{"objective":"..."}]'`.
|
|
182
182
|
- `create` and `prompt` require `--objectives-json` or `--objectives-file` with an ordered array of `{ "objective": "...", "title": "...", "autoAdvance": true }` objects. A single objective is just an array with one item. `--auto-advance` / `--no-auto-advance` map each opted-in item to authoritative Run Queue membership (default off).
|
|
183
183
|
- `add-objectives` uses the same per-item `autoAdvance` field and `--auto-advance` / `--no-auto-advance` mapping.
|
|
184
|
-
- Use `ovld protocol queue-objective --objective-id <id> [--queue <id|name>] [--after <queued-entry|objective>|--front|--position <rank>]
|
|
184
|
+
- Use `ovld protocol run-queue [--project-id <id|slug|name>|--objective-id <id>|--mission-id <id>] [--queue <id|name>]` to inspect live queues. Entry operations use `queue-objective --objective-id <id> [--queue <id|name>] [--after <queued-entry|objective>|--front|--position <rank>]`, `dequeue-objective --objective-id <id>`, and `reorder-run-queue --queue <id|name> --ordered-entries-json <json>`; they require `execution_request:create`. Queue-definition operations use `create-run-queue`, `update-run-queue`, `delete-run-queue`, and `reorder-project-run-queues`; they require `project:update` and therefore a full-scope token.
|
|
185
185
|
- `ovld protocol update-objective --objective-id <id> --auto-advance` / `--no-auto-advance` is retained as an enqueue/dequeue compatibility mapping. `autoAdvance` is deprecated and derived from `queueEntry`; legacy writes retire next release and column removal requires a later contract bump.
|
|
186
186
|
- `record-work` creates exactly one **completed** objective from a single `--objective` (or positional / an `objective` field in `--payload-json`) plus a `--summary` and file-change data — it does not take `--objectives-json`. See [record-work.md](record-work.md).
|
|
187
187
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MCP And API Defaults
|
|
2
2
|
|
|
3
|
-
- Every mission-scoped tool accepts `objectiveId` (hosted MCP) / `objective_id` (local shim) alongside `missionId`, taking an objective UUID or a display id such as `coo:756.k7xm`. A display id already names its mission, so `missionId` is **optional** whenever one is supplied — `overlord_load_mission_context`, `overlord_attach_session`, `overlord_update_session`, `overlord_deliver_session`, `overlord_add_artifact`, `overlord_add_objectives`, and `overlord_update_artifact` all resolve the mission from it. An objective **UUID** names no mission and still needs `missionId`. On `overlord_load_mission_context` and `overlord_attach_session` the objective is also a
|
|
3
|
+
- Every mission-scoped tool accepts `objectiveId` (hosted MCP) / `objective_id` (local shim) alongside `missionId`, taking an objective UUID or a display id such as `coo:756.k7xm`. A display id already names its mission, so `missionId` is **optional** whenever one is supplied — `overlord_load_mission_context`, `overlord_attach_session`, `overlord_update_session`, `overlord_deliver_session`, `overlord_add_artifact`, `overlord_add_objectives`, and `overlord_update_artifact` all resolve the mission from it. An objective **UUID** names no mission and still needs `missionId`. On `overlord_load_mission_context` and `overlord_attach_session` the objective is also a _pin_: it selects which objective to read or execute, which is the only way to address a mission that is running objectives in parallel.
|
|
4
4
|
- API requires `agentIdentifier` and `connectionMethod` on attach/connect/prompt. Connector adapters set the appropriate agent identifier; the CLI uses `cli` as the connection method, and the MCP tool defaults to `mcp`. Override with `--agent` / `--method` when calling from a different runtime.
|
|
5
5
|
- Hosted Overlord MCP (`/mcp`) uses camelCase JSON keys (`missionId`, `sessionKey`, `deviceFingerprint`) matching `POST /api/protocol/*` bodies. The local shim uses snake_case keys mapped to CLI flags (`mission_id`, `session_key`, `device_fingerprint`). Some local-only operations (`connect`, `revert`, `prompt`, runner queue tools) intentionally remain out of hosted MCP for now.
|
|
6
6
|
- `discover_project` accepts an explicit project id (`projectId` hosted, `project_id` local shim) or a working directory (`workingDirectory` hosted, `working_directory` local shim). When resolving by directory and a device fingerprint is available, include `deviceFingerprint` / `device_fingerprint` so resource-directory matching prefers the current device.
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
- `overlord_record_work` (hosted MCP) and `ovld protocol record-work` (CLI) record already-completed chat work as a single review-column mission with a completed objective, file-change rationales, and the standard Gemini delivery summary — no `attach`/`deliver`. Hosted MCP requires `projectId` (it never chooses a project implicitly); the CLI resolves the project from the working directory or `--project-id`. The submission format is in [record-work.md](record-work.md). The route is `POST /api/protocol/record-work`.
|
|
11
11
|
- `overlord_add_artifact` (hosted MCP) and `ovld protocol add-artifact` (CLI) create a mission artifact during a turn without delivering. Required: `type` / `--type`, `label` / `--label`, mission scope (`missionId` / `--mission-id`, or an objective display id as `objectiveId` / `--objective-id`), plus at least one of `contentText` / `--content-text`/`--content-text-file` or `externalUrl` / `--external-url`. Optional `sessionKey` / `--session-key` stamps session/objective provenance; `objectiveId` / `--objective-id` does the same when there is no live session, and the session key wins if both are given. Same service as REST `POST /api/missions/:id/artifacts`. The route is `POST /api/protocol/add-artifact`.
|
|
12
12
|
- `overlord_update_artifact` (hosted MCP) and `ovld protocol update-artifact` (CLI) revise an existing mission artifact's label, Markdown content, and/or HTTP(S) URL in place. Required: `artifactId` / `--artifact-id`, `expectedRevision` / `--expected-revision`, and mission scope (`missionId` / `--mission-id`, or an objective display id as `objectiveId` / `--objective-id`). Provide at least one editable field. No session key is required. Same service as REST `PATCH /api/missions/:id/artifacts/:artifactId`. The route is `POST /api/protocol/update-artifact`.
|
|
13
|
-
- `overlord_queue_objective` accepts `objectiveId`, optional `queue` / `after`, and `remove
|
|
13
|
+
- Run Queue MCP stays a thin Protocol surface: `overlord_list_run_queues` reads compact/full state; `overlord_reorder_run_queue` atomically replaces one queue's complete entry order; and `overlord_queue_objective` accepts `objectiveId`, optional `queue` / `after` / `front` / `position`, and `remove`. `overlord_manage_run_queue` creates, updates, deletes, and reorders queue definitions. Entry operations use `execution_request:create`; definition operations use `project:update`, so they require a full-scope token. `overlord_create_mission` / `overlord_add_objectives` optional `autoAdvance`, `overlord_update_objective.autoAdvance`, and `ovld protocol update-objective --auto-advance|--no-auto-advance` map to that same membership. `autoAdvance` is deprecated and derived from `queueEntry`; legacy storage writes retire next release and column removal requires a later contract bump. Instruction text remains editable only in `draft` or `future` state. The routes are `POST /api/protocol/run-queue`, `reorder-run-queue`, `queue-objective`, `dequeue-objective`, `create-run-queue`, `update-run-queue`, `delete-run-queue`, `reorder-project-run-queues`, and `update-objective`.
|
|
14
14
|
- Objective attachment tools follow the `<verb>_<noun>` MCP naming: `list_attachments`, `prepare_attachment_upload`, `finalize_attachment_upload`, `get_attachment_download_url`, `upload_attachment_file`. CLI commands use `attachment-*`. `mission_id` / `missionId` is optional for attachment calls when the objective or attachment id lets the server derive mission scope.
|
|
15
15
|
- "Artifacts" may be published mid-turn with `add-artifact` / `overlord_add_artifact`, revised with `update-artifact` / `overlord_update_artifact`, or attached at `deliver` time (next_steps, test_results, migration, decision, note, url) — not user-uploaded files. Files attached by users live on objectives via the attachment tools above.
|
|
@@ -108,6 +108,34 @@ function compactSearchResponse(response) {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
function compactRunQueueResponse(response) {
|
|
112
|
+
const value = response?.structuredContent;
|
|
113
|
+
if (!value || !Array.isArray(value.queues)) return response;
|
|
114
|
+
const compact = {
|
|
115
|
+
projectId: value.projectId,
|
|
116
|
+
queues: value.queues.map(queue => ({
|
|
117
|
+
id: queue.id,
|
|
118
|
+
name: queue.name,
|
|
119
|
+
isDefault: queue.isDefault,
|
|
120
|
+
paused: queue.paused,
|
|
121
|
+
entries: Array.isArray(queue.entries)
|
|
122
|
+
? queue.entries.map(entry => ({
|
|
123
|
+
position: entry.position,
|
|
124
|
+
state: entry.state,
|
|
125
|
+
objectiveDisplayId: entry.objectiveDisplayId,
|
|
126
|
+
objectiveTitle: entry.objectiveTitle,
|
|
127
|
+
missionTitle: entry.missionTitle,
|
|
128
|
+
blockedReason: entry.blockedReason
|
|
129
|
+
}))
|
|
130
|
+
: []
|
|
131
|
+
}))
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: 'text', text: JSON.stringify(compact, null, 2) }],
|
|
135
|
+
structuredContent: compact
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
111
139
|
const tools = [
|
|
112
140
|
{
|
|
113
141
|
name: 'overlord_resolve_project',
|
|
@@ -357,6 +385,49 @@ const tools = [
|
|
|
357
385
|
['objectiveId']
|
|
358
386
|
)
|
|
359
387
|
},
|
|
388
|
+
{
|
|
389
|
+
name: 'overlord_list_run_queues',
|
|
390
|
+
title: 'List Run Queues',
|
|
391
|
+
description:
|
|
392
|
+
"Use this to read a project's authoritative Run Queues before adding, moving, removing, or bulk-reordering entries. Compact detail is the default and includes ordering and blocking state; request full for the complete ProjectRunQueuesDto.",
|
|
393
|
+
inputSchema: objectSchema({
|
|
394
|
+
projectId: stringProperty('Optional project UUID, slug, or name.'),
|
|
395
|
+
objectiveId: stringProperty(
|
|
396
|
+
'Optional objective UUID or display id; derives the project when projectId is omitted.'
|
|
397
|
+
),
|
|
398
|
+
missionId: stringProperty(
|
|
399
|
+
'Optional mission UUID or display id; derives the project when projectId is omitted.'
|
|
400
|
+
),
|
|
401
|
+
queue: stringProperty('Optional Run Queue UUID or unambiguous name to return by itself.'),
|
|
402
|
+
detail: {
|
|
403
|
+
type: 'string',
|
|
404
|
+
enum: ['compact', 'full'],
|
|
405
|
+
description:
|
|
406
|
+
'Result detail: compact (default) returns queue ordering state; full returns the raw ProjectRunQueuesDto.'
|
|
407
|
+
}
|
|
408
|
+
})
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
name: 'overlord_reorder_run_queue',
|
|
412
|
+
title: 'Reorder Run Queue entries',
|
|
413
|
+
description:
|
|
414
|
+
'Use this only when the user explicitly asks to reorder every entry in one Run Queue. Supply every live entry exactly once, using entry UUIDs, objective UUIDs, or objective display ids. Running and dispatched entries cannot move. On a mismatch, the error returns the current order; re-read the queue and retry.',
|
|
415
|
+
inputSchema: objectSchema(
|
|
416
|
+
{
|
|
417
|
+
queue: stringProperty('Run Queue UUID or unambiguous name.'),
|
|
418
|
+
orderedObjectives: {
|
|
419
|
+
type: 'array',
|
|
420
|
+
description:
|
|
421
|
+
'Complete desired top-to-bottom entry order. Each item may be an entry UUID, objective UUID, or objective display id.',
|
|
422
|
+
items: stringProperty('Run Queue entry UUID, objective UUID, or objective display id.')
|
|
423
|
+
},
|
|
424
|
+
projectId: stringProperty(
|
|
425
|
+
'Optional project UUID, slug, or name; disambiguates queue names.'
|
|
426
|
+
)
|
|
427
|
+
},
|
|
428
|
+
['queue', 'orderedObjectives']
|
|
429
|
+
)
|
|
430
|
+
},
|
|
360
431
|
{
|
|
361
432
|
name: 'overlord_queue_objective',
|
|
362
433
|
title: 'Queue objective',
|
|
@@ -369,6 +440,11 @@ const tools = [
|
|
|
369
440
|
after: stringProperty(
|
|
370
441
|
'Optional queued predecessor entry id, objective UUID, or objective display id. Its queue is used when queue is omitted.'
|
|
371
442
|
),
|
|
443
|
+
front: booleanProperty('When true, place this objective first in the selected queue.'),
|
|
444
|
+
position: {
|
|
445
|
+
type: 'number',
|
|
446
|
+
description: 'Optional one-based insertion position in the selected queue.'
|
|
447
|
+
},
|
|
372
448
|
remove: booleanProperty(
|
|
373
449
|
'When true, remove this objective from the Run Queue instead of adding or moving it.'
|
|
374
450
|
)
|
|
@@ -376,6 +452,40 @@ const tools = [
|
|
|
376
452
|
['objectiveId']
|
|
377
453
|
)
|
|
378
454
|
},
|
|
455
|
+
{
|
|
456
|
+
name: 'overlord_manage_run_queue',
|
|
457
|
+
title: 'Manage Run Queues',
|
|
458
|
+
description:
|
|
459
|
+
"Use this only when the user explicitly asks to create, rename, pause, resume, delete, or reorder the project's Run Queue definitions. These are administrative project-configuration actions and require a full-scope token; adding, moving, or removing objectives inside a queue uses overlord_queue_objective and overlord_reorder_run_queue instead.",
|
|
460
|
+
inputSchema: objectSchema(
|
|
461
|
+
{
|
|
462
|
+
action: {
|
|
463
|
+
type: 'string',
|
|
464
|
+
enum: ['create', 'update', 'delete', 'reorder_queues'],
|
|
465
|
+
description:
|
|
466
|
+
'create a queue, update (rename/pause/resume) one, delete one, or reorder the queue definitions.'
|
|
467
|
+
},
|
|
468
|
+
projectId: stringProperty(
|
|
469
|
+
'Project UUID, slug, or name. Required for create and reorder_queues.'
|
|
470
|
+
),
|
|
471
|
+
queue: stringProperty('Run Queue UUID or unambiguous name. Required for update and delete.'),
|
|
472
|
+
name: stringProperty('New queue name for create, or the replacement name for update.'),
|
|
473
|
+
paused: booleanProperty(
|
|
474
|
+
'update only: true pauses dispatching from the queue, false resumes it.'
|
|
475
|
+
),
|
|
476
|
+
moveEntriesTo: stringProperty(
|
|
477
|
+
'delete only: destination queue UUID or unambiguous name. Required when the queue still holds entries.'
|
|
478
|
+
),
|
|
479
|
+
orderedQueues: {
|
|
480
|
+
type: 'array',
|
|
481
|
+
description:
|
|
482
|
+
'reorder_queues only: every live queue exactly once, top to bottom, by UUID or unambiguous name. The default queue must stay first.',
|
|
483
|
+
items: stringProperty('Run Queue UUID or unambiguous name.')
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
['action']
|
|
487
|
+
),
|
|
488
|
+
},
|
|
379
489
|
{
|
|
380
490
|
name: 'overlord_attach_session',
|
|
381
491
|
title: 'Attach to mission',
|
|
@@ -721,17 +831,120 @@ async function callOverlordTool(name, args) {
|
|
|
721
831
|
...(hasInstructionText ? { 'instruction-text': requiredString(args, 'instructionText') } : {})
|
|
722
832
|
});
|
|
723
833
|
}
|
|
834
|
+
if (name === 'overlord_list_run_queues') {
|
|
835
|
+
const detail = optionalString(args, 'detail') || 'compact';
|
|
836
|
+
if (detail !== 'compact' && detail !== 'full') {
|
|
837
|
+
throw new Error("detail must be 'compact' or 'full'");
|
|
838
|
+
}
|
|
839
|
+
const response = await runProtocol('run-queue', {
|
|
840
|
+
...(optionalString(args, 'projectId')
|
|
841
|
+
? { 'project-id': requiredString(args, 'projectId') }
|
|
842
|
+
: {}),
|
|
843
|
+
...(optionalString(args, 'objectiveId')
|
|
844
|
+
? { 'objective-id': requiredString(args, 'objectiveId') }
|
|
845
|
+
: {}),
|
|
846
|
+
...(optionalString(args, 'missionId')
|
|
847
|
+
? { 'mission-id': requiredString(args, 'missionId') }
|
|
848
|
+
: {}),
|
|
849
|
+
...(optionalString(args, 'queue') ? { queue: requiredString(args, 'queue') } : {})
|
|
850
|
+
});
|
|
851
|
+
return detail === 'compact' ? compactRunQueueResponse(response) : response;
|
|
852
|
+
}
|
|
853
|
+
if (name === 'overlord_reorder_run_queue') {
|
|
854
|
+
if (
|
|
855
|
+
!Array.isArray(args.orderedObjectives) ||
|
|
856
|
+
!args.orderedObjectives.every(item => typeof item === 'string')
|
|
857
|
+
) {
|
|
858
|
+
throw new Error('orderedObjectives must be an array of strings');
|
|
859
|
+
}
|
|
860
|
+
return runProtocol('reorder-run-queue', {
|
|
861
|
+
queue: requiredString(args, 'queue'),
|
|
862
|
+
'ordered-entries-json': args.orderedObjectives,
|
|
863
|
+
...(optionalString(args, 'projectId')
|
|
864
|
+
? { 'project-id': requiredString(args, 'projectId') }
|
|
865
|
+
: {})
|
|
866
|
+
});
|
|
867
|
+
}
|
|
724
868
|
if (name === 'overlord_queue_objective') {
|
|
869
|
+
const hasAfter = optionalString(args, 'after') !== null;
|
|
870
|
+
const hasFront = args.front === true;
|
|
871
|
+
const hasPosition = args.position !== undefined;
|
|
872
|
+
if (Number(hasAfter) + Number(hasFront) + Number(hasPosition) > 1) {
|
|
873
|
+
throw new Error('Choose only one placement option: after, front, or position');
|
|
874
|
+
}
|
|
875
|
+
if (hasPosition && (!Number.isInteger(args.position) || args.position < 1)) {
|
|
876
|
+
throw new Error('position must be a positive integer');
|
|
877
|
+
}
|
|
725
878
|
return runProtocol(args.remove === true ? 'dequeue-objective' : 'queue-objective', {
|
|
726
879
|
'objective-id': requiredString(args, 'objectiveId'),
|
|
727
880
|
...(args.remove === true
|
|
728
881
|
? {}
|
|
729
882
|
: {
|
|
730
883
|
...(optionalString(args, 'queue') ? { queue: requiredString(args, 'queue') } : {}),
|
|
731
|
-
...(
|
|
884
|
+
...(hasAfter ? { after: requiredString(args, 'after') } : {}),
|
|
885
|
+
...(hasFront ? { front: true } : {}),
|
|
886
|
+
...(hasPosition ? { position: String(args.position) } : {})
|
|
732
887
|
})
|
|
733
888
|
});
|
|
734
889
|
}
|
|
890
|
+
if (name === 'overlord_manage_run_queue') {
|
|
891
|
+
const action = optionalString(args, 'action');
|
|
892
|
+
if (action === null) throw new Error('action is required');
|
|
893
|
+
const projectRef = optionalString(args, 'projectId');
|
|
894
|
+
const queue = optionalString(args, 'queue');
|
|
895
|
+
const queueName = optionalString(args, 'name');
|
|
896
|
+
|
|
897
|
+
if (action === 'create') {
|
|
898
|
+
if (!projectRef) throw new Error("action 'create' requires projectId");
|
|
899
|
+
if (!queueName) throw new Error("action 'create' requires name");
|
|
900
|
+
return runProtocol('create-run-queue', { 'project-id': projectRef, name: queueName });
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
if (action === 'update') {
|
|
904
|
+
if (!queue) throw new Error("action 'update' requires queue");
|
|
905
|
+
const paused = args.paused;
|
|
906
|
+
if (paused !== undefined && typeof paused !== 'boolean') {
|
|
907
|
+
throw new Error('paused must be a boolean');
|
|
908
|
+
}
|
|
909
|
+
if (!queueName && paused === undefined) {
|
|
910
|
+
throw new Error("action 'update' requires name or paused");
|
|
911
|
+
}
|
|
912
|
+
return runProtocol('update-run-queue', {
|
|
913
|
+
queue,
|
|
914
|
+
...(projectRef ? { 'project-id': projectRef } : {}),
|
|
915
|
+
...(queueName ? { name: queueName } : {}),
|
|
916
|
+
...(paused === true ? { pause: true } : {}),
|
|
917
|
+
...(paused === false ? { resume: true } : {})
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
if (action === 'delete') {
|
|
922
|
+
if (!queue) throw new Error("action 'delete' requires queue");
|
|
923
|
+
const moveEntriesTo = optionalString(args, 'moveEntriesTo');
|
|
924
|
+
return runProtocol('delete-run-queue', {
|
|
925
|
+
queue,
|
|
926
|
+
...(projectRef ? { 'project-id': projectRef } : {}),
|
|
927
|
+
...(moveEntriesTo ? { 'move-entries-to': moveEntriesTo } : {})
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
if (action === 'reorder_queues') {
|
|
932
|
+
if (!projectRef) throw new Error("action 'reorder_queues' requires projectId");
|
|
933
|
+
if (
|
|
934
|
+
!Array.isArray(args.orderedQueues) ||
|
|
935
|
+
args.orderedQueues.length === 0 ||
|
|
936
|
+
!args.orderedQueues.every(item => typeof item === 'string')
|
|
937
|
+
) {
|
|
938
|
+
throw new Error("action 'reorder_queues' requires orderedQueues as an array of strings");
|
|
939
|
+
}
|
|
940
|
+
return runProtocol('reorder-project-run-queues', {
|
|
941
|
+
'project-id': projectRef,
|
|
942
|
+
'ordered-queues-json': args.orderedQueues
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
throw new Error(`Unsupported Run Queue action: ${action}`);
|
|
947
|
+
}
|
|
735
948
|
if (name === 'overlord_attach_session') {
|
|
736
949
|
return runProtocol('attach', {
|
|
737
950
|
...missionScopeFlags(args),
|
|
@@ -869,7 +1082,7 @@ process.stdin.on('data', async chunk => {
|
|
|
869
1082
|
result: {
|
|
870
1083
|
protocolVersion: PROTOCOL_VERSION,
|
|
871
1084
|
capabilities: { tools: { listChanged: false } },
|
|
872
|
-
serverInfo: { name: 'overlord-__OVERLORD_ADAPTER_KEY__', version: '0.3.
|
|
1085
|
+
serverInfo: { name: 'overlord-__OVERLORD_ADAPTER_KEY__', version: '0.3.32' }
|
|
873
1086
|
}
|
|
874
1087
|
});
|
|
875
1088
|
continue;
|