@halcyonlabs/app 0.47.0-halcyon.305 → 0.47.0-halcyon.307

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/index.d.ts +13 -13
  2. package/dist/index.js +1 -1
  3. package/host-daemon/dist/bb +2 -2
  4. package/host-daemon/dist/bb-chunks/{browser-CVGXUZIV.js → browser-AW5NKOND.js} +1 -1
  5. package/host-daemon/dist/bb-chunks/{chunk-O73WIYXN.js → chunk-2UXPXE2O.js} +1 -1
  6. package/host-daemon/dist/bb-chunks/{chunk-H2GY2N34.js → chunk-43VNS4QN.js} +1 -1
  7. package/host-daemon/dist/bb-chunks/chunk-CUJIB3FP.js +2 -0
  8. package/host-daemon/dist/bb-chunks/{chunk-QM6PHIQZ.js → chunk-HFESVZFF.js} +1 -1
  9. package/host-daemon/dist/bb-chunks/{chunk-EYZ2F3MM.js → chunk-K3TVW7MY.js} +1 -1
  10. package/host-daemon/dist/bb-chunks/{chunk-2CWSZFY7.js → chunk-SQPEPTGH.js} +1 -1
  11. package/host-daemon/dist/bb-chunks/{chunk-HCNN7UUL.js → chunk-VD753ECW.js} +1 -1
  12. package/host-daemon/dist/bb-chunks/{chunk-ICMMFTQP.js → chunk-W65ZRVTI.js} +1 -1
  13. package/host-daemon/dist/bb-chunks/{chunk-RJVNJ5XG.js → chunk-WJ756L4Q.js} +1 -1
  14. package/host-daemon/dist/bb-chunks/{chunk-PBRIL5OS.js → chunk-YBX55DE3.js} +1 -0
  15. package/host-daemon/dist/bb-chunks/{client-UV35D27E.js → client-AMEEMEF5.js} +1 -1
  16. package/host-daemon/dist/bb-chunks/{commander-errors-XLIZJOBF.js → commander-errors-NRLKCJHU.js} +1 -1
  17. package/host-daemon/dist/bb-chunks/{context-env-UEOAPE5B.js → context-env-DE2TLSQE.js} +1 -1
  18. package/host-daemon/dist/bb-chunks/{context-hints-PD24GE3A.js → context-hints-MDGUPKZ6.js} +1 -1
  19. package/host-daemon/dist/bb-chunks/{diagnostics-GPVRLMTJ.js → diagnostics-YHUPWZ2T.js} +1 -1
  20. package/host-daemon/dist/bb-chunks/{environment-QLNVPGZF.js → environment-WQORWGQT.js} +1 -1
  21. package/host-daemon/dist/bb-chunks/{file-ZZDVWAF7.js → file-V7DY5ID3.js} +1 -1
  22. package/host-daemon/dist/bb-chunks/{guide-UUJYDFIU.js → guide-NUYU7AGL.js} +1 -1
  23. package/host-daemon/dist/bb-chunks/{machine-YVURE6XR.js → machine-OWISQOWF.js} +1 -1
  24. package/host-daemon/dist/bb-chunks/{marketplace-2BWPNJU4.js → marketplace-CLSHYVNQ.js} +1 -1
  25. package/host-daemon/dist/bb-chunks/{permissions-UTWDUFI5.js → permissions-M32AWSBZ.js} +1 -1
  26. package/host-daemon/dist/bb-chunks/{plugin-6JKVXXRM.js → plugin-NWOGIHXO.js} +1 -1
  27. package/host-daemon/dist/bb-chunks/{plugin-cli-proxy-MTUKPES7.js → plugin-cli-proxy-W2UN4MSW.js} +1 -1
  28. package/host-daemon/dist/bb-chunks/{project-2M4727TR.js → project-HFNYH3RY.js} +1 -1
  29. package/host-daemon/dist/bb-chunks/{prompt-history-U6W4PCPN.js → prompt-history-CRGEJYCN.js} +1 -1
  30. package/host-daemon/dist/bb-chunks/{provider-CV5BWCSE.js → provider-QJNRA32S.js} +1 -1
  31. package/host-daemon/dist/bb-chunks/{schedule-CPPHUOWV.js → schedule-RWX3CLQX.js} +1 -1
  32. package/host-daemon/dist/bb-chunks/{server-5RORPSPH.js → server-6ZZ2AEVB.js} +1 -1
  33. package/host-daemon/dist/bb-chunks/{settings-UGO74N7P.js → settings-SRE5MGIO.js} +1 -1
  34. package/host-daemon/dist/bb-chunks/{skill-AO4D53MF.js → skill-KU3TQ7KZ.js} +1 -1
  35. package/host-daemon/dist/bb-chunks/{status-BCEAJTK5.js → status-XKUKCDWF.js} +1 -1
  36. package/host-daemon/dist/bb-chunks/{terminal-IKCT2IM4.js → terminal-C6XHWK6K.js} +1 -1
  37. package/host-daemon/dist/bb-chunks/{theme-FCUVQRCU.js → theme-E7TJEQZX.js} +1 -1
  38. package/host-daemon/dist/bb-chunks/{thread-UFGV2AEQ.js → thread-ULIWXZ6H.js} +10 -10
  39. package/host-daemon/dist/bb-chunks/{updates-CHUEMDVN.js → updates-B3DMRLW6.js} +1 -1
  40. package/host-daemon/dist/bb-chunks/{voice-ORHDMTAV.js → voice-UG35FOEO.js} +1 -1
  41. package/package.json +1 -1
  42. package/server/dist/builtin-plugins/orbit/dist/assets/assets/orbit-guidance/manifest.json +4 -0
  43. package/server/dist/builtin-plugins/orbit/dist/assets/assets/orbit-guidance/starter/plugins/orbit/front/context-core.md +3 -0
  44. package/server/dist/builtin-plugins/orbit/dist/assets/orbit/revision +1 -1
  45. package/server/dist/builtin-plugins/orbit/dist/server.js +274 -274
  46. package/server/dist/start-server.js +1 -1
  47. package/host-daemon/dist/bb-chunks/chunk-UW6DMUGP.js +0 -2
