@neta-art/cohub-cli 8.4.1 → 9.1.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 +66 -30
- package/dist/board-export.d.ts +21 -36
- package/dist/board-export.js +163 -88
- package/dist/board-kernel.d.ts +2 -3
- package/dist/board-kernel.js +3428 -3770
- package/dist/board-time.d.ts +3 -0
- package/dist/board-time.js +28 -0
- package/dist/commands/apps.js +2 -2
- package/dist/commands/auth.js +2 -2
- package/dist/commands/boards/examples.d.ts +8 -2
- package/dist/commands/boards/examples.js +79 -411
- package/dist/commands/boards.d.ts +4 -9
- package/dist/commands/boards.js +365 -286
- package/dist/commands/desktop.d.ts +1 -5
- package/dist/commands/desktop.js +5 -16
- package/dist/commands/generations.js +1 -1
- package/dist/commands/me.js +1 -1
- package/dist/commands/public.js +3 -3
- package/dist/commands/references.js +3 -0
- package/dist/commands/referrals.js +2 -2
- package/dist/commands/run.js +3 -3
- package/dist/commands/runtime.d.ts +1 -1
- package/dist/commands/runtime.js +14 -9
- package/dist/commands/sandboxd-binary.d.ts +1 -1
- package/dist/commands/sandboxd-binary.js +2 -23
- package/dist/commands/search.js +15 -7
- package/dist/commands/space-activity.js +3 -5
- package/dist/commands/space-displays.d.ts +2 -0
- package/dist/commands/space-displays.js +347 -0
- package/dist/commands/space-files.d.ts +5 -0
- package/dist/commands/space-files.js +215 -0
- package/dist/commands/space-invitations.js +3 -3
- package/dist/commands/spaces.d.ts +3 -11
- package/dist/commands/spaces.js +146 -75
- package/dist/index.js +8 -5
- package/dist/runtime/launch.d.ts +2 -0
- package/dist/runtime/launch.js +38 -8
- package/dist/runtime/presentation.d.ts +1 -0
- package/dist/runtime/presentation.js +3 -2
- package/dist/runtime/supervisor.d.ts +1 -0
- package/dist/runtime/supervisor.js +2 -1
- package/dist/space-files/limit.d.ts +2 -0
- package/dist/space-files/limit.js +16 -0
- package/dist/space-files/operands.d.ts +16 -0
- package/dist/space-files/operands.js +33 -0
- package/dist/space-files/transfer.d.ts +53 -0
- package/dist/space-files/transfer.js +296 -0
- package/dist/space-files/upload.d.ts +14 -0
- package/dist/space-files/upload.js +53 -0
- package/dist/space.d.ts +18 -16
- package/dist/space.js +86 -39
- package/dist/web.d.ts +1 -0
- package/dist/web.js +6 -0
- package/package.json +2 -2
- package/dist/commands/board-domain.d.ts +0 -2
- package/dist/commands/board-domain.js +0 -16
- package/dist/commands/boards/animation.d.ts +0 -2
- package/dist/commands/boards/animation.js +0 -171
- package/dist/commands/boards/appearance.d.ts +0 -2
- package/dist/commands/boards/appearance.js +0 -127
- package/dist/commands/boards/batch.d.ts +0 -4
- package/dist/commands/boards/batch.js +0 -62
- package/dist/commands/boards/connections.d.ts +0 -2
- package/dist/commands/boards/connections.js +0 -95
- package/dist/commands/boards/context.d.ts +0 -31
- package/dist/commands/boards/context.js +0 -71
- package/dist/commands/boards/items.d.ts +0 -2
- package/dist/commands/boards/items.js +0 -184
- package/dist/commands/boards/transactions.d.ts +0 -12
- 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;
|
package/dist/commands/desktop.js
CHANGED
|
@@ -2,28 +2,17 @@ import { readFileSync } from "node:fs";
|
|
|
2
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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) {
|
|
@@ -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)),
|
package/dist/commands/me.js
CHANGED
|
@@ -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.
|
|
74
|
+
table([activity.totals], [
|
|
75
75
|
{ key: "totalTokens", label: "Tokens" },
|
|
76
76
|
{ key: "costTotal", label: "Cost ($)" },
|
|
77
77
|
{ key: "requestCount", label: "Requests" },
|
package/dist/commands/public.js
CHANGED
|
@@ -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
|
-
|
|
5
|
-
return `${origin}/referrals/${code}`;
|
|
5
|
+
return webUrl(`/referrals/${code}`);
|
|
6
6
|
}
|
|
7
7
|
async function confirmRotate(opts) {
|
|
8
8
|
if (opts.yes)
|
package/dist/commands/run.js
CHANGED
|
@@ -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 <
|
|
114
|
-
cohub [-s <
|
|
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
|
|
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;
|
package/dist/commands/runtime.js
CHANGED
|
@@ -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,14 +34,16 @@ 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 <
|
|
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("
|
|
44
|
+
.option("--display [screen]", "Share a screen (default: auto when available), or xvfb[:WIDTHxHEIGHT] for a virtual one")
|
|
45
|
+
.option("--no-display", "Disable screen sharing and skip its confirmation")
|
|
46
|
+
.option("-y, --yes", "Accept defaults and authorize local execution, native sync, and screen sharing")
|
|
45
47
|
.option("--verbose", "Show diagnostic details")
|
|
46
48
|
.option("--json", "JSON output")
|
|
47
49
|
.action(async (dir, options) => {
|
|
@@ -54,7 +56,7 @@ export function registerRuntime(program) {
|
|
|
54
56
|
});
|
|
55
57
|
runtime.command("attach")
|
|
56
58
|
.description("Connect native harnesses to Cohub: install the Pi extension")
|
|
57
|
-
.option("-s, --space <
|
|
59
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
58
60
|
.option("--harness <name>", "Pi; repeatable", (value, previous) => [...previous, value], [])
|
|
59
61
|
.option("--json", "JSON output")
|
|
60
62
|
.action(async (options) => {
|
|
@@ -81,7 +83,7 @@ export function registerRuntime(program) {
|
|
|
81
83
|
});
|
|
82
84
|
runtime.command("detach")
|
|
83
85
|
.description("Pause native sync; keep all data")
|
|
84
|
-
.option("-s, --space <
|
|
86
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
85
87
|
.option("--harness <name>", "Pi or Codex; repeatable", (value, previous) => [...previous, value], [])
|
|
86
88
|
.option("--json", "JSON output")
|
|
87
89
|
.action(async (options) => {
|
|
@@ -110,7 +112,7 @@ export function registerRuntime(program) {
|
|
|
110
112
|
});
|
|
111
113
|
runtime.command("import [dir]")
|
|
112
114
|
.description("Import earlier local conversations, newest first")
|
|
113
|
-
.option("-s, --space <
|
|
115
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
114
116
|
.option("--harness <name>", "Filter by harness; repeatable", (value, previous) => [...previous, value], [])
|
|
115
117
|
.option("--session <id>", "Filter by native session ID")
|
|
116
118
|
.option("--concurrency <count>", `Conversations read in parallel, 1 to ${MAX_IMPORT_CONCURRENCY}`, String(DEFAULT_IMPORT_CONCURRENCY))
|
|
@@ -207,7 +209,7 @@ export function registerRuntime(program) {
|
|
|
207
209
|
}
|
|
208
210
|
});
|
|
209
211
|
runtime.command("status").description("Local and server status")
|
|
210
|
-
.option("-s, --space <
|
|
212
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
211
213
|
.option("--json", "JSON output")
|
|
212
214
|
.action(async (options) => {
|
|
213
215
|
try {
|
|
@@ -232,6 +234,9 @@ export function registerRuntime(program) {
|
|
|
232
234
|
else
|
|
233
235
|
process.stdout.write(`Local process Not running\nSpace ${spaceId}\nLogs ${result.diagnosticsPath}\n`);
|
|
234
236
|
process.stdout.write(`Server ${remote.error ? `Unknown — ${remote.error}` : remote.value?.online ? "Harness connected" : "Offline"}\nArchives ${pendingLocalArchives} pending · ${failedLocalArchives} failed\n`);
|
|
237
|
+
const displays = remote.value?.displays ?? [];
|
|
238
|
+
if (displays.length)
|
|
239
|
+
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
240
|
process.stdout.write(formatNativeSync(nativeSync.config, local?.native, nativeSync.error));
|
|
236
241
|
}
|
|
237
242
|
}
|
|
@@ -240,7 +245,7 @@ export function registerRuntime(program) {
|
|
|
240
245
|
}
|
|
241
246
|
});
|
|
242
247
|
runtime.command("down").description("Stop this local Runtime; retain all data")
|
|
243
|
-
.option("-s, --space <
|
|
248
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
244
249
|
.option("-y, --yes", "Stop even with unconfirmed executions")
|
|
245
250
|
.option("--json", "JSON output")
|
|
246
251
|
.action(async (options) => {
|
|
@@ -278,7 +283,7 @@ export function registerRuntime(program) {
|
|
|
278
283
|
}
|
|
279
284
|
});
|
|
280
285
|
runtime.command("logs").description("Read local Runtime diagnostics")
|
|
281
|
-
.option("-s, --space <
|
|
286
|
+
.option("-s, --space <space>", "Target Space: ID, slug, or username/slug")
|
|
282
287
|
.option("-l, --limit <count>", "Number of events", "100")
|
|
283
288
|
.option("--level <level>", "Minimum level: debug, info, warn, error", "info")
|
|
284
289
|
.option("-f, --follow", "Keep watching")
|
|
@@ -6,29 +6,8 @@ import { homedir, tmpdir } from "node:os";
|
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { pipeline } from "node:stream/promises";
|
|
8
8
|
import { Readable } from "node:stream";
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
// protocol ("1") guarantees backward compatibility.
|
|
12
|
-
//
|
|
13
|
-
// IMPORTANT: this must point at a tag whose CDN artifacts have already been
|
|
14
|
-
// published by .github/workflows/sandbox-binaries-build.yml. Only bump it AFTER
|
|
15
|
-
// that tag's publish-cdn job has succeeded, otherwise `runtime up` 404s on the
|
|
16
|
-
// default download.
|
|
17
|
-
//
|
|
18
|
-
// v2.54.0 is the first published tag with the private managed Runtime control
|
|
19
|
-
// pipe (`COHUB_RUNTIME_MANAGED` over fd 3), so `runtime up` reads connection
|
|
20
|
-
// state from the daemon instead of polling the API every five seconds. It also
|
|
21
|
-
// carries the optional workspace-search runner download. v2.53.1 already has
|
|
22
|
-
// the native FSEvents backends and the `runtimeId` control frame, and older
|
|
23
|
-
// releases stay usable through the compatibility readiness/restart path.
|
|
24
|
-
//
|
|
25
|
-
// v2.54.1 keeps the same wire protocol and adds relay diagnostics: data-channel
|
|
26
|
-
// pairing outlives the runner's dial timeout, dial failures distinguish a
|
|
27
|
-
// timeout from an explicit rejection, and teardown-time websocket write
|
|
28
|
-
// failures log at debug instead of warn. v2.55.0 republishes that compatible
|
|
29
|
-
// runner alongside the matching platform release; no new runner capability is
|
|
30
|
-
// required.
|
|
31
|
-
export const SANDBOXD_VERSION = "v2.55.0";
|
|
9
|
+
// Pin only after all platform artifacts are published to the public CDN.
|
|
10
|
+
export const SANDBOXD_VERSION = "v2.61.1";
|
|
32
11
|
const BINARY_NAME = "cohub-sandboxd";
|
|
33
12
|
// Public CDN prefix hosting the release archives (the repo is private, so the
|
|
34
13
|
// GitHub Release assets are not publicly downloadable). Overridable for staging
|
package/dist/commands/search.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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:
|
|
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
|
|
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
|
|
67
|
+
const { totals } = activity;
|
|
68
|
+
const showCost = totals.costTotal !== 0;
|
|
71
69
|
console.log(`\n Summary (last ${activity.days} days):`);
|
|
72
|
-
table([
|
|
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 }] : []),
|