Skip to content

feat(trae-solo): adapter — 19 commands (status/history/open/new-task/model + Skills/Automation/Mode/Message actions)#1801

Merged
jackwener merged 8 commits into
jackwener:mainfrom
LeoLin990405:feat/trae-solo-adapter
May 31, 2026
Merged

feat(trae-solo): adapter — 19 commands (status/history/open/new-task/model + Skills/Automation/Mode/Message actions)#1801
jackwener merged 8 commits into
jackwener:mainfrom
LeoLin990405:feat/trae-solo-adapter

Conversation

@LeoLin990405
Copy link
Copy Markdown
Contributor

Split from #1797. Greenfield adapter for TRAE SOLO desktop app.

Registers trae-solo (port 9235, bundle com.trae.solo.app) + ships 5 commands:

Command What it does
status CDP health
history Enumerate projects + tasks from .task-list-group sidebar
open <task> Click a task by substring match to enter chat view
new-task <project> Click the project's "New task" button
model [name] [--list] Read / list / switch the active model (15+ available — Gemini, MiniMax, Kimi, GPT, DeepSeek, Doubao, GLM, MiMo, Step variants)

Not exposed: delete/rename/pin for tasks. Trae SOLO does not expose these through right-click, hover overlay, or the project header 3-dot menu (which only offers view modes — List/Tree/Add File/New Folder/Refresh). Task management likely lives in the command palette (Cmd+Shift+P) or a server-side API. Followup needed.

Verified live:

  • history lists 4 projects + 6 tasks
  • model reads Doubao-Seed-2.0-Code, --list enumerates 15+, switch Doubao → Kimi-K2.5 verified by re-read

Model switch uses page.click (real CDP Input.dispatchMouseEvent) because Trae's React option handlers don't fire from synthetic events. Tolerant of "Promise was collected" / 30s timeout (eval reply unmounted by post-click re-render — click does fire).

@LeoLin990405 LeoLin990405 changed the title feat(trae-solo): new adapter — status/history/open/new-task/model feat(trae-solo): adapter — 19 commands (status/history/open/new-task/model + Skills/Automation/Mode/Message actions) May 31, 2026
@LeoLin990405
Copy link
Copy Markdown
Contributor Author

Update — 11 file-system commands added (commit 47cab6b4)

These complement the existing UI-driven skill-* / task-* commands. The UI versions need TRAE SOLO focused + visible (CDP-driven). These FS versions work even when Trae is closed, because they read/write Trae's on-disk state directly.

Storage layout probed:

  • ~/.trae/skills/ — installed-skills dir (49 on my machine)
  • ~/.trae/skill-config.jsonmanagedSkills registry
  • ~/.trae/user_rules.md — Trae's user-scope rules file
  • ~/Library/Application Support/TRAE SOLO/ModularData/ai-agent/snapshot/<uuid>/v2/.git — each chat is a real git repo with before-chat-turn-* / after-chat-turn-* tags
  • ~/Library/Application Support/TRAE SOLO/ModularData/ai-agent/agentconfig/<uuid>.json — per-task config + hooks

Read commands (no --yes needed):

Command What it does
skill-fs-list List ALL skills under ~/.trae/skills/
skill-fs-installed List skills currently in managedSkills
skill-fs-show <name> Print SKILL.md + on-disk path
task-fs-list List task uuids from disk
task-fs-turns <task-id> Show chat-turn timeline as git tags
task-fs-show <task-id> [--turn <id>] Workspace tree at a turn (via git ls-tree)
user-rules Print user_rules.md

Write commands (default dry-run, --yes to actually mutate):

Command Safety
skill-fs-install <name> [--source <dir>] [--source-tag <tag>] --yes Copies dir → ~/.trae/skills/<name>/, adds to managedSkills
skill-fs-uninstall <name> [--purge] --yes Removes from managedSkills; --purge also rm -rf disk dir
task-fs-delete <task-id> --yes Refuses if database.db-wal was touched in the last 5 s (i.e. Trae is actively writing)
user-rules-set <source.md> --yes Atomic tmp + rename overwrite

All commands use Strategy.LOCAL with browser: false — pure FS, no CDP.

E2E verified: Installed + uninstalled a throwaway skill (zz-opencli-roundtrip-test). managedSkills count went 49 → 50 → 49, on-disk dir created then removed.

