overlord-cli 3.5.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 +61 -0
- package/bin/_cli/attach.mjs +356 -0
- package/bin/_cli/auth.mjs +382 -0
- package/bin/_cli/credentials.mjs +267 -0
- package/bin/_cli/index.mjs +126 -0
- package/bin/_cli/launcher.mjs +196 -0
- package/bin/_cli/new-ticket.mjs +248 -0
- package/bin/_cli/protocol.mjs +1271 -0
- package/bin/_cli/setup.mjs +553 -0
- package/bin/_cli/ticket.mjs +55 -0
- package/bin/_cli/tickets.mjs +120 -0
- package/bin/ovld.mjs +8 -0
- package/package.json +30 -0
|
@@ -0,0 +1,120 @@
|
|
|
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, body) {
|
|
37
|
+
const res = await fetch(url, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
...buildAuthHeaders(token, localSecret),
|
|
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, agentToken, localSecret } = 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/list-tickets`,
|
|
71
|
+
agentToken,
|
|
72
|
+
localSecret,
|
|
73
|
+
body
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (!data.tickets?.length) {
|
|
77
|
+
console.log('No tickets found.');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
for (const t of data.tickets) {
|
|
82
|
+
const ref = t.id?.slice(-8).toUpperCase() ?? '?';
|
|
83
|
+
const title = t.title || t.objective?.slice(0, 60) || '(no title)';
|
|
84
|
+
console.log(` [${ref}] [${t.status ?? '?'}] ${title}`);
|
|
85
|
+
console.log(` ${t.id}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log(`\n${data.count ?? data.tickets.length} ticket(s)`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function runTicketsCommand(subcommand, args) {
|
|
92
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help') {
|
|
93
|
+
console.log(`ovld tickets <subcommand>
|
|
94
|
+
|
|
95
|
+
Subcommands:
|
|
96
|
+
create Create a new ticket
|
|
97
|
+
list List tickets
|
|
98
|
+
|
|
99
|
+
Examples:
|
|
100
|
+
ovld tickets create "Implement login page"
|
|
101
|
+
ovld tickets list
|
|
102
|
+
ovld tickets list --status draft
|
|
103
|
+
`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (subcommand === 'create') {
|
|
108
|
+
await ticketsCreate(args);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (subcommand === 'list') {
|
|
113
|
+
await ticketsList(args);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.error(`Unknown tickets subcommand: ${subcommand}\n`);
|
|
118
|
+
console.log('Run: ovld tickets help');
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
package/bin/ovld.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "overlord-cli",
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"description": "Overlord CLI — launch AI agents on tickets from anywhere",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ovld": "bin/ovld.mjs",
|
|
8
|
+
"overlord": "bin/ovld.mjs"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin/"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"overlord",
|
|
21
|
+
"ai",
|
|
22
|
+
"agents",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/cooperativ/overlord"
|
|
29
|
+
}
|
|
30
|
+
}
|