@neta-art/cohub-cli 2.3.3 → 2.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/dist/client.js +4 -1
- package/dist/commands/generations.js +1 -21
- package/dist/commands/references.js +49 -12
- package/dist/commands/spaces.js +0 -3
- package/dist/commands/works.js +3 -11
- package/package.json +2 -2
- package/dist/env-context.d.ts +0 -12
- package/dist/env-context.js +0 -33
package/dist/client.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { CohubHttpClient } from "@neta-art/cohub";
|
|
1
|
+
import { CohubHttpClient, readRequestSourceFromEnv } from "@neta-art/cohub";
|
|
2
2
|
import { clearAuthSession, resolveAccessToken } from "./auth.js";
|
|
3
3
|
export function createClient() {
|
|
4
4
|
return new CohubHttpClient({
|
|
5
5
|
getAccessToken: resolveAccessToken,
|
|
6
6
|
onUnauthorized: clearAuthSession,
|
|
7
|
+
requestSource: () => readRequestSourceFromEnv(process.env, { via: "cli" }) ?? {
|
|
8
|
+
via: "cli",
|
|
9
|
+
},
|
|
7
10
|
});
|
|
8
11
|
}
|
|
@@ -229,26 +229,6 @@ function parseMeta(value) {
|
|
|
229
229
|
}
|
|
230
230
|
return parsed;
|
|
231
231
|
}
|
|
232
|
-
function mergeCohubMeta(meta) {
|
|
233
|
-
const sessionId = envValue("COHUB_SESSION_ID");
|
|
234
|
-
const turnId = envValue("COHUB_TURN_ID");
|
|
235
|
-
const toolCallId = envValue("COHUB_TOOL_CALL_ID");
|
|
236
|
-
if (!sessionId && !turnId && !toolCallId)
|
|
237
|
-
return meta;
|
|
238
|
-
const existingCohub = meta?.cohub;
|
|
239
|
-
const cohub = existingCohub && typeof existingCohub === "object" && !Array.isArray(existingCohub)
|
|
240
|
-
? existingCohub
|
|
241
|
-
: {};
|
|
242
|
-
return {
|
|
243
|
-
...(meta ?? {}),
|
|
244
|
-
cohub: {
|
|
245
|
-
...cohub,
|
|
246
|
-
...(sessionId ? { sessionId } : {}),
|
|
247
|
-
...(turnId ? { turnId } : {}),
|
|
248
|
-
...(toolCallId ? { toolCallId } : {}),
|
|
249
|
-
},
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
232
|
export function registerGenerations(program) {
|
|
253
233
|
program
|
|
254
234
|
.command("generate")
|
|
@@ -296,7 +276,7 @@ Examples:
|
|
|
296
276
|
return error("Generation settings", policyError.message);
|
|
297
277
|
throw policyError;
|
|
298
278
|
}
|
|
299
|
-
const meta =
|
|
279
|
+
const meta = parseMeta(opts.meta);
|
|
300
280
|
const client = createClient();
|
|
301
281
|
const created = await client.generations.create({
|
|
302
282
|
spaceId,
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { createClient } from "../client.js";
|
|
2
2
|
import { table, json as outJson, jsonRequested, error, handleHttp } from "../output.js";
|
|
3
3
|
const RESOURCE_TYPES = new Set([
|
|
4
|
-
"
|
|
4
|
+
"turn",
|
|
5
5
|
"session",
|
|
6
|
+
"space",
|
|
6
7
|
"checkpoint",
|
|
7
8
|
]);
|
|
8
9
|
const REFERENCE_KINDS = new Set([
|
|
9
10
|
"session_fork",
|
|
10
11
|
"space_fork",
|
|
11
12
|
"checkpoint_fork",
|
|
13
|
+
"mod",
|
|
12
14
|
"mention",
|
|
13
15
|
"tool_call",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
+
"agent_tool_file_read",
|
|
17
|
+
"agent_tool_file_write",
|
|
18
|
+
"agent_tool_file_edit",
|
|
19
|
+
"agent_tool_file_ls",
|
|
20
|
+
"agent_tool_file_find",
|
|
21
|
+
"agent_tool_file_grep",
|
|
16
22
|
]);
|
|
17
23
|
const DIRECTIONS = new Set(["out", "in", "both"]);
|
|
18
|
-
const GROUP_BYS = new Set(["kind", "targetType", "sourceType", "day"]);
|
|
24
|
+
const GROUP_BYS = new Set(["kind", "targetType", "target", "sourceType", "day"]);
|
|
19
25
|
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
20
26
|
function parseSource(value) {
|
|
21
27
|
const idx = value.indexOf(":");
|
|
@@ -44,25 +50,35 @@ function clampNumber(value, fallback, min, max) {
|
|
|
44
50
|
return fallback;
|
|
45
51
|
return Math.min(Math.max(Math.floor(parsed), min), max);
|
|
46
52
|
}
|
|
53
|
+
const KINDS_HELP = `Kinds:
|
|
54
|
+
structural: session_fork, space_fork, checkpoint_fork, mod
|
|
55
|
+
content: mention, tool_call
|
|
56
|
+
file access: agent_tool_file_read, agent_tool_file_write, agent_tool_file_edit,
|
|
57
|
+
agent_tool_file_ls, agent_tool_file_find, agent_tool_file_grep`;
|
|
47
58
|
export function registerReferences(program) {
|
|
48
59
|
const references = program
|
|
49
60
|
.command("references")
|
|
50
|
-
.description("Inspect resource references (forks, mentions, tool calls, mods,
|
|
61
|
+
.description("Inspect resource references (forks, mentions, tool calls, mods, file access)")
|
|
62
|
+
.addHelpText("after", "\nAnalysis index for collaboration edges and file heat.\n");
|
|
51
63
|
references
|
|
52
64
|
.command("query")
|
|
53
65
|
.description("List references touching a resource")
|
|
54
|
-
.argument("<source>", "
|
|
66
|
+
.argument("<source>", "turn:<uuid> | session:<uuid> | space:<uuid> | checkpoint:<uuid>")
|
|
55
67
|
.option("--direction <dir>", "out | in | both", "both")
|
|
56
|
-
.option("--kinds <kinds>", "Comma-separated kinds
|
|
68
|
+
.option("--kinds <kinds>", "Comma-separated kinds (see list below)")
|
|
57
69
|
.option("--days <n>", "Only references seen within the last N days")
|
|
58
70
|
.option("--limit <n>", "Maximum rows, 1-500", "200")
|
|
59
71
|
.option("--json", "Output as JSON")
|
|
60
72
|
.addHelpText("after", `
|
|
61
73
|
|
|
74
|
+
${KINDS_HELP}
|
|
75
|
+
|
|
62
76
|
Examples:
|
|
77
|
+
cohub references query turn:<uuid> --kinds agent_tool_file_read,agent_tool_file_write
|
|
63
78
|
cohub references query session:<uuid> --json
|
|
79
|
+
cohub references query checkpoint:<uuid> --direction out
|
|
64
80
|
cohub references query space:<uuid> --direction in --kinds mention,tool_call
|
|
65
|
-
cohub references query space:<uuid> --kinds
|
|
81
|
+
cohub references query space:<uuid> --kinds agent_tool_file_read --days 30
|
|
66
82
|
`)
|
|
67
83
|
.action(async (source, opts) => {
|
|
68
84
|
const client = createClient();
|
|
@@ -86,7 +102,7 @@ Examples:
|
|
|
86
102
|
const rows = result.references.map((r) => ({
|
|
87
103
|
kind: r.kind,
|
|
88
104
|
source: `${r.sourceType}:${r.sourceId.slice(0, 8)}`,
|
|
89
|
-
target:
|
|
105
|
+
target: formatTarget(r.targetType, r.targetId),
|
|
90
106
|
count: r.count,
|
|
91
107
|
lastSeen: r.updatedAt.slice(0, 10),
|
|
92
108
|
}));
|
|
@@ -109,15 +125,22 @@ Examples:
|
|
|
109
125
|
.command("aggregate")
|
|
110
126
|
.description("Grouped reference counts for a space")
|
|
111
127
|
.argument("<spaceId>", "Space id")
|
|
112
|
-
.option("--group-by <field>", "kind | targetType | sourceType | day", "kind")
|
|
113
|
-
.option("--kinds <kinds>", "Comma-separated kinds
|
|
128
|
+
.option("--group-by <field>", "kind | targetType | target | sourceType | day", "kind")
|
|
129
|
+
.option("--kinds <kinds>", "Comma-separated kinds (see list below)")
|
|
114
130
|
.option("--days <n>", "Only references seen within the last N days")
|
|
131
|
+
.option("--limit <n>", "Maximum groups, 1-500", "200")
|
|
115
132
|
.option("--json", "Output as JSON")
|
|
116
133
|
.addHelpText("after", `
|
|
117
134
|
|
|
135
|
+
${KINDS_HELP}
|
|
136
|
+
|
|
137
|
+
Notes:
|
|
138
|
+
--group-by target: file targets look like {spaceId}:{path}
|
|
139
|
+
|
|
118
140
|
Examples:
|
|
119
141
|
cohub references aggregate <spaceId> --json
|
|
120
142
|
cohub references aggregate <spaceId> --group-by targetType
|
|
143
|
+
cohub references aggregate <spaceId> --group-by target --kinds agent_tool_file_read --limit 20
|
|
121
144
|
cohub references aggregate <spaceId> --group-by day --days 30
|
|
122
145
|
`)
|
|
123
146
|
.action(async (spaceId, opts) => {
|
|
@@ -130,7 +153,8 @@ Examples:
|
|
|
130
153
|
return error(`Invalid group-by: ${opts.groupBy}`);
|
|
131
154
|
const kinds = parseKinds(opts.kinds);
|
|
132
155
|
const days = opts.days ? clampNumber(opts.days, 30, 1, 365) : undefined;
|
|
133
|
-
const
|
|
156
|
+
const limit = clampNumber(opts.limit, 200, 1, 500);
|
|
157
|
+
const result = await client.references.aggregate({ spaceId: spaceId.trim(), groupBy, kinds, days, limit });
|
|
134
158
|
if (jsonRequested(opts))
|
|
135
159
|
return outJson(result);
|
|
136
160
|
const rows = result.groups.map((g) => ({
|
|
@@ -151,3 +175,16 @@ Examples:
|
|
|
151
175
|
}
|
|
152
176
|
});
|
|
153
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Render a target for the table. File targets are `{spaceId}:{path}`; show the
|
|
180
|
+
* short space id plus the full path rather than blindly truncating.
|
|
181
|
+
*/
|
|
182
|
+
function formatTarget(targetType, targetId) {
|
|
183
|
+
if (targetType === "file") {
|
|
184
|
+
const idx = targetId.indexOf(":");
|
|
185
|
+
if (idx > 0)
|
|
186
|
+
return `file:${targetId.slice(0, 8)}…${targetId.slice(idx)}`;
|
|
187
|
+
return `file:${targetId}`;
|
|
188
|
+
}
|
|
189
|
+
return `${targetType}:${targetId.slice(0, 8)}`;
|
|
190
|
+
}
|
package/dist/commands/spaces.js
CHANGED
|
@@ -235,7 +235,6 @@ async function sendPrompt(command, words, opts) {
|
|
|
235
235
|
const result = await client.space(spaceId).prompt({
|
|
236
236
|
sessionId,
|
|
237
237
|
title: sessionId === opts.session ? opts.title : undefined,
|
|
238
|
-
source: opts.source?.trim() || "cli",
|
|
239
238
|
content: promptContent,
|
|
240
239
|
model: opts.model,
|
|
241
240
|
provider: opts.provider,
|
|
@@ -342,7 +341,6 @@ export function registerPrompt(program) {
|
|
|
342
341
|
.description("Send or schedule a prompt in a space")
|
|
343
342
|
.option("--session <id>", "Target session ID")
|
|
344
343
|
.option("--title <title>", "Title for a newly created session or schedule")
|
|
345
|
-
.option("--source <source>", "Prompt source for newly created sessions", "cli")
|
|
346
344
|
.option("-m, --model <model>", "Model name")
|
|
347
345
|
.option("-p, --provider <provider>", "Provider name")
|
|
348
346
|
.option("--read-only", "Use read-only tools")
|
|
@@ -1219,7 +1217,6 @@ function registerSessions(spacesCmd) {
|
|
|
1219
1217
|
try {
|
|
1220
1218
|
const result = await client.space(spaceId).sessions.create({
|
|
1221
1219
|
title,
|
|
1222
|
-
source: "cli",
|
|
1223
1220
|
labelRefs: opts.label?.length ? opts.label : undefined,
|
|
1224
1221
|
});
|
|
1225
1222
|
if (jsonRequested(opts))
|
package/dist/commands/works.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { HttpError } from "@neta-art/cohub";
|
|
2
2
|
import { createClient } from "../client.js";
|
|
3
|
-
import { mergeSourceMeta } from "../env-context.js";
|
|
4
3
|
import { error, handleHttp, json as outJson, jsonRequested, ok, table } from "../output.js";
|
|
5
4
|
import { resolveSpace } from "../space.js";
|
|
6
5
|
import { registerWorkCommerce } from "./work-commerce.js";
|
|
@@ -101,14 +100,10 @@ async function confirmDelete(opts) {
|
|
|
101
100
|
if (answer !== "y" && answer !== "yes")
|
|
102
101
|
return error("Cancelled");
|
|
103
102
|
}
|
|
104
|
-
function resolveVersionMeta() {
|
|
105
|
-
return mergeSourceMeta(undefined);
|
|
106
|
-
}
|
|
107
103
|
async function publishWorkVersion(id, opts) {
|
|
108
104
|
const client = createClient();
|
|
109
105
|
try {
|
|
110
|
-
const
|
|
111
|
-
const result = await client.works.publishVersion(id, versionMeta ? { meta: versionMeta } : undefined);
|
|
106
|
+
const result = await client.works.publishVersion(id);
|
|
112
107
|
if (jsonRequested(opts))
|
|
113
108
|
return outJson(result);
|
|
114
109
|
ok(`Work version updated: v${result.version.version}`);
|
|
@@ -216,7 +211,6 @@ export function registerWorks(program) {
|
|
|
216
211
|
hideCohubBar: opts.hideCohubBar,
|
|
217
212
|
showCohubBar: opts.showCohubBar,
|
|
218
213
|
});
|
|
219
|
-
const versionMeta = resolveVersionMeta();
|
|
220
214
|
const input = {
|
|
221
215
|
spaceId,
|
|
222
216
|
slug,
|
|
@@ -227,7 +221,6 @@ export function registerWorks(program) {
|
|
|
227
221
|
workScopes: opts.workScope,
|
|
228
222
|
allowedViewerScopes: opts.viewerScope,
|
|
229
223
|
meta,
|
|
230
|
-
versionMeta,
|
|
231
224
|
};
|
|
232
225
|
try {
|
|
233
226
|
const result = await client.works.create(input);
|
|
@@ -254,7 +247,7 @@ export function registerWorks(program) {
|
|
|
254
247
|
meta,
|
|
255
248
|
});
|
|
256
249
|
const publishedVersion = status === "published"
|
|
257
|
-
? await client.works.publishVersion(work.id
|
|
250
|
+
? await client.works.publishVersion(work.id)
|
|
258
251
|
: null;
|
|
259
252
|
const result = publishedVersion ?? { work };
|
|
260
253
|
if (jsonRequested(opts))
|
|
@@ -328,9 +321,8 @@ export function registerWorks(program) {
|
|
|
328
321
|
return error("Nothing to update", "Pass --slug, --file, --dir, --port, --status, --visibility, --work-scope, --viewer-scope, --clear-work-scopes, --clear-viewer-scopes, --meta, --hide-cohub-bar, or --show-cohub-bar.");
|
|
329
322
|
try {
|
|
330
323
|
const updated = await client.works.update(id, input);
|
|
331
|
-
const versionMeta = resolveVersionMeta();
|
|
332
324
|
const publishedVersion = nextStatus === "published" && currentWork?.status !== "published"
|
|
333
|
-
? await client.works.publishVersion(updated.work.id
|
|
325
|
+
? await client.works.publishVersion(updated.work.id)
|
|
334
326
|
: null;
|
|
335
327
|
const result = publishedVersion ?? updated;
|
|
336
328
|
if (jsonRequested(opts))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neta-art/cohub-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@neta-art/generation": "^0.1.13",
|
|
19
19
|
"commander": "^15.0.0",
|
|
20
20
|
"sharp": "^0.35.3",
|
|
21
|
-
"@neta-art/cohub": "2.
|
|
21
|
+
"@neta-art/cohub": "2.13.0"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
package/dist/env-context.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/** Read a trimmed non-empty env value. */
|
|
2
|
-
export declare function envValue(name: string): string | undefined;
|
|
3
|
-
/**
|
|
4
|
-
* Merge sandbox provenance into meta under `source`.
|
|
5
|
-
* Prefer explicit values; fall back to COHUB_* env vars from the agent/tool runtime.
|
|
6
|
-
*/
|
|
7
|
-
export declare function mergeSourceMeta(meta: Record<string, unknown> | undefined, source?: {
|
|
8
|
-
spaceId?: string;
|
|
9
|
-
sessionId?: string;
|
|
10
|
-
turnId?: string;
|
|
11
|
-
toolCallId?: string;
|
|
12
|
-
}): Record<string, unknown> | undefined;
|
package/dist/env-context.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/** Read a trimmed non-empty env value. */
|
|
2
|
-
export function envValue(name) {
|
|
3
|
-
const value = process.env[name]?.trim();
|
|
4
|
-
return value || undefined;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Merge sandbox provenance into meta under `source`.
|
|
8
|
-
* Prefer explicit values; fall back to COHUB_* env vars from the agent/tool runtime.
|
|
9
|
-
*/
|
|
10
|
-
export function mergeSourceMeta(meta, source) {
|
|
11
|
-
const spaceId = source?.spaceId?.trim() || envValue("COHUB_SPACE_ID");
|
|
12
|
-
const sessionId = source?.sessionId?.trim() || envValue("COHUB_SESSION_ID");
|
|
13
|
-
const turnId = source?.turnId?.trim() || envValue("COHUB_TURN_ID");
|
|
14
|
-
const toolCallId = source?.toolCallId?.trim() || envValue("COHUB_TOOL_CALL_ID");
|
|
15
|
-
if (!spaceId && !sessionId && !turnId && !toolCallId)
|
|
16
|
-
return meta;
|
|
17
|
-
const existingSource = meta?.source;
|
|
18
|
-
const nextSource = existingSource && typeof existingSource === "object" && !Array.isArray(existingSource)
|
|
19
|
-
? { ...existingSource }
|
|
20
|
-
: {};
|
|
21
|
-
if (spaceId)
|
|
22
|
-
nextSource.spaceId = spaceId;
|
|
23
|
-
if (sessionId)
|
|
24
|
-
nextSource.sessionId = sessionId;
|
|
25
|
-
if (turnId)
|
|
26
|
-
nextSource.turnId = turnId;
|
|
27
|
-
if (toolCallId)
|
|
28
|
-
nextSource.toolCallId = toolCallId;
|
|
29
|
-
return {
|
|
30
|
-
...(meta ?? {}),
|
|
31
|
-
source: nextSource,
|
|
32
|
-
};
|
|
33
|
-
}
|