Feat/config webui - #391
Conversation
…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.
…s/roles/resources/recall)
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
|
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 A few things I'd like to align on before merging: 1. Please don't add a new command / new server — consolidate under Right now the PR adds a 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 2. Match the dashboard's visual style Please reuse the existing styling from 3. Please remove build artifacts from the PR This PR commits 4. Split out unrelated changes The PR also includes changes to The core ask is just one line: make this a new page inside |
Summary
Type of Change
Test Plan
npx tsc --noEmitpassesnpx vitest runpassesRelated Issues
Notes for Reviewers