@super-one/cli 0.67.0-alpha → 0.67.0-alpha.2

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/MANIFEST.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@super-one/cli",
3
- "version": "0.67.0-alpha",
3
+ "version": "0.67.0-alpha.2",
4
4
  "kind": "npm",
5
5
  "minNodeMajor": 20,
6
- "builtAt": "2026-09-15T09:05:55.894Z"
6
+ "builtAt": "2026-09-16T16:24:48.589Z"
7
7
  }
package/lib/cli.mjs CHANGED
@@ -359,7 +359,7 @@ var init_interaction_memory = __esm({
359
359
  });
360
360
 
361
361
  // ../../packages/shared/src/superone-tool-descriptions.ts
362
- var MANUAL_READ_DESCRIPTION, SETUP_MINI_APP_DEV_DESCRIPTION, REGISTER_DEV_MINIAPP_DESCRIPTION, PACK_MINI_APP_DESCRIPTION, UPDATE_SUPERONE_TYPES_DESCRIPTION, RENAME_SESSION_DESCRIPTION, SESSION_TAG_DESCRIPTION, SESSION_TAG_LIST_DESCRIPTION, PROJECT_LIST_DESCRIPTION, SESSION_LIST_DESCRIPTION, SESSION_SEARCH_DESCRIPTION, SESSION_READ_DESCRIPTION, SESSION_TAGS_FILTER_DESCRIPTION, SESSION_TAG_MATCH_DESCRIPTION, SESSION_CLEANUP_DESCRIPTION, CONFIG_READ_DESCRIPTION, CONFIG_APPLY_DESCRIPTION, LIST_MEDIA_PROVIDERS_DESCRIPTION, GENERATE_IMAGE_DESCRIPTION, GENERATE_VIDEO_DESCRIPTION, VIDEO_STATUS_DESCRIPTION, SESSION_LIST_AGENTS_DESCRIPTION, SESSION_REQUEST_AGENTS_DESCRIPTION, LAUNCH_SUMMARY_DESCRIPTION, LAUNCH_TASK_DESCRIPTION, LAUNCH_MODE_DESCRIPTION, LAUNCH_SESSION_ID_DESCRIPTION, LAUNCH_PERMISSION_MODE_DESCRIPTION, LAUNCH_CWD_DESCRIPTION, LAUNCH_WORKTREE_DESCRIPTION, LAUNCH_BRANCH_NAME_DESCRIPTION, SESSION_START_DESCRIPTION, SESSION_SEND_DESCRIPTION, SESSION_RETRIEVE_DESCRIPTION, AUTOMATION_LIST_DESCRIPTION, AUTOMATION_APPLY_DESCRIPTION, AUTOMATION_DELETE_DESCRIPTION;
362
+ var MANUAL_READ_DESCRIPTION, SETUP_MINI_APP_DEV_DESCRIPTION, REGISTER_DEV_MINIAPP_DESCRIPTION, PACK_MINI_APP_DESCRIPTION, UPDATE_SUPERONE_TYPES_DESCRIPTION, RENAME_SESSION_DESCRIPTION, SESSION_TAG_DESCRIPTION, SESSION_TAG_LIST_DESCRIPTION, PROJECT_LIST_DESCRIPTION, SESSION_LIST_DESCRIPTION, SESSION_SEARCH_DESCRIPTION, SESSION_READ_DESCRIPTION, SESSION_TAGS_FILTER_DESCRIPTION, SESSION_TAG_MATCH_DESCRIPTION, SESSION_CLEANUP_DESCRIPTION, CONFIG_READ_DESCRIPTION, CONFIG_APPLY_DESCRIPTION, LIST_MEDIA_PROVIDERS_DESCRIPTION, GENERATE_IMAGE_DESCRIPTION, GENERATE_VIDEO_DESCRIPTION, VIDEO_STATUS_DESCRIPTION, SESSION_LIST_AGENTS_DESCRIPTION, SESSION_REQUEST_AGENTS_DESCRIPTION, LAUNCH_SUMMARY_DESCRIPTION, LAUNCH_TASK_DESCRIPTION, LAUNCH_MODE_DESCRIPTION, LAUNCH_SESSION_ID_DESCRIPTION, LAUNCH_PERMISSION_MODE_DESCRIPTION, LAUNCH_CWD_DESCRIPTION, LAUNCH_WORKTREE_DESCRIPTION, LAUNCH_BRANCH_NAME_DESCRIPTION, SESSION_START_DESCRIPTION, SESSION_SEND_DESCRIPTION, SESSION_RETRIEVE_DESCRIPTION, AUTOMATION_LIST_DESCRIPTION, AUTOMATION_APPLY_DESCRIPTION, AUTOMATION_DELETE_DESCRIPTION, TERMINAL_TABS_DESCRIPTION, TERMINAL_SNAPSHOT_DESCRIPTION, TERMINAL_ACT_DESCRIPTION, TERMINAL_WAIT_FOR_DESCRIPTION;
363
363
  var init_superone_tool_descriptions = __esm({
364
364
  "../../packages/shared/src/superone-tool-descriptions.ts"() {
365
365
  "use strict";
@@ -400,6 +400,10 @@ var init_superone_tool_descriptions = __esm({
400
400
  AUTOMATION_LIST_DESCRIPTION = "List project automations with schedule and last/next run. Pass id for full prompt, agentConfig, and schedule; filter by query or enabled. Find unknown ids here before automation_apply or automation_delete; check for duplicates before creation when needed.";
401
401
  AUTOMATION_APPLY_DESCRIPTION = 'Create or update a project automation. create needs name, prompt, schedule; update needs id plus any field (pause via enabled=false). Call automation_list first for ids; remove with automation_delete. Always opens a user confirmation dialog and applies nothing without approval. For schedule and agentConfig shapes see read_manual({ domain: "product", topic: "automation" }).';
402
402
  AUTOMATION_DELETE_DESCRIPTION = "Permanently delete project automations by id (from automation_list). Always opens a user confirmation dialog. Current project only. Prefer automation_list to choose ids first.";
403
+ TERMINAL_TABS_DESCRIPTION = "Manage activity-panel terminal tabs for long-lived or interactive processes: dev servers, watch modes, REPLs, TUIs, ssh, wizards. One-shot commands (build, test, git) belong in your shell tool. action=list (default) returns this session's tabs plus the user's as a TOON table; other sessions' tabs are hidden. action=run asks to approve `command`, types it into a new or idle tab, and returns the screen; you control the tab only while that command is in the foreground. action=attach asks to control a command already running in a user tab. action=close kills a tab you opened, never one the user is using. Follow with terminal_act / terminal_wait_for / terminal_snapshot.";
404
+ TERMINAL_SNAPSHOT_DESCRIPTION = "Read a terminal tab as rendered text. `include` picks sections: screen (visible rows, default), scrollback (last `tail` lines including scrolled-off output), cursor, meta (title, cwd, status, foreground command, control). Use screen for prompts and full-screen programs, scrollback for server logs. Output over the tail cap is spilled to a file and returned as path + preview. Prefer this before terminal_act; use terminal_wait_for instead of polling.";
405
+ TERMINAL_ACT_DESCRIPTION = 'Send input to a terminal tab you control. actions is an array, e.g. [{type:"type",text:"yes"}] or [{type:"key",key:"Ctrl+C"}]; types: type (Enter by default), key (Enter, Tab, Escape, Up, Ctrl+C, F1\u2026), raw, resize, wait. ONE action per call by default; batch 2\u201320 only for an uninterruptible sequence (answer a wizard). Fail-fast. expect holds the call open until a screen condition is met (text, textGone, idleMs, exited); the screen after the batch is returned. Rejected with status=rejected when the approved command has exited or the user took over \u2014 do not retry, call terminal_tabs run again or ask. description is shown to the user instead of raw keystrokes.';
406
+ TERMINAL_WAIT_FOR_DESCRIPTION = "Block until a terminal tab reaches a state; conditions AND-combine: text (substring visible on screen or in new output), textGone, idleMs (no output for that long), exited (foreground command finished). Use after terminal_tabs run or terminal_act when output arrives asynchronously (a server banner, a build finishing). timeoutMs default 15000, max 120000. Do not sleep+poll with terminal_snapshot yourself.";
403
407
  }
404
408
  });
405
409
 
@@ -2786,7 +2790,7 @@ var WIDGET_SHOW_DESCRIPTION;
2786
2790
  var init_widget_tool_descriptions = __esm({
2787
2791
  "../../packages/shared/src/generative-ui/widget-tool-descriptions.ts"() {
2788
2792
  "use strict";
2789
- WIDGET_SHOW_DESCRIPTION = `Render SVG, diagrams, charts, or interactive HTML inline in chat. Pass widget_code for new content, or template + data to reuse a saved template. To show media you produced yourself, pass a @native/* template so it renders in SuperOne's own gallery (viewer, download, drag-out) instead of a lookalike you build in widget_code \u2014 call widget_list_templates for the list. To hand the user several files to look at one after another (screenshots, reports, changed sources), pass @native/files-previewer with data.files. Before the first new widget in a session, load the relevant design modules with read_manual({ domain: "widget", modules: [...] }).`;
2793
+ WIDGET_SHOW_DESCRIPTION = `Render SVG, diagrams, charts, interactive HTML, or a SuperOne native surface (media gallery, files previewer) inline in chat. Pass widget_code for new content, or template + data to reuse a saved template. To show media you produced yourself, pass a @native/* template so it renders in SuperOne's own gallery (viewer, download, drag-out) instead of a lookalike you build in widget_code \u2014 call widget_list_templates for the list. To hand the user several files to look at one after another (screenshots, reports, changed sources), pass @native/files-previewer with data.files. Before the first new widget in a session, load the relevant design modules with read_manual({ domain: "widget", modules: [...] }).`;
2790
2794
  }
2791
2795
  });
2792
2796
 
@@ -3622,6 +3626,132 @@ var init_host_action_browser_perf_descriptors = __esm({
3622
3626
  }
3623
3627
  });
3624
3628
 
3629
+ // ../../packages/shared/src/environment/host-action-terminal-descriptors.ts
3630
+ var TERMINAL_WAIT_CONDITION_PROPERTIES, TERMINAL_ACTION_INPUT_SCHEMA, HOST_ACTION_TERMINAL_DESCRIPTORS;
3631
+ var init_host_action_terminal_descriptors = __esm({
3632
+ "../../packages/shared/src/environment/host-action-terminal-descriptors.ts"() {
3633
+ "use strict";
3634
+ init_superone_tool_descriptions();
3635
+ TERMINAL_WAIT_CONDITION_PROPERTIES = {
3636
+ text: { type: "string", description: "Substring that must appear on screen or in recent output." },
3637
+ textGone: { type: "string", description: "Substring that must be absent from the screen." },
3638
+ idleMs: { type: "number", description: "No output for this many milliseconds." },
3639
+ exited: { type: "boolean", description: "The controlled command has left the foreground (or the tab exited)." }
3640
+ };
3641
+ TERMINAL_ACTION_INPUT_SCHEMA = {
3642
+ type: "object",
3643
+ description: "type: text (+Enter unless enter=false) \xB7 key: named key (Enter, Tab, Escape, Up, Ctrl+C, Alt+b, F1\u2026) with optional repeat \xB7 raw: bytes verbatim \xB7 resize: cols/rows \xB7 wait: ms (\u22645000, inside a batch).",
3644
+ properties: {
3645
+ type: { type: "string", enum: ["type", "key", "raw", "resize", "wait"] },
3646
+ text: { type: "string" },
3647
+ enter: { type: "boolean", description: "type only. Default true." },
3648
+ key: { type: "string" },
3649
+ repeat: { type: "number", description: "key only. 1\u2013100." },
3650
+ bytes: { type: "string" },
3651
+ cols: { type: "number" },
3652
+ rows: { type: "number" },
3653
+ ms: { type: "number" }
3654
+ },
3655
+ required: ["type"],
3656
+ additionalProperties: false
3657
+ };
3658
+ HOST_ACTION_TERMINAL_DESCRIPTORS = [
3659
+ {
3660
+ name: "terminal_tabs",
3661
+ description: TERMINAL_TABS_DESCRIPTION,
3662
+ inputSchema: {
3663
+ type: "object",
3664
+ properties: {
3665
+ action: { type: "string", enum: ["list", "run", "attach", "close"], description: "Default list." },
3666
+ tab: {
3667
+ type: ["string", "array"],
3668
+ items: { type: "string" },
3669
+ minItems: 1,
3670
+ description: "Tab id from list. run: reuse this idle tab instead of opening one. attach/close: the target (close accepts an array)."
3671
+ },
3672
+ command: { type: "string", description: "run only. The command the user approves and that is typed into the shell." },
3673
+ rule: {
3674
+ type: "string",
3675
+ description: 'run only. The rule offered as "always allow in this project" next to the approval: the command cut down to its stable leading words plus ":*", e.g. "bun run:*" for "bun run dev", "git commit:*" for "git commit -m \u2026". It must match `command`; keep it as narrow as the user would want (never a bare "sudo:*" / "ssh:*"). Default: derived from the command.'
3676
+ },
3677
+ cwd: { type: "string", description: "run only. Absolute working directory for a new tab. Default: the session working directory." },
3678
+ title: { type: "string", description: "run only. Tab title shown to the user. Default: the command name." },
3679
+ size: {
3680
+ type: "object",
3681
+ properties: { cols: { type: "number" }, rows: { type: "number" } },
3682
+ required: ["cols", "rows"],
3683
+ additionalProperties: false,
3684
+ description: "run only. Initial size of a new tab. Default 120\xD740."
3685
+ },
3686
+ yieldMs: { type: "number", description: "run only. How long to wait for the command to start and go quiet before returning. Default 5000, max 30000." },
3687
+ description: { type: "string", description: "Shown to the user instead of raw arguments." }
3688
+ },
3689
+ additionalProperties: false
3690
+ }
3691
+ },
3692
+ {
3693
+ name: "terminal_snapshot",
3694
+ description: TERMINAL_SNAPSHOT_DESCRIPTION,
3695
+ inputSchema: {
3696
+ type: "object",
3697
+ properties: {
3698
+ tab: { type: "string", description: "Tab id from terminal_tabs." },
3699
+ include: {
3700
+ type: "array",
3701
+ items: { type: "string", enum: ["screen", "scrollback", "cursor", "meta"] },
3702
+ description: "Sections to return. Default [screen]."
3703
+ },
3704
+ tail: { type: "number", description: "scrollback only. Lines from the end. Default 200, max 2000." }
3705
+ },
3706
+ required: ["tab"],
3707
+ additionalProperties: false
3708
+ }
3709
+ },
3710
+ {
3711
+ name: "terminal_act",
3712
+ description: TERMINAL_ACT_DESCRIPTION,
3713
+ inputSchema: {
3714
+ type: "object",
3715
+ properties: {
3716
+ tab: { type: "string", description: "Tab id from terminal_tabs." },
3717
+ actions: {
3718
+ type: "array",
3719
+ items: TERMINAL_ACTION_INPUT_SCHEMA,
3720
+ minItems: 1,
3721
+ maxItems: 20,
3722
+ description: "Normally one action. Use 2\u201320 only for a single uninterruptible sequence; they run in order, fail-fast."
3723
+ },
3724
+ expect: {
3725
+ type: "object",
3726
+ properties: TERMINAL_WAIT_CONDITION_PROPERTIES,
3727
+ additionalProperties: false,
3728
+ description: "Completion condition to wait for after the batch."
3729
+ },
3730
+ timeoutMs: { type: "number", description: "Maximum wait for expect. Default 15000, max 60000." },
3731
+ description: { type: "string", description: "Shown to the user instead of raw keystrokes." }
3732
+ },
3733
+ required: ["tab", "actions"],
3734
+ additionalProperties: false
3735
+ }
3736
+ },
3737
+ {
3738
+ name: "terminal_wait_for",
3739
+ description: TERMINAL_WAIT_FOR_DESCRIPTION,
3740
+ inputSchema: {
3741
+ type: "object",
3742
+ properties: {
3743
+ tab: { type: "string", description: "Tab id from terminal_tabs." },
3744
+ ...TERMINAL_WAIT_CONDITION_PROPERTIES,
3745
+ timeoutMs: { type: "number", description: "Maximum wait in milliseconds. Default 15000, max 120000." }
3746
+ },
3747
+ required: ["tab"],
3748
+ additionalProperties: false
3749
+ }
3750
+ }
3751
+ ];
3752
+ }
3753
+ });
3754
+
3625
3755
  // ../../packages/shared/src/environment/host-action-superone-descriptors.ts
3626
3756
  var HOST_ACTION_SUPERONE_TOOL_DESCRIPTORS;
3627
3757
  var init_host_action_superone_descriptors = __esm({
@@ -3639,6 +3769,7 @@ var init_host_action_superone_descriptors = __esm({
3639
3769
  init_host_action_automation_descriptors();
3640
3770
  init_host_action_device_descriptors();
3641
3771
  init_host_action_browser_perf_descriptors();
3772
+ init_host_action_terminal_descriptors();
3642
3773
  HOST_ACTION_SUPERONE_TOOL_DESCRIPTORS = [
3643
3774
  ...INTERACTION_MEMORY_TOOL_DEFS,
3644
3775
  ...HOST_ACTION_COLLABORATION_DESCRIPTORS,
@@ -3650,6 +3781,7 @@ var init_host_action_superone_descriptors = __esm({
3650
3781
  ...HOST_ACTION_COMPUTER_DESCRIPTORS,
3651
3782
  ...HOST_ACTION_WIDGET_DESCRIPTORS,
3652
3783
  ...HOST_ACTION_AUTOMATION_DESCRIPTORS,
3784
+ ...HOST_ACTION_TERMINAL_DESCRIPTORS,
3653
3785
  ...HOST_ACTION_DEVICE_DESCRIPTORS,
3654
3786
  ...HOST_ACTION_BROWSER_PERF_DESCRIPTORS
3655
3787
  ];
@@ -8448,17 +8580,19 @@ function superoneHostContext(extra) {
8448
8580
  ${superoneSystemPrompt(extra)}
8449
8581
  </superone-host-context>`;
8450
8582
  }
8451
- var SUPERONE_SYSTEM_PROMPT_APPEND;
8583
+ var SUPERONE_SYSTEM_PROMPT_APPEND, CLAUDE_TOOL_NAMING_APPEND, CLAUDE_SYSTEM_PROMPT_APPEND;
8452
8584
  var init_superone_system_prompt = __esm({
8453
8585
  "../../packages/shared/src/superone-system-prompt.ts"() {
8454
8586
  "use strict";
8455
8587
  init_browser_memory();
8456
8588
  SUPERONE_SYSTEM_PROMPT_APPEND = `You are running inside SuperOne, a desktop GUI app. Your replies render as rich Markdown in a chat panel.
8457
8589
 
8458
- SuperOne tools cover browser and device control, media, widgets, sessions, collaboration, automations, settings, and mini-apps. Read only the manual topics needed for the task; reuse guidance already in context.
8590
+ SuperOne tools cover browser, terminal and device control, media, widgets, sessions, collaboration, automations, settings, and mini-apps. Read only the manual topics needed for the task; reuse guidance already in context.
8459
8591
 
8460
8592
  Prefer SuperOne's built-in tools unless the user explicitly requests another tool or no suitable SuperOne tool is available.
8461
8593
 
8594
+ Terminals: your own shell tool stays the default for one-shot commands (build, test, git, scripts) that finish on their own. Anything that keeps running or waits for input \u2014 dev servers, watch/hot-reload modes, docker compose up, REPLs, full-screen programs, ssh, interactive wizards \u2014 goes through terminal_tabs run instead of being backgrounded in the shell tool (\`&\`, nohup, setsid): the shell would orphan the process and lose its output, while a terminal tab keeps it visible to the user and lets you keep working with it. Then terminal_wait_for for the ready line or prompt, terminal_snapshot to read the screen, terminal_act to type or send keys, and terminal_tabs close once its job is done. Each command is approved by the user and your control ends when it exits; a rejected result means stop and ask, not retry.
8595
+
8462
8596
  Experience memory:
8463
8597
  SuperOne keeps per-target experience notes on this node: browser_memory_* (domain), computer_memory_* (platform + appId), device_memory_* (platform + appId).
8464
8598
 
@@ -8478,11 +8612,12 @@ Response rendering:
8478
8612
  - Images: use ![description](/abs/path/image.png) to display an inline image.
8479
8613
  - Videos: use ![description](/abs/path/video.mp4) to display an inline video player.
8480
8614
  - Audio: use ![description](/abs/path/audio.mp3) to display an inline audio player.
8615
+ - Several media or files in a row (screenshots, recordings, PDFs, changed sources): show them in one card with widget_show({ template: "@native/files-previewer", data: { files: [{ path, note }] } }) instead of stacking embeds or links. A single file stays inline.
8481
8616
  - Wrap a link or media destination in angle brackets whenever the path contains spaces or parentheses, e.g. ![screenshot](</Users/me/Library/Application Support/SuperOne/shot.png>). A bare path with spaces is not valid Markdown and renders as literal text.
8482
8617
 
8483
- Show your work: embed a screenshot or recording when the user requested the capture or it directly supports a visual claim in your reply, and say what to look at. Screenshots needed to inspect content are allowed; reuse them as evidence when relevant. Omit captures that only document navigation or content extraction unless requested; ordinary reading needs no screenshot for the reply. Each file at most once per reply. Embed the user's existing media only when they ask to see or play it; otherwise link the file. For capture methods or multi-file presentation, read product/show-your-work.
8618
+ Show your work: embed a screenshot or recording when the user requested the capture or it directly supports a visual claim in your reply, and say what to look at. Screenshots needed to inspect content are allowed; reuse them as evidence when relevant. Omit captures that only document navigation or content extraction unless requested; ordinary reading needs no screenshot for the reply. Each file at most once per reply. Embed the user's existing media only when they ask to see or play it; otherwise link the file. Two or more evidence files go in one @native/files-previewer card. For capture methods, read product/show-your-work.
8484
8619
 
8485
- Leave surfaces as you found them: before ending a task, close the browser tabs you opened and no longer need (browser_tabs close), release the devices you hold (device_release), and quit the desktop apps you launched (no tool needed \u2014 quit the app itself, never kill by process name). What the user had open before, or is using now, stays open.
8620
+ Leave surfaces as you found them: before ending a task, close the browser tabs you opened and no longer need (browser_tabs close), close terminal tabs you opened whose command has finished (terminal_tabs close) \u2014 a server the user asked for stays running, say so instead \u2014 release the devices you hold (device_release), and quit the desktop apps you launched (no tool needed \u2014 quit the app itself, never kill by process name). What the user had open before, or is using now, stays open.
8486
8621
 
8487
8622
  Media generated by SuperOne's generation tools is displayed automatically. Do not embed or link the result again; describe it briefly.
8488
8623
 
@@ -8490,6 +8625,10 @@ Session organization:
8490
8625
  On the first substantive user request, call session_rename as your first tool call, before answering. Always include \`tags\`: 1\u20134 short kebab-case labels; reuse existing tags from session_tag_list when they fit, or invent suitable ones. When the session's purpose is fixing an issue or reviewing a PR, add a ref tag issue-N / pr-N in addition to the labels.
8491
8626
 
8492
8627
  Rename again when the title no longer describes the task. Update tags with session_tag as needed \u2014 in particular add pr-N right after opening a PR, so later sessions on that PR can find this one. Use a short title with a verb and concrete object in the user's language, without surrounding quotes or trailing punctuation.`;
8628
+ CLAUDE_TOOL_NAMING_APPEND = `Tool naming: SuperOne tools are named above without their server prefix. In your tool list they are mcp__superone__<name> (e.g. mcp__superone__terminal_tabs); when one is deferred, load it with ToolSearch by that full name.`;
8629
+ CLAUDE_SYSTEM_PROMPT_APPEND = `${SUPERONE_SYSTEM_PROMPT_APPEND}
8630
+
8631
+ ${CLAUDE_TOOL_NAMING_APPEND}`;
8493
8632
  }
8494
8633
  });
8495
8634
 
@@ -10764,7 +10903,7 @@ function isStaticHostOwnedSuperoneToolQualified(qualifiedName) {
10764
10903
  function isNeverAutoAllowSuperoneBareName(bare) {
10765
10904
  return NEVER_AUTO_ALLOW_SUPERONE_BARE_NAMES.includes(bare);
10766
10905
  }
10767
- var MCP_SUPERONE_TOOL_PREFIX, BROWSER_PRIMITIVE_TOOL_NAMES, BROWSER_ACTION_TOOL_NAMES, BROWSER_LEGACY_TOOL_NAMES, BROWSER_COMPACT_TOOL_NAMES, BROWSER_TOOL_NAMES, DEVICE_AGENT_TOOL_NAMES, BUILT_IN_SUPERONE_TOOL_NAMES, MINIAPP_LIST_BARE_NAME, MINIAPP_CALL_BARE_NAME, NEVER_AUTO_ALLOW_SUPERONE_BARE_NAMES, STATIC_HOST_OWNED_SUPERONE_QUALIFIED_TOOL_NAMES;
10906
+ var MCP_SUPERONE_TOOL_PREFIX, BROWSER_PRIMITIVE_TOOL_NAMES, BROWSER_ACTION_TOOL_NAMES, BROWSER_LEGACY_TOOL_NAMES, BROWSER_COMPACT_TOOL_NAMES, BROWSER_TOOL_NAMES, DEVICE_AGENT_TOOL_NAMES, TERMINAL_TOOL_NAMES, BUILT_IN_SUPERONE_TOOL_NAMES, MINIAPP_LIST_BARE_NAME, MINIAPP_CALL_BARE_NAME, NEVER_AUTO_ALLOW_SUPERONE_BARE_NAMES, STATIC_HOST_OWNED_SUPERONE_QUALIFIED_TOOL_NAMES;
10768
10907
  var init_superone_host_owned_tools = __esm({
10769
10908
  "../../packages/shared/src/superone-host-owned-tools.ts"() {
10770
10909
  "use strict";
@@ -10841,6 +10980,12 @@ var init_superone_host_owned_tools = __esm({
10841
10980
  "device_wait_for",
10842
10981
  "device_release"
10843
10982
  ];
10983
+ TERMINAL_TOOL_NAMES = [
10984
+ "terminal_tabs",
10985
+ "terminal_snapshot",
10986
+ "terminal_act",
10987
+ "terminal_wait_for"
10988
+ ];
10844
10989
  BUILT_IN_SUPERONE_TOOL_NAMES = [
10845
10990
  "browser_memory_read",
10846
10991
  "browser_memory_write",
@@ -10878,7 +11023,8 @@ var init_superone_host_owned_tools = __esm({
10878
11023
  "automation_apply",
10879
11024
  "automation_delete",
10880
11025
  ...BROWSER_TOOL_NAMES,
10881
- ...DEVICE_AGENT_TOOL_NAMES
11026
+ ...DEVICE_AGENT_TOOL_NAMES,
11027
+ ...TERMINAL_TOOL_NAMES
10882
11028
  ];
10883
11029
  MINIAPP_LIST_BARE_NAME = "miniapp_list";
10884
11030
  MINIAPP_CALL_BARE_NAME = "miniapp_call";
@@ -10980,6 +11126,187 @@ var init_slash_commands = __esm({
10980
11126
  }
10981
11127
  });
10982
11128
 
11129
+ // ../../packages/shared/src/harness/acp-brand.ts
11130
+ function isGrokAcpAgent(agentId) {
11131
+ if (!agentId) return false;
11132
+ const id = agentId.toLowerCase();
11133
+ return id.includes("grok");
11134
+ }
11135
+ function isOpenCodeAcpAgent(agentId) {
11136
+ if (!agentId) return false;
11137
+ return agentId.toLowerCase().includes("opencode");
11138
+ }
11139
+ function resolveHarnessBrandKey(harnessId, acpAgentId) {
11140
+ if (!harnessId) return "claude";
11141
+ if (harnessId !== "acp") return harnessId;
11142
+ if (isGrokAcpAgent(acpAgentId)) return "acp-grok";
11143
+ if (isOpenCodeAcpAgent(acpAgentId)) return "acp-opencode";
11144
+ if (acpAgentId?.trim()) {
11145
+ const short = acpAgentId.trim().toLowerCase().replace(/-build$/, "").replace(/[^a-z0-9]+/g, "-");
11146
+ return short ? `acp-${short}` : "acp";
11147
+ }
11148
+ return "acp";
11149
+ }
11150
+ function acpAgentDisplayName(agentId, catalogName) {
11151
+ if (catalogName?.trim()) {
11152
+ return catalogName.trim().replace(/\s+Build$/i, "");
11153
+ }
11154
+ if (isGrokAcpAgent(agentId)) return "Grok";
11155
+ if (isOpenCodeAcpAgent(agentId)) return "OpenCode";
11156
+ if (agentId?.trim()) {
11157
+ return agentId.trim().replace(/-build$/i, "").split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
11158
+ }
11159
+ return "ACP";
11160
+ }
11161
+ var init_acp_brand = __esm({
11162
+ "../../packages/shared/src/harness/acp-brand.ts"() {
11163
+ "use strict";
11164
+ }
11165
+ });
11166
+
11167
+ // ../../packages/shared/src/harness/harness-capabilities.ts
11168
+ var HARNESS_CAPABILITIES, ALL_GOAL_LIFECYCLE_ARGS;
11169
+ var init_harness_capabilities = __esm({
11170
+ "../../packages/shared/src/harness/harness-capabilities.ts"() {
11171
+ "use strict";
11172
+ init_acp_brand();
11173
+ HARNESS_CAPABILITIES = {
11174
+ claude: {
11175
+ supportsMcp: true,
11176
+ supportsPlanMode: true,
11177
+ supportsTodos: true,
11178
+ supportsSubagents: true,
11179
+ supportsCompact: true,
11180
+ supportsStreamingToolInput: true,
11181
+ supportsQueuedSteer: true,
11182
+ supportsQueuedSteerSoon: true,
11183
+ // SDK `additionalDirectories`.
11184
+ supportsAdditionalDirs: true,
11185
+ // SDK `forkSession()` copies + remaps the transcript jsonl.
11186
+ supportsFork: true,
11187
+ // Built-in `/goal <condition>`: a Stop hook re-checks the condition after
11188
+ // each turn and keeps going until it is met, so there is no paused state —
11189
+ // the goal is either live or cleared.
11190
+ goal: { lifecycleArgs: ["clear"], canPause: false, transport: "slash", semantics: "condition" },
11191
+ displayName: "Claude"
11192
+ },
11193
+ codex: {
11194
+ supportsMcp: true,
11195
+ supportsPlanMode: true,
11196
+ supportsTodos: false,
11197
+ supportsSubagents: false,
11198
+ supportsCompact: true,
11199
+ supportsStreamingToolInput: false,
11200
+ supportsQueuedSteer: true,
11201
+ // Core's queue item either interrupts the turn or waits it out.
11202
+ supportsQueuedSteerSoon: false,
11203
+ // sandbox_workspace_write.writable_roots, re-sent every turn.
11204
+ supportsAdditionalDirs: true,
11205
+ // app-server thread fork, truncatable at a turn id.
11206
+ supportsFork: true,
11207
+ // `thread/goal/{get,set,clear}` over the app server; SuperOne drives the
11208
+ // follow-up turns itself, so every transition is an explicit RPC.
11209
+ goal: { lifecycleArgs: [], canPause: true, transport: "rpc", semantics: "objective" },
11210
+ displayName: "Codex"
11211
+ },
11212
+ acp: {
11213
+ // Host injects SuperOne MCP on every ACP session; user MCP attach is a separate gap.
11214
+ supportsMcp: true,
11215
+ // Agent-driven plan + x.ai/exit_plan_mode approval is shipped (not host enter-plan).
11216
+ supportsPlanMode: true,
11217
+ // ACP session/update plan entries map to todo_write-style UI events.
11218
+ supportsTodos: true,
11219
+ // Subagent_* notifications already map to task rows, but there is no nested
11220
+ // child chrome for ACP. Keep false until Task UI can host those sessions.
11221
+ supportsSubagents: false,
11222
+ // Host intercepts `/compact` → `x.ai/compact_conversation`.
11223
+ supportsCompact: true,
11224
+ supportsStreamingToolInput: false,
11225
+ // Mid-turn send queues; steer inserts via `x.ai/interject` (no abort).
11226
+ // Interject has no now/next split — Claude's "soon" is a second SDK
11227
+ // priority, which Grok does not have.
11228
+ supportsQueuedSteer: true,
11229
+ supportsQueuedSteerSoon: false,
11230
+ // session/new additionalDirectories, gated per agent capability.
11231
+ supportsAdditionalDirs: true,
11232
+ // Cold `x.ai/session/fork` copies Grok session files; SuperOne then resumes the child.
11233
+ supportsFork: true,
11234
+ // Grok only — see `resolveGoalCapability`. The agent owns the loop and
11235
+ // reports back over `goal_updated`; the host just posts `/goal …` lines.
11236
+ goal: {
11237
+ lifecycleArgs: ["status", "pause", "resume", "clear"],
11238
+ canPause: true,
11239
+ transport: "slash",
11240
+ semantics: "objective"
11241
+ },
11242
+ displayName: "Others"
11243
+ },
11244
+ opencode: {
11245
+ supportsMcp: true,
11246
+ supportsPlanMode: true,
11247
+ supportsTodos: true,
11248
+ supportsSubagents: true,
11249
+ supportsCompact: true,
11250
+ supportsStreamingToolInput: false,
11251
+ supportsQueuedSteer: false,
11252
+ supportsQueuedSteerSoon: false,
11253
+ // Single `directory` only.
11254
+ supportsAdditionalDirs: false,
11255
+ // Server-side `forkSession(id, anchor)` + `moveSession`.
11256
+ supportsFork: true,
11257
+ goal: null,
11258
+ displayName: "OpenCode"
11259
+ },
11260
+ cursor: {
11261
+ supportsMcp: true,
11262
+ supportsPlanMode: true,
11263
+ // updateTodos / task tool deltas when event map lands (PR5+)
11264
+ supportsTodos: true,
11265
+ supportsSubagents: true,
11266
+ supportsCompact: false,
11267
+ supportsStreamingToolInput: true,
11268
+ supportsQueuedSteer: false,
11269
+ supportsQueuedSteerSoon: false,
11270
+ // Single cwd; multi-root parked in the harness design doc.
11271
+ supportsAdditionalDirs: false,
11272
+ // SDK has no transcript-fork API; the adapter creates a blank agent.
11273
+ supportsFork: false,
11274
+ goal: null,
11275
+ displayName: "Cursor"
11276
+ },
11277
+ dsh: {
11278
+ // In-process dsh Cordis tree (docs/draft/deepseek-harness-integration.md).
11279
+ // Flags flip only when the corresponding event path is wired: streaming
11280
+ // tool input → tool-call-delta mapping.
11281
+ // `supportsCompact`: `compaction-basic` compacts automatically at context
11282
+ // pressure and on provider overflow; `/compact` drives `compactNow()`.
11283
+ // `supportsMcp` covers both SuperOne's own tools (native dsh rows) and
11284
+ // third-party servers read from dsh's own profile patch layer.
11285
+ // `supportsSubagents`: foreground delegation (`dsh-tool-subagent` over the
11286
+ // in-process spawn provider), rendered as a Task block with the child's
11287
+ // steps nested under it. Background and continuable children are not wired.
11288
+ supportsMcp: true,
11289
+ supportsPlanMode: false,
11290
+ supportsTodos: true,
11291
+ supportsSubagents: true,
11292
+ supportsCompact: true,
11293
+ supportsStreamingToolInput: false,
11294
+ supportsQueuedSteer: false,
11295
+ supportsQueuedSteerSoon: false,
11296
+ // Single cwd.
11297
+ supportsAdditionalDirs: false,
11298
+ // `runtime.forkSession` copies the log prefix up to an event seq.
11299
+ supportsFork: true,
11300
+ goal: null,
11301
+ displayName: "DeepSeek"
11302
+ }
11303
+ };
11304
+ ALL_GOAL_LIFECYCLE_ARGS = [...new Set(
11305
+ Object.values(HARNESS_CAPABILITIES).flatMap((caps) => caps.goal?.lifecycleArgs ?? [])
11306
+ )];
11307
+ }
11308
+ });
11309
+
10983
11310
  // ../../packages/shared/src/session-goal.ts
10984
11311
  function sessionGoalFromClaudeActive(raw) {
10985
11312
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
@@ -10990,13 +11317,13 @@ function sessionGoalFromClaudeActive(raw) {
10990
11317
  return {
10991
11318
  objective: condition,
10992
11319
  status: "active",
10993
- ...typeof value.iterations === "number" && Number.isFinite(value.iterations) ? { iterations: value.iterations } : {},
10994
11320
  ...lastReason ? { lastReason } : {}
10995
11321
  };
10996
11322
  }
10997
11323
  var init_session_goal = __esm({
10998
11324
  "../../packages/shared/src/session-goal.ts"() {
10999
11325
  "use strict";
11326
+ init_harness_capabilities();
11000
11327
  }
11001
11328
  });
11002
11329
 
@@ -12374,7 +12701,7 @@ function buildLiveOptions(opts, onPermission, onQuestion, onPlan, signal, timing
12374
12701
  systemPrompt: {
12375
12702
  type: "preset",
12376
12703
  preset: "claude_code",
12377
- append: [SUPERONE_SYSTEM_PROMPT_APPEND, opts.systemPromptAppend].filter(Boolean).join("\n\n"),
12704
+ append: [CLAUDE_SYSTEM_PROMPT_APPEND, opts.systemPromptAppend].filter(Boolean).join("\n\n"),
12378
12705
  snapshot: false
12379
12706
  },
12380
12707
  ...opts.sessionId ? { resume: opts.sessionId } : {},
@@ -53006,7 +53333,7 @@ function tryParseJsonObject(text2) {
53006
53333
  }
53007
53334
  }
53008
53335
  }
53009
- var XAI_SESSION_NOTIFICATION, XAI_SESSION_UPDATE, XAI_TASK_BACKGROUNDED, XAI_TASK_COMPLETED, XAI_MONITOR_EVENT, XAI_FOLLOW_UPS, XAI_SCHEDULED_TASK_CREATED, XAI_SCHEDULED_TASK_FIRED, XAI_SCHEDULED_TASK_DELETED, XAI_SCHEDULED_TASK_INJECT_PROMPT, XAI_MCP_ELICIT, XAI_MCP_ELICIT_COMPLETE, XAI_SETTINGS_UPDATE, XAI_SESSION_INTERJECTION, SUBAGENT_LIFECYCLE, XAI_EXT_NOTIFICATION_METHODS;
53336
+ var XAI_SESSION_NOTIFICATION, XAI_SESSION_UPDATE, XAI_TASK_BACKGROUNDED, XAI_TASK_COMPLETED, XAI_MONITOR_EVENT, XAI_FOLLOW_UPS, XAI_SCHEDULED_TASK_CREATED, XAI_SCHEDULED_TASK_FIRED, XAI_SCHEDULED_TASK_DELETED, XAI_SCHEDULED_TASK_INJECT_PROMPT, XAI_ASK_USER_QUESTION, XAI_EXIT_PLAN_MODE, XAI_MCP_ELICIT, XAI_MCP_ELICIT_COMPLETE, XAI_SETTINGS_UPDATE, XAI_SESSION_INTERJECTION, SUBAGENT_LIFECYCLE, XAI_EXT_NOTIFICATION_METHODS;
53010
53337
  var init_xai_state = __esm({
53011
53338
  "../../packages/acp/src/xai-state.ts"() {
53012
53339
  "use strict";
@@ -53020,6 +53347,8 @@ var init_xai_state = __esm({
53020
53347
  XAI_SCHEDULED_TASK_FIRED = "x.ai/scheduled_task_fired";
53021
53348
  XAI_SCHEDULED_TASK_DELETED = "x.ai/scheduled_task_deleted";
53022
53349
  XAI_SCHEDULED_TASK_INJECT_PROMPT = "x.ai/scheduled_task_inject_prompt";
53350
+ XAI_ASK_USER_QUESTION = "x.ai/ask_user_question";
53351
+ XAI_EXIT_PLAN_MODE = "x.ai/exit_plan_mode";
53023
53352
  XAI_MCP_ELICIT = "x.ai/mcp/elicit";
53024
53353
  XAI_MCP_ELICIT_COMPLETE = "x.ai/mcp/elicit_complete";
53025
53354
  XAI_SETTINGS_UPDATE = "x.ai/settings/update";
@@ -54674,6 +55003,42 @@ function grokElicitToPendingInteraction(raw) {
54674
55003
  function formatGrokElicitOutcome(allow) {
54675
55004
  return { outcome: allow ? "accept" : "cancel" };
54676
55005
  }
55006
+ function formatGrokAskUserCancelled() {
55007
+ return { outcome: "cancelled" };
55008
+ }
55009
+ function formatGrokAskUserAccepted(answers) {
55010
+ if (!answers || typeof answers !== "object" || Array.isArray(answers)) {
55011
+ return formatGrokAskUserCancelled();
55012
+ }
55013
+ const record2 = answers;
55014
+ const wrapped = record2.answers !== null && typeof record2.answers === "object" && !Array.isArray(record2.answers);
55015
+ const source = wrapped ? record2.answers : record2;
55016
+ const normalized = {};
55017
+ for (const [question, value] of Object.entries(source)) {
55018
+ if (typeof value === "string") {
55019
+ if (value) normalized[question] = value.split(", ").map((part) => part.trim()).filter(Boolean);
55020
+ } else if (Array.isArray(value) && value.every((part) => typeof part === "string")) {
55021
+ normalized[question] = value;
55022
+ } else {
55023
+ return formatGrokAskUserCancelled();
55024
+ }
55025
+ }
55026
+ if (Object.keys(normalized).length === 0) return formatGrokAskUserCancelled();
55027
+ return {
55028
+ outcome: "accepted",
55029
+ answers: normalized,
55030
+ ...wrapped && record2.annotations && typeof record2.annotations === "object" && !Array.isArray(record2.annotations) ? { annotations: record2.annotations } : {}
55031
+ };
55032
+ }
55033
+ function formatGrokExitPlanCancelled(feedback) {
55034
+ const trimmed = feedback?.trim();
55035
+ return { outcome: "cancelled", ...trimmed ? { feedback: trimmed } : {} };
55036
+ }
55037
+ function formatGrokExitPlanFromDecision(decision, options) {
55038
+ if (decision === "approve") return { outcome: "approved" };
55039
+ const feedback = typeof options?.feedback === "string" ? options.feedback : void 0;
55040
+ return formatGrokExitPlanCancelled(feedback);
55041
+ }
54677
55042
  var init_xai_elicit = __esm({
54678
55043
  "../../packages/acp/src/xai-elicit.ts"() {
54679
55044
  "use strict";
@@ -54731,7 +55096,42 @@ function createAcpAgentTurnRunner(opts = {}) {
54731
55096
  });
54732
55097
  });
54733
55098
  };
54734
- let clientBuilder = client({ name: opts.clientName ?? "superone-node" }).onRequest(XAI_MCP_ELICIT, (raw) => raw, handleElicit).onRequest(`_${XAI_MCP_ELICIT}`, (raw) => raw, handleElicit).onRequest(methods.client.session.requestPermission, async (ctx) => {
55099
+ const handleAskUser = async (ctx) => {
55100
+ if (!input.onQuestion) return formatGrokAskUserCancelled();
55101
+ const raw = ctx.params && typeof ctx.params === "object" && !Array.isArray(ctx.params) ? ctx.params : {};
55102
+ const toolCallId = typeof raw.toolCallId === "string" ? raw.toolCallId : typeof raw.tool_call_id === "string" ? raw.tool_call_id : `acp_ask_${Date.now().toString(36)}`;
55103
+ try {
55104
+ const answers = await input.onQuestion({
55105
+ interactionId: toolCallId,
55106
+ kind: "question",
55107
+ toolUseId: toolCallId,
55108
+ input: raw,
55109
+ createdAt: Date.now()
55110
+ });
55111
+ return formatGrokAskUserAccepted(answers);
55112
+ } catch {
55113
+ return formatGrokAskUserCancelled();
55114
+ }
55115
+ };
55116
+ const handleExitPlan = async (ctx) => {
55117
+ if (!input.onPlan) return formatGrokExitPlanCancelled();
55118
+ const raw = ctx.params && typeof ctx.params === "object" && !Array.isArray(ctx.params) ? ctx.params : {};
55119
+ const toolCallId = typeof raw.toolCallId === "string" ? raw.toolCallId : typeof raw.tool_call_id === "string" ? raw.tool_call_id : `acp_plan_${Date.now().toString(36)}`;
55120
+ const planContent = typeof raw.planContent === "string" ? raw.planContent : typeof raw.plan_content === "string" ? raw.plan_content : "";
55121
+ try {
55122
+ const result = await input.onPlan({
55123
+ interactionId: toolCallId,
55124
+ kind: "plan",
55125
+ toolUseId: toolCallId,
55126
+ input: { planContent, ...raw },
55127
+ createdAt: Date.now()
55128
+ });
55129
+ return formatGrokExitPlanFromDecision(result.decision, result.options);
55130
+ } catch {
55131
+ return formatGrokExitPlanCancelled();
55132
+ }
55133
+ };
55134
+ let clientBuilder = client({ name: opts.clientName ?? "superone-node" }).onRequest(XAI_MCP_ELICIT, (raw) => raw, handleElicit).onRequest(`_${XAI_MCP_ELICIT}`, (raw) => raw, handleElicit).onRequest(XAI_ASK_USER_QUESTION, (raw) => raw, handleAskUser).onRequest(`_${XAI_ASK_USER_QUESTION}`, (raw) => raw, handleAskUser).onRequest(XAI_EXIT_PLAN_MODE, (raw) => raw, handleExitPlan).onRequest(`_${XAI_EXIT_PLAN_MODE}`, (raw) => raw, handleExitPlan).onRequest(methods.client.session.requestPermission, async (ctx) => {
54735
55135
  const mapped = mapPermissionRequest(ctx.params);
54736
55136
  pendingOptions = mapped.options;
54737
55137
  if (!input.onPermission) {
@@ -54786,7 +55186,12 @@ function createAcpAgentTurnRunner(opts = {}) {
54786
55186
  await connection.agent.request(methods.agent.initialize, {
54787
55187
  protocolVersion: PROTOCOL_VERSION,
54788
55188
  clientInfo: { name: opts.clientName ?? "superone-node", version: "0.0.0" },
54789
- clientCapabilities: {}
55189
+ clientCapabilities: {},
55190
+ _meta: {
55191
+ askUserQuestion: true,
55192
+ exitPlanMode: true,
55193
+ clientIdentifier: "superone"
55194
+ }
54790
55195
  });
54791
55196
  const mcpServers = opts.getMcpServers?.(input.session.sessionId) ?? opts.mcpServers ?? [];
54792
55197
  const active = await connection.agent.buildSession({ cwd, mcpServers }).start();
@@ -72157,8 +72562,8 @@ import { fileURLToPath } from "node:url";
72157
72562
  function resolveCliReleaseVersion() {
72158
72563
  const fromEnv = process.env.SUPERONE_CLI_VERSION?.trim();
72159
72564
  if (fromEnv) return fromEnv;
72160
- if ("0.67.0-alpha".trim()) {
72161
- return "0.67.0-alpha".trim();
72565
+ if ("0.67.0-alpha.2".trim()) {
72566
+ return "0.67.0-alpha.2".trim();
72162
72567
  }
72163
72568
  const fromDist = readDistManifestVersion();
72164
72569
  if (fromDist) return fromDist;
@@ -78895,6 +79300,20 @@ var HarnessManager = class {
78895
79300
  diagnostic: buildHarnessDiagnostic("simulated")
78896
79301
  };
78897
79302
  }
79303
+ getExternalLaunchConfig(id) {
79304
+ const row = this.db.prepare("SELECT config_json FROM harness_installations WHERE harness_id = ?").get(id);
79305
+ try {
79306
+ const config2 = JSON.parse(row?.config_json || "{}");
79307
+ return {
79308
+ ...typeof config2.usesDefaultArgs === "boolean" ? { usesDefaultArgs: config2.usesDefaultArgs } : {},
79309
+ ...typeof config2.command === "string" ? { command: config2.command } : {},
79310
+ ...["path", "explicit"].includes(config2.commandSource) ? { commandSource: config2.commandSource } : {},
79311
+ ...Array.isArray(config2.args) && config2.args.every((arg) => typeof arg === "string") ? { args: config2.args } : {}
79312
+ };
79313
+ } catch {
79314
+ return {};
79315
+ }
79316
+ }
78898
79317
  readPersisted(id) {
78899
79318
  const row = this.db.prepare(
78900
79319
  `SELECT harness_id, enabled, state, runtime_version, command,
@@ -83797,7 +84216,7 @@ function enableDeepseek(manager) {
83797
84216
  function enableAcpGrok(manager, opts) {
83798
84217
  const defaultArgs = ["agent", "stdio"];
83799
84218
  const args = sanitizeHarnessArgs(opts.args.length > 0 ? opts.args : defaultArgs);
83800
- const resolved = resolveExternalCommand(opts.command, ["grok"]);
84219
+ const resolved = resolveExternalCommand(opts.command, ["grok"], { preserveSymlinks: true });
83801
84220
  if (!resolved) {
83802
84221
  return manager.update("acp-grok", {
83803
84222
  enabled: true,
@@ -83805,7 +84224,7 @@ function enableAcpGrok(manager, opts) {
83805
84224
  command: null,
83806
84225
  diagnosticCode: "not_found",
83807
84226
  lastProbedAt: Date.now(),
83808
- configJson: JSON.stringify({ args, usesDefaultArgs: opts.args.length === 0 })
84227
+ configJson: JSON.stringify({ commandSource: opts.command ? "explicit" : "path", command: opts.command, args, usesDefaultArgs: opts.args.length === 0 })
83809
84228
  });
83810
84229
  }
83811
84230
  return manager.update("acp-grok", {
@@ -83816,6 +84235,7 @@ function enableAcpGrok(manager, opts) {
83816
84235
  lastProbedAt: Date.now(),
83817
84236
  configJson: JSON.stringify({
83818
84237
  command: resolved,
84238
+ commandSource: opts.command ? "explicit" : "path",
83819
84239
  args,
83820
84240
  usesDefaultArgs: opts.args.length === 0
83821
84241
  })
@@ -83832,7 +84252,7 @@ function requireRegularReadableFile(path) {
83832
84252
  accessSync2(abs, constants2.R_OK);
83833
84253
  return realpathSync3(abs);
83834
84254
  }
83835
- function resolveExternalCommand(explicit, searchNames) {
84255
+ function resolveExternalCommand(explicit, searchNames, options = {}) {
83836
84256
  if (explicit) {
83837
84257
  const abs = isAbsolute5(explicit) ? explicit : resolve9(explicit);
83838
84258
  if (!existsSync33(abs)) return null;
@@ -83842,9 +84262,9 @@ function resolveExternalCommand(explicit, searchNames) {
83842
84262
  } catch {
83843
84263
  return null;
83844
84264
  }
83845
- return realpathSync3(abs);
84265
+ return options.preserveSymlinks ? abs : realpathSync3(abs);
83846
84266
  }
83847
- const pathEnv = process.env.PATH || "";
84267
+ const pathEnv = options.pathEnv ?? process.env.PATH ?? "";
83848
84268
  const dirs = pathEnv.split(process.platform === "win32" ? ";" : ":");
83849
84269
  for (const name of searchNames) {
83850
84270
  for (const dir of dirs) {
@@ -83854,7 +84274,7 @@ function resolveExternalCommand(explicit, searchNames) {
83854
84274
  try {
83855
84275
  if (!statSync12(candidate).isFile()) continue;
83856
84276
  accessSync2(candidate, constants2.X_OK);
83857
- return realpathSync3(candidate);
84277
+ return options.preserveSymlinks ? candidate : realpathSync3(candidate);
83858
84278
  } catch {
83859
84279
  }
83860
84280
  }
@@ -85011,7 +85431,7 @@ var WorkspaceGitService = class {
85011
85431
  deletions: shortstat.deletions
85012
85432
  };
85013
85433
  } catch (err) {
85014
- throw Object.assign(new Error(err.message || "git status failed"), {
85434
+ throw Object.assign(new Error(gitErrorMessage(err) || "git status failed"), {
85015
85435
  code: "internal"
85016
85436
  });
85017
85437
  }
@@ -85509,38 +85929,8 @@ import { createHash as createHash9, randomBytes as randomBytes5, randomUUID as r
85509
85929
  import { existsSync as existsSync39, statSync as statSync15 } from "node:fs";
85510
85930
  import { resolve as pathResolve2 } from "node:path";
85511
85931
 
85512
- // ../../packages/shared/src/harness/acp-brand.ts
85513
- function isGrokAcpAgent(agentId) {
85514
- if (!agentId) return false;
85515
- const id = agentId.toLowerCase();
85516
- return id.includes("grok");
85517
- }
85518
- function isOpenCodeAcpAgent(agentId) {
85519
- if (!agentId) return false;
85520
- return agentId.toLowerCase().includes("opencode");
85521
- }
85522
- function resolveHarnessBrandKey(harnessId, acpAgentId) {
85523
- if (!harnessId) return "claude";
85524
- if (harnessId !== "acp") return harnessId;
85525
- if (isGrokAcpAgent(acpAgentId)) return "acp-grok";
85526
- if (isOpenCodeAcpAgent(acpAgentId)) return "acp-opencode";
85527
- if (acpAgentId?.trim()) {
85528
- const short = acpAgentId.trim().toLowerCase().replace(/-build$/, "").replace(/[^a-z0-9]+/g, "-");
85529
- return short ? `acp-${short}` : "acp";
85530
- }
85531
- return "acp";
85532
- }
85533
- function acpAgentDisplayName(agentId, catalogName) {
85534
- if (catalogName?.trim()) {
85535
- return catalogName.trim().replace(/\s+Build$/i, "");
85536
- }
85537
- if (isGrokAcpAgent(agentId)) return "Grok";
85538
- if (isOpenCodeAcpAgent(agentId)) return "OpenCode";
85539
- if (agentId?.trim()) {
85540
- return agentId.trim().replace(/-build$/i, "").split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
85541
- }
85542
- return "ACP";
85543
- }
85932
+ // ../../packages/shared/src/acp-brand.ts
85933
+ init_acp_brand();
85544
85934
 
85545
85935
  // src/session/collaboration.ts
85546
85936
  init_resolve_service();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@super-one/cli",
3
- "version": "0.67.0-alpha",
3
+ "version": "0.67.0-alpha.2",
4
4
  "description": "SuperOne headless node CLI — remote execution environment (RPC, workspaces, sessions).",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",