Why this matters: Lets agents inspect / curate Trae SOLO's skill library and task history without forcing the user to bring the app forward. Useful for batch operations, headless setups, and skill-marketplace tooling that wants to query "is X installed?" before recommending it.

@LeoLin990405
Copy link
Copy Markdown
Contributor Author

Final Trae SOLO coverage summary (commits 47cab6b4 + 87c1f3e7 + this push)

Did one more pass after the FS commands landed to make sure nothing on disk was being left on the table. Added 5 more read commands and a --workspace flag to the storage ones. Trae SOLO is now exhaustively wrapped at every layer that is reachable without violating ToS.

Total: 35 commands across 4 layers

Layer Commands
UI / CDP (Trae must be visible) status history open new-task model + 7 skill-* + mode back compact + react retry copy-message + 2 automation-* (19)
FS — Skills + Rules skill-fs-list skill-fs-installed skill-fs-show skill-fs-install skill-fs-uninstall user-rules user-rules-set (7)
FS — Tasks (git timeline) task-fs-list task-fs-turns task-fs-show task-fs-delete (4)
FS — VSCode state storage-keys storage-get recent-workspaces workspaces-list extensions-list (5)

What's NOT wrapped — and why:

  • 1.10-main.sock IPC at ~/Library/Application Support/TRAE SOLO/1.10-main.sock — Trae's internal Electron IPC socket. Reverse-engineering this protocol could be considered TOS-violating and risks breaking on any release. Intentionally skipped.
  • Backend API (/api/agent/* HTTP endpoints reachable via the in-app JWT token from boot-config.json) — uses an undocumented session token that's a private secret. Calling these from an external CLI would: (1) violate TOS, (2) require leaking the token, (3) break unpredictably. Intentionally skipped.
  • database.db (encrypted) — looks like SQLCipher. Pivoted to snapshot/<uuid>/v2/.git (the actual chat-turn data) + JSON configs instead. The git tag pattern (before-chat-turn-* / after-chat-turn-*) is much more useful than DB blobs would be.
  • Chromium internals (Cookies, DIPS-wal, GPUCache, etc.) — privacy-sensitive, not user-actionable for Trae state.

Safety patterns used across all write commands:

  • --yes flag required (default = dry-run that prints the planned mutation)
  • skill-fs-install copies via tmp+rename for the config file
  • task-fs-delete refuses if database.db-wal was touched in the last 5 s (refuses to race with a running Trae)
  • user-rules-set writes atomically via tmp+rename
  • storage-* commands are READ-ONLY by design (writing while Trae runs would corrupt the SQLite DB)

E2E verified end-to-end: skill install/uninstall round-trip on zz-opencli-roundtrip-test flipped managedSkills count 49 → 50 → 49 and created/removed the on-disk dir correctly.

Happy to split into smaller PRs if reviewer prefers — currently 4 commits in this branch, each is a coherent unit.

@LeoLin990405
Copy link
Copy Markdown
Contributor Author

Update — storage naming harmonization + renderer + settings-read (commit `e0f22b16`)

To match the cross-surface naming convention established by PRs #1798/#1799/#1800:

  • Renamed `storage-keys` / `storage-get` → `state-keys` / `state-get` (these query the on-disk VSCode state.vscdb; behavior unchanged)
  • Added `storage-keys` / `storage-get` / `cookies` / `idb-list` as new renderer-side commands (Electron CDP)
  • Added `settings-read` to parse `~/Library/Application Support/TRAE SOLO/User/settings.json` (JSONC-aware)

Final naming convention across all 4 Electron-app PRs:

  • `storage-*` = renderer-side localStorage / sessionStorage (via CDP)
  • `state-*` = on-disk VSCode state.vscdb (via sqlite3)
  • `cookies` / `idb-list` = renderer-side
  • `settings-read` = on-disk JSON config

Known limitation: Trae's renderer runs under `vscode-file://` with strict sandboxing — opencli's eval context returns SecurityError for the renderer storage commands. Direct CDP probes (bypassing opencli's session manager) DO see the data (22 LS keys + @byted/ve-rtc IDB), but the standard adapter pathway is blocked. The commands are wired correctly and will work on any Trae build that relaxes the sandbox.

Brings Trae SOLO to 44 commands.

@jackwener jackwener force-pushed the feat/trae-solo-adapter branch from e0f22b1 to 37fd015 Compare May 31, 2026 14:24
LeoLin990405 and others added 8 commits June 1, 2026 00:44
Greenfield adapter — TRAE SOLO had no opencli entry before.

src/electron-apps.ts:
  + 'trae-solo' { port: 9235, processName: 'TRAE SOLO',
                  executableNames: ['Electron', 'TRAE SOLO'],
                  bundleId: 'com.trae.solo.app',
                  displayName: 'Trae SOLO' }

clis/trae-solo/:
  + status.js     standard makeStatusCommand factory
  + history.js    list projects (.task-list-group) and tasks
                  (.task-list-row-wrapper) from sidebar
  + open.js       click a task by substring match to enter chat view
  + new-task.js   click the per-project 'New task' button
  + model.js      read / list / switch the active model

What's exposed by Trae SOLO UI:
  · Project list view: 4 projects in sidebar, each with N tasks.
    Per-row 3-dot button opens FILE-TREE options (List View / Tree
    View / Add File / New Folder / Refresh) — NOT task management.
    Right-click is a no-op on rows; hover gives only file-tree
    options. No delete/rename/pin in the project-list UI.
  · Chat view (after opening a task):
    - .core-model-select-trigger shows current model (15+ available:
      Gemini 3.1 Pro/Flash Preview, MiniMax-M2.7, Kimi-K2.5/K2.6,
      GPT-5.4/5.2, DeepSeek-V3.2/V4-Pro/V4-Flash,
      Doubao-Seed-2.0 Lite/Pro/Code, GLM-5/5-Turbo, MiMo-v2,
      Step-3.5-flash, step-router-v1)
    - .chat-input-v2-input-box-editable (Lexical composer)
    - [data-item-index] (Virtuoso virtualized message list)

What we DON'T ship:
  - delete / rename / pin for tasks — Trae SOLO does not expose
    these via right-click, hover overlay, or the project header
    3-dot menu (which only offers view modes). Task management
    likely lives in the command palette (Cmd+Shift+P) or a
    server-side API. Followup needed.

Verified live (TRAE SOLO 0.7.x on macOS, CDP :9235):

  $ opencli trae-solo status
    Status: Connected
    Url: vscode-file://.../solo-lite.html
    Title: TRAE SOLO

  $ opencli trae-solo history --limit 3
    leo / 1 / Say Pong
    leo / 2 / Implement Fyyur Project
    leo / 3 / Implement Quote Engine
    civagent / 1 / Harden Vite Local API Path Handling
    wechat-ai-native-archive / 1 / 读取项目并开始学习
    LeoLin990405/xiaotie / 1 / 开始项目迭代

  $ opencli trae-solo model
    - Status: Active, Model: Doubao-Seed-2.0-Code
  $ opencli trae-solo model --list
    Gemini-3.1-Pro-Preview / Gemini-3-Flash-Preview / MiniMax-M2.7 / ...
  $ opencli trae-solo model Kimi-K2.5
    - Status: switched, Model: Kimi-K2.5   (verified by re-read)

Model switch uses page.click (real CDP Input.dispatchMouseEvent) on
nth-of-type option because Trae's option-click is not picked up by
synthetic events alone. Tolerant of 'Promise was collected' errors
(eval reply unmounted by post-click re-render) — surfaces as a
warning, caller can re-read to confirm.
…e / Chat

Brings the trae-solo adapter to ~80% UI coverage with 19 total commands.

New commands (this commit):
  · 7 Skills marketplace commands:
      skill-list [--installed] [--limit N]
      skill-search <keyword> [--limit N]
      skill-category [name] [--list] [--limit N]
      skill-install <name> [--yes]      (dry-run by default)
      skill-uninstall <name> [--yes]    (dry-run by default)
      skill-run <name>
      skill-toggle <name> [on|off]
  · 2 Automation panel commands:
      automation-list [--tab=configured|run-history|task-template]
      automation-create [manually|in-chat] [--template <name>]
  · 1 Mode command:
      mode [code|work]                  (read current; switch if given)
  · 1 Navigation:
      back                              (chat view -> project list)
  · 1 View toggle:
      compact                           (mobile-compact view)
  · 3 Message-action commands:
      react <good|bad> [--msg N]        (default last msg)
      retry [--msg N]
      copy-message [--msg N]

Plus shared helper:
  clis/trae-solo/_actions.js  switchToPanel(name) + pointer helpers

Implementation notes:
  · All commands switch to the appropriate panel first (Skills / Automation
    / chat-view) via switchToPanel(panelName) — clicking the sidebar
    .task-list-new-task-item entry with full pointer chain.
  · Marketplace card resolution by skill name: aria-label of nested
    .skill-logo-svg (stable across builds).
  · Per-card actions (.card-v2-add-btn / .card-v2-run-btn) are hover-mounted
    — dispatch mouseenter then poll for the button up to ~1s.
  · Reaction buttons (Good/Bad/Copy All/Retry) are absolute-positioned
    overlays near the message; we filter by vertical proximity to the
    target [data-item-index] message.
  · Defer destructive clicks (uninstall, run, react, retry, copy) via
    Promise.resolve().then(...) so the eval reply returns before the
    action triggers a re-render that would otherwise eat it.
  · mode: aria-label flips between 'Switch to Work mode' and 'Switch to
    Code mode' — parsed via regex to read current state.

Verified live (TRAE SOLO 0.7.x, CDP :9235):
  $ opencli trae-solo skill-list --limit 3
    alipay-payment-integration / composition-patterns / douyin-interact-creation
  $ opencli trae-solo mode
    - Mode: code
  $ opencli trae-solo mode work
    - Status: switched, Mode: work
  $ opencli trae-solo mode code
    - Status: switched, Mode: code   (verified by re-read)

Known limitations:
  · skill-search: React input event fires but Trae's marketplace may not
    re-filter from programmatic input alone (verified by post-search
    enumeration showing unfiltered results). Workaround: use skill-list
    + grep, or skill-category for category-based filtering.
  · skill-toggle / skill-run / skill-uninstall: clicks scheduled via
    Promise.resolve().then(...) — tolerant of 'Promise was collected'
    eval timeouts (same pattern as antigravity).

What still isn't shipped (UI doesn't expose):
  - Task delete/rename/pin/archive — confirmed not in UI
  - Settings panel — entry not found
  - Command palette — Cmd+Shift+P unresponsive
…ules)

Read commands (work even when Trae SOLO is closed):
  skill-fs-list / skill-fs-installed / skill-fs-show
  task-fs-list / task-fs-turns / task-fs-show
  user-rules

Write commands (--yes gated, default dry-run):
  skill-fs-install   (with --source to copy dir, --source-tag to label)
  skill-fs-uninstall (with --purge to also remove disk dir)
  task-fs-delete     (refuses if database.db-wal touched in last 5s)
  user-rules-set     (atomic tmp+rename)

Storage locations probed:
  ~/.trae/skills/                                — 49 installed skills
  ~/.trae/skill-config.json                      — managedSkills registry
  ~/.trae/user_rules.md                          — Trae's user-scope rules
  ~/Library/Application Support/TRAE SOLO/
    ModularData/ai-agent/snapshot/<uuid>/v2/.git — chat-turn git repo
    ModularData/ai-agent/agentconfig/<uuid>.json — per-task config + hooks

All commands use Strategy.LOCAL with browser:false (pure FS, no CDP).
Verified E2E: install + uninstall round-trip on a throwaway skill flips
managedSkills count 49→50→49 and creates/removes the on-disk dir.

These complement (not replace) the existing UI-driven skill-*/task-*
commands. The UI versions need Trae focused + visible; the fs versions
work headless but require Trae to be quit (or its file-watcher) for
writes to take effect.
…es / extensions)

  storage-keys [--filter]    — list 52 keys in globalStorage state.vscdb
  storage-get <key>          — read one value (auto-decode JSON, truncatable)
  recent-workspaces          — pretty-print history.recentlyOpenedPathsList
  workspaces-list            — enum workspaceStorage uuids + resolved folder paths
  extensions-list            — installed VSCode extensions

