Skip to content

Go CLI core + swarm office topology & preview fixes#2

Merged
ybz21 merged 29 commits into
mainfrom
feat/go-cli-core
Jun 23, 2026
Merged

Go CLI core + swarm office topology & preview fixes#2
ybz21 merged 29 commits into
mainfrom
feat/go-cli-core

Conversation

@ybz21

@ybz21 ybz21 commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

本分支推进 Go 版 ttmux CLI 的核心能力,并完善 swarm「办公室」拓扑视图与文件预览体验。

Go CLI (cli/ttmux-cli-go)

  • 扩展命令架构、精简包布局(session / group / env / swarm / runtime)。
  • 加入 swarm status core,并让 ls --json / info --json 的原生列表隐藏 swarm 持有的 tmux 会话,对齐 shell CLI 的 _is_swarm_session

Swarm 拓扑(前端)

  • 新增动画化「办公室」拓扑视图:小人/工位/显示器、阵型默认值、移动端适配、空闲状态检测等。
  • 修复办公室视图里成员名字药丸(top:-18px)被 foreignObject 裁掉、看不见的问题——顶部预留 headroom 并允许溢出。

其他 UI 修复

  • 文件预览:代码 / JSON 现在撑满预览面板高度,而非被 420px 上限截断(CodeBox/Markdown 新增 fill 模式)。
  • 把 Claude 品牌标识的 🤖 emoji 换成品牌色星芒 ✳,与 Codex 的 ✸ 风格对齐(会话列表、标签栏、聊天标题、swarm 新增成员)。

Test

  • npx tsc --noEmit 通过(前端)。

🤖 Generated with Claude Code

ybz21 and others added 29 commits June 22, 2026 17:02
Wire swarm session detection into `ls --json` / `info --json` so the
native Go listings skip swarm-owned tmux sessions, matching the shell
CLI's _is_swarm_session behaviour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- File preview: code/JSON now fill the panel height instead of capping
  at 420px (add a `fill` mode to CodeBox/Markdown).
- Swarm office topology: give the foreignObject top headroom so the
  member name pill (top:-18px) is no longer clipped and stays visible.
- Replace the 🤖 emoji on Claude brand badges with a brand-colour ✳
  star to match the Codex ✸ style (session list, tabs, chat title,
  swarm add-member).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port the entire ttmux command surface from the bash CLI to native Go, so the
