@neta-art/cohub-cli 8.4.0 → 9.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.
Files changed (84) hide show
  1. package/README.md +25 -2
  2. package/dist/avatar.js +3 -1
  3. package/dist/board-export.d.ts +22 -41
  4. package/dist/board-export.js +178 -115
  5. package/dist/board-fonts.d.ts +7 -0
  6. package/dist/board-fonts.js +10 -0
  7. package/dist/board-kernel/browserAll.js +2760 -0
  8. package/dist/board-kernel/getPo2TextureFromSource.js +13138 -0
  9. package/dist/board-kernel/init.js +867 -0
  10. package/dist/board-kernel/webworkerAll.js +3 -0
  11. package/dist/board-kernel.d.ts +2 -0
  12. package/dist/board-kernel.js +28812 -0
  13. package/dist/board-time.d.ts +3 -0
  14. package/dist/board-time.js +28 -0
  15. package/dist/commands/apps.js +2 -2
  16. package/dist/commands/auth.js +2 -2
  17. package/dist/commands/boards/examples.d.ts +8 -2
  18. package/dist/commands/boards/examples.js +79 -411
  19. package/dist/commands/boards.d.ts +4 -9
  20. package/dist/commands/boards.js +356 -286
  21. package/dist/commands/desktop.d.ts +1 -5
  22. package/dist/commands/desktop.js +10 -19
  23. package/dist/commands/generations.js +1 -1
  24. package/dist/commands/me.js +1 -1
  25. package/dist/commands/public.js +3 -3
  26. package/dist/commands/references.js +3 -0
  27. package/dist/commands/referrals.js +2 -2
  28. package/dist/commands/run.js +3 -3
  29. package/dist/commands/runtime.d.ts +1 -1
  30. package/dist/commands/runtime.js +12 -8
  31. package/dist/commands/search.js +15 -7
  32. package/dist/commands/space-activity.js +3 -5
  33. package/dist/commands/space-displays.d.ts +2 -0
  34. package/dist/commands/space-displays.js +347 -0
  35. package/dist/commands/space-files.d.ts +5 -0
  36. package/dist/commands/space-files.js +215 -0
  37. package/dist/commands/space-invitations.js +3 -3
  38. package/dist/commands/spaces.d.ts +3 -11
  39. package/dist/commands/spaces.js +146 -75
  40. package/dist/fonts/geist-latin-400-normal.woff2 +0 -0
  41. package/dist/fonts/geist-latin-500-normal.woff2 +0 -0
  42. package/dist/fonts/geist-latin-600-normal.woff2 +0 -0
  43. package/dist/fonts/geist-latin-700-normal.woff2 +0 -0
  44. package/dist/fonts/geist-mono-latin-500-normal.woff2 +0 -0
  45. package/dist/fonts/geist-mono-latin-600-normal.woff2 +0 -0
  46. package/dist/fonts/geist-mono-latin-700-normal.woff2 +0 -0
  47. package/dist/index.js +7 -4
  48. package/dist/runtime/launch.d.ts +2 -0
  49. package/dist/runtime/launch.js +35 -8
  50. package/dist/runtime/presentation.d.ts +1 -0
  51. package/dist/runtime/presentation.js +3 -2
  52. package/dist/runtime/supervisor.d.ts +1 -0
  53. package/dist/runtime/supervisor.js +2 -1
  54. package/dist/self-update.d.ts +1 -0
  55. package/dist/self-update.js +52 -16
  56. package/dist/space-files/limit.d.ts +2 -0
  57. package/dist/space-files/limit.js +16 -0
  58. package/dist/space-files/operands.d.ts +16 -0
  59. package/dist/space-files/operands.js +33 -0
  60. package/dist/space-files/transfer.d.ts +53 -0
  61. package/dist/space-files/transfer.js +296 -0
  62. package/dist/space-files/upload.d.ts +14 -0
  63. package/dist/space-files/upload.js +53 -0
  64. package/dist/space.d.ts +18 -16
  65. package/dist/space.js +86 -39
  66. package/dist/web.d.ts +1 -0
  67. package/dist/web.js +6 -0
  68. package/package.json +8 -4
  69. package/dist/commands/board-domain.d.ts +0 -2
  70. package/dist/commands/board-domain.js +0 -16
  71. package/dist/commands/boards/animation.d.ts +0 -2
  72. package/dist/commands/boards/animation.js +0 -171
  73. package/dist/commands/boards/appearance.d.ts +0 -2
  74. package/dist/commands/boards/appearance.js +0 -127
  75. package/dist/commands/boards/batch.d.ts +0 -4
  76. package/dist/commands/boards/batch.js +0 -62
  77. package/dist/commands/boards/connections.d.ts +0 -2
  78. package/dist/commands/boards/connections.js +0 -95
  79. package/dist/commands/boards/context.d.ts +0 -31
  80. package/dist/commands/boards/context.js +0 -71
  81. package/dist/commands/boards/items.d.ts +0 -2
  82. package/dist/commands/boards/items.js +0 -184
  83. package/dist/commands/boards/transactions.d.ts +0 -12
  84. package/dist/commands/boards/transactions.js +0 -69
