@neta-art/cohub-cli 1.13.1 → 1.15.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.
@@ -171,7 +171,7 @@ function envValue(name) {
171
171
  const value = process.env[name]?.trim();
172
172
  return value || undefined;
173
173
  }
174
- function parseMetadata(value) {
174
+ function parseMeta(value) {
175
175
  if (!value)
176
176
  return undefined;
177
177
  let parsed;
@@ -179,25 +179,25 @@ function parseMetadata(value) {
179
179
  parsed = JSON.parse(value);
180
180
  }
181
181
  catch {
182
- return error("Invalid metadata", "--metadata must be a JSON object");
182
+ return error("Invalid meta", "--meta must be a JSON object");
183
183
  }
184
184
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
185
- return error("Invalid metadata", "--metadata must be a JSON object");
185
+ return error("Invalid meta", "--meta must be a JSON object");
186
186
  }
187
187
  return parsed;
188
188
  }
189
- function mergeCohubMetadata(metadata) {
189
+ function mergeCohubMeta(meta) {
190
190
  const sessionId = envValue("COHUB_SESSION_ID");
191
191
  const turnId = envValue("COHUB_TURN_ID");
192
192
  const toolCallId = envValue("COHUB_TOOL_CALL_ID");
193
193
  if (!sessionId && !turnId && !toolCallId)
194
- return metadata;
195
- const existingCohub = metadata?.cohub;
194
+ return meta;
195
+ const existingCohub = meta?.cohub;
196
196
  const cohub = existingCohub && typeof existingCohub === "object" && !Array.isArray(existingCohub)
197
197
  ? existingCohub
198
198
  : {};
199
199
  return {
200
- ...(metadata ?? {}),
200
+ ...(meta ?? {}),
201
201
  cohub: {
202
202
  ...cohub,
203
203
  ...(sessionId ? { sessionId } : {}),
@@ -217,7 +217,7 @@ export function registerGenerations(program) {
217
217
  .option("--audio <path-or-url>", "Audio input file path or URL; repeatable", collect, [])
218
218
  .option("--param <key=value>", "Generation parameter; repeatable, values may be JSON/number/boolean", collect, [])
219
219
  .option("--parameters <json>", "Generation parameters as a JSON object")
220
- .option("--metadata <json>", "Metadata as a JSON object")
220
+ .option("--meta <json>", "Meta as a JSON object")
221
221
  .option("-o, --output <path>", "Save generated output to a file or directory")
222
222
  .option("--async", "Queue the generation task and return immediately")
223
223
  .option("--timeout-ms <ms>", "Maximum time to wait in synchronous mode")
@@ -250,7 +250,7 @@ Examples:
250
250
  return error("Generation settings", policyError.message);
251
251
  throw policyError;
252
252
  }
253
- const metadata = mergeCohubMetadata(parseMetadata(opts.metadata));
253
+ const meta = mergeCohubMeta(parseMeta(opts.meta));
254
254
  const client = createClient();
255
255
  const created = await client.generations.create({
256
256
  spaceId,
@@ -259,7 +259,7 @@ Examples:
259
259
  model: opts.model,
260
260
  content,
261
261
  parameters,
262
- metadata,
262
+ meta,
263
263
  });
264
264
  if (opts.async) {
265
265
  if (jsonRequested(opts))
@@ -3,7 +3,7 @@ import { table, json as outJson, jsonRequested, error, handleHttp } from "../out
3
3
  const DEFAULT_LIMIT = 20;
4
4
  const MAX_TITLE_LENGTH = 72;
5
5
  const MAX_CONTEXT_LENGTH = 42;
6
- const SEARCH_TYPES = new Set(["turn", "session", "space"]);
6
+ const SEARCH_TYPES = new Set(["turn", "session", "space", "label"]);
7
7
  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;
8
8
  function clampLimit(value) {
9
9
  const parsed = Number(value ?? DEFAULT_LIMIT);
@@ -42,7 +42,7 @@ function parseSearchInput(opts) {
42
42
  const spaceId = opts.spaceId?.trim();
43
43
  if (spaceId && !UUID_PATTERN.test(spaceId))
44
44
  throw new Error("Invalid space id");
45
- return { types, spaceId: spaceId || undefined };
45
+ return { types, spaceId: spaceId || undefined, labelRef: opts.labelRef?.trim() || undefined };
46
46
  }
47
47
  function rowsFor(items) {
48
48
  return items.map((item) => ({
@@ -57,11 +57,12 @@ function rowsFor(items) {
57
57
  export function registerSearch(program) {
58
58
  program
59
59
  .command("search")
60
- .description("Search spaces, chats, and turns")
61
- .argument("<query>", "Search query")
60
+ .description("Search spaces, chats, turns, and label items")
61
+ .argument("[query]", "Search query")
62
62
  .option("--limit <n>", "Maximum results, 1-50", String(DEFAULT_LIMIT))
63
- .option("--types <types>", "Comma-separated result types: turn,session,space")
63
+ .option("--types <types>", "Comma-separated result types: turn,session,space,label")
64
64
  .option("--space-id <id>", "Limit search to a space")
65
+ .option("--label-ref <ref>", "Search items under an exact label ref")
65
66
  .option("--json", "Output as JSON")
66
67
  .addHelpText("after", `
67
68
 
@@ -69,17 +70,23 @@ Examples:
69
70
  cohub search "release notes"
70
71
  cohub search "failing tests" --limit 10
71
72
  cohub search "bug" --types turn,session --space-id <spaceId>
73
+ cohub search --types label --label-ref bug
74
+ cohub search "login" --types label --label-ref bug
72
75
  cohub search "design review" --json
73
76
  `)
74
77
  .action(async (query, opts) => {
75
78
  const client = createClient();
76
79
  try {
77
80
  const input = parseSearchInput(opts);
81
+ const q = query ?? "";
82
+ if (!q.trim() && !input.labelRef)
83
+ return error("Search query is required unless --label-ref is provided.");
78
84
  const result = await client.search.query({
79
- q: query,
85
+ q,
80
86
  limit: clampLimit(opts.limit),
81
87
  types: input.types,
82
88
  spaceId: input.spaceId,
89
+ labelRef: input.labelRef,
83
90
  });
84
91
  if (jsonRequested(opts))
85
92
  return outJson(result);
@@ -1417,4 +1417,52 @@ function registerCheckpoints(spacesCmd) {
1417
1417
  handleHttp(e);
1418
1418
  }
1419
1419
  });
1420
+ cpCmd
1421
+ .command("ls-tree <checkpointId> [path]")
1422
+ .description("List checkpoint tree")
1423
+ .option("--json", "Output as JSON")
1424
+ .action(async (checkpointId, path, opts) => {
1425
+ const spaceId = resolveSpace(spacesCmd);
1426
+ const client = createClient();
1427
+ try {
1428
+ const tree = await client.space(spaceId).checkpoints(checkpointId).files.list(path ?? "");
1429
+ if (jsonRequested(opts))
1430
+ return outJson(tree);
1431
+ if (tree.entries.length === 0) {
1432
+ console.log(" (empty)");
1433
+ return;
1434
+ }
1435
+ table(tree.entries, [
1436
+ { key: "name", label: "Name" },
1437
+ { key: "type", label: "Type" },
1438
+ { key: "size", label: "Size" },
1439
+ { key: "mimeType", label: "MIME" },
1440
+ { key: "mtimeMs", label: "Modified" },
1441
+ ]);
1442
+ }
1443
+ catch (e) {
1444
+ handleHttp(e);
1445
+ }
1446
+ });
1447
+ cpCmd
1448
+ .command("show <checkpointId> <path>")
1449
+ .description("Show checkpoint file content")
1450
+ .option("--json", "Output as JSON")
1451
+ .action(async (checkpointId, path, opts) => {
1452
+ const spaceId = resolveSpace(spacesCmd);
1453
+ const client = createClient();
1454
+ try {
1455
+ const file = await client.space(spaceId).checkpoints(checkpointId).files.read(path);
1456
+ if (jsonRequested(opts))
1457
+ return outJson(file);
1458
+ if (file.delivery === "url" && file.url) {
1459
+ console.log(file.url);
1460
+ return;
1461
+ }
1462
+ console.log(file.content);
1463
+ }
1464
+ catch (e) {
1465
+ handleHttp(e);
1466
+ }
1467
+ });
1420
1468
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub-cli",
3
- "version": "1.13.1",
3
+ "version": "1.15.0",
4
4
  "description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -13,10 +13,10 @@
13
13
  "README.md"
14
14
  ],
15
15
  "dependencies": {
16
- "@neta-art/generation": "^0.1.2",
16
+ "@neta-art/generation": "^0.1.3",
17
17
  "commander": "^14.0.3",
18
18
  "sharp": "^0.34.5",
19
- "@neta-art/cohub": "1.23.1"
19
+ "@neta-art/cohub": "1.25.0"
20
20
  },
21
21
  "publishConfig": {
22
22
  "access": "public"