package/dist/index.d.ts CHANGED
@@ -83,8 +83,8 @@ declare const appSettingsSchema: z$1.ZodObject<{
83
83
  providerOrder: z$1.ZodArray<z$1.ZodString>;
84
84
  defaultProviderId: z$1.ZodNullable<z$1.ZodString>;
85
85
  providerCompletedTurnDisplay: z$1.ZodRecord<z$1.ZodString, z$1.ZodEnum<{
86
- collapse: "collapse";
87
86
  flat: "flat";
87
+ collapse: "collapse";
88
88
  }>>;
89
89
  streamerMode: z$1.ZodBoolean;
90
90
  allowFastServiceTier: z$1.ZodBoolean;
@@ -105,8 +105,8 @@ declare const appSettingsUpdateSchema: z$1.ZodUnion<readonly [z$1.ZodObject<{
105
105
  providerOrder: z$1.ZodArray<z$1.ZodString>;
106
106
  defaultProviderId: z$1.ZodNullable<z$1.ZodString>;
107
107
  providerCompletedTurnDisplay: z$1.ZodRecord<z$1.ZodString, z$1.ZodEnum<{
108
- collapse: "collapse";
109
108
  flat: "flat";
109
+ collapse: "collapse";
110
110
  }>>;
111
111
  streamerMode: z$1.ZodBoolean;
112
112
  managedBranchPrefix: z$1.ZodString;
@@ -143,8 +143,8 @@ declare const appSettingsUpdateSchema: z$1.ZodUnion<readonly [z$1.ZodObject<{
143
143
  providerOrder: z$1.ZodArray<z$1.ZodString>;
144
144
  defaultProviderId: z$1.ZodNullable<z$1.ZodString>;
145
145
  providerCompletedTurnDisplay: z$1.ZodRecord<z$1.ZodString, z$1.ZodEnum<{
146
- collapse: "collapse";
147
146
  flat: "flat";
147
+ collapse: "collapse";
148
148
  }>>;
149
149
  streamerMode: z$1.ZodBoolean;
150
150
  machineServerUrl: z$1.ZodNullable<z$1.ZodString>;
@@ -191,10 +191,10 @@ declare const uiPreferenceDefinitions: {
191
191
  }>>;
192
192
  readonly "sidebar.threadGrouping.environment": UiPreferenceDefinition<z$1.ZodUnion<readonly [z$1.ZodLiteral<"auto">, z$1.ZodBoolean]>>;
193
193
  readonly "sidebar.chronologicalSort": UiPreferenceDefinition<z$1.ZodEnum<{
194
- none: "none";
195
194
  updated: "updated";
196
195
  created: "created";
197
196
  alpha: "alpha";
197
+ none: "none";
198
198
  }>>;
199
199
  readonly "sidebar.sortDirection": UiPreferenceDefinition<z$1.ZodEnum<{
200
200
  default: "default";
@@ -4240,8 +4240,8 @@ declare const providerInfoSchema: z$1.ZodObject<{
4240
4240
  }, z$1.core.$strip>;
4241
4241
  }, z$1.core.$strip>], "kind">>;
4242
4242
  completedTurnDisplay: z$1.ZodEnum<{
4243
- collapse: "collapse";
4244
4243
  flat: "flat";
4244
+ collapse: "collapse";
4245
4245
  }>;
4246
4246
  available: z$1.ZodBoolean;
4247
4247
  strings: z$1.ZodOptional<z$1.ZodObject<{
@@ -4329,8 +4329,8 @@ declare const threadTimelinePendingTodosSchema: z$1.ZodObject<{
4329
4329
  type ThreadTimelinePendingTodos = z$1.infer<typeof threadTimelinePendingTodosSchema>;
4330
4330
 
4331
4331
  declare const threadParentNotificationsSchema: z$1.ZodEnum<{
4332
- off: "off";
4333
4332
  auto: "auto";
4333
+ off: "off";
4334
4334
  stuck: "stuck";
4335
4335
  }>;
4336
4336
  type ThreadParentNotifications = z$1.infer<typeof threadParentNotificationsSchema>;
@@ -5766,9 +5766,9 @@ declare const hostDaemonCommandRegistry: {
5766
5766
  }, z$1.core.$strict>, z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
5767
5767
  kind: z$1.ZodLiteral<"wording">;
5768
5768
  status: z$1.ZodEnum<{
5769
+ unavailable: "unavailable";
5769
5770
  pass: "pass";
5770
5771
  revise: "revise";
5771
- unavailable: "unavailable";
5772
5772
  }>;
5773
5773
  }, z$1.core.$strict>, z$1.ZodObject<{
5774
5774
  kind: z$1.ZodLiteral<"review">;
@@ -6129,8 +6129,8 @@ declare const hostDaemonCommandRegistry: {
6129
6129
  skillFilePath: z$1.ZodString;
6130
6130
  }, z$1.core.$strict>], "kind">>;
6131
6131
  instructionMode: z$1.ZodEnum<{
6132
- replace: "replace";
6133
6132
  append: "append";
6133
+ replace: "replace";
6134
6134
  }>;
6135
6135
  type: z$1.ZodLiteral<"thread.rewind.prepare">;
6136
6136
  leaseId: z$1.ZodString;
@@ -6278,8 +6278,8 @@ declare const hostDaemonCommandRegistry: {
6278
6278
  skillFilePath: z$1.ZodString;
6279
6279
  }, z$1.core.$strict>], "kind">>;
6280
6280
  instructionMode: z$1.ZodEnum<{
6281
- replace: "replace";
6282
6281
  append: "append";
6282
+ replace: "replace";
6283
6283
  }>;
6284
6284
  type: z$1.ZodLiteral<"thread.start">;
6285
6285
  requestId: z$1.ZodString;
@@ -6742,8 +6742,8 @@ declare const hostDaemonCommandRegistry: {
6742
6742
  envPassthrough: z$1.ZodArray<z$1.ZodString>;
6743
6743
  }, z$1.core.$strict>;
6744
6744
  instructionMode: z$1.ZodEnum<{
6745
- replace: "replace";
6746
6745
  append: "append";
6746
+ replace: "replace";
6747
6747
  }>;
6748
6748
  projectId: z$1.ZodString;
6749
6749
  providerId: z$1.ZodString;
@@ -6958,8 +6958,8 @@ declare const hostDaemonCommandRegistry: {
6958
6958
  envPassthrough: z$1.ZodArray<z$1.ZodString>;
6959
6959
  }, z$1.core.$strict>;
6960
6960
  instructionMode: z$1.ZodEnum<{
6961
- replace: "replace";
6962
6961
  append: "append";
6962
+ replace: "replace";
6963
6963
  }>;
6964
6964
  projectId: z$1.ZodString;
6965
6965
  providerId: z$1.ZodString;
@@ -8184,8 +8184,8 @@ declare const hostDaemonCommandRegistry: {
8184
8184
  installed: z$1.ZodBoolean;
8185
8185
  installSource: z$1.ZodEnum<{
8186
8186
  notInstalled: "notInstalled";
8187
- npmGlobal: "npmGlobal";
8188
8187
  external: "external";
8188
+ npmGlobal: "npmGlobal";
8189
8189
  }>;
8190
8190
  currentVersion: z$1.ZodNullable<z$1.ZodString>;
8191
8191
  latestVersion: z$1.ZodNullable<z$1.ZodString>;
@@ -8735,8 +8735,8 @@ declare const providerCliStatusResponseSchema: z$1.ZodRecord<z$1.ZodString, z$1.
8735
8735
  installed: z$1.ZodBoolean;
8736
8736
  installSource: z$1.ZodEnum<{
8737
8737
  notInstalled: "notInstalled";
8738
- npmGlobal: "npmGlobal";
8739
8738
  external: "external";
8739
+ npmGlobal: "npmGlobal";
8740
8740
  }>;
8741
8741
  currentVersion: z$1.ZodNullable<z$1.ZodString>;
8742
8742
  latestVersion: z$1.ZodNullable<z$1.ZodString>;
package/dist/index.js CHANGED
@@ -23281,7 +23281,7 @@ var templateDefinitions = [
23281
23281
  },
23282
23282
  {
23283
23283
  "id": "bbGuideThreadInspection",
23284
- "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.',
23284
+ "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 --before-seq <seq> Page older events before this exclusive cursor; 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.',
23285
23285
  "variables": {}
23286
23286
  },
23287
23287
  {
@@ -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-UW6DMUGP.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-MTUKPES7.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-XLIZJOBF.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-XLIZJOBF.js"),import("./bb-chunks/context-hints-PD24GE3A.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-UEOAPE5B.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`
3
+ import{a as g,b as v,c as C}from"./bb-chunks/chunk-CUJIB3FP.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-W2UN4MSW.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-NRLKCJHU.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-NRLKCJHU.js"),import("./bb-chunks/context-hints-MDGUPKZ6.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-DE2TLSQE.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-EYZ2F3MM.js";import"./chunk-NCQMSH7M.js";import"./chunk-WWZ7D6EQ.js";import{b as I}from"./chunk-2CWSZFY7.js";import"./chunk-PBRIL5OS.js";import"./chunk-VLWNZSJS.js";import"./chunk-ICMMFTQP.js";import"./chunk-G5CP5ERL.js";import"./chunk-H2GY2N34.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(`
2
+ import{j as a}from"./chunk-K3TVW7MY.js";import"./chunk-NCQMSH7M.js";import"./chunk-WWZ7D6EQ.js";import{b as I}from"./chunk-SQPEPTGH.js";import"./chunk-YBX55DE3.js";import"./chunk-VLWNZSJS.js";import"./chunk-W65ZRVTI.js";import"./chunk-G5CP5ERL.js";import"./chunk-43VNS4QN.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(`