Reads ~/Library/Application Support/TRAE SOLO/User/globalStorage/state.vscdb
(VSCode-style ItemTable: key TEXT, value BLOB) by shelling out to
/usr/bin/sqlite3 (ships with macOS) — avoids pulling a native sqlite
dep into OpenCLI.

All READ-ONLY. Writing to state.vscdb while Trae runs would race with
its writer and corrupt the DB.

Exposes high-value state: recent workspaces (File → Open Recent menu),
currently-selected agent model, draft unsent messages per session,
recommended extensions, theme settings, panel hide states.
Lets the same two read commands target either:
  - the global state.vscdb (default), OR
  - a per-workspace state.vscdb (with --workspace <ws-id>)

Per-workspace DBs expose ~20 keys per workspace, including:
  chat.ChatSessionStore.index    — chat sessions belonging to that workspace
  chat.customModes               — user-defined modes scoped to workspace
  history.entries                — file edit history
  terminal                       — last terminal state
  vscode.git                     — git extension state

Avoids adding two near-duplicate workspace-storage-* commands.
…r + task-collapse-all)

Deep-audit pass enumerated every visible button on Trae's main view and
identified 3 wrap-worthy gaps (anonymous icon buttons hidden behind CSS
class names like .marketplace-upload-btn / .task-list-heading-action-btn.filter
/ .task-list-heading-action-btn.collapsed-expand):

  skill-upload <source> [--name] [--source-tag] [--yes]
       — install a local skill dir. Hybrid UI+FS: copies dir → ~/.trae/skills/,
         registers in skill-config.json (atomic), then clicks the marketplace
         Upload Skill button to trigger Trae's file-watcher refresh.
  task-filter
       — click the task-list filter icon and report visible filter menu items
         (All / Cloud / Local etc.).
  task-collapse-all [--expand]
       — click every visible task-list heading collapse button. Useful when
         sidebar has many task groups; --expand inverts.

