@halcyonlabs/app 0.47.0-halcyon.175 → 0.47.0-halcyon.177
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/index.d.ts +6 -6
- package/dist/index.js +2 -2
- package/host-daemon/dist/bb +2 -2
- package/host-daemon/dist/bb-chunks/{browser-PXOR4X6F.js → browser-AIEWZQ3E.js} +1 -1
- package/host-daemon/dist/bb-chunks/chunk-3TWPFIL5.js +2 -0
- package/host-daemon/dist/bb-chunks/{chunk-4BCVNZDB.js → chunk-7NTHDILD.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-KB4JEVSK.js → chunk-E4PMCYEU.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-D7LYWFZN.js → chunk-EMFQWLH7.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-CQDJJOYR.js → chunk-EWMKLXY5.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-RMWILRQL.js → chunk-GQEGYNYG.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-W6JBTZU3.js → chunk-IP4KOHXR.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-ALV4J5VN.js → chunk-JW5FL5ED.js} +6 -0
- package/host-daemon/dist/bb-chunks/{chunk-D2KWU4RX.js → chunk-PZWRD3L4.js} +1 -1
- package/host-daemon/dist/bb-chunks/{chunk-DCARCNP4.js → chunk-TWGWCMWP.js} +1 -1
- package/host-daemon/dist/bb-chunks/{client-RKKQXNZ7.js → client-6NTS6UNQ.js} +1 -1
- package/host-daemon/dist/bb-chunks/{commander-errors-EZ2NMF23.js → commander-errors-L43DYZIN.js} +1 -1
- package/host-daemon/dist/bb-chunks/{context-env-EL62ZC4K.js → context-env-UIQPBRDR.js} +1 -1
- package/host-daemon/dist/bb-chunks/{context-hints-YONLOIB2.js → context-hints-JYRVPQZN.js} +1 -1
- package/host-daemon/dist/bb-chunks/{diagnostics-UXMDENSE.js → diagnostics-IWGRR5JQ.js} +1 -1
- package/host-daemon/dist/bb-chunks/{environment-F6GZH2ZS.js → environment-VU4DI2MX.js} +1 -1
- package/host-daemon/dist/bb-chunks/{file-IBKZG2L2.js → file-SA6W4GFW.js} +1 -1
- package/host-daemon/dist/bb-chunks/{guide-Q6F6N45N.js → guide-B7K2T4A7.js} +1 -1
- package/host-daemon/dist/bb-chunks/{machine-AZEA455T.js → machine-ME6PSM5J.js} +1 -1
- package/host-daemon/dist/bb-chunks/{marketplace-2YDWW3NX.js → marketplace-BU45RX2M.js} +1 -1
- package/host-daemon/dist/bb-chunks/{plugin-TJV2N7FU.js → plugin-S2VWEZRH.js} +1 -1
- package/host-daemon/dist/bb-chunks/{plugin-cli-proxy-72GJCUWQ.js → plugin-cli-proxy-DZRIWXRY.js} +1 -1
- package/host-daemon/dist/bb-chunks/{project-D5Q37M6H.js → project-HDDACRJI.js} +1 -1
- package/host-daemon/dist/bb-chunks/{prompt-history-4TVCGE4C.js → prompt-history-HSFW3YTM.js} +1 -1
- package/host-daemon/dist/bb-chunks/{provider-DW234NFS.js → provider-REPTPBZG.js} +1 -1
- package/host-daemon/dist/bb-chunks/{server-JPRTWHFW.js → server-QF4LDH5G.js} +1 -1
- package/host-daemon/dist/bb-chunks/{settings-JKLVC2XX.js → settings-6RI2TA4F.js} +1 -1
- package/host-daemon/dist/bb-chunks/{skill-XILUFL7N.js → skill-F3GMPC7V.js} +1 -1
- package/host-daemon/dist/bb-chunks/{status-YMK2HOUU.js → status-NES4Z6N4.js} +1 -1
- package/host-daemon/dist/bb-chunks/{terminal-2JYO63CF.js → terminal-G7BFWNBZ.js} +1 -1
- package/host-daemon/dist/bb-chunks/{theme-2GK2M6XU.js → theme-X5J4ACHA.js} +1 -1
- package/host-daemon/dist/bb-chunks/thread-HWDDONCT.js +29 -0
- package/host-daemon/dist/bb-chunks/{updates-5IICEDZH.js → updates-YEES76AW.js} +1 -1
- package/host-daemon/dist/bb-chunks/{voice-Z5BS2D4I.js → voice-GW5I2STS.js} +1 -1
- package/package.json +1 -1
- package/server/dist/builtin-plugins/github-pr-status/dist/server.js +5 -5
- package/server/dist/builtin-plugins/marketplace.json +1 -1
- package/server/dist/builtin-plugins/orbit/dist/assets/orbit/revision +1 -1
- package/server/dist/start-server.js +2 -2
- package/host-daemon/dist/bb-chunks/chunk-YK2XUHXL.js +0 -2
- package/host-daemon/dist/bb-chunks/thread-4CMRHEBV.js +0 -29
package/dist/index.d.ts
CHANGED
|
@@ -7456,8 +7456,8 @@ declare const hostDaemonCommandRegistry: {
|
|
|
7456
7456
|
skillFilePath: z$1.ZodString;
|
|
7457
7457
|
}, z$1.core.$strict>], "kind">>;
|
|
7458
7458
|
instructionMode: z$1.ZodEnum<{
|
|
7459
|
-
append: "append";
|
|
7460
7459
|
replace: "replace";
|
|
7460
|
+
append: "append";
|
|
7461
7461
|
}>;
|
|
7462
7462
|
type: z$1.ZodLiteral<"thread.rewind.prepare">;
|
|
7463
7463
|
leaseId: z$1.ZodString;
|
|
@@ -7605,8 +7605,8 @@ declare const hostDaemonCommandRegistry: {
|
|
|
7605
7605
|
skillFilePath: z$1.ZodString;
|
|
7606
7606
|
}, z$1.core.$strict>], "kind">>;
|
|
7607
7607
|
instructionMode: z$1.ZodEnum<{
|
|
7608
|
-
append: "append";
|
|
7609
7608
|
replace: "replace";
|
|
7609
|
+
append: "append";
|
|
7610
7610
|
}>;
|
|
7611
7611
|
type: z$1.ZodLiteral<"thread.start">;
|
|
7612
7612
|
requestId: z$1.ZodString;
|
|
@@ -8069,8 +8069,8 @@ declare const hostDaemonCommandRegistry: {
|
|
|
8069
8069
|
envPassthrough: z$1.ZodArray<z$1.ZodString>;
|
|
8070
8070
|
}, z$1.core.$strict>;
|
|
8071
8071
|
instructionMode: z$1.ZodEnum<{
|
|
8072
|
-
append: "append";
|
|
8073
8072
|
replace: "replace";
|
|
8073
|
+
append: "append";
|
|
8074
8074
|
}>;
|
|
8075
8075
|
projectId: z$1.ZodString;
|
|
8076
8076
|
providerId: z$1.ZodString;
|
|
@@ -8285,8 +8285,8 @@ declare const hostDaemonCommandRegistry: {
|
|
|
8285
8285
|
envPassthrough: z$1.ZodArray<z$1.ZodString>;
|
|
8286
8286
|
}, z$1.core.$strict>;
|
|
8287
8287
|
instructionMode: z$1.ZodEnum<{
|
|
8288
|
-
append: "append";
|
|
8289
8288
|
replace: "replace";
|
|
8289
|
+
append: "append";
|
|
8290
8290
|
}>;
|
|
8291
8291
|
projectId: z$1.ZodString;
|
|
8292
8292
|
providerId: z$1.ZodString;
|
|
@@ -9510,9 +9510,9 @@ declare const hostDaemonCommandRegistry: {
|
|
|
9510
9510
|
executablePath: z$1.ZodNullable<z$1.ZodString>;
|
|
9511
9511
|
installed: z$1.ZodBoolean;
|
|
9512
9512
|
installSource: z$1.ZodEnum<{
|
|
9513
|
-
external: "external";
|
|
9514
9513
|
notInstalled: "notInstalled";
|
|
9515
9514
|
npmGlobal: "npmGlobal";
|
|
9515
|
+
external: "external";
|
|
9516
9516
|
}>;
|
|
9517
9517
|
currentVersion: z$1.ZodNullable<z$1.ZodString>;
|
|
9518
9518
|
latestVersion: z$1.ZodNullable<z$1.ZodString>;
|
|
@@ -10061,9 +10061,9 @@ declare const providerCliStatusResponseSchema: z$1.ZodRecord<z$1.ZodString, z$1.
|
|
|
10061
10061
|
executablePath: z$1.ZodNullable<z$1.ZodString>;
|
|
10062
10062
|
installed: z$1.ZodBoolean;
|
|
10063
10063
|
installSource: z$1.ZodEnum<{
|
|
10064
|
-
external: "external";
|
|
10065
10064
|
notInstalled: "notInstalled";
|
|
10066
10065
|
npmGlobal: "npmGlobal";
|
|
10066
|
+
external: "external";
|
|
10067
10067
|
}>;
|
|
10068
10068
|
currentVersion: z$1.ZodNullable<z$1.ZodString>;
|
|
10069
10069
|
latestVersion: z$1.ZodNullable<z$1.ZodString>;
|
package/dist/index.js
CHANGED
|
@@ -23142,7 +23142,7 @@ var templateDefinitions = [
|
|
|
23142
23142
|
},
|
|
23143
23143
|
{
|
|
23144
23144
|
"id": "bbGuideJson",
|
|
23145
|
-
"body": 'JSON output\n\nEvery core command accepts --json except the plugin authoring tools (`bb plugin\nnew`, `types`, `migrate`, `build`, `dev`, `run`, `logs`, `update`). Success\nprints one JSON value on stdout and exits 0. Nothing else is written to stdout.\n\nErrors\n\nA failed command exits non-zero. With --json it prints this envelope on stdout\nand still prints the readable message on stderr:\n\n {"ok": false, "error": {"code": "unknown_option", "message": "...", "hint": "..."}}\n\n`hint` is present only when bb knows the fix: the flag to add, the nearest\ncommand or option, or the usage line. Codes for mistakes in the invocation:\nunknown_command, unknown_option, missing_required, unexpected_argument,\ninvalid_value, missing_command. A failed server request uses the server\'s error\ncode, such as thread_not_found or terminal_output_unavailable; otherwise the\ncode is http_<status> or error.\n\nParse stdout only. `2>&1` mixes the readable message into the JSON, and\n`2>/dev/null` hides it. Check the exit code, or test `.ok == false`, before\nreading fields.\n\nShapes\n\nList commands do not share one wrapper. Most print a bare array; a few wrap it.\nFields beyond those shown exist; these are the ones scripts use. The `--help` of\nthe most-parsed commands ends with the same shape.\n\n bb status --json\n {project: {id, name} | null, thread: {id, status, title, parentThreadId, environment: {hostId, display} | null} | null, childThreads: [{id, status, title}] | null, pendingTodos, pluginsNeedingAttention: [{id, status}], dataDir}\n\n bb thread list --json\n [{id, projectId, environmentId, providerId, title, status, parentThreadId, sectionId, visibility, archivedAt, pinnedAt, createdAt, updatedAt, activity}] (bare array; title can be null)\n\n bb thread show <id> --json\n {thread: {id, status, title, projectId, environmentId, parentThreadId, ...}, environment: {id, hostId, path, branchName, ...} | null, pendingTodos} (thread fields are under .thread)\n\n bb thread log <id> --json\n [{id, seq, type, createdAt, threadId, scope, data}] (bare array of raw events, oldest first; page with --after-seq <seq>); with --message: {message, before, after} of conversation rows\n\n bb thread output <id> --json\n {output}\n\n bb thread spawn ... --json\n the created thread: {id, status, title, projectId, environmentId, ...}\n\n bb thread tell <id> ... --json\n {threadId, ...delivery outcome}\n\n bb thread wait <id> --json\n {threadId, matched: true, target}\n\n bb thread count --json\n {total}\n\n bb thread search <query> --json\n {active: {total, results}, archived: {total, results}}\n\n bb prompt-history list --json\n {entries: [{id, createdAt, input, projectId, threadId, scope}], nextCursor: string | null}\n\n bb thread section list --json\n [{id, name, createdAt, updatedAt}]\n\n bb thread queue list <id> --json, bb thread interactions list <id> --json, bb thread history <id> --json\n bare arrays\n\n bb project list --json\n [{id, kind, name, gitRemoteUrl, sources: [{id, hostId, path, isDefault}]}] (bare array)\n\n bb project show <id> --json\n {id, kind, name, gitRemoteUrl, sources}\n\n bb machine list --json\n [{id, name, type, status, lifecycle, maxPermissionMode, lastSeenAt}] (bare array)\n\n bb provider list --json\n [{id, displayName, available, capabilities, reasoningLevels, serviceTiers}] (bare array)\n\n bb provider models [providerId] --json\n [{id, model, displayName, supportedReasoningEfforts, defaultReasoningEffort, supportedServiceTiers?, isDefault}] (bare array)\n\n bb environment list --json\n [{id, name, projectId, hostId, path, branchName, status, lifecycle}] (bare array)\n\n bb environment show <id> --json\n {id, name, projectId, hostId, path, branchName, baseBranch, status, lifecycle}\n\n bb terminal list --thread <id> --json\n {sessions: [{id, title, status, exitCode, closeReason, cols, rows}]} (wrapped in .sessions)\n\n bb terminal output <terminalId> --json\n {chunks: [{seq, dataBase64}], nextSeq, truncated, status, exitCode, closeReason} (chunk data is base64; status is "exited" once the command has finished)\n\n bb terminal wait <terminalId> ... --json\n {terminalId, matched, nextSeq, exitCode}\n\n bb plugin list --json\n {plugins: [{id, version, enabled, status, source, rootDir}]} (wrapped in .plugins)\n\n bb skill list --json\n {skills: [{id, name, description, scope, provider, filePath}]} (wrapped in .skills)\n\n bb marketplace list --json\n bare array\n\n bb settings show --json\n one object keyed by settings area (generalSettings, serverAccess, keybindings, experiments, appearance, ...)\n\n bb guide commands [group] --json\n {chapter, commands: [{path, aliases, arguments, options, description}]}\n\nCommands contributed by plugins document their own JSON in `bb <command> --help`\nand the plugin\'s skill.',
|
|
23145
|
+
"body": 'JSON output\n\nEvery core command accepts --json except the plugin authoring tools (`bb plugin\nnew`, `types`, `migrate`, `build`, `dev`, `run`, `logs`, `update`). Success\nprints one JSON value on stdout and exits 0. Nothing else is written to stdout.\n\nErrors\n\nA failed command exits non-zero. With --json it prints this envelope on stdout\nand still prints the readable message on stderr:\n\n {"ok": false, "error": {"code": "unknown_option", "message": "...", "hint": "..."}}\n\n`hint` is present only when bb knows the fix: the flag to add, the nearest\ncommand or option, or the usage line. Codes for mistakes in the invocation:\nunknown_command, unknown_option, missing_required, unexpected_argument,\ninvalid_value, missing_command. A failed server request uses the server\'s error\ncode, such as thread_not_found or terminal_output_unavailable; otherwise the\ncode is http_<status> or error.\n\nParse stdout only. `2>&1` mixes the readable message into the JSON, and\n`2>/dev/null` hides it. Check the exit code, or test `.ok == false`, before\nreading fields.\n\nShapes\n\nList commands do not share one wrapper. Most print a bare array; a few wrap it.\nFields beyond those shown exist; these are the ones scripts use. The `--help` of\nthe most-parsed commands ends with the same shape.\n\n bb status --json\n {project: {id, name} | null, thread: {id, status, title, parentThreadId, environment: {hostId, display} | null} | null, childThreads: [{id, status, title}] | null, pendingTodos, pluginsNeedingAttention: [{id, status}], dataDir}\n\n bb thread list --json\n [{id, projectId, environmentId, providerId, title, status, parentThreadId, sectionId, visibility, archivedAt, pinnedAt, createdAt, updatedAt, activity}] (bare array; title can be null)\n\n bb thread show <id> --json\n {thread: {id, status, title, projectId, environmentId, parentThreadId, ...}, environment: {id, hostId, path, branchName, ...} | null, pendingTodos} (thread fields are under .thread)\n\n bb thread log <id> --json\n [{id, seq, type, createdAt, threadId, scope, data}] (bare array of raw events, oldest first; page with --after-seq <seq>); with --message: {message, before, after} of conversation rows\n\n bb thread output <id> --json\n {output}\n\n bb thread spawn ... --json\n the created thread: {id, status, title, projectId, environmentId, ...}\n\n bb thread tell <id> ... --json\n {threadId, ...delivery outcome}\n\n bb thread wait <id> --json\n {threadId, matched: true, target}\n\n bb thread count --json\n {total}\n\n bb thread search <query> --json\n {active: {total, results}, archived: {total, results}}\n\n bb prompt-history list --json\n {entries: [{id, createdAt, input, projectId, threadId, scope}], nextCursor: string | null}\n\n bb thread section list --json\n [{id, name, createdAt, updatedAt}]\n\n bb thread queue list <id> --json, bb thread interactions list <id> --json, bb thread history <id> --json\n bare arrays\n\n bb project list --json\n [{id, kind, name, gitRemoteUrl, sources: [{id, hostId, path, isDefault}]}] (bare array)\n\n bb project show <id> --json\n {id, kind, name, gitRemoteUrl, sources}\n\n bb machine list --json\n [{id, name, type, status, lifecycle, maxPermissionMode, lastSeenAt}] (bare array)\n\n bb provider list --json\n [{id, displayName, available, capabilities, reasoningLevels, serviceTiers}] (bare array)\n\n bb provider models [providerId] --json\n [{id, model, displayName, supportedReasoningEfforts, defaultReasoningEffort, supportedServiceTiers?, isDefault}] (bare array)\n\n bb environment list --json\n [{id, name, projectId, hostId, path, branchName, status, lifecycle}] (bare array)\n\n bb environment show <id> --json\n {id, name, projectId, hostId, path, branchName, baseBranch, status, lifecycle}\n\n bb terminal list --thread <id> --json\n {sessions: [{id, title, status, exitCode, closeReason, cols, rows}]} (wrapped in .sessions)\n\n bb terminal output <terminalId> --json\n {chunks: [{seq, dataBase64}], nextSeq, truncated, status, exitCode, closeReason} (chunk data is base64; status is "exited" once the command has finished)\n\n bb terminal wait <terminalId> ... --json\n {terminalId, matched, nextSeq, exitCode}\n\n bb plugin list --json\n {plugins: [{id, version, enabled, status, source, rootDir}]} (wrapped in .plugins)\n\n bb skill list --json\n {skills: [{id, name, description, scope, provider, filePath}]} (wrapped in .skills)\n\n bb marketplace list --json\n bare array\n\n bb settings show --json\n one object keyed by settings area (generalSettings, serverAccess, keybindings, experiments, appearance, ...)\n\n bb guide commands [group] --json\n {chapter, commands: [{path, aliases, arguments, options, description}]}\n\nFor `bb thread log`, `--latest` reads a bounded newest-first event window and\naccepts `--types <comma-separated types>` to filter that window. These flags\nrequire JSON output; the ordinary event shape above is unchanged.\n\nCommands contributed by plugins document their own JSON in `bb <command> --help`\nand the plugin\'s skill.',
|
|
23146
23146
|
"variables": {}
|
|
23147
23147
|
},
|
|
23148
23148
|
{
|
|
@@ -23177,7 +23177,7 @@ var templateDefinitions = [
|
|
|
23177
23177
|
},
|
|
23178
23178
|
{
|
|
23179
23179
|
"id": "bbGuideThreadInspection",
|
|
23180
|
-
"body": 'Thread inspection\n\nRead-only commands take a thread ID or --self where supported.\n\nListing:\n\n bb thread list List threads\n --project <id> Filter by project\n --environment <id> Filter by environment\n --machine <id-or-name> Filter by the machine the environment is on (alias --host)\n --parent-thread <id> Filter by parent thread\n --thread <id> Only this thread; unknown or deleted IDs are left out (repeatable, up to 200)\n --archived Show only archived threads\n --section <id> Filter by section\n --unsectioned Show only threads outside sections\n --include-hidden Include hidden threads\n\n The table prints ID, Title, Project, and Status. Title uses the thread\n title, then the fallback title from the first prompt, then "-". Long\n titles are cut at 60 characters. Project shows the project name; the\n personal project shows "-". Use --json for the full thread records.\n\n bb thread search <query> [--limit <1-50>]\n Search threads and messages\n bb thread history <id> List prompt history\n\n bb thread count Count threads without listing them\n --status <status> Count threads in this status: pending, idle, starting, active, stopping, error\n --host <id> Count threads whose environment is on this machine\n --provider <id> Count threads running on this provider\n --project <id> Count threads in this project\n --parent <id|none> Count one thread\'s children, or \'none\' for threads with no parent\n --by <dimension> Group the count by host, provider, or project\n\n Counting happens in the database, so use it instead of listing threads and\n counting rows: `bb thread list` pages a bounded window and would miscount\n (SDK: `threads.count({ status, hostId, providerId, projectId, parentThreadId, groupBy })`).\n Archived, deleted, and hidden threads are excluded. Without --by the command\n prints one number; with --by it prints a count per group (threads with no\n host/provider/project group under "-") followed by the total.\n\nSections:\n\n bb thread section list\n bb thread section create <name>\n bb thread section rename <id> <name>\n bb thread section delete <id> [--yes]\n\nInspecting:\n\n bb thread context [id] Show recorded context usage and available breakdown (--self, --json)\n bb thread commands [id] List the slash commands the thread\'s agent has advertised (--self, --json)\n bb thread options [id] List the session options the agent reports, with current values (--self, --json)\n --set <option=value> Choose a value, applied on the thread\'s next turn (repeatable)\n --clear <option> Drop a choice that has not been applied yet (repeatable)\n bb thread show [id] Show thread details and pull request status\n --self Target current thread\n --work-status Include git working-tree status\n --git-diff Include git diff\n --diff-target <type> Diff scope: uncommitted, branch_committed, all, commit\n --diff-sha <sha> Commit SHA (for --diff-target commit)\n --diff-merge-base <branch> Override merge-base branch for diff\n\n Shows pull request status for the attached environment branch when available.\n\n `thread context` reads the latest stored context measurement without starting\n a provider request; `--json` prints `{ usage: ... }` (`null` when unavailable).\n Claude Code includes an estimated breakdown when available; other providers\n report totals. When the provider reports the session\'s cumulative cost,\n `usage.cost` is `{ amount, currency }`. With the `compactExpiredCache`\n experiment on, `usage.compactionOfferAt` is when the provider\'s prompt cache\n for this context expires (Claude Code and Pi report cache lifetimes); after\n it, `bb thread tell --compact-first` avoids re-reading the context uncached.\n\n `thread commands` lists the slash commands advertised for the current\n session; ACP agents and Claude Code report these live, so the list is empty\n until the agent sends one. `bb project commands` also lists Claude Code\'s\n commands before a thread starts. `thread options --set` takes `true` or `false` for an on/off\n option; `bb provider models <provider>` lists the options a model declares.\n\n bb thread log [id] Show thread event log\n --self Target current thread\n --format <format> Output format: json, minimal, verbose\n --limit <count> Max entries: events for json (oldest first, default 100);\n user-message turns for minimal/verbose (newest first, default 20, max 100)\n --after-seq <seq> Paginate after sequence number (json only)\n --all Print the whole thread, paging through every entry\n --message <seq> Print one message\n --context <count> With --message, also print this many messages around it (max 20)\n\n Human formats end with a notice when older history was omitted; --json warns\n on stderr when more events exist beyond the printed page. Human-format --all\n walks a consistent history snapshot and joins paginated group contents.\n Appends stay outside that walk; rerun the command if a history edit invalidates it.\n\n bb thread output [id] Get the final output of a thread\n --self Target current thread\n\n bb thread wait <id> Wait for a thread status or event (defaults to --status idle)\n --status <status> Wait for this status\n --event <type> Wait for this event type\n --timeout <duration> Seconds, or a duration with a unit: 90s, 20m, 4h (default: 1200s / 20 min)\n --poll-interval <duration> Milliseconds, or a duration with a unit\n\nOpening threads and files in the app:\n\n In chat, reference a thread as @thread:thr_abc123, substituting its actual ID.\n BB renders the correct project-aware link; do not construct thread URLs manually.\n (Pasting a bb thread URL into the app composer converts it to the same mention;\n CLI prompts are not converted, so use @thread:<id>.)\n Reference one message as @thread:thr_abc123#msg=42, taking the number from\n sourceSeq in `bb thread search --json`. Read it, or a copied message link\n (\u2026/threads/thr_abc123#msg=42), with `bb thread log thr_abc123 --message 42`.\n\n bb thread open <path> Open a file in the current BB thread panel\n bb thread open <thread-id> [path] Open a thread, optionally with a panel file\n --line <number> Line number to focus\n --split <placement> right, down, left, top, or replace (default)\n bb thread pane <action> [thread-id] Maximize, restore, toggle, spotlight, or clear spotlight\n\n Inside a BB thread, BB_THREAD_ID selects the current thread automatically and\n the thread ID argument is omitted for file-only opens. Outside a BB thread,\n pass the thread ID as the first argument. A thread already open in a pane is focused instead of\n duplicated. Edge placement creates panes through the eighth pane; at eight\n panes, it replaces the focused pane.\n Pane actions broadcast to connected BB app windows and affect the matching\n already-open pane without changing its split tree, and report how many\n clients received the action (SDK: `threads.paneAction({ threadId, action })`).\n Spotlight focuses that\n pane and dims the others; clear-spotlight focuses it and removes split dimming.\n The app command `pane.maximize.toggle` (default `Mod+Shift+E`) maximizes or\n restores the focused split pane and can be rebound with `bb settings keyboard set`.\n Paths can be thread-relative workspace paths, or absolute paths inside the\n target thread workspace. Absolute paths under BB_THREAD_STORAGE open as\n thread-storage files for the current thread. Use this for Markdown or HTML\n artifacts you create for the user so they open in the BB IDE.\n\nPersisted panel tabs:\n\n bb thread tabs show <thread-id>\n bb thread tabs set <thread-id> --expected-revision <n> --tabs-json \'<json>\'\n\nCore Info and Diff use plugin id `core` and tab ids `info` and `diff`. Legacy `thread-info` and `git-diff` entries convert automatically without changing their order.\n\nPinned plugin tabs use `{ "id": "plugin-fixed:<plugin-id>:<tab-id>", "kind": "plugin-fixed", "pluginId": "<plugin-id>", "tabId": "<tab-id>" }`.\nThe id encodes each plugin/tab id with percent escapes. The app shows registered,\nvisible tabs and retains saved identities while plugins are hidden or disabled.\nThe SDK uses `threads.tabs.get({ threadId })` and\n`threads.tabs.update({ threadId, expectedRevision, tabs })` for the same state.\nSelection stays local to each client. Plugin authors can find registration and\nnavigation details in the Plugin Guide\'s Thread side-panel tabs surface.',
|
|
23180
|
+
"body": 'Thread inspection\n\nRead-only commands take a thread ID or --self where supported.\n\nListing:\n\n bb thread list List threads\n --project <id> Filter by project\n --environment <id> Filter by environment\n --machine <id-or-name> Filter by the machine the environment is on (alias --host)\n --parent-thread <id> Filter by parent thread\n --thread <id> Only this thread; unknown or deleted IDs are left out (repeatable, up to 200)\n --archived Show only archived threads\n --section <id> Filter by section\n --unsectioned Show only threads outside sections\n --include-hidden Include hidden threads\n\n The table prints ID, Title, Project, and Status. Title uses the thread\n title, then the fallback title from the first prompt, then "-". Long\n titles are cut at 60 characters. Project shows the project name; the\n personal project shows "-". Use --json for the full thread records.\n\n bb thread search <query> [--limit <1-50>]\n Search threads and messages\n bb thread history <id> List prompt history\n\n bb thread count Count threads without listing them\n --status <status> Count threads in this status: pending, idle, starting, active, stopping, error\n --host <id> Count threads whose environment is on this machine\n --provider <id> Count threads running on this provider\n --project <id> Count threads in this project\n --parent <id|none> Count one thread\'s children, or \'none\' for threads with no parent\n --by <dimension> Group the count by host, provider, or project\n\n Counting happens in the database, so use it instead of listing threads and\n counting rows: `bb thread list` pages a bounded window and would miscount\n (SDK: `threads.count({ status, hostId, providerId, projectId, parentThreadId, groupBy })`).\n Archived, deleted, and hidden threads are excluded. Without --by the command\n prints one number; with --by it prints a count per group (threads with no\n host/provider/project group under "-") followed by the total.\n\nSections:\n\n bb thread section list\n bb thread section create <name>\n bb thread section rename <id> <name>\n bb thread section delete <id> [--yes]\n\nInspecting:\n\n bb thread context [id] Show recorded context usage and available breakdown (--self, --json)\n bb thread commands [id] List the slash commands the thread\'s agent has advertised (--self, --json)\n bb thread options [id] List the session options the agent reports, with current values (--self, --json)\n --set <option=value> Choose a value, applied on the thread\'s next turn (repeatable)\n --clear <option> Drop a choice that has not been applied yet (repeatable)\n bb thread show [id] Show thread details and pull request status\n --self Target current thread\n --work-status Include git working-tree status\n --git-diff Include git diff\n --diff-target <type> Diff scope: uncommitted, branch_committed, all, commit\n --diff-sha <sha> Commit SHA (for --diff-target commit)\n --diff-merge-base <branch> Override merge-base branch for diff\n\n Shows pull request status for the attached environment branch when available.\n\n `thread context` reads the latest stored context measurement without starting\n a provider request; `--json` prints `{ usage: ... }` (`null` when unavailable).\n Claude Code includes an estimated breakdown when available; other providers\n report totals. When the provider reports the session\'s cumulative cost,\n `usage.cost` is `{ amount, currency }`. With the `compactExpiredCache`\n experiment on, `usage.compactionOfferAt` is when the provider\'s prompt cache\n for this context expires (Claude Code and Pi report cache lifetimes); after\n it, `bb thread tell --compact-first` avoids re-reading the context uncached.\n\n `thread commands` lists the slash commands advertised for the current\n session; ACP agents and Claude Code report these live, so the list is empty\n until the agent sends one. `bb project commands` also lists Claude Code\'s\n commands before a thread starts. `thread options --set` takes `true` or `false` for an on/off\n option; `bb provider models <provider>` lists the options a model declares.\n\n bb thread log [id] Show thread event log\n --self Target current thread\n --format <format> Output format: json, minimal, verbose\n --limit <count> Max entries: events for json (oldest first, default 100);\n user-message turns for minimal/verbose (newest first, default 20, max 100)\n --latest Bounded newest-first raw events (json only; no --all or --after-seq)\n --types <types> Comma-separated event types; requires --latest\n --after-seq <seq> Paginate after sequence number (json only)\n --all Print the whole thread, paging through every entry\n --message <seq> Print one message\n --context <count> With --message, also print this many messages around it (max 20)\n\n Human formats end with a notice when older history was omitted; --json warns\n on stderr when more events exist beyond the printed page. Human-format --all\n walks a consistent history snapshot and joins paginated group contents.\n Appends stay outside that walk; rerun the command if a history edit invalidates it.\n\n bb thread output [id] Get the final output of a thread\n --self Target current thread\n\n bb thread wait <id> Wait for a thread status or event (defaults to --status idle)\n --status <status> Wait for this status\n --event <type> Wait for this event type\n --timeout <duration> Seconds, or a duration with a unit: 90s, 20m, 4h (default: 1200s / 20 min)\n --poll-interval <duration> Milliseconds, or a duration with a unit\n\nOpening threads and files in the app:\n\n In chat, reference a thread as @thread:thr_abc123, substituting its actual ID.\n BB renders the correct project-aware link; do not construct thread URLs manually.\n (Pasting a bb thread URL into the app composer converts it to the same mention;\n CLI prompts are not converted, so use @thread:<id>.)\n Reference one message as @thread:thr_abc123#msg=42, taking the number from\n sourceSeq in `bb thread search --json`. Read it, or a copied message link\n (\u2026/threads/thr_abc123#msg=42), with `bb thread log thr_abc123 --message 42`.\n\n bb thread open <path> Open a file in the current BB thread panel\n bb thread open <thread-id> [path] Open a thread, optionally with a panel file\n --line <number> Line number to focus\n --split <placement> right, down, left, top, or replace (default)\n bb thread pane <action> [thread-id] Maximize, restore, toggle, spotlight, or clear spotlight\n\n Inside a BB thread, BB_THREAD_ID selects the current thread automatically and\n the thread ID argument is omitted for file-only opens. Outside a BB thread,\n pass the thread ID as the first argument. A thread already open in a pane is focused instead of\n duplicated. Edge placement creates panes through the eighth pane; at eight\n panes, it replaces the focused pane.\n Pane actions broadcast to connected BB app windows and affect the matching\n already-open pane without changing its split tree, and report how many\n clients received the action (SDK: `threads.paneAction({ threadId, action })`).\n Spotlight focuses that\n pane and dims the others; clear-spotlight focuses it and removes split dimming.\n The app command `pane.maximize.toggle` (default `Mod+Shift+E`) maximizes or\n restores the focused split pane and can be rebound with `bb settings keyboard set`.\n Paths can be thread-relative workspace paths, or absolute paths inside the\n target thread workspace. Absolute paths under BB_THREAD_STORAGE open as\n thread-storage files for the current thread. Use this for Markdown or HTML\n artifacts you create for the user so they open in the BB IDE.\n\nPersisted panel tabs:\n\n bb thread tabs show <thread-id>\n bb thread tabs set <thread-id> --expected-revision <n> --tabs-json \'<json>\'\n\nCore Info and Diff use plugin id `core` and tab ids `info` and `diff`. Legacy `thread-info` and `git-diff` entries convert automatically without changing their order.\n\nPinned plugin tabs use `{ "id": "plugin-fixed:<plugin-id>:<tab-id>", "kind": "plugin-fixed", "pluginId": "<plugin-id>", "tabId": "<tab-id>" }`.\nThe id encodes each plugin/tab id with percent escapes. The app shows registered,\nvisible tabs and retains saved identities while plugins are hidden or disabled.\nThe SDK uses `threads.tabs.get({ threadId })` and\n`threads.tabs.update({ threadId, expectedRevision, tabs })` for the same state.\nSelection stays local to each client. Plugin authors can find registration and\nnavigation details in the Plugin Guide\'s Thread side-panel tabs surface.',
|
|
23181
23181
|
"variables": {}
|
|
23182
23182
|
},
|
|
23183
23183
|
{
|
package/host-daemon/dist/bb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
3
|
-
import{a as g,b as v,c as C}from"./bb-chunks/chunk-
|
|
4
|
-
`),process.exitCode=1;return}process.exit(s.status===null?1:s.status)}process.env.FORCE_COLOR!==void 0&&delete process.env.NO_COLOR;b();var m=new p;m.name("bb").description("Moonlet CLI - manage your AI coding agents").enablePositionalOptions().exitOverride().showSuggestionAfterError(!1).version(u());var O=new Set([...g.map(e=>e.name),"help"]);function A(e){let n,r=()=>n??=e.createCliRuntimeContext();return{getUrl:()=>e.resolveServerUrl(r()),getContext:()=>e.resolveContextSnapshot(r())}}async function L(e,n,r){let t=await import("./bb-chunks/plugin-cli-proxy-
|
|
3
|
+
import{a as g,b as v,c as C}from"./bb-chunks/chunk-3TWPFIL5.js";import{a as d,b as p,d as u}from"./bb-chunks/chunk-NCQMSH7M.js";import"./bb-chunks/chunk-5PWLIQO6.js";import{spawnSync as _}from"node:child_process";import{realpathSync as R}from"node:fs";import{resolve as S,win32 as B}from"node:path";var f="BB_CLI_REEXEC";function I(e){return e.platform==="win32"&&B.extname(e.target)===""?{command:e.nodePath,args:[e.target,...e.argv]}:{command:e.target,args:e.argv}}function x(e){try{return R(S(e))}catch{return null}}function b(e={}){let n=e.env??process.env;if(n[f]==="1")return;let r=n.BB_CLI?.trim();if(!r)return;let t=e.currentExecutablePath??process.argv[1];if(!t)return;let o=x(r),a=x(t);if(o===null||a===null||o===a)return;let i=e.argv??process.argv.slice(2),c={...n,[f]:"1"};if(e.reexec){e.reexec({target:o,argv:i,env:c});return}let l=I({argv:i,nodePath:process.execPath,platform:process.platform,target:o}),s=_(l.command,l.args,{env:c,stdio:"inherit"});if(s.error){process.stderr.write(`Moonlet: failed to re-exec BB_CLI=${o}: ${s.error.message}
|
|
4
|
+
`),process.exitCode=1;return}process.exit(s.status===null?1:s.status)}process.env.FORCE_COLOR!==void 0&&delete process.env.NO_COLOR;b();var m=new p;m.name("bb").description("Moonlet CLI - manage your AI coding agents").enablePositionalOptions().exitOverride().showSuggestionAfterError(!1).version(u());var O=new Set([...g.map(e=>e.name),"help"]);function A(e){let n,r=()=>n??=e.createCliRuntimeContext();return{getUrl:()=>e.resolveServerUrl(r()),getContext:()=>e.resolveContextSnapshot(r())}}async function L(e,n,r){let t=await import("./bb-chunks/plugin-cli-proxy-DZRIWXRY.js"),o=await t.fetchPluginCliContributions(n());if(o.outcome==="unreachable"){if(r)return;let s=t.describeUnreachableServer(n(),o.cause,o.lastTimeoutMs,o.attempts);console.error(s);let{isJsonInvocation:E,writeCliErrorEnvelope:y}=await import("./bb-chunks/cli-error-output-KERMGTKZ.js");y({code:"server_unreachable",hint:null,message:s},E(process.argv)),process.exit(1)}if(o.outcome==="invalid")return;let a=t.findPluginCliCommand(o.contributions,e);if(a===void 0){let s=await t.findDisabledPluginForCommand(n(),e);s!==null&&(console.error(`bb ${e} is provided by the "${s}" plugin, which is disabled \u2014 run \`bb plugin enable ${s}\` or enable it in Plugins.`),process.exit(1));return}let i=process.argv.slice(3),c=a.commands.find(s=>s.name===i[0]);c!==void 0&&a.rendersHelp!==!0&&i.slice(1).some(s=>s==="--help"||s==="-h")&&(console.log(c.usage),process.exit(0));let l=await t.runPluginCliCommand(n(),a.pluginId,i);l!==0&&await w({code:"plugin_command_failed",command:t.pluginCommandLabel(a,i),exitCode:l,token:null}),process.exit(l)}async function w(e){let[{appendCliErrorLogEntry:n},{commandPathLabel:r}]=await Promise.all([import("./bb-chunks/cli-error-log-PHJFENHA.js"),import("./bb-chunks/commander-errors-L43DYZIN.js")]);n({at:new Date().toISOString(),cliVersion:u(),code:e.code,command:e.command??r(m,process.argv),exitCode:e.exitCode,threadId:process.env.BB_THREAD_ID??null,token:e.token})}async function P(e,n){e.exitCode===0&&process.exit(0);let[r,t]=await Promise.all([import("./bb-chunks/commander-errors-L43DYZIN.js"),import("./bb-chunks/context-hints-JYRVPQZN.js")]),o=await r.summarizeCommanderError({argv:process.argv,error:e,program:m,resolveHostId:n===null?async()=>null:t.createContextHostIdResolver(n)});r.writeCommanderErrorSummary(o,process.argv),await w({code:o.code,command:null,exitCode:e.exitCode,token:o.logToken}),process.exit(e.exitCode)}async function h(e){try{await m.parseAsync(process.argv)}catch(n){throw n instanceof d&&await P(n,e),n}}async function M(e){let n=await import("./bb-chunks/command-resolution-U7GVB5KQ.js");if(!n.hasHelpFlag(process.argv))return;let r=n.resolveInvocation(m,process.argv);if(r.unknownSubcommand===null)return;let t=`error: unknown command '${r.unknownSubcommand}'`;console.error(t),await P(new d(1,"commander.unknownCommand",t),e)}async function k(){let[{JSON_SHAPE_BY_COMMAND_PATH:e,jsonShapeHelp:n},r]=await Promise.all([import("./bb-chunks/json-shapes-TGDCNQZQ.js"),import("./bb-chunks/command-resolution-U7GVB5KQ.js")]);for(let t of Object.keys(e)){let o=r.resolveInvocation(m,["node","bb",...t.split(" ")]),a=n(t);a===null||o.path.join(" ")!==t||o.command.addHelpText("after",a)}}async function D(){let e=process.argv[2],n=v(e);if(n.length===0){await h(null);return}let[r,...t]=await Promise.all([import("./bb-chunks/context-env-UIQPBRDR.js"),...n.map(i=>i.load())]),o=A(r);m.addHelpText("after",()=>{let i=o.getContext(),c=i.projectId??"<unset>",l=i.threadId??"<unset>";return`
|
|
5
5
|
|
|
6
6
|
Current context:
|
|
7
7
|
BB_PROJECT_ID: ${c}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{j as a}from"./chunk-
|
|
2
|
+
import{j as a}from"./chunk-EMFQWLH7.js";import"./chunk-NCQMSH7M.js";import"./chunk-WWZ7D6EQ.js";import{b as I}from"./chunk-EWMKLXY5.js";import"./chunk-JW5FL5ED.js";import"./chunk-VLWNZSJS.js";import"./chunk-E4PMCYEU.js";import"./chunk-G5CP5ERL.js";import"./chunk-TWGWCMWP.js";import"./chunk-E7J2DJY7.js";import{a as r}from"./chunk-BNG7SSF7.js";import"./chunk-5PWLIQO6.js";import{writeFile as y}from"node:fs/promises";var x=["chrome","chromium","helium","edge","brave","vivaldi","opera","arc","dia","firefox","zen","safari"],h=r.union([r.enum(x),r.string().regex(/^storage-[a-f0-9]{64}$/)]),k=r.enum(["notInstalled","needsKeychainApproval","keychainItemMissing","needsFullDiskAccess","browserRunning","unsupportedPlatform"]),B=r.enum([...k.options,"keychainUnavailable","unknownSource","unknownSourceProfile","readFailed"]),g=r.string().min(1).max(4096),v=r.object({directory:g,name:r.string().min(1).max(256),cookieCount:r.number().int().nonnegative().optional()}).strict(),T=r.object({id:h,name:r.string().min(1).max(64),profiles:r.array(v).max(100),unavailable:k.optional(),icon:r.string().max(256*1024).regex(/^data:image\/[a-z+]+;base64,/u).optional()}).strict(),E=r.object({sourceId:h,sourceProfileDirectory:g}),D=r.object({imported:r.number().int().nonnegative(),skipped:r.number().int().nonnegative(),skippedDomains:r.array(r.string().max(1024)).max(20)}).strict(),j=r.discriminatedUnion("ok",[D.extend({ok:r.literal(!0)}).strict(),r.object({ok:r.literal(!1),reason:B}).strict()]),R={notInstalled:"Not installed on this machine.",needsKeychainApproval:"Needs Keychain access to read its cookie encryption key. Approve the prompt and try again.",keychainItemMissing:"No matching encryption key was found in your Keychain. Open and sign in to the source browser, then try again. Browsers with custom key names may need additional support.",needsFullDiskAccess:"Give BB Full Disk Access in System Settings \u2192 Privacy & Security, then try again.",browserRunning:"Quit the browser first so its cookie database can be read.",unsupportedPlatform:"Importing from this browser isn't possible on this platform."},S={...R,keychainUnavailable:"The system keyring could not be reached. Make sure it is running and unlocked, then try again.",unknownSource:"That browser is no longer available to import from.",unknownSourceProfile:"That browser profile no longer exists.",readFailed:"The browser's cookie database could not be read."};function p(n){return{hostId:n.host,instanceId:n.instance,generation:n.generation,threadId:n.thread}}function O(n){return n.requiredOption("--host <id>","Browser host ID").requiredOption("--instance <id>","Desktop window instance ID").requiredOption("--generation <id>","Desktop connection generation").option("--json","Print machine-readable JSON output")}function $(n){return n.sources.map(s=>{let i=s.unavailable??"ready",o=s.profiles.map(e=>`${e.directory}${e.name===e.directory?"":` "${e.name}"`}${e.cookieCount===void 0?"":` (${e.cookieCount})`}`).join(", ");return`${s.id} ${i} ${o}`.trimEnd()}).join(`
|
|
3
3
|
`)||"No importable browsers found"}function P(n){if(!n.ok)return`Import failed: ${S[n.reason]}`;let l=n.skipped>0?`, skipped ${n.skipped}${n.skippedDomains.length>0?` (${n.skippedDomains.join(", ")})`:""}`:"";return`Imported ${n.imported} cookies${l}`}function d(n){return n.requiredOption("--host <id>","Browser host ID").requiredOption("--instance <id>","Desktop window instance ID").requiredOption("--generation <id>","Desktop connection generation").requiredOption("--thread <id>","Owning thread ID").option("--json","Print machine-readable JSON output")}function c(n,l,s){console.log(l.json?JSON.stringify(n):s)}function _(n,l){let s=n.command("browser").description("Experimental built-in desktop browser control"),i=()=>I(l()).experimental_desktopBrowsers;s.command("instances").description("List connected desktop windows on a host").requiredOption("--host <id>","Browser host ID").option("--json","Print machine-readable JSON output").action(a(async o=>{let e=await i().listInstances({hostId:o.host});c(e,o,e.instances.map(t=>`${t.instanceId} ${t.generation} ${t.label}`).join(`
|
|
4
4
|
`)||"No connected desktop windows")})),d(s.command("tabs").description("List a thread's native browser tabs")).action(a(async o=>{let e=await i().listTabs(p(o));c(e,o,e.tabs.map(t=>`${t.tabId} ${t.title||t.url} ${t.control?.controllerLabel??"Available"}`).join(`
|
|
5
5
|
`)||"No browser tabs in this thread")})),d(s.command("create").description("Create a tab in the Moonlet browser profile")).option("--url <url>","Initial HTTP(S) URL; defaults to about:blank").option("--reveal","Show the new native tab").action(a(async o=>{let e=await i().createTab({...p(o),...o.url===void 0?{}:{url:o.url},...o.reveal?{presentation:"reveal"}:{}});c(e,o,`Created tab ${e.tab.tabId}`)})),d(s.command("acquire <tabIds...>").description("Acquire exclusive, expiring control of selected tabs")).requiredOption("--controller <label>","Visible controller name").option("--ttl-ms <ms>","Lease duration; defaults to five minutes, maximum thirty").action(a(async(o,e)=>{let t=await i().acquireControl({...p(e),tabIds:o,controllerLabel:e.controller,...e.ttlMs===void 0?{}:{ttlMs:Number(e.ttlMs)}});c(t,e,`Control lease ${t.leaseId} expires ${new Date(t.expiresAt).toISOString()}`)})),d(s.command("connection <leaseId>").description("Write private CDP connection JSON to a new local file")).requiredOption("--output <file>","New credential file (mode 0600); endpoint works only on browser host").action(a(async(o,e)=>{let t=await i().openConnection({...p(e),leaseId:o});await y(e.output,JSON.stringify(t),{mode:384,flag:"wx"}),c({path:e.output,hostId:t.hostId,expiresAt:t.expiresAt},e,`Wrote private connection to ${e.output}`)})),d(s.command("release <leaseId>").description("Stop automation and keep tabs open")).action(a(async(o,e)=>{c(await i().releaseControl({...p(e),leaseId:o}),e,"Released browser control")}));for(let o of["reveal","close"])d(s.command(`${o} <tabId>`).description(o==="close"?"Close a native tab":"Reveal a native tab in its desktop window")).action(a(async(e,t)=>{let m={...p(t),tabId:e};c(await(o==="close"?i().closeTab(m):i().revealTab(m)),t,`${o==="close"?"Closed":"Revealed"} tab ${e}`)}));d(s.command("capture <tabId>").description("Save a native tab screenshot without focusing it")).requiredOption("--output <file>","New local JPEG file").action(a(async(o,e)=>{let t=await i().captureTab({...p(e),tabId:o});await y(e.output,Buffer.from(t.base64,"base64"),{flag:"wx",mode:384}),c({path:e.output,mimeType:t.mimeType},e,`Saved screenshot to ${e.output}`)})),O(s.command("import-sources").description("List browsers on the desktop host whose cookies can be imported")).action(a(async o=>{let e=await i().listImportSources({hostId:o.host,instanceId:o.instance,generation:o.generation});c(e,o,$(e))})),O(s.command("import-cookies").description("Copy signed-in cookies from an installed browser into the Moonlet browser")).requiredOption("--from <source>","Source browser ID from `bb browser import-sources`").requiredOption("--profile <directory>","Source profile directory as printed by `bb browser import-sources`").action(a(async o=>{let e=await i().importCookies({hostId:o.host,instanceId:o.instance,generation:o.generation,sourceId:h.parse(o.from),sourceProfileDirectory:o.profile});c(e,o,P(e)),e.ok||(process.exitCode=1)})),d(s.command("watch").description("Print changed tab snapshots every two seconds until interrupted")).action(a(async o=>{await new Promise((e,t)=>{let m=i().subscribe({...p(o),onChange:b=>c(b,o,b.tabs.map(w=>`${w.tabId} ${w.title||w.url} ${w.control?.controllerLabel??"Available"}`).join(`
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
+
function o(e,r,t){return{name:e,load:()=>r().then(t)}}var m=[o("browser",()=>import("./browser-AIEWZQ3E.js"),e=>(r,t)=>e.registerBrowserCommands(r,t.getUrl)),o("status",()=>import("./status-NES4Z6N4.js"),e=>(r,t)=>e.registerStatusCommand(r,t.getUrl,t.getContext)),o("settings",()=>import("./settings-6RI2TA4F.js"),e=>(r,t)=>e.registerSettingsCommands(r,t.getUrl)),o("project",()=>import("./project-HDDACRJI.js"),e=>(r,t)=>e.registerProjectCommands(r,t.getUrl)),o("prompt-history",()=>import("./prompt-history-HSFW3YTM.js"),e=>(r,t)=>e.registerPromptHistoryCommands(r,t.getUrl)),o("provider",()=>import("./provider-REPTPBZG.js"),e=>(r,t)=>e.registerProviderCommands(r,t.getUrl)),o("machine",()=>import("./machine-ME6PSM5J.js"),e=>(r,t)=>e.registerMachineCommands(r,t.getUrl)),o("server",()=>import("./server-QF4LDH5G.js"),e=>(r,t)=>e.registerServerCommands(r,t.getUrl)),o("updates",()=>import("./updates-YEES76AW.js"),e=>(r,t)=>e.registerUpdatesCommands(r,t.getUrl)),o("terminal",()=>import("./terminal-G7BFWNBZ.js"),e=>(r,t)=>e.registerTerminalCommands(r,t.getUrl)),o("thread",()=>import("./thread-HWDDONCT.js"),e=>(r,t)=>e.registerThreadCommands(r,t.getUrl)),o("environment",()=>import("./environment-VU4DI2MX.js"),e=>(r,t)=>e.registerEnvironmentCommands(r,t.getUrl)),o("file",()=>import("./file-SA6W4GFW.js"),e=>(r,t)=>e.registerFileCommands(r,t.getUrl)),o("theme",()=>import("./theme-X5J4ACHA.js"),e=>(r,t)=>e.registerThemeCommands(r,t.getUrl)),o("plugin",()=>import("./plugin-S2VWEZRH.js"),e=>(r,t)=>e.registerPluginCommands(r,t.getUrl)),o("marketplace",()=>import("./marketplace-BU45RX2M.js"),e=>(r,t)=>e.registerMarketplaceCommands(r,t.getUrl)),o("skill",()=>import("./skill-F3GMPC7V.js"),e=>(r,t)=>e.registerSkillCommands(r,t.getUrl,t.getContext)),o("guide",()=>import("./guide-B7K2T4A7.js"),e=>r=>e.registerGuideCommand(r)),o("diagnostics",()=>import("./diagnostics-IWGRR5JQ.js"),e=>r=>e.registerDiagnosticsCommands(r)),o("voice",()=>import("./voice-GW5I2STS.js"),e=>(r,t)=>e.registerVoiceCommands(r,t.getUrl))];function n(e){if(e==="--version"||e==="-V")return[];let r=m.find(t=>t.name===e);return r===void 0?m:[r]}function i(e,r){return e===void 0||e.length===0||e.startsWith("-")||r.has(e)?null:e}export{m as a,n as b,i as c};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{da as n}from"./chunk-
|
|
2
|
+
import{da as n}from"./chunk-JW5FL5ED.js";var o;async function e(){if(o===void 0&&(o=await n()),!o)throw new Error("Cannot reach local host daemon. Is it running?");return o}export{e as a};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{c as t,d as s}from"./chunk-G5CP5ERL.js";import{i as d}from"./chunk-
|
|
2
|
+
import{c as t,d as s}from"./chunk-G5CP5ERL.js";import{i as d}from"./chunk-TWGWCMWP.js";var n=class extends Error{code;hint;constructor(r){super(r.message),this.name="CliUsageError",this.code=r.code,this.hint=r.hint}};var l=/^[a-zA-Z0-9_-]+$/;function f(e={}){return{cliConfig:e.cliConfig??s()}}function i(e,r){if(!l.test(e))throw new Error(`Invalid ID from ${r}: "${e}". IDs must contain only letters, digits, hyphens, and underscores.`);return e}function p(e){return e.cliConfig.BB_SERVER_URL}function g(){let e=t(process.env.BB_PROJECT_ID);if(e)return i(e,"BB_PROJECT_ID")}function a(){let e=t(process.env.BB_THREAD_ID);if(e)return i(e,"BB_THREAD_ID")}function u(e){let r=t(e.value);if(r)return i(r,e.flagName)}function x(e){let r=u({flagName:"<threadId> argument",value:e});if(r)return r;throw new Error("Missing thread ID. Pass <threadId>.")}function E(e,r){if(r.self&&e)throw new Error("Cannot combine a thread ID argument with --self.");if(r.self){let o=a();if(!o)throw new Error("--self requires BB_THREAD_ID to be set.");return o}if(e)return i(e,"<threadId> argument");throw new n({code:"missing_required",hint:d(),message:"Missing thread ID. Pass <threadId> or use --self."})}function R(e=f()){return{projectId:g(),threadId:a(),serverUrl:e.cliConfig.BB_SERVER_URL}}export{n as a,f as b,p as c,g as d,a as e,u as f,x as g,E as h,R as i};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{b as l,d as x}from"./chunk-NCQMSH7M.js";import{a as p,c as g,d as h,e as E}from"./chunk-WWZ7D6EQ.js";import{ba as f}from"./chunk-
|
|
2
|
+
import{b as l,d as x}from"./chunk-NCQMSH7M.js";import{a as p,c as g,d as h,e as E}from"./chunk-WWZ7D6EQ.js";import{ba as f}from"./chunk-JW5FL5ED.js";import{d,e as m}from"./chunk-VLWNZSJS.js";import{a as c}from"./chunk-E4PMCYEU.js";import{createInterface as w}from"node:readline/promises";var A=d;function $(n,o){return n.json?(console.log(JSON.stringify(o,null,2)),h(),!0):!1}function D(n,o){return[...o,n]}function J(n){n.source==="env"&&console.error(`Thread ${n.id} (from BB_THREAD_ID)`)}async function P(n){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Refusing destructive action without an interactive terminal. Re-run with --yes to confirm.");let o=w({input:process.stdin,output:process.stdout});try{let e=(await o.question(`${n} [y/N] `)).trim().toLowerCase();return e==="y"||e==="yes"}finally{o.close()}}function u(n){if(!(n instanceof Error))return String(n);let o=new Set,r=[],e=[n];for(;e.length>0;){let t=e.pop();if(t===void 0||o.has(t))continue;o.add(t),t.message.length>0&&r.push(t.message);let i=[];t.cause instanceof Error&&i.push(t.cause),t instanceof AggregateError&&i.push(...t.errors.filter(s=>s instanceof Error));for(let s=i.length-1;s>=0;s-=1)e.push(i[s])}return r.join(": ")}function B(n){if(n===void 0)return;let o=m.safeParse(n);if(o.success)return o.data;throw new Error(`Invalid reasoning level '${n}'. Expected a level id the model lists, such as ${y(A)}.`)}function _(n,o){return new Error(`${n}: ${u(o)}`)}function y(n){return n.map(o=>`'${o}'`).join(" or ")}var a=class extends Error{code;exitCode;hint;constructor(o,r,e={code:"error",hint:null}){super(o),this.name="CliExitError",this.code=e.code,this.exitCode=r,this.hint=e.hint}};function z(n){return async(...o)=>{g();try{await n(...o)}catch(r){if(R(r))throw r;let e=r instanceof a?r.exitCode:1,t=r instanceof a?r.message:u(r),i=r instanceof c||r instanceof a?r.hint:null,s=v(r);console.error(`Error: ${t}`),i!==null&&console.error(i),E({code:s,hint:i,message:t},T(o)),await I({code:s,command:b(o),exitCode:e}),process.exit(e)}}}function v(n){return n instanceof c||n instanceof a?n.code:n instanceof f?n.code??`http_${n.status}`:"error"}function C(n){let o=n[n.length-1];return o instanceof l?o:null}function T(n){let o=C(n);if(o===null)return p();let r=o.opts();return r.json===!0||r.format==="json"}function b(n){let o=C(n);if(o===null)return"";let r=[];for(let e=o;e!==null&&e.parent!==null;e=e.parent)r.unshift(e.name());return r.join(" ")}async function I(n){try{let{appendCliErrorLogEntry:o}=await import("./cli-error-log-PHJFENHA.js");o({at:new Date().toISOString(),cliVersion:x(),code:n.code,command:n.command,exitCode:n.exitCode,threadId:process.env.BB_THREAD_ID??null,token:null})}catch{}}function R(n){return n instanceof Error&&n.message.startsWith("process.exit:")}export{$ as a,D as b,J as c,P as d,u as e,B as f,_ as g,y as h,a as i,z as j};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{ca as t}from"./chunk-
|
|
2
|
+
import{ca as t}from"./chunk-JW5FL5ED.js";function r(e,i){return fetch(e,i)}function c(e){return t({baseUrl:e,fetch:r})}export{r as a,c as b};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{W as i}from"./chunk-
|
|
2
|
+
import{W as i}from"./chunk-JW5FL5ED.js";async function l(n){if(n.environmentProviderId===null)return{status:"loaded",provider:null};let o=(await n.sdk.environments.listProviders()).find(r=>r.id===n.environmentProviderId);return{status:"loaded",provider:o===void 0?null:{id:o.id,displayName:o.displayName,icon:o.icon}}}async function p(n){try{let e=await n.sdk.environments.get({environmentId:n.environmentId});return{display:i({environment:e,host:{locality:"local",identity:null},providerLookup:await l({environmentProviderId:e.environmentProviderId,sdk:n.sdk})}),hostId:e.hostId}}catch{return null}}function u(n){console.log(` Environment: ${n.display.modeLabel} (${n.display.id})`)}async function v(n){try{return(await n.sdk.threads.timeline({threadId:n.threadId,summaryOnly:"true"})).pendingTodos}catch{return null}}var m={in_progress:"[>]",pending:"[ ]",completed:"[x]"},d={in_progress:0,pending:1,completed:2};function a(n){let e=0;for(let o of n)o.status==="completed"&&(e+=1);return{completed:e,total:n.length}}function f(n){if(!n||n.items.length===0)return;let e=a(n.items);console.log("");let o=e.completed===0?`TODOs (${e.total}):`:`TODOs (${e.completed}/${e.total} done):`;console.log(o);let r=[...n.items].sort((t,s)=>d[t.status]-d[s.status]);for(let t of r)console.log(` ${m[t.status]} ${t.text}`)}export{p as a,u as b,v as c,f as d};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module";import { dirname as __pathDirname } from "node:path";import { fileURLToPath as __fileURLToPath } from "node:url";const require = __createRequire(import.meta.url);const __filename = __fileURLToPath(import.meta.url);const __dirname = __pathDirname(__filename);
|
|
2
|
-
import{c as T,d as _}from"./chunk-XSBF3HQR.js";import{a as p,d as H,i as P,j as l}from"./chunk-
|
|
2
|
+
import{c as T,d as _}from"./chunk-XSBF3HQR.js";import{a as p,d as H,i as P,j as l}from"./chunk-EMFQWLH7.js";import{b as h}from"./chunk-EWMKLXY5.js";import{b as R}from"./chunk-VLWNZSJS.js";import{b as D}from"./chunk-G5CP5ERL.js";import{a as u}from"./chunk-BNG7SSF7.js";function $(t,n){if(!p(n,t)){console.log(`Built-in GitHub: ${t.builtInGit.status} \u2014 ${t.builtInGit.statusMessage}`);for(let o of t.variables)console.log(`${o.name}=${o.secret?"[secret]":o.value}${o.note?` (${o.note})`:""}`)}}async function G(){if(process.stdin.isTTY)throw new Error("Pipe the value to stdin; environment values are never accepted in command arguments.");let t=[],n=0;for await(let o of process.stdin){let s=Buffer.isBuffer(o)?o:Buffer.from(o);if(n+=s.byteLength,n>65536)throw new Error("Environment value exceeds 65536 bytes.");t.push(s)}return Buffer.concat(t).toString("utf8").replace(/\r?\n$/u,"")}function A(t,n){let o=t.command("env").description("Configure global or project machine environment variables");o.command("list").option("--project <id>","Show this project's overrides and inherited global variables").option("--json","Print machine-readable JSON output").action(l(async s=>{let e=h(n()),i=s.project?await e.projects.machineEnvironment({projectId:s.project}):{...await e.system.machineEnvironment(),inheritedVariables:[]};if($(i,s),!s.json&&s.project)for(let a of i.inheritedVariables){let r=i.variables.some(c=>c.name===a.name);console.log(`${a.name}=[secret] (Global${r?"; overridden by project":"; inherited"})`)}})),o.command("set <NAME>").description("Read a value from stdin; remove one trailing newline").option("--project <id>","Set an override for this project").option("--note <text>","Describe this variable").option("--json","Print machine-readable JSON output").action(l(async(s,e)=>{let i=h(n()),a={name:s,value:await G(),note:e.note??null};$(e.project?await i.projects.setMachineEnvironmentVariable({...a,projectId:e.project}):await i.system.setMachineEnvironmentVariable(a),e)})),o.command("unset <NAME>").option("--project <id>","Remove this project's override and restore inheritance").option("--json","Print machine-readable JSON output").action(l(async(s,e)=>{let i=h(n());$(e.project?await i.projects.deleteMachineEnvironmentVariable({projectId:e.project,name:s}):await i.system.deleteMachineEnvironmentVariable({name:s}),e)}))}import{execFile as K}from"node:child_process";import{promisify as Y}from"node:util";import{randomUUID as Z}from"node:crypto";import{mkdir as B,readFile as Q,rename as X,rm as ee,writeFile as ne,symlink as te,access as oe}from"node:fs/promises";import{homedir as ie,hostname as re}from"node:os";import{join as f,resolve as F}from"node:path";import{createServer as ae}from"node:net";var z=u.string().url().refine(t=>{let n=new URL(t);return["http:","https:"].includes(n.protocol)&&!n.username&&!n.password&&!n.search&&!n.hash}),se=u.strictObject({hostId:u.string().min(1),serverUrl:z,headers:u.record(u.string(),u.string()).optional(),credential:u.string().min(1),expiresAt:u.number().finite().positive(),reconnect:u.literal(!0).optional(),dataDir:u.string().min(1).optional()}),x=u.looseObject({serverUrl:z.optional(),serverHeaders:u.record(u.string(),u.string()).optional()}),N=u.object({hostId:u.string().min(1),hostKey:u.string().min(1)});function j(t){let n=new URL(t);return n.hostname==="localhost"&&(n.hostname="127.0.0.1"),n.href.replace(/\/+$/u,"")}async function b(t){try{return await Q(t,"utf8")}catch(n){if(n instanceof Error&&"code"in n&&n.code==="ENOENT")return null;throw new Error("Could not read machine identity state")}}async function J(t,n){let o=`${t}.${Z()}.tmp`;try{await ne(o,n,{mode:384,flag:"wx"}),await X(o,t)}finally{await ee(o,{force:!0})}}async function ce(t){let n=f(t,"host-daemon-port");if(await b(n)!==null)return;let o=ae();try{await new Promise((e,i)=>{o.once("error",i),o.listen(0,"127.0.0.1",e)});let s=o.address();if(s===null||typeof s=="string")throw new Error("Could not choose a machine daemon port");await J(n,`${s.port}
|
|
3
3
|
`)}finally{o.listening&&await new Promise(s=>o.close(()=>s()))}}async function U(t,n={}){let o=n.env??process.env;if(!!t.bootstrapFile==!!t.bootstrapEnv)throw new Error("Specify exactly one of --bootstrap-file or --bootstrap-env");let s;if(t.bootstrapEnv){if(!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(t.bootstrapEnv))throw new Error("Invalid bootstrap environment variable name");let m=o[t.bootstrapEnv];if(!m)throw new Error("Bootstrap environment variable is empty");s=m,delete o[t.bootstrapEnv]}else{let m=await b(t.bootstrapFile);if(m===null)throw new Error("Bootstrap file was not found");s=m}let e;try{e=se.parse(JSON.parse(s))}catch{throw new Error("Invalid machine enrollment bootstrap")}let i=n.homeDir??ie(),a=j(e.serverUrl),r=F(o.BB_DATA_DIR??e.dataDir??f(i,".bb-machines",new URL(e.serverUrl).host.replace(/[^a-zA-Z0-9.-]/gu,"-")));if(r===F(i,".bb")&&(await b(f(r,"host-id")))?.trim()!==e.hostId)throw new Error("Machine enrollment cannot use the default Moonlet data directory");let c=await b(f(r,"auth.json"));if(c!==null){let m,y;try{m=N.parse(JSON.parse(c)),y=x.parse(JSON.parse(await b(f(r,"config.json"))??"{}"))}catch{throw new Error("Invalid persisted machine identity")}let k=(await b(f(r,"host-id")))?.trim();if(m.hostId!==e.hostId||k&&k!==e.hostId||y.serverUrl&&j(y.serverUrl)!==a)throw new Error("Refusing to overwrite a different machine identity");if(!y.serverUrl)throw new Error("Persisted machine server identity is missing");if(!e.reconnect)return{hostId:m.hostId}}else if(e.reconnect&&(await b(f(r,"host-id")))?.trim()!==e.hostId)throw new Error(`Machine ${e.hostId} is not installed in ${r} on this computer; run the command on the computer where it runs`);await B(r,{recursive:!0,mode:448});let d,w;try{d=x.parse(JSON.parse(await b(f(r,"config.json"))??"{}"));let m=await b(f(r,"auth.json"));w=m===null?null:N.parse(JSON.parse(m))}catch{throw new Error("Invalid persisted machine identity")}let v=(await b(f(r,"host-id")))?.trim();if(w&&w.hostId!==e.hostId||v&&v!==e.hostId||d.serverUrl&&j(d.serverUrl)!==a)throw new Error("Refusing to overwrite a different machine identity");async function E(){await ce(r);let m=f(r,"npm","bin","bb-app");try{await oe(m)}catch{let y=await Y(K)("sh",["-c","command -v bb-app"],{env:o}).catch(()=>null);y?.stdout.trim()&&(await B(f(r,"npm","bin"),{recursive:!0}),await te(y.stdout.trim(),m))}}if(w&&!e.reconnect){if(!d.serverUrl)throw new Error("Persisted machine server identity is missing");return await E(),{hostId:w.hostId}}if(e.expiresAt<=Date.now())throw new Error("Machine enrollment bootstrap has expired");let O=n.fetchFn??fetch,M=AbortSignal.timeout(6e4),I=f(r,"config.json");d=await D({path:I,read:async()=>x.parse(JSON.parse(await b(I)??"{}")),mutate:m=>{if(m.serverUrl&&j(m.serverUrl)!==a)throw new Error("Refusing to overwrite a different machine identity");let y={...m,serverUrl:a,serverHeaders:e.headers};return delete y.machineCredential,delete y.connectMachineId,y}}),await J(f(r,"host-id"),`${e.hostId}
|
|
4
4
|
`),await E();let S;try{let m=await O(new URL("/internal/hosts/enroll",a),{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.credential}`,...d.serverHeaders},body:JSON.stringify({hostId:e.hostId,hostName:re()}),signal:M});if(m.status!==201)throw new Error;S=N.parse(await m.json())}catch{throw new Error("Could not exchange machine enrollment credential")}if(S.hostId!==e.hostId)throw new Error("Enrollment returned a different machine identity");return await J(f(r,"auth.json"),`${JSON.stringify(S)}
|
|
5
5
|
`),{hostId:S.hostId}}function de(t){return t===null?"This command expires once it is used.":`This command expires at ${new Date(t).toLocaleTimeString()}.`}var L=15*6e4,q=500;async function C(t){let n=t.host,o=Date.now()+L;for(;n.lifecycle.phase!==t.targetPhase;){let s=n.lifecycle.message;if(s?.startsWith("Machine suspension failed:")||s?.startsWith("Machine resume failed:"))throw new Error(s);if(n.lifecycle.phase==="removing"||n.lifecycle.phase==="destroyed")throw new Error(n.lifecycle.message??`Machine entered the ${n.lifecycle.phase} phase`);if(Date.now()>=o)throw new Error(`Timed out after ${L/1e3} seconds waiting for machine ${n.id} to become ${t.targetPhase}`);await new Promise(e=>setTimeout(e,q)),n=await t.getHost()}return n}function V(t){let n=t.trim();if(n.length===0)throw new Error("provider ID must not be empty.");return n}function W(t){return t.length===0?"none":t.map(n=>`${n.name} (${n.id})`).join(", ")}function De(t,n){return n==="all"?[...t]:t.filter(o=>o.type!=="ephemeral")}function me(t,n){let o=n.trim(),s=t.find(i=>i.id===o);if(s)return s.id;let e=t.filter(i=>i.name===o);if(e.length===1)return e[0].id;throw e.length>1?new Error(`Machine name '${o}' is ambiguous. Matches: ${W(e)}.`):new Error(`Machine '${o}' was not found. Available machines: ${W(t)}.`)}function le(t){if(t.machine&&t.host)throw new Error("Cannot combine --machine with --host.");return t.machine??t.host}async function He(t,n){let o=le(t);if(o!==void 0&&t.environment!==void 0)throw new Error("Cannot combine --machine or --host with --environment; the environment already selects its machine.");return t.environment!==void 0?{environmentId:t.environment}:o!==void 0?{hostId:await g({serverUrl:n,target:o})}:{}}function he(t,n=Date.now()){if(t===null)return"never";let o=Math.max(0,n-t),s=60*1e3,e=60*s,i=24*e;return o<s?"just now":o<e?`${Math.floor(o/s)}m ago`:o<i?`${Math.floor(o/e)}h ago`:`${Math.floor(o/i)}d ago`}async function g(t){let n=await h(t.serverUrl).hosts.list({includeCreating:!0}),o=me(n,t.target);if(t.requireConnected&&n.find(s=>s.id===o)?.status!=="connected")throw new Error(`Machine '${t.target.trim()}' is disconnected.`);return o}function Te(t,n){let o=t.command("machine").description("Inspect execution machines");A(o,n),o.command("enroll").description("Enroll this machine using a private bootstrap bundle").option("--bootstrap-file <path>","Read the bootstrap bundle from a file").option("--bootstrap-env <name>","Consume the bootstrap bundle from an environment variable").option("--json","Print machine-readable JSON output").action(l(async e=>{let i=await U(e);p(e,i)||console.log(`Machine ${i.hostId} enrolled`)})),o.command("join-code",{hidden:!0}).description("Compatibility notice for removed machine join codes").option("--json","Print machine-readable JSON output").action(l(async()=>{throw new P("bb machine join-code has been removed.",1,{code:"removed_command",hint:"Use `bb machine create --provider manual` and run the printed enrollment command."})})),o.command("create").description("Create a machine using an installed provider").option("--no-wait","Return the creating host ID immediately").requiredOption("--provider <id>","Machine provider ID").option("--key <idempotency-key>","Reuse a stable key when retrying creation").option("--inputs <JSON>","Provider inputs as JSON").option("--json","Print machine-readable JSON output").action(l(async e=>{let i=V(e.provider),a=e.key?.trim();if(a==="")throw new Error("Creation key must not be empty.");let r=null;if(e.inputs!==void 0)try{r=R.parse(JSON.parse(e.inputs))}catch{throw new Error("--inputs must be valid JSON.")}let c=new AbortController,d=()=>c.abort();process.once("SIGINT",d);try{let w=h(n());c.signal.throwIfAborted();let v=await w.hosts.experimental_create({machineProviderId:i,inputs:r,...a===void 0?{}:{key:a},wait:!1,signal:c.signal});if(!e.wait){p(e,v)||console.log(v.id);return}let E=!1,O=async M=>{if(E||M.lifecycle.phase!=="creating")return;let I=await w.hosts.experimental_getEnrollmentCommand({hostId:M.id,signal:c.signal});I!==null&&(console.error("On macOS or Linux, run:"),console.error(I.command),console.error("On Windows, run in PowerShell:"),console.error(I.windowsCommand),console.error(de(I.expiresAt)),E=!0)};await O(v),console.error(`Following machine ${v.id}`),v=await C({host:v,targetPhase:"active",getHost:async()=>{let M=await w.hosts.get({hostId:v.id,signal:c.signal});return await O(M),M}}),p(e,v)||console.log(`Machine ${v.name} created`)}catch(w){throw c.signal.aborted?new P("Stopped following; creation continues. Use bb machine remove <host-id> to cancel.",130):w}finally{process.off("SIGINT",d)}})),o.command("providers").description("List installed machine providers").option("--json","Print machine-readable JSON output").action(l(async e=>{let i=await h(n()).hosts.experimental_listProviders();if(!p(e,i)){if(i.length===0){console.log("No machine providers found");return}console.log(i.map(a=>`${a.id} ${a.displayName}`).join(`
|
|
@@ -455,6 +455,10 @@ the most-parsed commands ends with the same shape.
|
|
|
455
455
|
bb guide commands [group] --json
|
|
456
456
|
{chapter, commands: [{path, aliases, arguments, options, description}]}
|
|
457
457
|
|
|
458
|
+
For \`bb thread log\`, \`--latest\` reads a bounded newest-first event window and
|
|
459
|
+
accepts \`--types <comma-separated types>\` to filter that window. These flags
|
|
460
|
+
require JSON output; the ordinary event shape above is unchanged.
|
|
461
|
+
|
|
458
462
|
Commands contributed by plugins document their own JSON in \`bb <command> --help\`
|
|
459
463
|
and the plugin's skill.`,variables:{}},{id:"bbGuideMachines",body:`Machine commands
|
|
460
464
|
|
|
@@ -1662,6 +1666,8 @@ Inspecting:
|
|
|
1662
1666
|
--format <format> Output format: json, minimal, verbose
|
|
1663
1667
|
--limit <count> Max entries: events for json (oldest first, default 100);
|
|
1664
1668
|
user-message turns for minimal/verbose (newest first, default 20, max 100)
|
|
1669
|
+
--latest Bounded newest-first raw events (json only; no --all or --after-seq)
|
|
1670
|
+
--types <types> Comma-separated event types; requires --latest
|
|
1665
1671
|
--after-seq <seq> Paginate after sequence number (json only)
|
|
1666
1672
|
--all Print the whole thread, paging through every entry
|
|
1667
1673
|
--message <seq> Print one message
|