@@ -1,11 +1,7 @@
1
1
  import { resolveOpenSurface } from "@neta-art/cohub";
2
2
  import type { Command } from "commander";
3
3
  export { resolveOpenSurface };
4
- /**
5
- * Optional disambiguation for file:// vs app://. Unlike ordinary
6
- * Space-scoped commands, an unbound directory must not fall back to Home:
7
- * the plain target should remain eligible for App resolution.
8
- */
4
+ /** Never falls back to Home, so a plain target stays eligible for App resolution. */
9
5
  export declare function resolveOptionalSpaceId(command: Command, options?: {
10
6
  cwd?: string;
11
7
  bindingsPath?: string;
@@ -1,29 +1,18 @@
1
1
  import { readFileSync } from "node:fs";
2
- import { HttpError, parseAppRef, resolveOpenSurface, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS, DESKTOP_COMMAND_MAX_TIMEOUT_MS, } from "@neta-art/cohub";
2
+ import { HttpError, parseAppRef, resolveOpenSurface, DESKTOP_COMMAND_ACCEPT_TIMEOUT_MS, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS, DESKTOP_COMMAND_MAX_TIMEOUT_MS, DESKTOP_COMMAND_OPEN_TIMEOUT_MS, } from "@neta-art/cohub";
3
3
  import { createClient } from "../client.js";
4
4
  import { error, handleHttp, json as outJson, jsonRequested, ok } from "../output.js";
5
- import { resolveBoundSpace } from "../space.js";
5
+ import { explicitSpace, failSpaceTarget, resolveBoundSpace, resolveSpaceRef } from "../space.js";
6
6
  import { getAppByRef } from "../app-ref.js";
7
7
  export { resolveOpenSurface };
8
8
  const FILE_SCHEME = "file://";
9
9
  const APP_SCHEME = "app://";
10
10
  const LEGACY_WORK_SCHEME = "work://";
11
- /**
12
- * Optional disambiguation for file:// vs app://. Unlike ordinary
13
- * Space-scoped commands, an unbound directory must not fall back to Home:
14
- * the plain target should remain eligible for App resolution.
15
- */
11
+ /** Never falls back to Home, so a plain target stays eligible for App resolution. */
16
12
  export async function resolveOptionalSpaceId(command, options = {}) {
17
- let current = command;
18
- while (current) {
19
- const opts = current.opts();
20
- if (typeof opts.space === "string" && opts.space.trim())
21
- return opts.space.trim();
22
- current = current.parent ?? null;
23
- }
24
- const fromEnvironment = process.env.COHUB_SPACE_ID?.trim();
25
- if (fromEnvironment)
26
- return fromEnvironment;
13
+ const explicit = explicitSpace(command);
14
+ if (explicit)
15
+ return resolveSpaceRef(explicit).catch(failSpaceTarget);
27
16
  return (await resolveBoundSpace(options)) ?? undefined;
28
17
  }
29
18
  function parseFilePath(value) {
@@ -66,7 +55,7 @@ function readCallInput(opts) {
66
55
  }
67
56
  function parseTimeout(value) {
68
57
  if (!value)
69
- return DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS;
58
+ return undefined;
70
59
  const parsed = Math.floor(Number(value));
71
60
  if (!Number.isFinite(parsed) || parsed <= 0 || parsed > DESKTOP_COMMAND_MAX_TIMEOUT_MS) {
72
61
  return error("Invalid timeout", `--timeout-ms must be between 1 and ${DESKTOP_COMMAND_MAX_TIMEOUT_MS} milliseconds.`);
@@ -200,6 +189,8 @@ Notes:
200
189
  scheme is still accepted.
201
190
  - A plain target checks the explicit Space or current directory Runtime binding for a file before resolving an app; it does not fall back to Home.
202
191
  - Opening a window is idempotent; repeating it re-activates the same tab.
192
+ - A desktop that does not respond within ${DESKTOP_COMMAND_ACCEPT_TIMEOUT_MS / 1_000} seconds (closed, asleep, or
193
+ offline) fails fast with no_active_client instead of waiting out the timeout.
203
194
  - --as picks the surface: window (a preview tab) or overlay (a transparent
204
195
  layer above the workspace). Without it, an App published with
205
196
  <meta name="cohub:surface" content="overlay"> opens as an overlay.
@@ -217,7 +208,7 @@ function registerOpen(parent, deprecated) {
217
208
  .option("--command-id <id>", "Stable id so retries never dispatch twice")
218
209
  .option("--no-wait", "Dispatch the command and exit without waiting for a result")
219
210
  .option("--as <surface>", "Surface role for app targets: window (default) or overlay")
220
- .option("--timeout-ms <ms>", `How long to wait for the desktop (default: ${DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS}; max: ${DESKTOP_COMMAND_MAX_TIMEOUT_MS})`)
211
+ .option("--timeout-ms <ms>", `How long to wait for the desktop (default: ${DESKTOP_COMMAND_OPEN_TIMEOUT_MS}, or ${DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS} with --call; max: ${DESKTOP_COMMAND_MAX_TIMEOUT_MS})`)
221
212
  .option("--json", "Output as JSON")
222
213
  .action(async (target, opts, thisCommand) => {
223
214
  if (deprecated) {
@@ -300,7 +300,7 @@ Examples:
300
300
  `)
301
301
  .action(async (prompt, opts) => {
302
302
  try {
303
- const spaceId = await resolveSpace(program);
303
+ const spaceId = await resolveSpace(program, { home: true });
304
304
  const sessionId = envValue("COHUB_SESSION_ID");
305
305
  const inputs = await Promise.all([
306
306
  ...opts.image.map((value) => parseMediaInput("image", value)),
@@ -71,7 +71,7 @@ export function registerMe(program) {
71
71
  if (jsonRequested(opts))
72
72
  return outJson(activity);
73
73
  console.log(`\n ${formatLocalDateTime(activity.range.from)} → ${formatLocalDateTime(activity.range.to)}`);
74
- table([activity.summary], [
74
+ table([activity.totals], [
75
75
  { key: "totalTokens", label: "Tokens" },
76
76
  { key: "costTotal", label: "Cost ($)" },
77
77
  { key: "requestCount", label: "Requests" },
@@ -182,7 +182,7 @@ function publicUrlPrefix(destination, entry) {
182
182
  }
183
183
  async function uploadPublic(command, source, destination, opts, deps) {
184
184
  const client = deps.createClient?.() ?? createClient();
185
- const spaceId = await resolveSpace(command);
185
+ const spaceId = await resolveSpace(command, { home: true });
186
186
  try {
187
187
  const upload = await collectPublicUpload(source, destination);
188
188
  const plan = await client.space(spaceId).publicFiles.createUpload({
@@ -247,7 +247,7 @@ async function uploadPublic(command, source, destination, opts, deps) {
247
247
  async function listPublic(command, path, opts, deps) {
248
248
  const client = deps.createClient?.() ?? createClient();
249
249
  try {
250
- const publicFiles = client.space(await resolveSpace(command)).publicFiles;
250
+ const publicFiles = client.space(await resolveSpace(command, { home: true })).publicFiles;
251
251
  const entries = [];
252
252
  let cursor;
253
253
  do {
@@ -274,7 +274,7 @@ async function listPublic(command, path, opts, deps) {
274
274
  async function printPublicUrl(command, path, deps) {
275
275
  const client = deps.createClient?.() ?? createClient();
276
276
  try {
277
- const result = await client.space(await resolveSpace(command)).publicFiles.url(path);
277
+ const result = await client.space(await resolveSpace(command, { home: true })).publicFiles.url(path);
278
278
  console.log(result.url);
279
279
  }
280
280
  catch (exception) {
@@ -14,6 +14,7 @@ const REFERENCE_KINDS = new Set([
14
14
  "mod",
15
15
  "mention",
16
16
  "tool_call",
17
+ "turn_trigger",
17
18
  "agent_tool_file_read",
18
19
  "agent_tool_file_write",
19
20
  "agent_tool_file_edit",
@@ -53,6 +54,7 @@ function clampNumber(value, fallback, min, max) {
53
54
  const KINDS_HELP = `Kinds:
54
55
  structural: session_fork, space_fork, checkpoint_fork, mod
55
56
  content: mention, tool_call
57
+ causality: turn_trigger
56
58
  file access: agent_tool_file_read, agent_tool_file_write, agent_tool_file_edit,
57
59
  agent_tool_file_ls, agent_tool_file_find, agent_tool_file_grep`;
58
60
  export function registerReferences(program) {
@@ -75,6 +77,7 @@ ${KINDS_HELP}
75
77
 
76
78
  Examples:
77
79
  cohub references query turn:<uuid> --kinds agent_tool_file_read,agent_tool_file_write
80
+ cohub references query turn:<uuid> --direction out --kinds turn_trigger
78
81
  cohub references query session:<uuid> --json
79
82
  cohub references query checkpoint:<uuid> --direction out
80
83
  cohub references query space:<uuid> --direction in --kinds mention,tool_call
@@ -1,8 +1,8 @@
1
1
  import { createClient } from "../client.js";
2
2
  import { error, handleHttp, json as outJson, jsonRequested, ok, table } from "../output.js";
3
+ import { webUrl } from "../web.js";
3
4
  function referralUrl(code) {
4
- const origin = process.env.COHUB_WEB_URL?.replace(/\/+$/, "") ?? "https://cohub.live";
5
- return `${origin}/referrals/${code}`;
5
+ return webUrl(`/referrals/${code}`);
6
6
  }
7
7
  async function confirmRotate(opts) {
8
8
  if (opts.yes)
@@ -110,8 +110,8 @@ export async function parseRunCliOptions(argv, spaceOptions = {}) {
110
110
  export function printRunHelp() {
111
111
  process.stdout.write(`
112
112
  Usage:
113
- cohub [-s <spaceId>] run [options] -- <shell command>
114
- cohub [-s <spaceId>] run --command <shell command>
113
+ cohub [-s <space>] run [options] -- <shell command>
114
+ cohub [-s <space>] run --command <shell command>
115
115
 
116
116
  Options:
117
117
  -c, --command <command> Shell command to execute in the space workspace
@@ -125,7 +125,7 @@ Examples:
125
125
  cohub -s <spaceId> run -- git status -sb
126
126
 
127
127
  Notes:
128
- - Without -s or COHUB_SPACE_ID, the command uses the current directory Runtime binding, then Home.
128
+ - Without -s or COHUB_SPACE_ID, the command uses the current directory Runtime binding; it never falls back to Home.
129
129
  - Use --command for commands that contain leading flags, or use -- before the shell command.
130
130
  - The command runs in /workspace.
131
131
  `);
@@ -1,3 +1,3 @@
1
1
  import type { Command } from "commander";
2
- export { resolveLocalSpaceName, parseRuntimeHarnesses } from "../runtime/launch.js";
2
+ export { resolveLocalSpaceName, parseRuntimeDisplay, parseRuntimeHarnesses } from "../runtime/launch.js";
3
3
  export declare function registerRuntime(program: Command): void;
@@ -12,7 +12,7 @@ import { installPiExtension, piExtensionState } from "../runtime/native/install.
12
12
  import { controlRuntimeInstance, requestRuntimeInstance, runtimeInstanceDirectory } from "../runtime/instance.js";
13
13
  import { atLeastLevel, diagnosticLevels, formatDiagnostic, formatImportProgress, formatNativeSync, printRuntimeSummary } from "../runtime/presentation.js";
14
14
  import { readRuntimeDiagnosticEvents, RuntimeDiagnosticReader, runtimeDiagnosticsDirectory, serializeDiagnosticError } from "../runtime/diagnostics.js";
15
- export { resolveLocalSpaceName, parseRuntimeHarnesses } from "../runtime/launch.js";
15
+ export { resolveLocalSpaceName, parseRuntimeDisplay, parseRuntimeHarnesses } from "../runtime/launch.js";
16
16
  const reportFailure = (cause) => {
17
17
  process.stderr.write(`Runtime failed: ${serializeDiagnosticError(cause).message}\n`);
18
18
  process.exitCode = 1;
@@ -34,13 +34,14 @@ export function registerRuntime(program) {
34
34
  const runtime = program.command("runtime").description("Connect a local workspace");
35
35
  runtime.command("up [dir]")
36
36
  .description("Connect local Harnesses and files")
37
- .option("-s, --space <id>", "Target Space")
37
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
38
38
  .option("-n, --new", "Create a new Space")
39
39
  .option("--name <name>", "New Space name")
40
40
  .option("-d, --detach", "Run in the background")
41
41
  .option("--harness <name>", "Pi or Codex; repeatable", (value, previous) => [...previous, value], [])
42
42
  .option("--pi <path>", "Pi executable")
43
43
  .option("--codex <path>", "Codex executable")
44
+ .option("--display [screen]", "Share a screen: auto (this computer), or xvfb[:WIDTHxHEIGHT] for a virtual one")
44
45
  .option("-y, --yes", "Accept defaults and authorize local execution and native sync")
45
46
  .option("--verbose", "Show diagnostic details")
46
47
  .option("--json", "JSON output")
@@ -54,7 +55,7 @@ export function registerRuntime(program) {
54
55
  });
55
56
  runtime.command("attach")
56
57
  .description("Connect native harnesses to Cohub: install the Pi extension")
57
- .option("-s, --space <id>", "Target Space")
58
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
58
59
  .option("--harness <name>", "Pi; repeatable", (value, previous) => [...previous, value], [])
59
60
  .option("--json", "JSON output")
60
61
  .action(async (options) => {
@@ -81,7 +82,7 @@ export function registerRuntime(program) {
81
82
  });
82
83
  runtime.command("detach")
83
84
  .description("Pause native sync; keep all data")
84
- .option("-s, --space <id>", "Target Space")
85
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
85
86
  .option("--harness <name>", "Pi or Codex; repeatable", (value, previous) => [...previous, value], [])
86
87
  .option("--json", "JSON output")
87
88
  .action(async (options) => {
@@ -110,7 +111,7 @@ export function registerRuntime(program) {
110
111
  });
111
112
  runtime.command("import [dir]")
112
113
  .description("Import earlier local conversations, newest first")
113
- .option("-s, --space <id>", "Target Space")
114
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
114
115
  .option("--harness <name>", "Filter by harness; repeatable", (value, previous) => [...previous, value], [])
115
116
  .option("--session <id>", "Filter by native session ID")
116
117
  .option("--concurrency <count>", `Conversations read in parallel, 1 to ${MAX_IMPORT_CONCURRENCY}`, String(DEFAULT_IMPORT_CONCURRENCY))
@@ -207,7 +208,7 @@ export function registerRuntime(program) {
207
208
  }
208
209
  });
209
210
  runtime.command("status").description("Local and server status")
210
- .option("-s, --space <id>", "Target Space")
211
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
211
212
  .option("--json", "JSON output")
212
213
  .action(async (options) => {
213
214
  try {
@@ -232,6 +233,9 @@ export function registerRuntime(program) {
232
233
  else
233
234
  process.stdout.write(`Local process Not running\nSpace ${spaceId}\nLogs ${result.diagnosticsPath}\n`);
234
235
  process.stdout.write(`Server ${remote.error ? `Unknown — ${remote.error}` : remote.value?.online ? "Harness connected" : "Offline"}\nArchives ${pendingLocalArchives} pending · ${failedLocalArchives} failed\n`);
236
+ const displays = remote.value?.displays ?? [];
237
+ if (displays.length)
238
+ process.stdout.write(`Displays ${displays.map((display) => `${display.name || display.id} ${display.width}x${display.height}${display.needs?.length ? ` (needs ${display.needs.join(", ")})` : display.input ? "" : " (view only)"}`).join(" · ")}\n`);
235
239
  process.stdout.write(formatNativeSync(nativeSync.config, local?.native, nativeSync.error));
236
240
  }
237
241
  }
@@ -240,7 +244,7 @@ export function registerRuntime(program) {
240
244
  }
241
245
  });
242
246
  runtime.command("down").description("Stop this local Runtime; retain all data")
243
- .option("-s, --space <id>", "Target Space")
247
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
244
248
  .option("-y, --yes", "Stop even with unconfirmed executions")
245
249
  .option("--json", "JSON output")
246
250
  .action(async (options) => {
@@ -278,7 +282,7 @@ export function registerRuntime(program) {
278
282
  }
279
283
  });
280
284
  runtime.command("logs").description("Read local Runtime diagnostics")
281
- .option("-s, --space <id>", "Target Space")
285
+ .option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
282
286
  .option("-l, --limit <count>", "Number of events", "100")
283
287
  .option("--level <level>", "Minimum level: debug, info, warn, error", "info")
284
288
  .option("-f, --follow", "Keep watching")
@@ -4,7 +4,8 @@ import { formatLocalDateTime, table, json as outJson, jsonRequested, error, hand
4
4
  const DEFAULT_LIMIT = 20;
5
5
  const MAX_TITLE_LENGTH = 72;
6
6
  const MAX_CONTEXT_LENGTH = 42;
7
- const SEARCH_TYPES = new Set(["turn", "session", "space", "label"]);
7
+ const MAX_MATCH_LENGTH = 60;
8
+ const SEARCH_TYPES = new Set(["chat", "space", "label"]);
8
9
  function clampLimit(value) {
9
10
  const parsed = Number(value ?? DEFAULT_LIMIT);
10
11
  if (!Number.isFinite(parsed))
@@ -17,7 +18,14 @@ function contextFor(item) {
17
18
  return `@${owner.username}`;
18
19
  if (owner?.displayName)
19
20
  return owner.displayName;
20
- return item.href;
21
+ if (item.type === "label")
22
+ return item.labelRef ?? "";
23
+ return item.spaceName ?? "";
24
+ }
25
+ function matchFor(item) {
26
+ if (item.hit)
27
+ return item.hit.excerpt;
28
+ return item.matchedField;
21
29
  }
22
30
  function parseTypes(value) {
23
31
  const types = value
@@ -41,9 +49,9 @@ function parseSearchInput(opts) {
41
49
  function rowsFor(items) {
42
50
  return items.map((item) => ({
43
51
  type: item.type,
44
- title: truncateText(item.title, MAX_TITLE_LENGTH),
52
+ title: truncateText(item.title || "New chat", MAX_TITLE_LENGTH),
45
53
  context: truncateText(contextFor(item), MAX_CONTEXT_LENGTH),
46
- match: item.matchedField,
54
+ match: truncateText(matchFor(item), MAX_MATCH_LENGTH),
47
55
  updated: item.updatedAt ? formatLocalDateTime(item.updatedAt).slice(0, 10) : "",
48
56
  href: item.href,
49
57
  }));
@@ -51,10 +59,10 @@ function rowsFor(items) {
51
59
  export function registerSearch(program) {
52
60
  program
53
61
  .command("search")
54
- .description("Search spaces, chats, turns, and label items")
62
+ .description("Search spaces, chats, and label items")
55
63
  .argument("[query]", "Search query")
56
64
  .option("--limit <n>", "Maximum results, 1-50", String(DEFAULT_LIMIT))
57
- .option("--types <types>", "Comma-separated result types: turn,session,space,label")
65
+ .option("--types <types>", "Comma-separated result types: chat,space,label")
58
66
  .option("--space-id <id>", "Limit search to a space")
59
67
  .option("--label-ref <ref>", "Search items under an exact label ref")
60
68
  .option("--json", "Output as JSON")
@@ -63,7 +71,7 @@ export function registerSearch(program) {
63
71
  Examples:
64
72
  cohub search "release notes"
65
73
  cohub search "failing tests" --limit 10
66
- cohub search "bug" --types turn,session --space-id <spaceId>
74
+ cohub search "bug" --types chat --space-id <spaceId>
67
75
  cohub search --types label --label-ref bug
68
76
  cohub search "login" --types label --label-ref bug
69
77
  cohub search "design review" --json
@@ -63,13 +63,11 @@ export function toAppRankingRows(apps) {
63
63
  id: app.appId,
64
64
  }));
65
65
  }
66
- function hasCost(activity) {
67
- return activity.summary.costTotal !== 0;
68
- }
69
66
  export function printActivityReport(activity) {
70
- const showCost = hasCost(activity);
67
+ const { totals } = activity;
68
+ const showCost = totals.costTotal !== 0;
71
69
  console.log(`\n Summary (last ${activity.days} days):`);
72
- table([activity.summary], [
70
+ table([totals], [
73
71
  { key: "totalTokens", label: "Tokens", format: formatNumber },
74
72
  { key: "requestCount", label: "Requests", format: formatNumber },
75
73
  ...(showCost ? [{ key: "costTotal", label: "Cost", format: formatCost }] : []),
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerSpaceDisplays(spacesCmd: Command): void;