@overlordai/developer-cli 1.0.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/auth/api-client.d.ts +15 -0
- package/dist/auth/api-client.d.ts.map +1 -0
- package/dist/auth/api-client.js +79 -0
- package/dist/auth/api-client.js.map +1 -0
- package/dist/auth/token-store.d.ts +13 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +52 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/commands/attach.d.ts +3 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +48 -0
- package/dist/commands/attach.js.map +1 -0
- package/dist/commands/config.d.ts +11 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +100 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/helpers.d.ts +15 -0
- package/dist/commands/helpers.d.ts.map +1 -0
- package/dist/commands/helpers.js +41 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +83 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +16 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/machine.d.ts +3 -0
- package/dist/commands/machine.d.ts.map +1 -0
- package/dist/commands/machine.js +81 -0
- package/dist/commands/machine.js.map +1 -0
- package/dist/commands/notifications.d.ts +3 -0
- package/dist/commands/notifications.d.ts.map +1 -0
- package/dist/commands/notifications.js +55 -0
- package/dist/commands/notifications.js.map +1 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +61 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +58 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/task.d.ts +3 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +347 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +32 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +32 -0
- package/dist/main.js.map +1 -0
- package/dist/output/formatter.d.ts +18 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +63 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/terminal/pty-client.d.ts +20 -0
- package/dist/terminal/pty-client.d.ts.map +1 -0
- package/dist/terminal/pty-client.js +133 -0
- package/dist/terminal/pty-client.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ApiResponse<T = unknown> {
|
|
2
|
+
status: number;
|
|
3
|
+
data: T;
|
|
4
|
+
}
|
|
5
|
+
export declare class ApiClient {
|
|
6
|
+
private readonly baseUrl;
|
|
7
|
+
private readonly token;
|
|
8
|
+
constructor(baseUrl: string, token: string);
|
|
9
|
+
get<T = unknown>(path: string): Promise<ApiResponse<T>>;
|
|
10
|
+
post<T = unknown>(path: string, body?: unknown): Promise<ApiResponse<T>>;
|
|
11
|
+
put<T = unknown>(path: string, body?: unknown): Promise<ApiResponse<T>>;
|
|
12
|
+
delete<T = unknown>(path: string): Promise<ApiResponse<T>>;
|
|
13
|
+
private request;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAKpC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIvD,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIxE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIvE,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIhE,OAAO,CAAC,OAAO;CAkEhB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as http from 'node:http';
|
|
2
|
+
import * as https from 'node:https';
|
|
3
|
+
import { URL } from 'node:url';
|
|
4
|
+
export class ApiClient {
|
|
5
|
+
baseUrl;
|
|
6
|
+
token;
|
|
7
|
+
constructor(baseUrl, token) {
|
|
8
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
9
|
+
this.token = token;
|
|
10
|
+
}
|
|
11
|
+
async get(path) {
|
|
12
|
+
return this.request('GET', path);
|
|
13
|
+
}
|
|
14
|
+
async post(path, body) {
|
|
15
|
+
return this.request('POST', path, body);
|
|
16
|
+
}
|
|
17
|
+
async put(path, body) {
|
|
18
|
+
return this.request('PUT', path, body);
|
|
19
|
+
}
|
|
20
|
+
async delete(path) {
|
|
21
|
+
return this.request('DELETE', path);
|
|
22
|
+
}
|
|
23
|
+
request(method, apiPath, body) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const url = new URL(`${this.baseUrl}${apiPath}`);
|
|
26
|
+
const isHttps = url.protocol === 'https:';
|
|
27
|
+
const transport = isHttps ? https : http;
|
|
28
|
+
const headers = {
|
|
29
|
+
'Authorization': `Bearer ${this.token}`,
|
|
30
|
+
'Accept': 'application/json',
|
|
31
|
+
};
|
|
32
|
+
let bodyStr;
|
|
33
|
+
if (body !== undefined) {
|
|
34
|
+
bodyStr = JSON.stringify(body);
|
|
35
|
+
headers['Content-Type'] = 'application/json';
|
|
36
|
+
headers['Content-Length'] = Buffer.byteLength(bodyStr).toString();
|
|
37
|
+
}
|
|
38
|
+
const req = transport.request({
|
|
39
|
+
hostname: url.hostname,
|
|
40
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
41
|
+
path: url.pathname + url.search,
|
|
42
|
+
method,
|
|
43
|
+
headers,
|
|
44
|
+
}, (res) => {
|
|
45
|
+
const chunks = [];
|
|
46
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
47
|
+
res.on('end', () => {
|
|
48
|
+
const rawBody = Buffer.concat(chunks).toString('utf-8');
|
|
49
|
+
let data;
|
|
50
|
+
try {
|
|
51
|
+
data = JSON.parse(rawBody);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
data = rawBody;
|
|
55
|
+
}
|
|
56
|
+
const status = res.statusCode ?? 0;
|
|
57
|
+
if (status === 401) {
|
|
58
|
+
reject(new Error('Authentication failed. Please run `ov login` to re-authenticate.'));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (status === 429) {
|
|
62
|
+
const retryAfter = res.headers['retry-after'];
|
|
63
|
+
reject(new Error(`Rate limited. Retry after ${retryAfter ?? 'unknown'} seconds.`));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
resolve({ status, data });
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
req.on('error', (err) => {
|
|
70
|
+
reject(new Error(`Request failed: ${err.message}`));
|
|
71
|
+
});
|
|
72
|
+
if (bodyStr) {
|
|
73
|
+
req.write(bodyStr);
|
|
74
|
+
}
|
|
75
|
+
req.end();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface Credentials {
|
|
2
|
+
server: string;
|
|
3
|
+
token: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class TokenStore {
|
|
6
|
+
private readonly configDir;
|
|
7
|
+
private readonly credentialsPath;
|
|
8
|
+
constructor(configDir?: string);
|
|
9
|
+
save(server: string, token: string): void;
|
|
10
|
+
load(): Credentials | null;
|
|
11
|
+
clear(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,SAAS,CAAC,EAAE,MAAM;IAO9B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAYzC,IAAI,IAAI,WAAW,GAAG,IAAI;IAgB1B,KAAK,IAAI,IAAI;CASd"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'overlord');
|
|
5
|
+
const CREDENTIALS_PATH = path.join(CONFIG_DIR, 'credentials.json');
|
|
6
|
+
export class TokenStore {
|
|
7
|
+
configDir;
|
|
8
|
+
credentialsPath;
|
|
9
|
+
constructor(configDir) {
|
|
10
|
+
this.configDir = configDir ?? CONFIG_DIR;
|
|
11
|
+
this.credentialsPath = configDir
|
|
12
|
+
? path.join(configDir, 'credentials.json')
|
|
13
|
+
: CREDENTIALS_PATH;
|
|
14
|
+
}
|
|
15
|
+
save(server, token) {
|
|
16
|
+
if (!fs.existsSync(this.configDir)) {
|
|
17
|
+
fs.mkdirSync(this.configDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
const data = { server, token };
|
|
20
|
+
fs.writeFileSync(this.credentialsPath, JSON.stringify(data, null, 2), {
|
|
21
|
+
encoding: 'utf-8',
|
|
22
|
+
mode: 0o600,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
load() {
|
|
26
|
+
try {
|
|
27
|
+
if (!fs.existsSync(this.credentialsPath)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const raw = fs.readFileSync(this.credentialsPath, 'utf-8');
|
|
31
|
+
const data = JSON.parse(raw);
|
|
32
|
+
if (!data.server || !data.token) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
clear() {
|
|
42
|
+
try {
|
|
43
|
+
if (fs.existsSync(this.credentialsPath)) {
|
|
44
|
+
fs.unlinkSync(this.credentialsPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Ignore errors during cleanup
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAO9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAEnE,MAAM,OAAO,UAAU;IACJ,SAAS,CAAS;IAClB,eAAe,CAAS;IAEzC,YAAY,SAAkB;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,UAAU,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,SAAS;YAC9B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC;YAC1C,CAAC,CAAC,gBAAgB,CAAC;IACvB,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,KAAa;QAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC5C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;YACpE,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBACxC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,eAAO,MAAM,aAAa,SAkCtB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getServerUrl, getToken } from './helpers.js';
|
|
3
|
+
import { ApiClient } from '../auth/api-client.js';
|
|
4
|
+
import { PtyClient } from '../terminal/pty-client.js';
|
|
5
|
+
import { formatter } from '../output/formatter.js';
|
|
6
|
+
async function getChannelToken(serverUrl, taskId, token) {
|
|
7
|
+
const client = new ApiClient(serverUrl, token);
|
|
8
|
+
const res = await client.post(`/api/web/tasks/${taskId}/pty-token`);
|
|
9
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
10
|
+
throw new Error(`Failed to obtain PTY channel token (status ${res.status})`);
|
|
11
|
+
}
|
|
12
|
+
return res.data.channelToken;
|
|
13
|
+
}
|
|
14
|
+
export const attachCommand = new Command('attach')
|
|
15
|
+
.description('Connect to a task PTY terminal')
|
|
16
|
+
.argument('<taskId>', 'Task ID to attach to')
|
|
17
|
+
.option('--takeover', 'Take over PTY control from current user')
|
|
18
|
+
.option('--watch', 'Read-only observer mode')
|
|
19
|
+
.option('--session <sessionId>', 'Session ID for takeover')
|
|
20
|
+
.action(async (taskId, opts) => {
|
|
21
|
+
let mode = 'interactive';
|
|
22
|
+
if (opts.takeover)
|
|
23
|
+
mode = 'takeover';
|
|
24
|
+
if (opts.watch)
|
|
25
|
+
mode = 'watch';
|
|
26
|
+
const serverUrl = getServerUrl();
|
|
27
|
+
const token = getToken();
|
|
28
|
+
formatter.info(`Attaching to task #${taskId} (${mode} mode)...`);
|
|
29
|
+
if (mode !== 'watch') {
|
|
30
|
+
formatter.info('Press Ctrl+] to detach.');
|
|
31
|
+
}
|
|
32
|
+
const client = new PtyClient({
|
|
33
|
+
serverUrl,
|
|
34
|
+
taskId,
|
|
35
|
+
token,
|
|
36
|
+
mode,
|
|
37
|
+
sessionId: opts.session,
|
|
38
|
+
getChannelToken,
|
|
39
|
+
});
|
|
40
|
+
try {
|
|
41
|
+
await client.connect();
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=attach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,MAAc,EAAE,KAAa;IAC7E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAA2B,kBAAkB,MAAM,YAAY,CAAC,CAAC;IAC9F,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,8CAA8C,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,gCAAgC,CAAC;KAC7C,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;KAC5C,MAAM,CAAC,YAAY,EAAE,yCAAyC,CAAC;KAC/D,MAAM,CAAC,SAAS,EAAE,yBAAyB,CAAC;KAC5C,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;KAC1D,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAA+D,EAAE,EAAE;IAChG,IAAI,IAAI,GAAyC,aAAa,CAAC;IAC/D,IAAI,IAAI,CAAC,QAAQ;QAAE,IAAI,GAAG,UAAU,CAAC;IACrC,IAAI,IAAI,CAAC,KAAK;QAAE,IAAI,GAAG,OAAO,CAAC;IAE/B,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,SAAS,CAAC,IAAI,CAAC,sBAAsB,MAAM,KAAK,IAAI,WAAW,CAAC,CAAC;IACjE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,SAAS;QACT,MAAM;QACN,KAAK;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,OAAO;QACvB,eAAe;KAChB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,SAAS,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface CliConfig {
|
|
3
|
+
server?: string;
|
|
4
|
+
default_project?: string;
|
|
5
|
+
output_format?: string;
|
|
6
|
+
color?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function loadConfig(configPath?: string): CliConfig;
|
|
9
|
+
export declare function saveConfig(config: CliConfig, configPath?: string): void;
|
|
10
|
+
export declare const configCommand: Command;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAKD,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAWzD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAOvE;AAED,eAAO,MAAM,aAAa,SACS,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
import { formatter } from '../output/formatter.js';
|
|
6
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'overlord');
|
|
7
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
|
|
8
|
+
export function loadConfig(configPath) {
|
|
9
|
+
const filePath = configPath ?? CONFIG_PATH;
|
|
10
|
+
try {
|
|
11
|
+
if (!fs.existsSync(filePath)) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
15
|
+
return JSON.parse(raw);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function saveConfig(config, configPath) {
|
|
22
|
+
const filePath = configPath ?? CONFIG_PATH;
|
|
23
|
+
const dir = path.dirname(filePath);
|
|
24
|
+
if (!fs.existsSync(dir)) {
|
|
25
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2), 'utf-8');
|
|
28
|
+
}
|
|
29
|
+
export const configCommand = new Command('config')
|
|
30
|
+
.description('CLI configuration');
|
|
31
|
+
configCommand
|
|
32
|
+
.command('set <key> <value>')
|
|
33
|
+
.description('Set a configuration value (server, default-project)')
|
|
34
|
+
.action((key, value) => {
|
|
35
|
+
const config = loadConfig();
|
|
36
|
+
switch (key) {
|
|
37
|
+
case 'server':
|
|
38
|
+
// Validate URL format
|
|
39
|
+
try {
|
|
40
|
+
new URL(value);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
formatter.error(`Invalid server URL: ${value}`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
config.server = value;
|
|
48
|
+
break;
|
|
49
|
+
case 'default-project':
|
|
50
|
+
config.default_project = value;
|
|
51
|
+
break;
|
|
52
|
+
case 'output-format':
|
|
53
|
+
config.output_format = value;
|
|
54
|
+
break;
|
|
55
|
+
case 'color':
|
|
56
|
+
config.color = value === 'true';
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
formatter.error(`Unknown config key: ${key}. Valid keys: server, default-project, output-format, color`);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
saveConfig(config);
|
|
64
|
+
formatter.success(`${key} = ${value}`);
|
|
65
|
+
});
|
|
66
|
+
configCommand
|
|
67
|
+
.command('get <key>')
|
|
68
|
+
.description('Get a configuration value')
|
|
69
|
+
.action((key) => {
|
|
70
|
+
const config = loadConfig();
|
|
71
|
+
const configMap = {
|
|
72
|
+
'server': config.server,
|
|
73
|
+
'default-project': config.default_project,
|
|
74
|
+
'output-format': config.output_format,
|
|
75
|
+
'color': config.color,
|
|
76
|
+
};
|
|
77
|
+
if (!(key in configMap)) {
|
|
78
|
+
formatter.error(`Unknown config key: ${key}`);
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const value = configMap[key];
|
|
83
|
+
console.log(value !== undefined ? String(value) : '(not set)');
|
|
84
|
+
});
|
|
85
|
+
configCommand
|
|
86
|
+
.command('list')
|
|
87
|
+
.description('List all configuration values')
|
|
88
|
+
.option('--json', 'Output as JSON')
|
|
89
|
+
.action((opts) => {
|
|
90
|
+
if (opts.json)
|
|
91
|
+
formatter.setJsonMode(true);
|
|
92
|
+
const config = loadConfig();
|
|
93
|
+
formatter.detail({
|
|
94
|
+
server: config.server ?? '(not set)',
|
|
95
|
+
'default-project': config.default_project ?? '(not set)',
|
|
96
|
+
'output-format': config.output_format ?? 'table',
|
|
97
|
+
color: config.color !== false ? 'true' : 'false',
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ApiClient } from '../auth/api-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get an authenticated API client from saved credentials.
|
|
4
|
+
* Exits with an error if not logged in.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getApiClient(): ApiClient;
|
|
7
|
+
/**
|
|
8
|
+
* Get the server URL from saved credentials.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getServerUrl(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the saved token.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getToken(): string;
|
|
15
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/commands/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAUxC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAUrC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAUjC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { TokenStore } from '../auth/token-store.js';
|
|
2
|
+
import { ApiClient } from '../auth/api-client.js';
|
|
3
|
+
import { formatter } from '../output/formatter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get an authenticated API client from saved credentials.
|
|
6
|
+
* Exits with an error if not logged in.
|
|
7
|
+
*/
|
|
8
|
+
export function getApiClient() {
|
|
9
|
+
const store = new TokenStore();
|
|
10
|
+
const creds = store.load();
|
|
11
|
+
if (!creds) {
|
|
12
|
+
formatter.error('Not logged in. Run `ov login` first.');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
return new ApiClient(creds.server, creds.token);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the server URL from saved credentials.
|
|
19
|
+
*/
|
|
20
|
+
export function getServerUrl() {
|
|
21
|
+
const store = new TokenStore();
|
|
22
|
+
const creds = store.load();
|
|
23
|
+
if (!creds) {
|
|
24
|
+
formatter.error('Not logged in. Run `ov login` first.');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
return creds.server;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the saved token.
|
|
31
|
+
*/
|
|
32
|
+
export function getToken() {
|
|
33
|
+
const store = new TokenStore();
|
|
34
|
+
const creds = store.load();
|
|
35
|
+
if (!creds) {
|
|
36
|
+
formatter.error('Not logged in. Run `ov login` first.');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
return creds.token;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/commands/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,SAAS,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,SAAS,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,SAAS,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,YAAY,SAqErB,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as readline from 'node:readline';
|
|
3
|
+
import { TokenStore } from '../auth/token-store.js';
|
|
4
|
+
import { ApiClient } from '../auth/api-client.js';
|
|
5
|
+
import { formatter } from '../output/formatter.js';
|
|
6
|
+
import { loadConfig } from './config.js';
|
|
7
|
+
export const loginCommand = new Command('login')
|
|
8
|
+
.description('Authenticate with the Overlord server')
|
|
9
|
+
.option('--token <token>', 'Provide token directly (for CI/CD)')
|
|
10
|
+
.option('--force', 'Force re-login even if already authenticated')
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
const store = new TokenStore();
|
|
13
|
+
const existing = store.load();
|
|
14
|
+
if (existing && !opts.force && !opts.token) {
|
|
15
|
+
try {
|
|
16
|
+
const client = new ApiClient(existing.server, existing.token);
|
|
17
|
+
const res = await client.get('/api/web/profile');
|
|
18
|
+
if (res.status === 200) {
|
|
19
|
+
formatter.info(`Already logged in as ${res.data.name}. Use --force to re-login.`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Token invalid, proceed with login
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const config = loadConfig();
|
|
28
|
+
let server = config.server;
|
|
29
|
+
if (!server) {
|
|
30
|
+
server = await promptInput('Enter Overlord server URL: ');
|
|
31
|
+
if (!server) {
|
|
32
|
+
formatter.error('Server URL is required.');
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
server = server.replace(/\/+$/, '');
|
|
38
|
+
let token = opts.token;
|
|
39
|
+
if (!token) {
|
|
40
|
+
console.log('');
|
|
41
|
+
console.log(' ┌─────────────────────────────────────────────────────────┐');
|
|
42
|
+
console.log(` │ Open this URL in your browser to create a token: │`);
|
|
43
|
+
console.log(` │ ${server}/settings/tokens`);
|
|
44
|
+
console.log(' └─────────────────────────────────────────────────────────┘');
|
|
45
|
+
console.log('');
|
|
46
|
+
token = await promptInput('Paste your Personal Access Token: ');
|
|
47
|
+
}
|
|
48
|
+
if (!token) {
|
|
49
|
+
formatter.error('Token is required.');
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Validate token
|
|
54
|
+
try {
|
|
55
|
+
const client = new ApiClient(server, token);
|
|
56
|
+
const res = await client.get('/api/web/profile');
|
|
57
|
+
if (res.status === 200) {
|
|
58
|
+
store.save(server, token);
|
|
59
|
+
formatter.success(`Logged in as ${res.data.name} (${res.data.role})`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
formatter.error('Invalid token, please try again.');
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
formatter.error(`Login failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
function promptInput(prompt) {
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
const rl = readline.createInterface({
|
|
74
|
+
input: process.stdin,
|
|
75
|
+
output: process.stderr,
|
|
76
|
+
});
|
|
77
|
+
rl.question(prompt, (answer) => {
|
|
78
|
+
rl.close();
|
|
79
|
+
resolve(answer.trim());
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAatB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { TokenStore } from '../auth/token-store.js';
|
|
3
|
+
import { formatter } from '../output/formatter.js';
|
|
4
|
+
export const logoutCommand = new Command('logout')
|
|
5
|
+
.description('Clear saved credentials')
|
|
6
|
+
.action(() => {
|
|
7
|
+
const store = new TokenStore();
|
|
8
|
+
const existing = store.load();
|
|
9
|
+
if (!existing) {
|
|
10
|
+
formatter.info('Not currently logged in.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
store.clear();
|
|
14
|
+
formatter.success('Logged out successfully.');
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,SAAS,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../../src/commands/machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,eAAO,MAAM,cAAc,SACc,CAAC"}
|