overlord-cli 0.2605101225.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 +128 -0
- package/bin/_cli/attach.mjs +357 -0
- package/bin/_cli/auth.mjs +696 -0
- package/bin/_cli/cli-update.mjs +119 -0
- package/bin/_cli/credentials.mjs +723 -0
- package/bin/_cli/index.mjs +170 -0
- package/bin/_cli/launcher.mjs +474 -0
- package/bin/_cli/new-ticket.mjs +306 -0
- package/bin/_cli/postinstall.mjs +43 -0
- package/bin/_cli/protocol.mjs +1799 -0
- package/bin/_cli/setup.mjs +1634 -0
- package/bin/_cli/ticket.mjs +55 -0
- package/bin/_cli/tickets.mjs +121 -0
- package/bin/_cli/version.mjs +7 -0
- package/bin/ovld.mjs +13 -0
- package/package.json +36 -0
- package/plugins/claude/.claude-plugin/plugin.json +34 -0
- package/plugins/claude/README.md +42 -0
- package/plugins/claude/commands/connect.md +19 -0
- package/plugins/claude/commands/create.md +17 -0
- package/plugins/claude/commands/load.md +19 -0
- package/plugins/claude/commands/spawn.md +17 -0
- package/plugins/claude/hooks/hooks.json +15 -0
- package/plugins/claude/scripts/permission-hook.sh +21 -0
- package/plugins/claude/skills/overlord-ticket/SKILL.md +164 -0
- package/plugins/cursor/.cursor-plugin/plugin.json +14 -0
- package/plugins/cursor/commands/connect.md +3 -0
- package/plugins/cursor/commands/create.md +11 -0
- package/plugins/cursor/commands/load.md +3 -0
- package/plugins/cursor/commands/spawn.md +3 -0
- package/plugins/cursor/mcp.json +8 -0
- package/plugins/cursor/rules/overlord-local.mdc +10 -0
- package/plugins/cursor/scripts/overlord-mcp.mjs +150 -0
- package/plugins/cursor/skills/overlord-ticket/SKILL.md +49 -0
- package/plugins/overlord/.codex-plugin/plugin.json +35 -0
- package/plugins/overlord/.mcp.json +11 -0
- package/plugins/overlord/README.md +42 -0
- package/plugins/overlord/assets/icon.png +0 -0
- package/plugins/overlord/assets/logo.png +0 -0
- package/plugins/overlord/assets/screenshot.svg +28 -0
- package/plugins/overlord/scripts/overlord-mcp.mjs +688 -0
- package/plugins/overlord/skills/overlord-ticket/SKILL.md +146 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { buildAuthHeaders, resolveAuth } from './credentials.mjs';
|
|
4
|
+
|
|
5
|
+
export async function ticketContext(ticketId) {
|
|
6
|
+
if (!ticketId) {
|
|
7
|
+
// Fall back to TICKET_ID env var
|
|
8
|
+
ticketId = process.env.TICKET_ID;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!ticketId) {
|
|
12
|
+
console.error('Error: ticket ID is required.\n');
|
|
13
|
+
console.error('Usage: ovld ticket context <ticketId>');
|
|
14
|
+
console.error(' TICKET_ID=<id> ovld ticket context');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { platformUrl, bearerToken, localSecret, organizationId } = await resolveAuth();
|
|
19
|
+
|
|
20
|
+
const url = `${platformUrl}/api/protocol/context/${ticketId}`;
|
|
21
|
+
const res = await fetch(url, {
|
|
22
|
+
headers: buildAuthHeaders(bearerToken, localSecret, organizationId)
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
throw new Error(`Failed to fetch ticket context (${res.status}): ${await res.text()}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const text = await res.text();
|
|
30
|
+
process.stdout.write(text);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function runTicketCommand(subcommand, args) {
|
|
34
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
35
|
+
console.log(`ovld ticket <subcommand>
|
|
36
|
+
|
|
37
|
+
Subcommands:
|
|
38
|
+
context <ticketId> Print ticket context (objective, acceptance criteria, tools)
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
ovld ticket context abc-123
|
|
42
|
+
TICKET_ID=abc-123 ovld ticket context
|
|
43
|
+
`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (subcommand === 'context') {
|
|
48
|
+
await ticketContext(args[0]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.error(`Unknown ticket subcommand: ${subcommand}\n`);
|
|
53
|
+
console.log('Run: ovld ticket help');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { buildAuthHeaders, resolveAuth } from './credentials.mjs';
|
|
4
|
+
import { runCreateCommand } from './new-ticket.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parse simple CLI flags: --key value or --key=value
|
|
8
|
+
* @param {string[]} args
|
|
9
|
+
* @param {string[]} knownFlags
|
|
10
|
+
* @returns {Record<string, string | boolean>}
|
|
11
|
+
*/
|
|
12
|
+
function parseFlags(args, knownFlags) {
|
|
13
|
+
const result = {};
|
|
14
|
+
for (let i = 0; i < args.length; i++) {
|
|
15
|
+
const arg = args[i];
|
|
16
|
+
if (arg.startsWith('--')) {
|
|
17
|
+
const eqIdx = arg.indexOf('=');
|
|
18
|
+
if (eqIdx !== -1) {
|
|
19
|
+
const key = arg.slice(2, eqIdx);
|
|
20
|
+
result[key] = arg.slice(eqIdx + 1);
|
|
21
|
+
} else {
|
|
22
|
+
const key = arg.slice(2);
|
|
23
|
+
// If the next arg is not a flag, treat it as the value
|
|
24
|
+
if (i + 1 < args.length && !args[i + 1].startsWith('--')) {
|
|
25
|
+
result[key] = args[i + 1];
|
|
26
|
+
i++;
|
|
27
|
+
} else {
|
|
28
|
+
result[key] = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function apiPost(url, token, localSecret, organizationId, body) {
|
|
37
|
+
const res = await fetch(url, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
...buildAuthHeaders(token, localSecret, organizationId),
|
|
41
|
+
'Content-Type': 'application/json'
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify(body)
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const data = await res.json().catch(() => ({}));
|
|
47
|
+
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
throw new Error(`API error (${res.status}): ${data.error ?? JSON.stringify(data)}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function ticketsCreate(args) {
|
|
56
|
+
await runCreateCommand(args);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function ticketsList(args) {
|
|
60
|
+
const flags = parseFlags(args, ['status', 'include-completed']);
|
|
61
|
+
|
|
62
|
+
const { platformUrl, bearerToken, localSecret, organizationId } = await resolveAuth();
|
|
63
|
+
|
|
64
|
+
const body = {
|
|
65
|
+
includeCompleted: flags['include-completed'] !== false,
|
|
66
|
+
...(flags.status ? { statuses: [String(flags.status)] } : {})
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const data = await apiPost(
|
|
70
|
+
`${platformUrl}/api/protocol/search-tickets`,
|
|
71
|
+
bearerToken,
|
|
72
|
+
localSecret,
|
|
73
|
+
organizationId,
|
|
74
|
+
body
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (!data.tickets?.length) {
|
|
78
|
+
console.log('No tickets found.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (const t of data.tickets) {
|
|
83
|
+
const ref = t.id?.slice(-8).toUpperCase() ?? '?';
|
|
84
|
+
const title = t.title || t.objective?.slice(0, 60) || '(no title)';
|
|
85
|
+
console.log(` [${ref}] [${t.status ?? '?'}] ${title}`);
|
|
86
|
+
console.log(` ${t.id}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(`\n${data.count ?? data.tickets.length} ticket(s)`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function runTicketsCommand(subcommand, args) {
|
|
93
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
94
|
+
console.log(`ovld tickets <subcommand>
|
|
95
|
+
|
|
96
|
+
Subcommands:
|
|
97
|
+
create Create a new ticket
|
|
98
|
+
list List tickets
|
|
99
|
+
|
|
100
|
+
Examples:
|
|
101
|
+
ovld tickets create "Implement login page"
|
|
102
|
+
ovld tickets list
|
|
103
|
+
ovld tickets list --status draft
|
|
104
|
+
`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (subcommand === 'create') {
|
|
109
|
+
await ticketsCreate(args);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (subcommand === 'list') {
|
|
114
|
+
await ticketsList(args);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.error(`Unknown tickets subcommand: ${subcommand}\n`);
|
|
119
|
+
console.log('Run: ovld tickets help');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
package/bin/ovld.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Canonical CLI entrypoint. Used by both the npm package and the Electron app.
|
|
5
|
+
* All CLI source files live in _cli/ alongside this file.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { runCli } from './_cli/index.mjs';
|
|
9
|
+
|
|
10
|
+
runCli({ primaryCommand: 'ovld' }).catch((error) => {
|
|
11
|
+
console.error(error instanceof Error ? error.message : error);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "overlord-cli",
|
|
3
|
+
"version": "0.2605101225.0",
|
|
4
|
+
"description": "Overlord CLI — launch AI agents on tickets from anywhere",
|
|
5
|
+
"homepage": "https://www.ovld.ai/docs/",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"overlord": "bin/ovld.mjs",
|
|
9
|
+
"ovld": "bin/ovld.mjs"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/",
|
|
16
|
+
"plugins/"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"postinstall": "node bin/_cli/postinstall.mjs || true"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"overlord",
|
|
26
|
+
"ai",
|
|
27
|
+
"agents",
|
|
28
|
+
"cli"
|
|
29
|
+
],
|
|
30
|
+
"license": "Proprietary",
|
|
31
|
+
"repository": {
|
|
32
|
+
"private": true,
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/cooperativ-labs/overlord/packages/overlord-cli.git"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "overlord",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Overlord ticket protocol workflow for Claude Code — attach/update/ask/deliver, slash commands, and a PermissionRequest notifier.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Cooperativ",
|
|
7
|
+
"url": "https://github.com/cooperativ"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://www.ovld.ai",
|
|
10
|
+
"repository": "https://github.com/cooperativ/overlord",
|
|
11
|
+
"license": "UNLICENSED",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"overlord",
|
|
14
|
+
"tickets",
|
|
15
|
+
"agents",
|
|
16
|
+
"workflow",
|
|
17
|
+
"protocol",
|
|
18
|
+
"claude-code"
|
|
19
|
+
],
|
|
20
|
+
"userConfig": {
|
|
21
|
+
"overlord_url": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"title": "Overlord URL",
|
|
24
|
+
"description": "Overlord platform URL (e.g. https://www.ovld.ai or http://localhost:3000).",
|
|
25
|
+
"sensitive": false
|
|
26
|
+
},
|
|
27
|
+
"agent_token": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"title": "Agent token",
|
|
30
|
+
"description": "Overlord agent token. Pull from Overlord Settings → Agents & MCP or from ~/.ovld/credentials.json.",
|
|
31
|
+
"sensitive": true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Overlord — Claude Code plugin
|
|
2
|
+
|
|
3
|
+
Claude Code plugin that exposes the Overlord local ticket workflow to any Claude Code surface (CLI, VS Code extension, Claude Code desktop app).
|
|
4
|
+
|
|
5
|
+
## What ships
|
|
6
|
+
|
|
7
|
+
- `skills/overlord-ticket/SKILL.md` — durable attach → update → ask → deliver workflow.
|
|
8
|
+
- `commands/{connect,load,create,prompt}.md` — slash commands for session routing and ticket creation.
|
|
9
|
+
- `hooks/hooks.json` + `scripts/permission-hook.sh` — PermissionRequest notifier that calls `ovld protocol permission-request`.
|
|
10
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, the workflow tells agents to request permission escalation or network access before retrying.
|
|
11
|
+
- `userConfig` for `overlord_url`. Current installs should authenticate with `ovld auth repair` first when a shared session already exists, then `ovld auth login` or Overlord Desktop; env vars remain optional overrides for remote shells, CI, and explicit OAuth token injection.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Overlord CLI (`ovld`) on `PATH`. See the Overlord docs / Settings → Agents & MCP.
|
|
16
|
+
- `TICKET_ID` is exported automatically when a Claude session is launched from Overlord; outside that launch, set it manually before calling the permission hook.
|
|
17
|
+
|
|
18
|
+
## Install (local dev)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
claude --plugin-dir /absolute/path/to/overlord/plugins/claude
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Install (marketplace)
|
|
25
|
+
|
|
26
|
+
Once published:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
claude plugin marketplace add cooperativ/overlord-marketplace
|
|
30
|
+
claude plugin install overlord@cooperativ
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Older plugin versions prompted for `overlord_url` and a legacy token at install time. The current hook goes through `ovld protocol`, so the CLI resolves auth from env vars or the shared `~/.ovld` credentials written by CLI/Desktop login.
|
|
34
|
+
|
|
35
|
+
## Namespaced components
|
|
36
|
+
|
|
37
|
+
Inside Claude Code the components are surfaced with the plugin prefix:
|
|
38
|
+
|
|
39
|
+
- skill → `overlord:overlord-ticket`
|
|
40
|
+
- commands → `/overlord:connect`, `/overlord:load`, `/overlord:create`, `/overlord:prompt`
|
|
41
|
+
|
|
42
|
+
Prompts generated by Overlord (see `lib/overlord/ticket-prompt.ts`) already reference these names in `bundle` instruction mode.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Connect this session to another Overlord ticket by ticket ID
|
|
3
|
+
argument-hint: <ticket_id>
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Connect this session to another Overlord ticket.
|
|
8
|
+
|
|
9
|
+
Treat `$ARGUMENTS` as the target ticket ID.
|
|
10
|
+
If no ticket ID was provided, ask the user for one and stop.
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
`ovld protocol connect --ticket-id <ticketId>`
|
|
14
|
+
|
|
15
|
+
Rules:
|
|
16
|
+
- Use `connect`, not `attach`.
|
|
17
|
+
- Do not load extra ticket context unless the user explicitly asks for it.
|
|
18
|
+
- After the command succeeds, report the returned `SESSION_KEY` and confirm that future updates should use that ticket.
|
|
19
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a draft Overlord ticket from the current conversation
|
|
3
|
+
argument-hint: <objective or raw flags>
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Create a draft Overlord ticket from the user's request.
|
|
8
|
+
|
|
9
|
+
Use `$ARGUMENTS` as the input.
|
|
10
|
+
If it already contains flags such as `--title`, `--priority`, `--project-id`, or `--execution-target`, pass those flags through after `ovld protocol create --agent claude-code`.
|
|
11
|
+
Otherwise, treat `$ARGUMENTS` as the objective text and run:
|
|
12
|
+
`ovld protocol create --agent claude-code --objective "<objective>"`
|
|
13
|
+
|
|
14
|
+
If no objective was provided, ask the user for one and stop.
|
|
15
|
+
|
|
16
|
+
After the command succeeds, report the new `TICKET_ID`.
|
|
17
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Load Overlord ticket context without creating a new session
|
|
3
|
+
argument-hint: <ticket_id>
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Load Overlord ticket context without attaching to the ticket.
|
|
8
|
+
|
|
9
|
+
Treat `$ARGUMENTS` as the target ticket ID.
|
|
10
|
+
If no ticket ID was provided, ask the user for one and stop.
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
`ovld protocol load-context --ticket-id <ticketId>`
|
|
14
|
+
|
|
15
|
+
Rules:
|
|
16
|
+
- Use `load-context`, not `attach`.
|
|
17
|
+
- Do not create or switch sessions.
|
|
18
|
+
- Summarize the returned ticket details, history, artifacts, and shared context for the user.
|
|
19
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new Overlord ticket from the current conversation
|
|
3
|
+
argument-hint: <objective or raw flags>
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Create a new Overlord ticket from the user's request.
|
|
8
|
+
|
|
9
|
+
Use `$ARGUMENTS` as the input.
|
|
10
|
+
If it already contains flags such as `--title`, `--priority`, `--project-id`, or `--execution-target`, pass those flags through after `ovld protocol spawn --agent claude-code`.
|
|
11
|
+
Otherwise, treat `$ARGUMENTS` as the objective text and run:
|
|
12
|
+
`ovld protocol spawn --agent claude-code --objective "<objective>"`
|
|
13
|
+
|
|
14
|
+
If no objective was provided, ask the user for one and stop.
|
|
15
|
+
|
|
16
|
+
After the command succeeds, report the new `TICKET_ID` and `SESSION_KEY`.
|
|
17
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Overlord PermissionRequest notification hook (plugin-managed).
|
|
3
|
+
#
|
|
4
|
+
# Prefers plugin userConfig values (CLAUDE_PLUGIN_OPTION_*) when set, and falls
|
|
5
|
+
# back to the raw OVERLORD_URL / OVERLORD_ACCESS_TOKEN env vars Overlord-launched
|
|
6
|
+
# shells already export. Silently no-ops if we can't authenticate — the hook must
|
|
7
|
+
# never block the user or leak errors into the Claude session.
|
|
8
|
+
BODY=$(cat -)
|
|
9
|
+
OVERLORD_BASE_URL="${CLAUDE_PLUGIN_OPTION_OVERLORD_URL:-$OVERLORD_URL}"
|
|
10
|
+
OVERLORD_TOKEN="${CLAUDE_PLUGIN_OPTION_OVERLORD_ACCESS_TOKEN:-$OVERLORD_ACCESS_TOKEN}"
|
|
11
|
+
if [ -n "$OVERLORD_BASE_URL" ] && [ -n "$OVERLORD_TOKEN" ] && [ -n "$TICKET_ID" ]; then
|
|
12
|
+
curl -sf -m 5 \
|
|
13
|
+
-X POST "$OVERLORD_BASE_URL/api/protocol/permission-request?ticketId=$TICKET_ID" \
|
|
14
|
+
-H "Authorization: Bearer $OVERLORD_TOKEN" \
|
|
15
|
+
-H "X-Overlord-Local-Secret: $OVERLORD_LOCAL_SECRET" \
|
|
16
|
+
-H "Content-Type: application/json" \
|
|
17
|
+
-d "$BODY" \
|
|
18
|
+
>/dev/null 2>&1 &
|
|
19
|
+
disown
|
|
20
|
+
fi
|
|
21
|
+
exit 0
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: overlord-ticket
|
|
3
|
+
description: Overlord local workflow protocol for Claude Code, covering both Overlord-launched tickets and chat-invoked Overlord work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Overlord Ticket
|
|
7
|
+
|
|
8
|
+
Use this skill whenever Claude Code needs to work with Overlord, whether the session was launched by Overlord Desktop/CLI or the user asks from chat to engage with Overlord.
|
|
9
|
+
|
|
10
|
+
## Mode 1: Launched From Overlord Desktop Or CLI
|
|
11
|
+
|
|
12
|
+
Use this mode when the prompt already contains a ticket ID or explicitly says the session was launched by Overlord.
|
|
13
|
+
|
|
14
|
+
1. Attach first with `ovld protocol attach --ticket-id <ticket_id>`.
|
|
15
|
+
2. Keep the returned `session.sessionKey` for all follow-up calls.
|
|
16
|
+
3. Treat the Overlord ticket prompt as authoritative for the objective, constraints, and delivery target.
|
|
17
|
+
4. Post updates while working with `ovld protocol update --phase execute`.
|
|
18
|
+
5. If the user sends a follow-up message after the initial ticket, publish it immediately with `--event-type user_follow_up`.
|
|
19
|
+
6. If blocked, call `ovld protocol ask` and stop.
|
|
20
|
+
7. Deliver last with `ovld protocol deliver`, including `changeRationales` for each meaningful behavioral file change.
|
|
21
|
+
|
|
22
|
+
### Mode 1 Reference
|
|
23
|
+
|
|
24
|
+
Attach:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ovld protocol attach --ticket-id $TICKET_ID
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Update:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ovld protocol update --session-key <sessionKey> --ticket-id $TICKET_ID --summary "What you did and why." --phase execute
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Supported `--phase` values:
|
|
37
|
+
- `draft`
|
|
38
|
+
- `execute`
|
|
39
|
+
- `review`
|
|
40
|
+
- `deliver`
|
|
41
|
+
- `complete`
|
|
42
|
+
- `blocked`
|
|
43
|
+
- `cancelled`
|
|
44
|
+
|
|
45
|
+
These are hardcoded CLI-supported values for the `--phase` flag. They are not user-defined phase types.
|
|
46
|
+
|
|
47
|
+
Event types:
|
|
48
|
+
- `update` for standard progress updates
|
|
49
|
+
- `user_follow_up` for human follow-up messages after the initial ticket
|
|
50
|
+
- `alert` for warnings or non-blocking issues
|
|
51
|
+
|
|
52
|
+
Ask when blocked:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
ovld protocol ask --session-key <sessionKey> --ticket-id $TICKET_ID --question "Specific question for the PM."
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Deliver:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
ovld protocol deliver --session-key <sessionKey> \
|
|
62
|
+
--ticket-id $TICKET_ID \
|
|
63
|
+
--summary "Narrative: what you did, next steps." \
|
|
64
|
+
--artifacts-json '[{"type":"next_steps","label":"Next steps","content":"..."}]' \
|
|
65
|
+
--change-rationales-json '[{"label":"Short reviewer title","file_path":"path/to/file.ts","summary":"What changed.","why":"Why it changed.","impact":"Behavioral impact.","hunks":[{"header":"@@ -10,6 +10,14 @@"}]}]'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed. If you use `--payload-file`, `--artifacts-file`, or `--change-rationales-file` with a real path, treat that file as ephemeral scratch data outside the repository and remove it after delivery.
|
|
69
|
+
|
|
70
|
+
## Mode 2: Asked From Chat To Use Overlord
|
|
71
|
+
|
|
72
|
+
Use this mode when the conversation starts normally and the user asks Claude to create, inspect, connect to, or otherwise use Overlord.
|
|
73
|
+
|
|
74
|
+
1. If the user wants to create tickets (and does not ask to start execution), run `ovld protocol create --agent claude-code --objective "..."`.
|
|
75
|
+
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
76
|
+
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to the caller's configured Overlord `project_user.local_working_directory`, then creates a standalone draft.
|
|
77
|
+
2. Default to `create` for new tickets. Only use `/overlord:spawn` or `ovld protocol spawn --agent claude-code --objective "..."` when the user explicitly asks to create and execute immediately.
|
|
78
|
+
`spawn` creates the ticket in `execute` status and attaches immediately.
|
|
79
|
+
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>`.
|
|
80
|
+
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>`.
|
|
81
|
+
5. If the user wants to find a ticket but does not know the ID, use `ovld attach` for interactive ticket search and agent launch, or ask the user for the ticket ID if staying strictly inside chat is the better fit.
|
|
82
|
+
6. If you need other lifecycle commands or flags, run `ovld protocol help` and use the real subcommand list instead of guessing.
|
|
83
|
+
7. Once you attach to a ticket, switch back to Mode 1 and follow the full ticket lifecycle.
|
|
84
|
+
|
|
85
|
+
## Change Rationales
|
|
86
|
+
|
|
87
|
+
Always include `changeRationales` when delivering. Optionally include them on updates during long-running work.
|
|
88
|
+
|
|
89
|
+
Before delivering, make sure every meaningful git-tracked file change is represented in `changeRationales`; do not send `file_changes` as an artifact.
|
|
90
|
+
|
|
91
|
+
These are structured protocol payloads that Overlord stores as first-class rows in the `file_changes` table. Prefer inline JSON or the dedicated command below. For larger full delivery payloads, prefer `--payload-file -` so summary, artifacts, and change rationales stay in one JSON document without creating a temporary file. Ordinary deliver artifacts should use `next_steps`, `test_results`, `migration`, `note`, `url`, or `decision`.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ovld protocol record-change-rationales --session-key <sessionKey> --ticket-id $TICKET_ID \
|
|
95
|
+
--summary "Recorded rationale details for the latest code changes." --phase execute \
|
|
96
|
+
--change-rationales-json '[{"label":"Add backoff","file_path":"lib/api.ts","summary":"Added retry.","why":"Transient failures.","impact":"Retries 3x.","hunks":[{"header":"@@ -22,4 +22,18 @@"}]}]'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
ovld protocol update --session-key <sessionKey> --ticket-id $TICKET_ID \
|
|
101
|
+
--summary "Added retry logic." --phase execute \
|
|
102
|
+
--change-rationales-json '[{"label":"Add backoff","file_path":"lib/api.ts","summary":"Added retry.","why":"Transient failures.","impact":"Retries 3x.","hunks":[{"header":"@@ -22,4 +22,18 @@"}]}]'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Record only meaningful behavioral changes. Skip formatting-only noise.
|
|
106
|
+
|
|
107
|
+
## Project Discovery And Ticket Creation
|
|
108
|
+
|
|
109
|
+
When creating tickets from within a repository:
|
|
110
|
+
- Prefer `create` by default for draft ticket creation.
|
|
111
|
+
- Use `spawn` only when the user explicitly asks to start execution immediately.
|
|
112
|
+
- Both commands can resolve the project from the current working directory; use `--working-directory` to override.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
ovld protocol create --agent claude-code --objective "Capture follow-up work from this repository"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
ovld protocol spawn --agent claude-code --objective "Implement feature X" --priority medium
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
To inspect project resolution explicitly:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
ovld protocol discover-project
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
You can override with `--project-id` or `--working-directory` if needed.
|
|
129
|
+
|
|
130
|
+
### Choosing `--execution-target`
|
|
131
|
+
|
|
132
|
+
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
133
|
+
|
|
134
|
+
- **`agent`** — any task an AI agent can complete in a computer environment: coding, internet research, document editing, data analysis, automated testing, etc.
|
|
135
|
+
- **`human`** — any task requiring human presence or judgment: setting credentials or tokens in a third-party UI (e.g. Vercel, AWS), sending physical mail, making a product or business decision, physical-world actions.
|
|
136
|
+
|
|
137
|
+
When in doubt, ask yourself: *can this be done entirely inside a terminal or browser by an AI without human intervention?* If yes → `agent`. If it requires a human to log in, decide, or act in the real world → `human`.
|
|
138
|
+
|
|
139
|
+
## Context And Artifacts
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
ovld protocol read-context --session-key <sessionKey> --ticket-id $TICKET_ID
|
|
143
|
+
ovld protocol write-context --session-key <sessionKey> --ticket-id $TICKET_ID --key "key" --value '"json-value"'
|
|
144
|
+
ovld protocol attachment-list --session-key <sessionKey> --ticket-id $TICKET_ID
|
|
145
|
+
ovld protocol attachment-upload-file --session-key <sessionKey> --ticket-id $TICKET_ID --objective-id <objective-id> --file ./spec.pdf --content-type application/pdf
|
|
146
|
+
ovld protocol attachment-download-url --session-key <sessionKey> --ticket-id $TICKET_ID --attachment-id <attachment-id>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
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.
|
|
150
|
+
|
|
151
|
+
## Rules
|
|
152
|
+
|
|
153
|
+
- Always attach first and always deliver last once you are on a ticket.
|
|
154
|
+
- Use `ovld protocol` commands and the plugin's slash commands instead of ad hoc scripts.
|
|
155
|
+
- Do not invent protocol subcommands. Use `ovld protocol help` when unsure.
|
|
156
|
+
- The `summary` in deliver is what the PM reads first, so write it as a narrative, not a command list.
|
|
157
|
+
- Use `write-context` for facts a future agent session should know.
|
|
158
|
+
- If `ovld` reports `OVERLORD_URL` is unreachable, request permission escalation or network access before retrying.
|
|
159
|
+
- 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.
|
|
160
|
+
- 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.
|
|
161
|
+
- Do not add or commit changes unless the user explicitly asks you to commit.
|
|
162
|
+
- Delivery is the concluding step. After delivering, stop unless the user follows up or the ticket is reopened.
|
|
163
|
+
|
|
164
|
+
<!-- version: 0.2.6 -->
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "overlord",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local Overlord workflow plugin for Cursor terminal agents.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Cooperativ",
|
|
7
|
+
"url": "https://github.com/cooperativ"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/cooperativ/overlord",
|
|
10
|
+
"repository": "https://github.com/cooperativ/overlord",
|
|
11
|
+
"license": "UNLICENSED",
|
|
12
|
+
"skills": "./skills/",
|
|
13
|
+
"mcpServers": "./mcp.json"
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Create a draft Overlord ticket.
|
|
2
|
+
|
|
3
|
+
Use the text after `/create` as the objective unless raw flags are present.
|
|
4
|
+
|
|
5
|
+
Run:
|
|
6
|
+
`ovld protocol create --agent cursor --objective "<objective>"`
|
|
7
|
+
|
|
8
|
+
If raw flags are present, pass them through after:
|
|
9
|
+
`ovld protocol create --agent cursor`
|
|
10
|
+
|
|
11
|
+
If `ovld` reports `OVERLORD_URL` is unreachable, stop and request permission escalation or network access before retrying.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Overlord local workflow protocol for Cursor.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Overlord Local Workflow
|
|
7
|
+
|
|
8
|
+
- If the session was launched by Overlord Desktop or CLI, attach first with `ovld protocol attach --ticket-id $TICKET_ID`, update during work, ask when blocked, and deliver last.
|
|
9
|
+
- If the user asks from chat to use Overlord, use `/spawn` for new tickets, `/load` for read-only context by ticket ID, `/connect` to route the session onto an existing ticket, and `search_tickets` to find tickets by keyword or status.
|
|
10
|
+
- If you need other protocol commands or flags, run `ovld protocol help` instead of guessing.
|