binary is fully standalone (only tmux at runtime — no bash, python3, or
sqlite3 CLI) and cross-compiles with CGO_ENABLED=0 to linux/macOS/*BSD.

- session/window/pane, task orchestration (spawn + claude/codex agent launch),
  env, info, help, completion, and the interactive menu — all native.
- swarm data plane via pure-Go modernc.org/sqlite with parameterized queries:
  new/add/done/activate/adopt/ls/status/collect/archive/rm/sql, dependency
  engine, plaza (say/feed/watch/listen), board (task/board), migrate.
  Byte-compatible with the bash CLI on the same meta.db/swarm.db.
- Agent mode (TTMUX_AGENT=1 / -q): colors off, messages to stderr, stdout
  carries only data (e.g. cid=$(ttmux -q swarm task add ...)).
- e2e/e2e.sh: 74-check end-to-end suite (isolated tmux + temp dirs) plus a
  Makefile (build/test/vet/e2e/dist).
- install.sh: hybrid — build the Go binary when a Go toolchain is present,
  otherwise fall back to the bash script.

The bash CLI under cli/ttmux-cli/ is retained for reference and interop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The root `ttmux`/`chrome` were generated build outputs checked into git
(consumed by install via cp/raw-download). Remove them from the repo and
.gitignore them; install now produces them instead of copying committed files:

- local checkout: build from source (ttmux → go build, falling back to the
  bash build.sh when no Go toolchain; chrome → cli/chrome-cli/build.sh)
- curl|bash remote: download prebuilt assets from the latest GitHub Release
  (ttmux-<os>-<arch>, chrome)
- .github/workflows/release.yml builds the five ttmux binaries + chrome and
  uploads them on tag push (and Makefile `dist` names match the release assets)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The backend reads data via TTMUX_BIN=$(pwd)/ttmux. Now that the generated
ttmux is no longer committed, build it from cli/ttmux-cli-go on startup
(incremental, like the frontend/backend builds) so the dev UI always has a
current binary to call. Without this a fresh checkout had no ./ttmux and the
web UI showed empty data.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Run install.sh on startup (builds ttmux/chrome into ~/.local/bin, syncs
skills, installs completion) and point TTMUX_BIN at the PATH `ttmux` instead
of the repo-root artifact. The generated ttmux/chrome are never committed and
no longer need to live in the repo root for the backend to find them.

Replaces the previous repo-local ./ttmux build step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Narrow strip: hidden tabs (display:none) never fit, so terminals stayed
at the default 80 cols and rendered as a left strip. Guard sendResize
against zero-size/hidden elements, retry fit across rAF frames on tab
activation, and set tmux window-size=latest + aggressive-resize on each
attach so a smaller/background client no longer shrinks the active one.

Mojibake: tmux renders CJK by the client locale and `ls` by the pane
shell locale; under C/POSIX they garble. Ensure a UTF-8 locale for the
web attach (utf8Env in pty.go) and for the shell CLI (00-header.sh),
only when the inherited locale isn't already UTF-8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PWA: register a minimal service worker (passthrough for /api + WS,
network-first navigation, cache-first hashed assets) to meet Android
installability, plus a usePwaInstall() hook and an "Install app" entry
in the sidebar, mobile "more" menu and Settings. Shows a native prompt
when available, otherwise a per-platform (iOS/Android/desktop) guide;
hides once running standalone.

Also commits the Git panel feature already present in the working tree
(backend/api/git.go, GitPanel.tsx, git.* i18n, right-drawer wiring) so
the shared files (App.tsx, i18n) compile as one buildable snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Go CLI:
- swarm new --dir <d>: mkdir the working directory and pass it to the
  Leader (adopt), so the Leader session cd's into it. adopt also mkdir's
  a real --dir. Backend already threads dir/adopt; this makes the native
  CLI honor it end-to-end.

Frontend (Swarm topology + detail header):
- Draw the Leader vertex from detail.supervisor when a swarm has a Leader
  but no members yet. Previously the layout returned an empty graph
  (all.length===0 && !masterMember), so a freshly created swarm showed no
  node at all — the Leader was running but invisible.
- Truncate an over-long swarm goal in the detail header to a single line
  with a hover Tooltip (scrollable, preserves newlines) instead of letting
  a 96-line goal blow up the header bar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
自动拉起的 Leader(swarm new / adopt)原来只发裸 /cc-swarm,导致它
不拆任务派活、自己闷头把活全干完。改为渲染开场白模板下发:

- 新增 backend/api/prompts/auto_leader.md.tmpl:身份/目标/工作目录/
  可用 skill/必读 cc-swarm + 完整生命周期 + 「严禁单干」硬性要求;
  无目标时切纯监护文案。
- backend/api: 抽出 renderPrompt(),新增 renderLeaderKickoff();
  SwarmNew(master) 经 --leader-prompt、SwarmAdopt 经 --prompt 下发。
- CLI: swarm adopt 加 --prompt、swarm new 加 --leader-prompt;
  adopt() 收到 prompt 即用作开场白,否则回退裸 /cc-swarm。多行 prompt
  落盘后用 "$(cat …)" 注入,避免换行被 send-keys 当回车提前执行。

一并提交本分支其余在途改动(browser screencast、chrome-cli、
frontend、install.sh、skills 同步等 WIP)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ybz21 ybz21 merged commit e348ad1 into main Jun 23, 2026
2 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.

1 participant