E2E verified live against Leo's Trae SOLO:
  task-filter        → 10 items (All + per-workspace Cloud/Local pairs)
  task-collapse-all  → clicked 1 heading; --expand toggled it back
  skill-upload       → dry-run printed planned 3-step action correctly

Settings entry-point was searched for and NOT found via the renderer DOM:
clicking the user profile card (.userProfileWithCard-module__wrapper) does
not surface a menu. Trae's Preferences appear to be in the host-OS native
menubar (File > Preferences > Settings, Cmd+,) which is OUTSIDE the
Electron renderer's DOM and not reachable via CDP Runtime.evaluate. This
is documented as an intentional gap, not an oversight.

Brings Trae SOLO to 38 commands.
Cross-surface naming harmonization (matches PR jackwener#1798 Grok / jackwener#1799 Codex /
jackwener#1800 Antigravity):
  storage-* → renderer-side localStorage / sessionStorage (via CDP)
  state-*   → on-disk VSCode state.vscdb (via sqlite3)

Changes:
  - Renamed storage-keys → state-keys + storage-get → state-get
    (these query state.vscdb, kept their behavior 100% identical)
  - Added renderer-storage.js: storage-keys / storage-get / cookies / idb-list
    (CDP-based, query the Electron renderer's LS/SS/cookies/IDB)
  - Added settings.js: settings-read (parse User/settings.json, JSONC-aware)

E2E verified against Leo's Trae SOLO:
  state-keys --filter "AI.agent"  → 3 AI.agent.* keys (renamed, same behavior)
  settings-read                   → 1 key: AI.toolcall.v2.command.allowList

Known limitation: renderer storage-keys / storage-get / cookies / idb-list
return SecurityError on Trae SOLO because Trae's renderer runs under
vscode-file:// scheme with strict sandboxing — opencli's eval context
hits an isolated world without access to the main page's
localStorage/cookies/IndexedDB. Direct CDP probes (bypassing opencli's
session manager) CAN see the data (22 LS keys + @byted/ve-rtc IDB),
but the standard adapter pathway is blocked. Documented as a structural
limitation; the commands are wired correctly and will work on any Trae
build that relaxes the sandbox.

Brings Trae SOLO to 44 commands (38 + 1 settings-read + 4 renderer + 1
state-* alias gap).
@jackwener jackwener force-pushed the feat/trae-solo-adapter branch from 37fd015 to 4a45896 Compare May 31, 2026 16:50
@jackwener jackwener merged commit 1aec5c5 into jackwener:main May 31, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants