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.
Files changed (42) hide show
  1. package/README.md +128 -0
  2. package/bin/_cli/attach.mjs +357 -0
  3. package/bin/_cli/auth.mjs +696 -0
  4. package/bin/_cli/cli-update.mjs +119 -0
  5. package/bin/_cli/credentials.mjs +723 -0
  6. package/bin/_cli/index.mjs +170 -0
  7. package/bin/_cli/launcher.mjs +474 -0
  8. package/bin/_cli/new-ticket.mjs +306 -0
  9. package/bin/_cli/postinstall.mjs +43 -0
  10. package/bin/_cli/protocol.mjs +1799 -0
  11. package/bin/_cli/setup.mjs +1634 -0
  12. package/bin/_cli/ticket.mjs +55 -0
  13. package/bin/_cli/tickets.mjs +121 -0
  14. package/bin/_cli/version.mjs +7 -0
  15. package/bin/ovld.mjs +13 -0
  16. package/package.json +36 -0
  17. package/plugins/claude/.claude-plugin/plugin.json +34 -0
  18. package/plugins/claude/README.md +42 -0
  19. package/plugins/claude/commands/connect.md +19 -0
  20. package/plugins/claude/commands/create.md +17 -0
  21. package/plugins/claude/commands/load.md +19 -0
  22. package/plugins/claude/commands/spawn.md +17 -0
  23. package/plugins/claude/hooks/hooks.json +15 -0
  24. package/plugins/claude/scripts/permission-hook.sh +21 -0
  25. package/plugins/claude/skills/overlord-ticket/SKILL.md +164 -0
  26. package/plugins/cursor/.cursor-plugin/plugin.json +14 -0
  27. package/plugins/cursor/commands/connect.md +3 -0
  28. package/plugins/cursor/commands/create.md +11 -0
  29. package/plugins/cursor/commands/load.md +3 -0
  30. package/plugins/cursor/commands/spawn.md +3 -0
  31. package/plugins/cursor/mcp.json +8 -0
  32. package/plugins/cursor/rules/overlord-local.mdc +10 -0
  33. package/plugins/cursor/scripts/overlord-mcp.mjs +150 -0
  34. package/plugins/cursor/skills/overlord-ticket/SKILL.md +49 -0
  35. package/plugins/overlord/.codex-plugin/plugin.json +35 -0
  36. package/plugins/overlord/.mcp.json +11 -0
  37. package/plugins/overlord/README.md +42 -0
  38. package/plugins/overlord/assets/icon.png +0 -0
  39. package/plugins/overlord/assets/logo.png +0 -0
  40. package/plugins/overlord/assets/screenshot.svg +28 -0
  41. package/plugins/overlord/scripts/overlord-mcp.mjs +688 -0
  42. package/plugins/overlord/skills/overlord-ticket/SKILL.md +146 -0
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFile } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+
6
+ const execFileAsync = promisify(execFile);
7
+ const OVLD_BIN = process.env.OVLD_BIN?.trim() || 'ovld';
8
+ const PROTOCOL_VERSION = '2025-06-18';
9
+ let buffer = Buffer.alloc(0);
10
+
11
+ function send(message) {
12
+ const json = JSON.stringify(message);
13
+ const body = Buffer.from(json, 'utf8');
14
+ const header = Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, 'utf8');
15
+ process.stdout.write(Buffer.concat([header, body]));
16
+ }
17
+
18
+ function parseMessages(chunk) {
19
+ buffer = Buffer.concat([buffer, chunk]);
20
+ const messages = [];
21
+ while (true) {
22
+ const headerEnd = buffer.indexOf('\r\n\r\n');
23
+ if (headerEnd === -1) break;
24
+ const headerText = buffer.subarray(0, headerEnd).toString('utf8');
25
+ const lengthMatch = headerText.match(/Content-Length:\s*(\d+)/i);
26
+ if (!lengthMatch) throw new Error('Missing Content-Length header');
27
+ const contentLength = Number(lengthMatch[1]);
28
+ const totalLength = headerEnd + 4 + contentLength;
29
+ if (buffer.length < totalLength) break;
30
+ const body = buffer.subarray(headerEnd + 4, totalLength).toString('utf8');
31
+ buffer = buffer.subarray(totalLength);
32
+ messages.push(JSON.parse(body));
33
+ }
34
+ return messages;
35
+ }
36
+
37
+ async function runProtocol(subcommand, args = {}) {
38
+ const flags = Object.entries(args).flatMap(([key, value]) => {
39
+ if (value === undefined || value === null) return [];
40
+ if (typeof value === 'boolean') return value ? [`--${key}`] : [];
41
+ if (Array.isArray(value)) return [`--${key}`, JSON.stringify(value)];
42
+ if (typeof value === 'object') return [`--${key}-json`, JSON.stringify(value)];
43
+ return [`--${key}`, String(value)];
44
+ });
45
+
46
+ try {
47
+ const { stdout } = await execFileAsync(OVLD_BIN, ['protocol', subcommand, ...flags], {
48
+ env: {
49
+ ...process.env,
50
+ AGENT_IDENTIFIER: process.env.AGENT_IDENTIFIER ?? 'cursor-overlord-plugin'
51
+ },
52
+ maxBuffer: 20 * 1024 * 1024
53
+ });
54
+ const data = stdout.trim() ? JSON.parse(stdout) : {};
55
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }], structuredContent: data };
56
+ } catch (error) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ return { content: [{ type: 'text', text: message }], isError: true };
59
+ }
60
+ }
61
+
62
+ process.stdin.on('data', async chunk => {
63
+ for (const message of parseMessages(chunk)) {
64
+ if (!message || typeof message !== 'object' || !('id' in message)) continue;
65
+ if (message.method === 'initialize') {
66
+ send({
67
+ jsonrpc: '2.0',
68
+ id: message.id,
69
+ result: {
70
+ protocolVersion: PROTOCOL_VERSION,
71
+ capabilities: { tools: { listChanged: false } },
72
+ serverInfo: { name: 'overlord-cursor', version: '0.1.0' }
73
+ }
74
+ });
75
+ continue;
76
+ }
77
+ if (message.method === 'tools/list') {
78
+ send({
79
+ jsonrpc: '2.0',
80
+ id: message.id,
81
+ result: {
82
+ tools: [
83
+ {
84
+ name: 'attach_ticket',
85
+ description: 'Attach to an Overlord ticket.',
86
+ inputSchema: { type: 'object', properties: { ticket_id: { type: 'string' } }, required: ['ticket_id'] }
87
+ },
88
+ {
89
+ name: 'post_update',
90
+ description: 'Post a progress update.',
91
+ inputSchema: {
92
+ type: 'object',
93
+ properties: { session_key: { type: 'string' }, ticket_id: { type: 'string' }, summary: { type: 'string' } },
94
+ required: ['session_key', 'ticket_id', 'summary']
95
+ }
96
+ },
97
+ {
98
+ name: 'deliver_ticket',
99
+ description: 'Deliver completed work.',
100
+ inputSchema: {
101
+ type: 'object',
102
+ properties: { session_key: { type: 'string' }, ticket_id: { type: 'string' }, summary: { type: 'string' } },
103
+ required: ['session_key', 'ticket_id', 'summary']
104
+ }
105
+ }
106
+ ]
107
+ }
108
+ });
109
+ continue;
110
+ }
111
+ if (message.method === 'tools/call') {
112
+ const toolName = message.params?.name;
113
+ const args = message.params?.arguments ?? {};
114
+ if (toolName === 'attach_ticket') {
115
+ send({ jsonrpc: '2.0', id: message.id, result: await runProtocol('attach', { 'ticket-id': args.ticket_id }) });
116
+ } else if (toolName === 'post_update') {
117
+ send({
118
+ jsonrpc: '2.0',
119
+ id: message.id,
120
+ result: await runProtocol('update', {
121
+ 'session-key': args.session_key,
122
+ 'ticket-id': args.ticket_id,
123
+ summary: args.summary,
124
+ phase: 'execute'
125
+ })
126
+ });
127
+ } else if (toolName === 'deliver_ticket') {
128
+ send({
129
+ jsonrpc: '2.0',
130
+ id: message.id,
131
+ result: await runProtocol('deliver', {
132
+ 'session-key': args.session_key,
133
+ 'ticket-id': args.ticket_id,
134
+ summary: args.summary
135
+ })
136
+ });
137
+ } else {
138
+ send({ jsonrpc: '2.0', id: message.id, error: { code: -32602, message: `Unknown tool: ${toolName}` } });
139
+ }
140
+ continue;
141
+ }
142
+ if (message.method === 'ping') {
143
+ send({ jsonrpc: '2.0', id: message.id, result: {} });
144
+ continue;
145
+ }
146
+ send({ jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not found: ${message.method}` } });
147
+ }
148
+ });
149
+
150
+ process.stdin.resume();
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: overlord-ticket
3
+ description: Overlord local workflow protocol for Cursor, covering both Overlord-launched tickets and chat-invoked Overlord work.
4
+ ---
5
+
6
+ # Overlord Ticket
7
+
8
+ Use this skill whenever Cursor 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
+ 1. Attach first with `ovld protocol attach --ticket-id <ticket_id>`.
13
+ 2. Keep the returned `session.sessionKey` for all follow-up calls.
14
+ 3. Treat the Overlord ticket prompt as authoritative for the objective, constraints, and delivery target.
15
+ 4. Post updates while working with `ovld protocol update --phase execute`.
16
+ 5. If the user sends a follow-up message after the initial ticket, publish it immediately with `--event-type user_follow_up`.
17
+ 6. If blocked, call `ovld protocol ask` and stop.
18
+ 7. Deliver last with `ovld protocol deliver`, including `changeRationales` for each meaningful behavioral file change.
19
+
20
+ ## Mode 2: Asked From Chat To Use Overlord
21
+
22
+ 1. If the user wants to create tickets (and does not ask to start execution), use `/create` or run `ovld protocol create --agent cursor --objective "..."`.
23
+ 2. Default to `create` for new tickets. Only use `/spawn` or `ovld protocol spawn --agent cursor --objective "..."` when the user explicitly asks to create and execute immediately.
24
+ 3. If the user already has a ticket ID and only wants to inspect it, use `/load` or run `ovld protocol load-context --ticket-id <ticket_id>`.
25
+ 4. If the user wants to route the current session onto an existing ticket by ID, use `/connect` or run `ovld protocol connect --ticket-id <ticket_id>`.
26
+ 5. If the user wants to search for tickets by keyword or status, use the `search_tickets` MCP tool.
27
+ 6. If you need other lifecycle commands or flags, run `ovld protocol help` and use the real subcommand list instead of guessing.
28
+ 7. Once you attach to a ticket, switch back to Mode 1 and follow the full ticket lifecycle.
29
+
30
+ ## Choosing `--execution-target` When Creating Tickets
31
+
32
+ Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
33
+
34
+ - **`agent`** — any task an AI agent can complete in a computer environment: coding, internet research, document editing, data analysis, automated testing, etc.
35
+ - **`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.
36
+
37
+ 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`.
38
+
39
+ ## Rules
40
+
41
+ - Always attach first and always deliver last once you are on a ticket.
42
+ - Use `ovld protocol` commands, the plugin commands, and the MCP tool instead of ad hoc scripts.
43
+ - Do not invent protocol subcommands. Use `ovld protocol help` when unsure.
44
+ - If `ovld` reports `OVERLORD_URL` is unreachable, request permission escalation or network access before retrying.
45
+ - 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.
46
+ - Include at least one progress update before delivering.
47
+ - When creating follow-up tickets, always set `--execution-target` explicitly using the `agent`/`human` rule above.
48
+
49
+ <!-- version: 0.2.4 -->
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "overlord",
3
+ "version": "0.2.1",
4
+ "description": "Chat-driven access to Overlord ticket protocol workflows.",
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
+ "keywords": ["overlord", "tickets", "agents", "workflow", "protocol", "mcp", "codex-plugin"],
13
+ "skills": "./skills/",
14
+ "mcpServers": "./.mcp.json",
15
+ "interface": {
16
+ "displayName": "Overlord",
17
+ "shortDescription": "Run Overlord ticket workflows from Codex chat",
18
+ "longDescription": "Connect Codex to Overlord's local ticket workflow through the existing `ovld protocol` CLI. The plugin bundles workflow skills plus MCP tools for ticket attachment, progress updates, shared context, artifacts, delivery, and follow-up ticket creation.",
19
+ "developerName": "Cooperativ",
20
+ "category": "Productivity",
21
+ "capabilities": ["Interactive", "Write"],
22
+ "websiteURL": "https://www.ovld.ai/docs",
23
+ "privacyPolicyURL": "https://www.ovld.ai/privacy",
24
+ "termsOfServiceURL": "https://www.ovld.ai/terms",
25
+ "defaultPrompt": [
26
+ "Create an Overlord ticket with the objective 'Implement feature X' and summarize the context before editing code",
27
+ "Execute Overlord ticket [ticket-id]",
28
+ "Find all Overlord tickets with the status 'next-up' and prioritize the most important one"
29
+ ],
30
+ "brandColor": "#1E6B5C",
31
+ "composerIcon": "./assets/icon.png",
32
+ "logo": "./assets/logo.png",
33
+ "screenshots": ["./assets/screenshot.png"]
34
+ }
35
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "overlord": {
4
+ "command": "node",
5
+ "args": [
6
+ "./scripts/overlord-mcp.mjs"
7
+ ],
8
+ "note": "Local MCP bridge for the Overlord `ovld protocol` CLI. Requires `ovld` on PATH plus valid OVERLORD_URL and AGENT_TOKEN credentials when talking to a live server."
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,42 @@
1
+ # Overlord Plugin
2
+
3
+ This plugin exposes the installed `ovld protocol` workflow to Codex as a local plugin bundle.
4
+
5
+ It now includes:
6
+
7
+ - MCP tools for the Overlord ticket protocol
8
+ - a bundled Codex skill for the local ticket lifecycle
9
+ - branded plugin assets for the Codex install surfaces
10
+
11
+ The plugin is designed for personal installs under `~/.codex/plugins/overlord` with a
12
+ personal marketplace entry at `~/.agents/plugins/marketplace.json`.
13
+
14
+ ## Requirements
15
+
16
+ - Install the Overlord CLI so `ovld` is available on `PATH`.
17
+ - If a shared session already exists but looks stale, authenticate with `ovld auth repair` first. If repair does not help, use `ovld auth login` or Overlord Desktop. `OVERLORD_URL` can be used to point the CLI at a non-default host.
18
+ - Optionally set `OVLD_BIN` if the CLI lives at a non-standard path.
19
+ - If `ovld` reports `OVERLORD_URL` is unreachable, the bundled workflow tells Codex to request permission escalation or network access before retrying.
20
+
21
+ ## Tool coverage
22
+
23
+ - Project resolution: `discover_project`
24
+ - Ticket search: `search_tickets` — keyword search + status/filter (direct API call)
25
+ - Ticket session flow: `attach_ticket`, `connect_ticket`, `load_ticket_context`, `spawn_ticket`
26
+ - Progress and review flow: `post_update`, `record_change_rationales`, `ask_blocking_question`, `deliver_ticket`
27
+ - Shared context: `read_shared_context`, `write_shared_context`
28
+ - Objective attachments: `list_attachments`, `prepare_attachment_upload`, `finalize_attachment_upload`, `get_attachment_download_url`, `upload_attachment_file`
29
+
30
+ The MCP server shells into the installed `ovld` binary so the plugin stays aligned with the shipped CLI behavior instead of depending on this repository checkout.
31
+
32
+ ## Skill coverage
33
+
34
+ - `skills/overlord-ticket/SKILL.md` teaches Codex the durable local workflow:
35
+ attach first, update during work, ask when blocked, and deliver last.
36
+
37
+ ## App surface status
38
+
39
+ The Codex plugin docs support an optional `.app.json` file, but the current file format
40
+ expects a real OpenAI-issued `asdk_app_*` or `connector_*` identifier. This repo does not
41
+ yet have an issued Overlord app ID to point at, so the plugin intentionally does not ship
42
+ an `.app.json` mapping yet.
Binary file
Binary file
@@ -0,0 +1,28 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 640" role="img" aria-labelledby="title">
2
+ <title>Overlord Codex Plugin Screenshot</title>
3
+ <rect width="960" height="640" rx="32" fill="#EEE8DC" />
4
+ <rect x="28" y="28" width="904" height="584" rx="24" fill="#102A26" />
5
+ <rect x="56" y="56" width="220" height="528" rx="20" fill="#173D37" />
6
+ <rect x="300" y="56" width="604" height="528" rx="20" fill="#F6F3EC" />
7
+ <rect x="80" y="88" width="96" height="14" rx="7" fill="#F4B35D" />
8
+ <rect x="80" y="130" width="160" height="14" rx="7" fill="#D5E4DE" opacity="0.92" />
9
+ <rect x="80" y="160" width="132" height="14" rx="7" fill="#D5E4DE" opacity="0.62" />
10
+ <rect x="80" y="226" width="172" height="42" rx="21" fill="#1E6B5C" />
11
+ <rect x="332" y="96" width="184" height="18" rx="9" fill="#214D43" />
12
+ <rect x="332" y="146" width="520" height="18" rx="9" fill="#CFD8D3" />
13
+ <rect x="332" y="180" width="470" height="18" rx="9" fill="#CFD8D3" />
14
+ <rect x="332" y="214" width="550" height="18" rx="9" fill="#CFD8D3" />
15
+ <rect x="332" y="276" width="524" height="116" rx="18" fill="#F0EADF" />
16
+ <rect x="356" y="304" width="168" height="14" rx="7" fill="#173D37" />
17
+ <rect x="356" y="336" width="468" height="14" rx="7" fill="#B9C7C2" />
18
+ <rect x="356" y="360" width="384" height="14" rx="7" fill="#B9C7C2" />
19
+ <rect x="332" y="430" width="180" height="44" rx="22" fill="#1E6B5C" />
20
+ <rect x="530" y="430" width="140" height="44" rx="22" fill="#E0D8CA" />
21
+ <text
22
+ x="332"
23
+ y="538"
24
+ fill="#214D43"
25
+ font-family="IBM Plex Mono, monospace"
26
+ font-size="24"
27
+ >Attach, update, ask, deliver</text>
28
+ </svg>