#14397 split `shared/types.ts` into 46 per-domain modules but kept the path as
a re-export barrel so the import sites did not have to change. This removes
the barrel: every consumer now imports from the module that actually declares
the type, and `src/shared/types.ts` is deleted.
Barrels hide where a type lives, make every consumer look like it depends on
the whole domain, and let an unrelated edit invalidate a module that ~2,000
files transitively import.
2,323 import declarations across 2,321 files. Rewritten mechanically: each
specifier was resolved to an absolute path via the TypeScript AST and
recomputed, rather than string-substituted, so alias forms (`@/../../shared/
types`) and per-specifier `type` modifiers survive.
Four cases the mechanical pass had to handle, each found by a gate rather than
by reading the diff:
- Modules inside `src/shared` import the barrel as `./types`, not
`shared/types`. A pre-filter on the latter string skipped 176 of them and
left imports dangling at a deleted file, which surfaced as confusing
`Property 'x' is optional in type 'Repo' but required in Pick<Repo, ...>`
errors rather than "module not found".
- The barrel RENAMED one type on the way through
(`WorkspaceSource as WorkspaceCreateTelemetrySource`), so the original name
in the owning module has to be re-aliased at each consumer.
- Three test files put `;(globalThis as ...)` on the line after the import.
TypeScript parses that `;` as the import statement's terminator, so
replacing through `statement.getEnd()` deletes it and breaks ASI. The
rewrite now stops at the module specifier.
- A file that already imported directly from a module got a SECOND import
from it, because the barrel re-exported those same names — which trips
`import/no-duplicates` under `--deny-warnings`. A post-pass merges
declarations sharing a specifier and type-only-ness; the `import type` plus
`import` pair from one module is left alone, since that form is allowed.
Splitting one barrel import into several genuinely adds lines, which pushed
`terminal-layout-pty-ownership.ts` to 301 counted lines: its 107-character
import must wrap, and neither local type collapses onto one line (101 and 116
characters). Rather than contort a type declaration to fit a line budget,
`collectLeafIds` and `pruneLeaves` move to `terminal-pane-layout-tree.ts` —
they are pure structural operations on the layout tree and independent of PTY
ownership. `visible-worktrees.ts` similarly loses its own mini-barrel
re-export of `isDefaultBranchWorkspace`, with the four real consumers
repointed at the declaring module. No `max-lines` bypass added.
Verified: cold `tsc --noEmit` green on node, cli, and web (buildinfo deleted
first — these projects are `composite: true` and reuse stale caches); the full
`pnpm lint` green, not just bare oxlint — the narrower local check is what let
the duplicate imports reach CI; max-lines ratchet OK at 344.
* feat: [AI-GEN] add Trae CLI as a supported TUI agent
Closes#10579.
Wire trae-cli into the desktop and mobile agent catalogs following the
same integration pattern as other CLI agents (e.g. Ante, Devin):
- src/shared/types.ts, tui-agent-config.ts: register 'trae' with
detectCmdAliases (traecli/trae-agent) and argv prompt injection,
matching trae-cli's `trae-cli [prompt]` contract. The CLI's own
third documented alias `ta` is intentionally excluded — too generic
a 2-letter name to use as a PATH-existence detection signal without
false-positiving on unrelated tools.
- src/shared/trae-headless-command.ts: recognize `--print`/`-p` and
`--output-format json|stream-json` as one-shot headless invocations
(same shape as claude-headless-command.ts) so they aren't mistaken
for a live interactive session.
- agent-kind.ts, telemetry-events.ts, agent-status-types.ts,
agent-type-label.ts, tui-agent-display-names.ts,
tui-agent-permissions.ts (YOLO via trae-cli's own --yolo flag),
tui-agent-selection.ts: standard per-agent registrations.
- agent-catalog.tsx, agent-favicon-assets.ts,
mobile/src/tasks/mobile-tui-agents.ts,
mobile/src/components/mobile-agent-icon-assets.ts: catalog entries
and bundled favicon (fetched from docs.trae.cn, required by mobile's
offline-icon invariant test).
- i18n: add the "Trae" label to all five locale catalogs (en/es/ja/ko/zh).
- Tests: agent-process-recognition, agent-status, tui-agent-startup.
Verified with `pnpm typecheck` (desktop + mobile), the relevant vitest
suites (869 tests across 12 files, all green), oxlint (clean), and a
real end-to-end launch of the actual trae-cli binary through Orca's
pty.spawn IPC path (confirmed via the OS process table).
* fix: [AI-GEN] point Trae catalog entry at the real CLI quick-start doc
docs.trae.cn/cli (what the installed CLI's own --help text prints as
its "User manual" link) soft-404s — the docs site restructured and the
working page is docs.trae.cn/cli_get-started-with-trae-cli (confirmed
by HTTP fetch: real page title "TRAE CLI 快速开始" vs the old path's
"404 - 页面不存在"). Addresses CodeRabbit's homepageUrl review comment.
* fix: [AI-GEN] detect Trae on traecli, not the ambiguous trae-cli name
Per @AmethystLiang's review: the open-source bytedance/trae-agent
project (MIT, ~12k stars) registers its own console script as
`trae-cli` (pyproject.toml: `trae-cli = "trae_agent.cli:main"`), an
entirely unrelated CLI with a different contract (`trae-cli run
"task"`, `-p` short for `--provider`). Detecting on bare `trae-cli`
would false-positive on that project's installs and break launch for
anyone who has it instead of the actual TRAE CN CLI.
- tui-agent-config.ts: detectCmd/launchCmd/expectedProcess -> `traecli`
(TRAE CN's own installer symlinks this alias too, but the other
project does not ship it). Dropped the `trae-agent` alias entirely —
it's the colliding project's literal repo name, the highest
false-positive string available.
- agent-catalog.tsx: cmd -> `traecli` to match; faviconDomain ->
`www.trae.cn` (bare `trae.cn` 404s on Google's favicon service;
`www.trae.cn` is the product-root domain that actually resolves).
- mobile-tui-agents.ts: faviconDomain -> `www.trae.cn` to match.
- Tests updated: agent-process-recognition now asserts `trae-cli` and
`trae-agent` are NOT recognized as Trae (regression guard against
reintroducing the collision); tui-agent-startup updated for the new
launch command.
promptInjectionMode stays `argv` and the headless-command file stays
as-is — both verified against the real TRAE CN CLI's actual --help
output (pasted in the PR review thread), not assumptions.
* refactor: [AI-GEN] share one print-mode headless matcher across agents
trae-headless-command.ts was a rename-only fork of claude-headless-command.ts,
and ante-headless-command.ts carried a third copy of optionName. Collapse both
print-mode files into print-mode-headless-command.ts, dispatch from a
Partial<Record<TuiAgent, ...>> table instead of an if-chain, and compress the
Trae comments to the repo's one-line style.
* fix: [AI-GEN] terminate Trae flag parsing before the positional prompt
`traecli` is a Cobra CLI with subcommands, so an argv prompt starting with
`help`, `config`, `-…` was dispatched as a subcommand or flag instead of being
run as the task. Add `argvPromptSeparator: '--'` (same reason Grok has it), and
stop the shared print-mode headless matcher at `--` so a prompt that reads like
`--print` no longer drops the pane out of agent recognition.
* docs: [AI-GEN] name both Trae CLIs explicitly in the detect-name comment
Co-authored-by: Orca <help@stably.ai>
* docs: [AI-GEN] drop the vendor tag from the Trae union comment
Co-authored-by: Orca <help@stably.ai>
* fix: [AI-GEN] guard the nullable startup plan in the Trae separator test
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: 陈泽榜 <chenzebang@jianzhikeji.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>