Skip to content

Feat/config webui - #391

Open
xiaoaf45 wants to merge 9 commits into
Tencent:mainfrom
xiaoaf45:feat/config-webui
Open

Feat/config webui#391
xiaoaf45 wants to merge 9 commits into
Tencent:mainfrom
xiaoaf45:feat/config-webui

Conversation

@xiaoaf45

@xiaoaf45 xiaoaf45 commented Sep 2, 2026

Copy link
Copy Markdown

Summary

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npx vitest run passes
  • Added/updated tests for the change

Related Issues

Notes for Reviewers

huangweizhao and others added 9 commits September 1, 2026 18:16
…roject scope

pull/init now append a marker-delimited block (.teamai/, .claude/, AGENTS.md)
to the business repo's .gitignore so teamai-synced paths stop showing up as
untracked-file noise. Idempotent, disabled via TEAMAI_MANAGE_GITIGNORE=0.
… with SSH-first fallbacks and branch tracking

Upstream sync:
- Base moved 0.20.0 -> origin/main (b8f5585 generic private-host provider,
  51a4372 official GitLab provider, REST v4 + PAT).
- Our SSH-first path ported on top of the official provider: banner-username
  auth when no token, scp-style ssh clone, prefilled MR form fallback,
  ensureInstalled no-op without token, push-to-create hint on createRepo.
- TEAMAI_GITLAB_HOSTS (comma list) accepted as alias of TEAMAI_GITLAB_HOST.

Branch tracking (product-line variants of one team repo):
- LocalConfig.repo.branch + teamai init --branch <name>.
- utils/branch-manager: pinCloneToBranch (fetch+checkout+tracking+set-head),
  ensureBranchState self-heal on pull (any repair invalidates rev cache),
  installed-skills ledger with diff-based orphan cleanup (only teamai
  installs are ever removed; user skills untouched).
- TEAMAI_BRANCH_PREFIX override for generateBranchName (pre-receive
  whitelists), business-repo .gitignore auto-manage (carried from fork).
The v2 integration commit (91eab85) was built from a tree where the
provider edits had been stashed away by an accidental git stash before
the gitignore cherry-pick; ssh-fallback.ts was committed as an orphan with
nothing importing it, and dist shipped the token-only upstream provider.

Restores: banner-username auth, scp-style ssh clone when no token,
prefilled MR form fallback, no-token ensureInstalled no-op, and the
TEAMAI_GITLAB_HOSTS alias. Verified: sshProbeUsername present in dist.
…nches

pinCloneToBranch created the local branch with checkout -b (forking from
the current HEAD, i.e. the default branch right after a fresh clone), so a
pinned clone sat on the wrong commit and every later  failed
with "Need to specify how to reconcile divergent branches". New machines
hit this on their very first init --branch.

- pinCloneToBranch: checkoutBranch(branch, origin/<branch>) so the local
  branch is born on the remote tip with tracking configured.
- ensureBranchState: fetch first, then detect true divergence via
  rev-list --left-right --count; realign to origin/<branch> with reset
  --hard (the pinned clone is a disposable mirror; discarded local-only
  commits are logged and stay recoverable via reflog). Also heals clones
  mis-pinned by the previous version.
- Real-git integration tests for both paths (bare-origin fixture whose
  clone lands on the default branch, like a real init).
…the remote

Product-line branches can get renamed (happened today: develop/linux_vdr_gps
-> develop/linux_vdr). Members' pull then failed with an opaque transport
error (rpc canceled / couldn't find remote ref) and stale local state.

- BranchVanishedError with an actionable message (check ls-remote, re-init
  --branch <new-name>, or edit config.yaml) raised by pinCloneToBranch and
  ensureBranchState via a cheap ls-remote existence probe.
- pull aborts the scope loudly on BranchVanishedError instead of silently
  syncing from a stale clone or the wrong branch.
- Real-git test covering the rename scenario (remote branch deleted).

Also verified in production today: skill deletions committed directly to
the tracked branch DO propagate to members via the installed-skills ledger
(Removed skill 'debug-target'/'embedded-workflow' on pull).
…gate

copyDir is merge-style (overwrite same-name files, never delete extras), so
a cleanup commit inside a skill (e.g. removing stale reference docs from
app-api-ref) never reached members' machines: the installed copy kept the
deleted files forever (observed in production: repo 69 files vs member
install 135, with api/app, api/dal, api/port lingering).

pullItem now removes the installed dir before copying. The dir is fully
teamai-owned (ledger-tracked), so wholesale replacement is safe, and skill-
internal file deletions now sync on pull like whole-skill deletions do.
Six-tab local web console (teamai config ui, 127.0.0.1:3722) plus the
teamai config list/get/set CLI family sharing one validation pipeline:

- config-fields.ts: field registry (single source of truth for CLI +
  UI form + validation); coverage test enforces every editable
  LocalConfigSchema key is classified exactly once
- config-service.ts: readConfigBundle / applyConfigPatch (zod-validated
  single write channel) with afterSave side effects reusing
  branch-manager pin and recall-toggle artifact routines
- config-ui.ts: zero-dependency HTTP server with loopback-only bind,
  no CORS headers, Origin/Host guards, 1MB JSON body cap; repo/branches/
  roles/resources/preview/recall APIs read-only toward the team repo
- config-ui-jobs.ts: job runner spawning init --branch -> pull --force
  (injectable spawn; ls-remote whitelist guards branch input; busy 409)
- config-ui-html.ts: single-file Chinese-first UI, six tabs (repo/
  branches/roles/resources/settings/sync), diff-preview settings form,
  live job log console, preview drawer; env values never serialized
- WebUI text is Chinese per direct user request (recorded in the design
  doc); CLI output stays English per repo convention
- bilingual README + usage-guide chapters; 8 new test files (87 tests),
  full suite 2542 green
@jeff-r2026
jeff-r2026 self-requested a review September 2, 2026 09:10
@jeff-r2026

Copy link
Copy Markdown
Collaborator

Thanks for this PR! The direction is great — this visual config Web UI is essentially what #17 (Skills visual console) is asking for. I'd suggest linking them: add Closes #17 (or Related to #17) to the Related Issues section so both sides connect.

A few things I'd like to align on before merging:

1. Please don't add a new command / new server — consolidate under teamai dashboard

Right now the PR adds a teamai config ui subcommand and spins up a separate web server (startConfigUi, port 3722). But we already have teamai dashboard (port 3721, src/dashboard.ts), which is a complete local Web UI (GET / serves HTML + /api/* serves JSON + /events for SSE).

Two local Web UIs + two ports + two visual styles is fragmented from a user's perspective. I'd suggest instead: add a new page/tab inside the existing dashboard (e.g. "Config" / "Skills"), reuse the same HTTP server, and add routes like /api/config, /api/skills. No new config ui subcommand. This keeps ports, navigation, and visual style unified.

2. Match the dashboard's visual style

Please reuse the existing styling from dashboard-html.ts (colors, layout, component style) for the new page, so we don't end up with two different design languages.

3. Please remove build artifacts from the PR

This PR commits dist/index.js (~39.5k lines) and dist/index.js.map. These are build outputs and shouldn't be checked in — please drop them.

4. Split out unrelated changes

The PR also includes changes to gitlab/ssh-fallback.ts, utils/branch-manager.ts, pull.ts, etc., which aren't directly related to the config webui. If they aren't required by this PR, please split them into a separate PR; if they are dependencies, please note that in the description.

The core ask is just one line: make this a new page inside teamai dashboard, not a new command / new server. The rest of the functionality (list / enable / disable / per-skill model config) is all great — looking forward to merging once adjusted 🙏

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