overlord-cli 0.2605161310.0 → 0.2605170853.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/bin/_cli/local-config.mjs +91 -0
- package/bin/_cli/protocol.mjs +15 -0
- package/bin/_cli/setup.mjs +45 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/commands/record-work.md +28 -0
- package/plugins/claude/skills/overlord-ticket/SKILL.md +24 -8
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor/commands/record-work.md +9 -0
- package/plugins/cursor/skills/overlord-ticket/SKILL.md +55 -1
- package/plugins/overlord/skills/overlord-ticket/SKILL.md +19 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Read/merge/write logic for the per-folder `overlord.json` file.
|
|
2
|
+
// Mirrors lib/overlord-config/local-config.ts for CLI use.
|
|
3
|
+
|
|
4
|
+
import { promises as fs } from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
|
|
7
|
+
export const OVERLORD_CONFIG_FILENAME = 'overlord.json';
|
|
8
|
+
|
|
9
|
+
const FILE_COMMENT =
|
|
10
|
+
'This file lets Overlord (https://www.ovld.ai) identify which project this folder belongs to. It is created automatically when the folder is added as a project resource. DO NOT EDIT MANUALLY.';
|
|
11
|
+
|
|
12
|
+
function buildConfig(projects) {
|
|
13
|
+
return { _comment: FILE_COMMENT, projects };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isProjectArray(value) {
|
|
17
|
+
return (
|
|
18
|
+
Array.isArray(value) &&
|
|
19
|
+
value.every(
|
|
20
|
+
entry =>
|
|
21
|
+
entry &&
|
|
22
|
+
typeof entry === 'object' &&
|
|
23
|
+
typeof entry.id === 'string' &&
|
|
24
|
+
typeof entry.name === 'string'
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function readExistingProjects(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
32
|
+
const parsed = JSON.parse(raw);
|
|
33
|
+
if (parsed && typeof parsed === 'object' && isProjectArray(parsed.projects)) {
|
|
34
|
+
return parsed.projects;
|
|
35
|
+
}
|
|
36
|
+
return [];
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error && error.code === 'ENOENT') return null;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Ensures `directoryPath/overlord.json` lists the project. Returns
|
|
45
|
+
* `{ filePath, action: 'created' | 'added-project' | 'unchanged' }`.
|
|
46
|
+
*/
|
|
47
|
+
export async function upsertLocalOverlordConfig({ directoryPath, project }) {
|
|
48
|
+
const filePath = path.join(directoryPath, OVERLORD_CONFIG_FILENAME);
|
|
49
|
+
const existing = await readExistingProjects(filePath);
|
|
50
|
+
|
|
51
|
+
if (existing === null) {
|
|
52
|
+
await fs.writeFile(filePath, `${JSON.stringify(buildConfig([project]), null, 2)}\n`, 'utf8');
|
|
53
|
+
return { filePath, action: 'created' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const idx = existing.findIndex(entry => entry.id === project.id);
|
|
57
|
+
if (idx >= 0) {
|
|
58
|
+
if (existing[idx].name === project.name) return { filePath, action: 'unchanged' };
|
|
59
|
+
const updated = existing.slice();
|
|
60
|
+
updated[idx] = project;
|
|
61
|
+
await fs.writeFile(filePath, `${JSON.stringify(buildConfig(updated), null, 2)}\n`, 'utf8');
|
|
62
|
+
return { filePath, action: 'unchanged' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const merged = [...existing, project];
|
|
66
|
+
await fs.writeFile(filePath, `${JSON.stringify(buildConfig(merged), null, 2)}\n`, 'utf8');
|
|
67
|
+
return { filePath, action: 'added-project' };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Removes `projectId` from `directoryPath/overlord.json`. Deletes the file
|
|
72
|
+
* when the resulting projects list is empty. Returns
|
|
73
|
+
* `{ filePath, action: 'removed-project' | 'deleted-file' | 'not-found' | 'unchanged' }`.
|
|
74
|
+
*/
|
|
75
|
+
export async function removeProjectFromLocalOverlordConfig({ directoryPath, projectId }) {
|
|
76
|
+
const filePath = path.join(directoryPath, OVERLORD_CONFIG_FILENAME);
|
|
77
|
+
const existing = await readExistingProjects(filePath);
|
|
78
|
+
|
|
79
|
+
if (existing === null) return { filePath, action: 'not-found' };
|
|
80
|
+
|
|
81
|
+
const filtered = existing.filter(entry => entry.id !== projectId);
|
|
82
|
+
if (filtered.length === existing.length) return { filePath, action: 'unchanged' };
|
|
83
|
+
|
|
84
|
+
if (filtered.length === 0) {
|
|
85
|
+
await fs.unlink(filePath);
|
|
86
|
+
return { filePath, action: 'deleted-file' };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await fs.writeFile(filePath, `${JSON.stringify(buildConfig(filtered), null, 2)}\n`, 'utf8');
|
|
90
|
+
return { filePath, action: 'removed-project' };
|
|
91
|
+
}
|
package/bin/_cli/protocol.mjs
CHANGED
|
@@ -1720,6 +1720,21 @@ async function protocolAddProjectResource(args) {
|
|
|
1720
1720
|
if (data.resource?.id) {
|
|
1721
1721
|
process.stderr.write(`\nRESOURCE_ID=${data.resource.id}\n`);
|
|
1722
1722
|
}
|
|
1723
|
+
|
|
1724
|
+
if (data.project?.id && data.project?.name) {
|
|
1725
|
+
try {
|
|
1726
|
+
const { upsertLocalOverlordConfig } = await import('./local-config.mjs');
|
|
1727
|
+
const result = await upsertLocalOverlordConfig({
|
|
1728
|
+
directoryPath,
|
|
1729
|
+
project: { id: data.project.id, name: data.project.name }
|
|
1730
|
+
});
|
|
1731
|
+
process.stderr.write(`OVERLORD_CONFIG=${result.filePath} (${result.action})\n`);
|
|
1732
|
+
} catch (configError) {
|
|
1733
|
+
process.stderr.write(
|
|
1734
|
+
`\nWarning: could not write overlord.json: ${configError instanceof Error ? configError.message : configError}\n`
|
|
1735
|
+
);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1723
1738
|
}
|
|
1724
1739
|
|
|
1725
1740
|
// ---------------------------------------------------------------------------
|
package/bin/_cli/setup.mjs
CHANGED
|
@@ -407,6 +407,24 @@ disable-model-invocation: true
|
|
|
407
407
|
---
|
|
408
408
|
|
|
409
409
|
Run \`ovld protocol prompt --agent claude-code\` with \`$ARGUMENTS\`. If no flags are present, treat the arguments as the objective and call \`ovld protocol prompt --agent claude-code --objective "<objective>"\`.`
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
path: path.join(base, 'record-work.md'),
|
|
413
|
+
content: `---
|
|
414
|
+
description: Record completed-from-chat work as a ticket in review + feed post (no attach)
|
|
415
|
+
argument-hint: [optional additional context]
|
|
416
|
+
disable-model-invocation: true
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
Immediately record the work you just completed in this chat as a new Overlord ticket via \`ovld protocol record-work\`. No agent session is opened — the work is already done.
|
|
420
|
+
|
|
421
|
+
Synthesize from the current conversation: \`objective\` (what was asked/done), \`summary\` (reviewer-friendly narrative), \`changeRationales\` (one entry per meaningful git-tracked file change — \`label\`, \`file_path\`, \`summary\`, \`why\`, \`impact\`, optional \`hunks\`; use \`git status\`/\`git diff\` to enumerate), and optional \`artifacts\` (\`next_steps\`, \`test_results\`, \`decision\`, \`note\`, \`url\`).
|
|
422
|
+
|
|
423
|
+
If \`$ARGUMENTS\` is non-empty, treat it as additional context for the summary.
|
|
424
|
+
|
|
425
|
+
Run \`ovld protocol record-work --payload-file -\` and stream the JSON payload \`{ "objective": "...", "summary": "...", "artifacts": [...], "changeRationales": [...] }\` on stdin via a single-quoted heredoc. Report the new \`TICKET_ID\`.
|
|
426
|
+
|
|
427
|
+
Do NOT use this for in-progress work — use \`/prompt\` for that. The CLI validates that every changed git-tracked file is represented in \`changeRationales\` unless \`--skip-file-change-check\` is passed. If project resolution fails, re-run with \`--project-id <id>\` or \`--personal\`.`
|
|
410
428
|
}
|
|
411
429
|
];
|
|
412
430
|
}
|
|
@@ -433,6 +451,11 @@ Run \`ovld protocol prompt --agent claude-code\` with \`$ARGUMENTS\`. If no flag
|
|
|
433
451
|
path: path.join(base, 'prompt.md'),
|
|
434
452
|
content:
|
|
435
453
|
'Create a new Overlord ticket.\n\nRun `ovld protocol prompt --agent cursor --objective "<objective>"` using the text after `/prompt` unless raw flags were provided. If raw flags were provided, pass them after `ovld protocol prompt --agent cursor`.\n'
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
path: path.join(base, 'record-work.md'),
|
|
457
|
+
content:
|
|
458
|
+
'Record completed-from-chat work as a ticket in review + feed post (no attach).\n\nImmediately record the work you just completed in this chat as a new Overlord ticket via `ovld protocol record-work`. No agent session is opened — the work is already done.\n\nSynthesize from the current conversation: `objective` (what was asked/done), `summary` (reviewer-friendly narrative), `changeRationales` (one entry per meaningful git-tracked file change — `label`, `file_path`, `summary`, `why`, `impact`, optional `hunks`; use `git status`/`git diff` to enumerate), and optional `artifacts` (`next_steps`, `test_results`, `decision`, `note`, `url`).\n\nIf text was provided after `/record-work`, treat it as additional context for the summary.\n\nRun `ovld protocol record-work --payload-file -` and stream the JSON payload on stdin via a single-quoted heredoc. Report the new TICKET_ID.\n\nDo NOT use for in-progress work — use `/prompt` for that. The CLI validates that every changed git-tracked file is represented in `changeRationales` unless `--skip-file-change-check` is passed. If project resolution fails, re-run with `--project-id <id>` or `--personal`.\n'
|
|
436
459
|
}
|
|
437
460
|
];
|
|
438
461
|
}
|
|
@@ -459,6 +482,11 @@ Run \`ovld protocol prompt --agent claude-code\` with \`$ARGUMENTS\`. If no flag
|
|
|
459
482
|
path: path.join(base, 'prompt.toml'),
|
|
460
483
|
content:
|
|
461
484
|
'description = "Create a new Overlord ticket from the current conversation."\nprompt = """\nRun `ovld protocol prompt --agent gemini --objective "<objective>"` using `{{args}}` as the objective unless raw flags were provided. If raw flags were provided, pass them after `ovld protocol prompt --agent gemini`.\n"""\n'
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
path: path.join(base, 'record-work.toml'),
|
|
488
|
+
content:
|
|
489
|
+
'description = "Record completed-from-chat work as a ticket in review + feed post (no attach)."\nprompt = """\nImmediately record the work you just completed in this chat as a new Overlord ticket via `ovld protocol record-work`. No agent session is opened — the work is already done.\n\nSynthesize from the current conversation: `objective` (what was asked/done), `summary` (reviewer-friendly narrative), `changeRationales` (one entry per meaningful git-tracked file change — `label`, `file_path`, `summary`, `why`, `impact`, optional `hunks`; use `git status`/`git diff` to enumerate), and optional `artifacts` (`next_steps`, `test_results`, `decision`, `note`, `url`).\n\nIf `{{args}}` is non-empty, treat it as additional context for the summary.\n\nRun `ovld protocol record-work --payload-file -` and stream the JSON payload on stdin via a single-quoted heredoc. Report the new TICKET_ID.\n\nDo NOT use for in-progress work — use `/prompt` for that. The CLI validates that every changed git-tracked file is represented in `changeRationales` unless `--skip-file-change-check` is passed. If project resolution fails, re-run with `--project-id <id>` or `--personal`.\n"""\n'
|
|
462
490
|
}
|
|
463
491
|
];
|
|
464
492
|
}
|
|
@@ -500,6 +528,23 @@ agent: build
|
|
|
500
528
|
---
|
|
501
529
|
|
|
502
530
|
Run \`ovld protocol prompt --agent opencode\` with \`$ARGUMENTS\`. If no flags are present, treat the arguments as the objective and call \`ovld protocol prompt --agent opencode --objective "<objective>"\`.`
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
path: path.join(base, 'record-work.md'),
|
|
534
|
+
content: `---
|
|
535
|
+
description: Record completed-from-chat work as a ticket in review + feed post (no attach)
|
|
536
|
+
agent: build
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
Immediately record the work you just completed in this chat as a new Overlord ticket via \`ovld protocol record-work\`. No agent session is opened — the work is already done.
|
|
540
|
+
|
|
541
|
+
Synthesize from the current conversation: \`objective\` (what was asked/done), \`summary\` (reviewer-friendly narrative), \`changeRationales\` (one entry per meaningful git-tracked file change — \`label\`, \`file_path\`, \`summary\`, \`why\`, \`impact\`, optional \`hunks\`; use \`git status\`/\`git diff\` to enumerate), and optional \`artifacts\` (\`next_steps\`, \`test_results\`, \`decision\`, \`note\`, \`url\`).
|
|
542
|
+
|
|
543
|
+
If \`$ARGUMENTS\` is non-empty, treat it as additional context for the summary.
|
|
544
|
+
|
|
545
|
+
Run \`ovld protocol record-work --payload-file -\` and stream the JSON payload on stdin via a single-quoted heredoc. Report the new \`TICKET_ID\`.
|
|
546
|
+
|
|
547
|
+
Do NOT use for in-progress work — use \`/prompt\` for that. The CLI validates that every changed git-tracked file is represented in \`changeRationales\` unless \`--skip-file-change-check\` is passed. If project resolution fails, re-run with \`--project-id <id>\` or \`--personal\`.`
|
|
503
548
|
}
|
|
504
549
|
];
|
|
505
550
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Record completed-from-chat work as a ticket in review + feed post (no attach)
|
|
3
|
+
argument-hint: [optional additional context]
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Immediately record the work you just completed in this chat as a new Overlord ticket via `ovld protocol record-work`. No agent session is opened — the work is already done.
|
|
8
|
+
|
|
9
|
+
Synthesize from the current conversation:
|
|
10
|
+
- `objective`: what was asked / what was done (1–3 sentences).
|
|
11
|
+
- `summary`: reviewer-friendly narrative of what changed and why.
|
|
12
|
+
- `changeRationales`: one entry per meaningful git-tracked file change (`label`, `file_path`, `summary`, `why`, `impact`, optional `hunks`). Use `git status` and `git diff` to enumerate changed files.
|
|
13
|
+
- `artifacts` (optional): `next_steps`, `test_results`, `decision`, `note`, `url`.
|
|
14
|
+
|
|
15
|
+
If `$ARGUMENTS` is non-empty, treat it as additional context to weave into the summary.
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
`ovld protocol record-work --payload-file -`
|
|
19
|
+
|
|
20
|
+
and stream a JSON object `{ "objective": "...", "summary": "...", "artifacts": [...], "changeRationales": [...] }` on stdin via a single-quoted heredoc (`<<'EOF'`).
|
|
21
|
+
|
|
22
|
+
After the command succeeds, report the new `TICKET_ID`.
|
|
23
|
+
|
|
24
|
+
Rules:
|
|
25
|
+
- Do NOT use this for in-progress work. Use `/prompt` for that.
|
|
26
|
+
- The CLI validates that every changed git-tracked file is represented in `changeRationales` unless `--skip-file-change-check` is passed.
|
|
27
|
+
- If project resolution fails, re-run with `--project-id <id>` or `--personal`.
|
|
28
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -94,8 +94,7 @@ Use this mode when the conversation starts normally and the user asks Claude to
|
|
|
94
94
|
1. If the user wants to create tickets (and does not ask to start execution), run `ovld protocol create --agent claude-code --objective "..."`.
|
|
95
95
|
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
96
96
|
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to Overlord `local_working_directory`, then creates a standalone draft.
|
|
97
|
-
2. Default to `create` for new draft tickets. Only use `/overlord:prompt` or `ovld protocol prompt --agent claude-code --objective "..."` when the user explicitly asks to create and execute immediately. If the work is already complete in chat and just needs to be recorded, use `ovld protocol record-work` instead.
|
|
98
|
-
`prompt` creates the ticket in `execute` status and attaches immediately.
|
|
97
|
+
2. Default to `create` for new draft tickets. Only use `/overlord:prompt` or `ovld protocol prompt --agent claude-code --objective "..."` when the user explicitly asks to create and execute immediately. If the work is already complete in chat and just needs to be recorded, use `ovld protocol record-work` instead.`prompt` creates the ticket in `execute` status and attaches immediately.
|
|
99
98
|
3. If the user already has a ticket ID and only wants to inspect it, use `/overlord:load` or run `ovld protocol load-context --ticket-id <ticket_id>`.
|
|
100
99
|
4. If the user wants to route the current session onto an existing ticket by ID, use `/overlord:connect` or run `ovld protocol connect --ticket-id <ticket_id>`.
|
|
101
100
|
5. If the user wants to establish a persistent session with a ticket by ID, use `/overlord:attach` or run `ovld protocol attach --ticket-id <ticket_id>`.
|
|
@@ -175,9 +174,6 @@ When creating tickets from within a repository:
|
|
|
175
174
|
|
|
176
175
|
```bash
|
|
177
176
|
ovld protocol create --agent claude-code --objective "Capture follow-up work from this repository"
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
177
|
ovld protocol prompt --agent claude-code --objective "Implement feature X" --priority medium
|
|
182
178
|
```
|
|
183
179
|
|
|
@@ -189,6 +185,24 @@ ovld protocol discover-project
|
|
|
189
185
|
|
|
190
186
|
You can override with `--project-id` or `--working-directory` if needed.
|
|
191
187
|
|
|
188
|
+
### Resolving the project ID when you don't have one
|
|
189
|
+
|
|
190
|
+
When you need a project ID for a protocol command and the ticket prompt did not supply one, resolve it in this order.
|
|
191
|
+
|
|
192
|
+
**Locally (CLI inside a shell on the user's machine):**
|
|
193
|
+
|
|
194
|
+
1. `--project-id` if explicitly provided.
|
|
195
|
+
2. Otherwise, let the CLI match the current working directory (the default behavior of `create`, `prompt`, `discover-project`).
|
|
196
|
+
3. If working-directory resolution returns nothing, read `overlord.json` from the cwd (or any ancestor you have access to) and pass its project id via `--project-id`.
|
|
197
|
+
|
|
198
|
+
**Over MCP (web agents and hosted tools, where the server cannot see the agent's cwd):**
|
|
199
|
+
|
|
200
|
+
1. `--project-id` / `projectId` if explicitly provided.
|
|
201
|
+
2. Read `overlord.json` from the directory the user is accessing and pass its project id as `projectId`.
|
|
202
|
+
3. As a last resort, try `workingDirectory` resolution.
|
|
203
|
+
|
|
204
|
+
If `overlord.json` contains more than one project, show the user the project **names** from that file and ask which one to use before calling any protocol command — never silently pick one.
|
|
205
|
+
|
|
192
206
|
### Choosing `--execution-target`
|
|
193
207
|
|
|
194
208
|
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
@@ -210,6 +224,10 @@ ovld protocol attachment-download-url --session-key <sessionKey> --ticket-id $TI
|
|
|
210
224
|
|
|
211
225
|
The `attach` and `load-context` responses already include `attachments` and `objectives` arrays — use those for `<attachment-id>` and `<objective-id>` values. Run `attachment-list` mid-session if new files have been uploaded since attach.
|
|
212
226
|
|
|
227
|
+
Objective attachment uploads also expose two-step variants — `attachment-prepare-upload` and `attachment-finalize-upload` — for callers that need a signed URL directly. Prefer `attachment-upload-file` for one-shot uploads.
|
|
228
|
+
|
|
229
|
+
"Artifacts" in `deliver` are the structured records an agent submits at delivery time (next_steps, test_results, migration, decision, note, url) — not user-uploaded files.
|
|
230
|
+
|
|
213
231
|
## Large Artifacts
|
|
214
232
|
|
|
215
233
|
For large artifacts such as planning documents, architecture decisions, research summaries, or design documents: **save the full content as a markdown file in the linked repository, then summarize it in the artifact returned to the ticket.**
|
|
@@ -226,8 +244,6 @@ This keeps the ticket feed readable while preserving the full document in versio
|
|
|
226
244
|
- Hosted Overlord MCP (`/functions/v1/mcp`) uses the same canonical tool names as any local MCP shim that shells into `ovld protocol` (`attach`, `update`, `deliver`, `record_work`, …). Hosted calls use camelCase JSON keys (`ticketId`, `sessionKey`) matching `POST /api/protocol/*` bodies; the local shim uses snake_case keys mapped to CLI flags (`ticket_id`, `session_key`).
|
|
227
245
|
- `permission-request` is invoked by the Claude Code permission hook installed by the bundle. Agents do not normally call it directly.
|
|
228
246
|
- `record_change_rationales` (MCP) and `ovld protocol record-change-rationales` (CLI) both write to the same `file_changes` table. The dedicated CLI route is `POST /api/protocol/record-change-rationales`.
|
|
229
|
-
- 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-*` and require `--objective-id` for upload/finalize.
|
|
230
|
-
- "Artifacts" in `deliver` are the structured records an agent submits at delivery 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.
|
|
231
247
|
|
|
232
248
|
## Rules
|
|
233
249
|
|
|
@@ -242,4 +258,4 @@ This keeps the ticket feed readable while preserving the full document in versio
|
|
|
242
258
|
- Do not add or commit changes unless the user explicitly asks you to commit.
|
|
243
259
|
- Delivery is the concluding step. After delivering, stop unless the user follows up or the ticket is reopened.
|
|
244
260
|
|
|
245
|
-
<!-- version: 0.4.
|
|
261
|
+
<!-- version: 0.4.11 -->
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Run `ovld protocol record-work --payload-file -` to record completed-from-chat work as a ticket in review + feed post (no attach).
|
|
2
|
+
|
|
3
|
+
Synthesize from the current conversation: `objective` (what was asked/done), `summary` (reviewer-friendly narrative), `changeRationales` (one entry per meaningful git-tracked file change — `label`, `file_path`, `summary`, `why`, `impact`, optional `hunks`; use `git status`/`git diff` to enumerate), and optional `artifacts` (`next_steps`, `test_results`, `decision`, `note`, `url`).
|
|
4
|
+
|
|
5
|
+
If text was provided after `/record-work`, treat it as additional context for the summary.
|
|
6
|
+
|
|
7
|
+
Stream the JSON payload on stdin via a single-quoted heredoc. Report the new TICKET_ID.
|
|
8
|
+
|
|
9
|
+
Do NOT use for in-progress work — use `/prompt` for that. If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -90,6 +90,36 @@ ovld protocol revert --objective-id <objective-id>
|
|
|
90
90
|
|
|
91
91
|
Use `ovld protocol record-work` when the user has done work directly in chat (no attached ticket) and wants to record it as a ticket plus publish a feed post. This is distinct from `create` (drafts future work), `prompt` (creates + executes), and `deliver` (concludes an attached session). `record-work` creates a ticket in `review` with a completed objective and triggers the feed-post generator atomically. Project resolution mirrors `prompt`: cwd is matched against `project_user.local_working_directory`; if no match, ask the user for `--project-id` or pass `--personal`. Do NOT use for in-progress work.
|
|
92
92
|
|
|
93
|
+
Do NOT use `record-work` for in-progress work. Use it only when the work is already done in the chat.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ovld protocol record-work \
|
|
97
|
+
--objective "User asked me to X; I did Y by..." \
|
|
98
|
+
--summary "Narrative for the feed post and reviewer." \
|
|
99
|
+
--change-rationales-file -
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Or stream the full payload via stdin to avoid quote escaping:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ovld protocol record-work --payload-file - <<'EOF'
|
|
106
|
+
{
|
|
107
|
+
"objective": "...",
|
|
108
|
+
"summary": "...",
|
|
109
|
+
"artifacts": [{"type": "next_steps", "label": "...", "content": "..."}],
|
|
110
|
+
"changeRationales": [{"label": "...", "file_path": "...", "summary": "...", "why": "...", "impact": "...", "hunks": [{"header": "@@ ..."}]}]
|
|
111
|
+
}
|
|
112
|
+
EOF
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Project resolution mirrors `prompt`/`create`: cwd is matched against the caller's `project_user.local_working_directory`. If no match:
|
|
116
|
+
|
|
117
|
+
1. **Ask the user for a `--project-id`** if the work is project-related. Show them a brief description of what you're about to record so they can pick the right project.
|
|
118
|
+
2. If the user confirms the work is not tied to any project, pass `--personal` to create a private ticket.
|
|
119
|
+
|
|
120
|
+
Validation: in a git workspace, `record-work` checks that uncommitted changes are represented by `changeRationales` and rejects if they aren't (same check as `deliver`). Pass `--skip-file-change-check` only when intentionally bypassing.
|
|
121
|
+
|
|
122
|
+
|
|
93
123
|
## Change Rationales
|
|
94
124
|
|
|
95
125
|
Always include `changeRationales` when delivering. Optionally include them on updates during long-running work.
|
|
@@ -120,9 +150,32 @@ When creating tickets from within a repository:
|
|
|
120
150
|
```bash
|
|
121
151
|
ovld protocol create --agent cursor --objective "Capture follow-up work from this repository"
|
|
122
152
|
ovld protocol prompt --agent cursor --objective "Implement feature X" --priority medium
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
To inspect project resolution explicitly:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
123
158
|
ovld protocol discover-project
|
|
124
159
|
```
|
|
125
160
|
|
|
161
|
+
### Resolving the project ID when you don't have one
|
|
162
|
+
|
|
163
|
+
When you need a project ID for a protocol command and the ticket prompt did not supply one, resolve it in this order.
|
|
164
|
+
|
|
165
|
+
**Locally (CLI inside a shell on the user's machine):**
|
|
166
|
+
|
|
167
|
+
1. `--project-id` if explicitly provided.
|
|
168
|
+
2. Otherwise, let the CLI match the current working directory (the default behavior of `create`, `prompt`, `discover-project`).
|
|
169
|
+
3. If working-directory resolution returns nothing, read `overlord.json` from the cwd (or any ancestor you have access to) and pass its project id via `--project-id`.
|
|
170
|
+
|
|
171
|
+
**Over MCP (web agents and hosted tools, where the server cannot see the agent's cwd):**
|
|
172
|
+
|
|
173
|
+
1. `--project-id` / `projectId` if explicitly provided.
|
|
174
|
+
2. Read `overlord.json` from the directory the user is accessing and pass its project id as `projectId`.
|
|
175
|
+
3. As a last resort, try `workingDirectory` resolution.
|
|
176
|
+
|
|
177
|
+
If `overlord.json` contains more than one project, show the user the project **names** from that file and ask which one to use before calling any protocol command — never silently pick one.
|
|
178
|
+
|
|
126
179
|
### Choosing `--execution-target`
|
|
127
180
|
|
|
128
181
|
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
@@ -174,6 +227,7 @@ This keeps the ticket feed readable while preserving the full document in versio
|
|
|
174
227
|
- The `summary` in deliver is what the PM reads first, so write it as a narrative, not a command list.
|
|
175
228
|
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
176
229
|
- If you must run `ovld auth login`, always include `--organization-id <id>` — use the organization ID from the ticket prompt context to select the organization non-interactively and avoid a blocking TTY prompt.
|
|
230
|
+
- Do not add or commit changes unless the user explicitly asks you to commit.
|
|
177
231
|
- Delivery is the concluding step. After delivering, stop unless the user follows up or the ticket is reopened.
|
|
178
232
|
|
|
179
|
-
<!-- version: 0.4.
|
|
233
|
+
<!-- version: 0.4.11 -->
|
|
@@ -106,6 +106,24 @@ ovld protocol create --agent codex --objective "Capture follow-up work from this
|
|
|
106
106
|
ovld protocol prompt --agent codex --objective "Implement feature X" --priority medium
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
### Resolving the project ID when you don't have one
|
|
110
|
+
|
|
111
|
+
When you need a project ID for a protocol command and the ticket prompt did not supply one, resolve it in this order.
|
|
112
|
+
|
|
113
|
+
**Locally (CLI inside a shell on the user's machine):**
|
|
114
|
+
|
|
115
|
+
1. `--project-id` if explicitly provided.
|
|
116
|
+
2. Otherwise, let the CLI match the current working directory (the default behavior of `create`, `prompt`, `discover-project`).
|
|
117
|
+
3. If working-directory resolution returns nothing, read `overlord.json` from the cwd (or any ancestor you have access to) and pass its project id via `--project-id`.
|
|
118
|
+
|
|
119
|
+
**Over MCP (web agents and hosted tools, where the server cannot see the agent's cwd):**
|
|
120
|
+
|
|
121
|
+
1. `--project-id` / `projectId` if explicitly provided.
|
|
122
|
+
2. Read `overlord.json` from the directory the user is accessing and pass its project id as `projectId`.
|
|
123
|
+
3. As a last resort, try `workingDirectory` resolution.
|
|
124
|
+
|
|
125
|
+
If `overlord.json` contains more than one project, show the user the project **names** from that file and ask which one to use before calling any protocol command — never silently pick one.
|
|
126
|
+
|
|
109
127
|
### Choosing `--execution-target`
|
|
110
128
|
|
|
111
129
|
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
@@ -195,4 +213,4 @@ This keeps the ticket feed readable while preserving the full document in versio
|
|
|
195
213
|
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
196
214
|
- If you must run `ovld auth login`, always include `--organization-id <id>` — use the organization ID from the ticket prompt context to select the organization non-interactively and avoid a blocking TTY prompt.
|
|
197
215
|
|
|
198
|
-
<!-- version: 0.4.
|
|
216
|
+
<!-- version: 0.4.11 -->
|