@neta-art/cohub-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/README.md +15 -0
- package/bin/cohub.js +2 -0
- package/dist/auth.d.ts +9 -0
- package/dist/auth.js +35 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +7 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +51 -0
- package/dist/commands/channels.d.ts +2 -0
- package/dist/commands/channels.js +84 -0
- package/dist/commands/cron-jobs.d.ts +2 -0
- package/dist/commands/cron-jobs.js +136 -0
- package/dist/commands/models.d.ts +2 -0
- package/dist/commands/models.js +34 -0
- package/dist/commands/prompts.d.ts +2 -0
- package/dist/commands/prompts.js +33 -0
- package/dist/commands/session-access.d.ts +2 -0
- package/dist/commands/session-access.js +72 -0
- package/dist/commands/spaces.d.ts +2 -0
- package/dist/commands/spaces.js +675 -0
- package/dist/commands/tasks.d.ts +2 -0
- package/dist/commands/tasks.js +104 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +37 -0
- package/dist/output.d.ts +14 -0
- package/dist/output.js +91 -0
- package/package.json +29 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { resolveToken } from "../auth.js";
|
|
2
|
+
import { createClient } from "../client.js";
|
|
3
|
+
import { table, json as outJson, ok, error, handleHttp } from "../output.js";
|
|
4
|
+
export function registerTasks(program) {
|
|
5
|
+
const cmd = program.command("tasks").description("Task management");
|
|
6
|
+
cmd
|
|
7
|
+
.command("ls")
|
|
8
|
+
.alias("list")
|
|
9
|
+
.description("List task runs")
|
|
10
|
+
.option("--cron-job <id>", "Filter by cron job")
|
|
11
|
+
.option("--space <id>", "Filter by space")
|
|
12
|
+
.option("--json", "Output as JSON")
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
const token = resolveToken();
|
|
15
|
+
if (!token)
|
|
16
|
+
return error("Not authenticated", "Run 'cohub auth login <token>'");
|
|
17
|
+
const client = createClient(token);
|
|
18
|
+
try {
|
|
19
|
+
const filters = {};
|
|
20
|
+
if (opts.cronJob)
|
|
21
|
+
filters.cronJobId = opts.cronJob;
|
|
22
|
+
if (opts.space)
|
|
23
|
+
filters.spaceId = opts.space;
|
|
24
|
+
const result = await client.tasks.list(filters);
|
|
25
|
+
if (opts.json)
|
|
26
|
+
return outJson(result);
|
|
27
|
+
if (result.runs.length === 0)
|
|
28
|
+
return console.log(" (empty)");
|
|
29
|
+
table(result.runs, [
|
|
30
|
+
{ key: "id", label: "ID" },
|
|
31
|
+
{ key: "taskType", label: "Type" },
|
|
32
|
+
{ key: "status", label: "Status" },
|
|
33
|
+
{ key: "createdAt", label: "Created" },
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
handleHttp(e);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
cmd
|
|
41
|
+
.command("get <id>")
|
|
42
|
+
.description("Task run details")
|
|
43
|
+
.option("--json", "Output as JSON")
|
|
44
|
+
.action(async (id, opts) => {
|
|
45
|
+
const token = resolveToken();
|
|
46
|
+
if (!token)
|
|
47
|
+
return error("Not authenticated");
|
|
48
|
+
const client = createClient(token);
|
|
49
|
+
try {
|
|
50
|
+
const result = await client.tasks.get(id);
|
|
51
|
+
if (opts.json)
|
|
52
|
+
return outJson(result);
|
|
53
|
+
table([result.run], [
|
|
54
|
+
{ key: "id", label: "ID" },
|
|
55
|
+
{ key: "taskType", label: "Type" },
|
|
56
|
+
{ key: "status", label: "Status" },
|
|
57
|
+
{ key: "attemptCount", label: "Attempts" },
|
|
58
|
+
{ key: "createdAt", label: "Created" },
|
|
59
|
+
]);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
handleHttp(e);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
cmd
|
|
66
|
+
.command("create")
|
|
67
|
+
.description("Create a scheduled task")
|
|
68
|
+
.requiredOption("-t, --task-type <type>", "Task type")
|
|
69
|
+
.requiredOption("--schedule-at <time>", "ISO timestamp")
|
|
70
|
+
.option("--payload <json>", "Task payload as JSON")
|
|
71
|
+
.option("--space <id>", "Space ID")
|
|
72
|
+
.option("--session <id>", "Session ID")
|
|
73
|
+
.option("--json", "Output as JSON")
|
|
74
|
+
.action(async (opts) => {
|
|
75
|
+
const token = resolveToken();
|
|
76
|
+
if (!token)
|
|
77
|
+
return error("Not authenticated");
|
|
78
|
+
let payload = {};
|
|
79
|
+
if (opts.payload) {
|
|
80
|
+
try {
|
|
81
|
+
payload = JSON.parse(opts.payload);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return error("Invalid JSON", "--payload must be valid JSON");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const client = createClient(token);
|
|
88
|
+
try {
|
|
89
|
+
const result = await client.tasks.createScheduled({
|
|
90
|
+
taskType: opts.taskType,
|
|
91
|
+
payload,
|
|
92
|
+
scheduleAt: opts.scheduleAt,
|
|
93
|
+
spaceId: opts.space,
|
|
94
|
+
sessionId: opts.session,
|
|
95
|
+
});
|
|
96
|
+
if (opts.json)
|
|
97
|
+
return outJson(result);
|
|
98
|
+
ok(`Task scheduled — taskRunId: ${result.taskRunId}`);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
handleHttp(e);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { registerAuth } from "./commands/auth.js";
|
|
5
|
+
import { registerChannels } from "./commands/channels.js";
|
|
6
|
+
import { registerCronJobs } from "./commands/cron-jobs.js";
|
|
7
|
+
import { registerModels } from "./commands/models.js";
|
|
8
|
+
import { registerPrompts } from "./commands/prompts.js";
|
|
9
|
+
import { registerSessionAccess } from "./commands/session-access.js";
|
|
10
|
+
import { registerSpaces } from "./commands/spaces.js";
|
|
11
|
+
import { registerTasks } from "./commands/tasks.js";
|
|
12
|
+
const VERSION = (() => {
|
|
13
|
+
try {
|
|
14
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
15
|
+
return pkg.version;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return "1.0.0";
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
const program = new Command("cohub");
|
|
22
|
+
program
|
|
23
|
+
.version(VERSION)
|
|
24
|
+
.description("CLI for Cohub — spaces, sessions, and agent collaboration.")
|
|
25
|
+
.option("-s, --space <id>", "Target space ID")
|
|
26
|
+
.option("--json", "Output as JSON")
|
|
27
|
+
.option("--env <name>", "Cohub environment (default: production)", "production")
|
|
28
|
+
.helpOption("-h, --help", "Show help");
|
|
29
|
+
registerAuth(program);
|
|
30
|
+
registerSpaces(program);
|
|
31
|
+
registerChannels(program);
|
|
32
|
+
registerModels(program);
|
|
33
|
+
registerPrompts(program);
|
|
34
|
+
registerTasks(program);
|
|
35
|
+
registerCronJobs(program);
|
|
36
|
+
registerSessionAccess(program);
|
|
37
|
+
program.parse();
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type Row = Record<string, unknown>;
|
|
2
|
+
export declare function table(rows: Row[], columns: {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
}[]): void;
|
|
6
|
+
export declare function json(data: unknown): void;
|
|
7
|
+
export declare function ok(msg: string): void;
|
|
8
|
+
export declare function error(msg: string, detail?: string): never;
|
|
9
|
+
export declare function handleHttp(e: unknown): never;
|
|
10
|
+
export declare function spinner(): {
|
|
11
|
+
start(msg: string): void;
|
|
12
|
+
stop(msg: string): void;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
function colWidth(rows, key, label) {
|
|
3
|
+
const maxVal = rows.reduce((m, r) => {
|
|
4
|
+
const v = r[key] ?? "";
|
|
5
|
+
const s = typeof v === "object" ? JSON.stringify(v) : String(v);
|
|
6
|
+
return Math.max(m, s.length);
|
|
7
|
+
}, 0);
|
|
8
|
+
return Math.max(label.length, maxVal) + 2;
|
|
9
|
+
}
|
|
10
|
+
export function table(rows, columns) {
|
|
11
|
+
if (rows.length === 0) {
|
|
12
|
+
console.log(" (empty)");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const widths = columns.map((c) => colWidth(rows, c.key, c.label));
|
|
16
|
+
const header = columns
|
|
17
|
+
.map((c, i) => c.label.padEnd(widths[i]))
|
|
18
|
+
.join(" │ ")
|
|
19
|
+
.trimEnd();
|
|
20
|
+
console.log(header);
|
|
21
|
+
console.log("─".repeat(header.length));
|
|
22
|
+
for (const row of rows) {
|
|
23
|
+
const line = columns
|
|
24
|
+
.map((c, i) => {
|
|
25
|
+
const v = row[c.key] ?? "";
|
|
26
|
+
const s = typeof v === "object" ? JSON.stringify(v) : String(v);
|
|
27
|
+
return s.padEnd(widths[i]);
|
|
28
|
+
})
|
|
29
|
+
.join(" │ ")
|
|
30
|
+
.trimEnd();
|
|
31
|
+
console.log(line);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// -- Output helpers ----------------------------------------------------------
|
|
35
|
+
export function json(data) {
|
|
36
|
+
console.log(JSON.stringify(data, null, 2));
|
|
37
|
+
}
|
|
38
|
+
export function ok(msg) {
|
|
39
|
+
console.log(`\n ✓ ${msg}\n`);
|
|
40
|
+
}
|
|
41
|
+
export function error(msg, detail) {
|
|
42
|
+
process.stderr.write(`\n ✗ ${msg}\n`);
|
|
43
|
+
if (detail)
|
|
44
|
+
process.stderr.write(` ${detail}\n`);
|
|
45
|
+
process.stderr.write("\n");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// -- HTTP error handler ------------------------------------------------------
|
|
49
|
+
export function handleHttp(e) {
|
|
50
|
+
const status = e.status;
|
|
51
|
+
const body = e.body;
|
|
52
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
53
|
+
let detail;
|
|
54
|
+
if (status)
|
|
55
|
+
detail = `HTTP ${status}`;
|
|
56
|
+
if (body && typeof body === "object" && "message" in body) {
|
|
57
|
+
detail = `${detail ? detail + " — " : ""}${body.message}`;
|
|
58
|
+
}
|
|
59
|
+
error(msg, detail);
|
|
60
|
+
}
|
|
61
|
+
// -- Spinner -----------------------------------------------------------------
|
|
62
|
+
export function spinner() {
|
|
63
|
+
let interval = null;
|
|
64
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
65
|
+
let i = 0;
|
|
66
|
+
return {
|
|
67
|
+
start(msg) {
|
|
68
|
+
if (process.env.CI || !process.stderr.isTTY) {
|
|
69
|
+
process.stderr.write(` ${msg}...\n`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
process.stderr.write(` ${msg} `);
|
|
73
|
+
interval = setInterval(() => {
|
|
74
|
+
process.stderr.clearLine?.(0);
|
|
75
|
+
process.stderr.cursorTo?.(0);
|
|
76
|
+
process.stderr.write(` ${frames[i++ % frames.length]} ${msg} `);
|
|
77
|
+
}, 80);
|
|
78
|
+
},
|
|
79
|
+
stop(msg) {
|
|
80
|
+
if (interval)
|
|
81
|
+
clearInterval(interval);
|
|
82
|
+
if (process.env.CI || !process.stderr.isTTY) {
|
|
83
|
+
process.stderr.write(` ${msg}\n`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
process.stderr.clearLine?.(0);
|
|
87
|
+
process.stderr.cursorTo?.(0);
|
|
88
|
+
process.stderr.write(` ✓ ${msg}\n`);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neta-art/cohub-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cohub": "./bin/cohub.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"bin",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"commander": "^13.1.0",
|
|
16
|
+
"@neta-art/cohub": "1.1.0"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.0.0",
|
|
23
|
+
"typescript": "^6.0.3"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.build.json",
|
|
27
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
28
|
+
}
|
|
29
|
+
}
|