docs: snapshot of the project's Claude Code memory

Decisions, environment quirks and pitfalls learned while working on AgentHub
(docs/claude-memory/, indexed by MEMORY.md). Notes holding personal account
details are left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 15:27:35 +07:00
parent d72a255294
commit 9c573f1e3c
28 changed files with 721 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
- [AgentHub release state](agenthub-release-state.md) — v2.7.4 released 10-12 (b3fe10a4, release 571); v2.7.3 = 5d8fc9bb/570; v2.7.2 = 3a8be55b/569; v2.7.1 = 2fd0c903/568; v2.7.0 = f6f1bf4a/567; v2.6.2 = f0dc1445/566; notes EN then VI, never mention server mode or roles
- [Plugin update chicken-and-egg](agenthub-plugin-update-chicken-egg.md) — installs ≤1.5.9 can never see a release; one manual command per machine.
- [Test env quirks](agenthub-flaky-codex-ingest-tests.md) — NODE_ENV=test for client/commit; npm install needs NODE_ENV=development --include=dev (else dev deps pruned); rtk hides output; kill orphan vitest workers after a hung run; test servers need env -u TMUX; pre-commit in a linked worktree sets core.bare=true; pane env AGENTHUB_MODE + AGENTHUB_USERS_ROOT break server tests (env -u ALL AGENTHUB_* vars)
- [macOS auto-start](agenthub-no-launchd-on-macos.md) — LaunchAgent built 09-25, untested on a real Mac; checklist in INSTALL.md § macOS
- [No agenthub agents/skills](no-agenthub-agents-skills.md) — never dispatch agenthub:* agents or skills; too quota-heavy
- [agy auto-updates on any run](agy-auto-updates-on-run.md) — spike run replaced ~/.local/bin/agy 1.0.0→1.2.13; warn first
- [Multi-user server goal](agenthub-multi-user-goal.md) — server MODE, no fork, released v2.6.0; prod :4820 = system unit on worktree server-s3 (moved to v2.7.1 on 10-12); plan in docs/plans/server-mode/
- [Remote clients plan](agenthub-remote-clients-plan.md) — 10-09: users run AgentHub local, hub keeps accounts+records; account only via AgentHub; plan docs/plans/remote-clients
- [NEVER tmux kill-server](never-tmux-kill-server.md) — $TMUX beats TMUX_TMPDIR; it killed the real server + this session twice
- [Analytics parity plan](analytics-parity-plan.md) — phases 2–7 shipped in v2.4.0; ../agenthub-analytics now redundant; OpenAPI for new routes still missing
- [Dev/prod ports share one DB](agenthub-dev-prod-ports.md) — 4820 prod (systemd), 4830 user's dev in Warp; same dashboard.db, dev migrations hit prod
- [Workspace rename step 4](workspace-rename-step4.md) — remove `agenthub lanes`/`--lane` only ≥3 releases after aliases ship; never rename stored data
- [No git stash here](no-git-stash-shared-checkout.md) — parallel sessions share this checkout; use a worktree to test clean HEAD
- [Update never kills panes](update-never-kills-panes.md) — updates/restarts keep tmux lane panes; only Quit AgentHub (#65) closes them; KillMode=process
- [Claude Code changelog ≤2.1.295](claude-code-changelog-2-1-293.md) — 2.1.285–295 (to 10-08): hooks onFailure:block (keep AgentHub fail-open), OSC 7501 tested (no use), Workflow scriptPath rules
- [Claude Haiku 5.5](claude-haiku-5-5.md) — 10-07 release, $0.10/$0.50 split at 100k prompt; AgentHub models it as long_* subset columns (not a PK dim)
- [Remove ineffective skills](remove-ineffective-skills.md) — delete skills with no effect or that lower quality; judge by usage/eval evidence
- [Link = learn & remember](link-means-learn-and-remember.md) — a bare docs/changelog URL means: extract what is useful for me, save to memory, no code changes
- [Claude Code @mention line range](claude-code-line-mention-syntax.md) — only `@path#L5-10` reads lines; `#5-10` attaches the whole file
- [Server box hardware](agenthub-server-box-hardware.md) — 4c/15GB, HDD bind mounts caused lag; AgentHub ok to ~100 hooks/s+10 viewers; reinstall all-SSD, HDD for backups
- [S3→main merge notes](s3-main-merge-notes.md) — tmux capturePane/sendKey → onServerOf, drop route via dropDir+member uid, one onServerOf only
- [/tmp wiped on reboot](tmp-wiped-on-reboot.md) — keep long-run scripts/renders in ~/.cache/<project>/ (tri-vi pipeline: ~/.cache/tri-vi-bake/)
- [OSC 7501 vs hooks](osc7501-vs-hooks.md) — tested: no replacement for hooks; needs a probe reply, never reaches through tmux; only a per-pane pty proxy would work
- [Fast bump/release](fast-bump-release.md) — release quickly: no full suites, --no-verify — but ALWAYS `tsc -b` (v2.7.0 broke every update)
- [Sandbox browser repro](agenthub-sandbox-browser-repro.md) — isolated server+build+playwright-core on :4899; no login, never the user's tmux
- [Instructions for other tools](instructions-other-tools.md) — only Claude/Codex take them; Cursor plugin-dir gated by server flag, agy global-only (tested 10-12)
+13
View File
@@ -0,0 +1,13 @@
# Claude Code project memory (snapshot)
A copy of the auto-memory Claude Code keeps for this project
(`~/.claude/projects/<project>/memory/`): one fact per file, indexed by
`MEMORY.md`. It records decisions, environment quirks and pitfalls learned
while working on AgentHub that the code and git history do not show.
- It is a SNAPSHOT: the live copy is the one on the developer's machine, and
this folder changes only when someone copies it again.
- Notes that hold personal account details (Keychain item names, personal
GitHub/Supabase/Vercel accounts) are left out on purpose.
- Every note reflects what was true when written; check a named file, flag or
command still exists before relying on it.
@@ -0,0 +1,15 @@
---
name: agenthub-dev-prod-ports
description: "4820 = production (systemd, plugin cache build), 4830 = the user's dev server from the checkout in Warp — both on the SAME dashboard.db"
metadata:
node_type: memory
type: project
originSessionId: e662d0be-af24-4c90-9939-45acfd40e6c3
modified: 2026-10-05T09:07:39.143Z
---
Port 4820 is production (`agenthub.service`, plugin-cache release build); port 4830 is the user's dev server (`DASHBOARD_PORT=4830 node server/index.js` from the checkout, started by hand in a Warp terminal). As of 2026-10-05 both use the same `~/.claude/agenthub/dashboard.db`.
**Why:** a dev server's migrations run on production data (ad6e801 dropping `idx_events_session` froze prod's `/api/workflows`), and every checkout start re-wrote duplicate hooks into `~/.claude/settings.json` (fixed 10-05 in `installHooks`). Hooks reach only the lowest port, so 4830 receives no hook traffic of its own.
**How to apply:** when diagnosing lag, check BOTH ports and which code each runs; a hung 4830 is the user's dev instance — tell them to restart it, never kill it yourself. Suggest a separate `DASHBOARD_DATA_DIR` for dev when schema changes are involved. Related: [[agenthub-multi-user-goal]], [[agenthub-flaky-codex-ingest-tests]].
@@ -0,0 +1,48 @@
---
name: agenthub-flaky-codex-ingest-tests
description: Client suite needs NODE_ENV=test in this shell; rtk wrapper hides prettier/grep output; old flaky codex-ingest tests removed 09-25
metadata:
node_type: memory
type: project
originSessionId: 073fe263-c67b-478a-860e-b8fc3028000e
modified: 2026-10-07T03:36:34.531Z
---
This shell exports `NODE_ENV=production`, which breaks the whole client suite
with "act(...) is not supported in production builds" (567 failures). Run client
tests as `cd client && NODE_ENV=test npx vitest run`. The pre-commit hook (`.husky/pre-commit`) runs the client suite too, so commit as `NODE_ENV=test git commit …` or it aborts with ~570 act() failures.
`server/__tests__/codex-ingest.test.js` used to be flaky (1–4 failures per run on
a clean tree, stage-detection cases). On 2026-09-25 codex lanes lost their
pipeline and the file was rewritten to cover only the idle↔running mirror; the
suite ran 1974/1974 green afterwards.
**Why:** a red client run here is usually the env, not the change.
**How to apply:** always set `NODE_ENV=test` for client tests; if codex-ingest
turns flaky again, treat it as a new issue — the old cause is gone.
2026-09-28: `codex-ingest.test.js` "a second pass with nothing new changes nothing" failed once in a full `npm run test:server` (1 !== 0), passed 3/3 alone and on the full rerun — still timing-flaky under load; rerun before chasing it.
2026-09-29: the shell's `rtk` wrapper hides/mangles output of `npx prettier --check`, `grep` (regex with `\|` or `(` errors) and `git diff`. Use `node node_modules/prettier/bin/prettier.cjs --list-different`, `command grep -F -e … -e …`, and python `subprocess.run(["git","diff",…])` instead.
2026-10-01: `npm install` under the shell's NODE_ENV=production PRUNES dev deps (vitest, @types → tsc breaks). Install as `NODE_ENV=development npm install --include=dev`.
2026-10-02: a preview server started from the checkout with `DASHBOARD_DATA_DIR=<tmp>` REWRITES the real `~/.claude/settings.json` hooks at startup (`installHooks` sees no `<data dir>/runtime/state.json`, so thinks no plugin). That time it only reordered existing checkout entries, but check `settings.json.agenthub-bak` after any such preview. Also never `pkill -f "<pattern>"` with a pattern typed in the same command line — it kills the calling shell (exit 144); kill the preview by its port's pid.
2026-10-02: SAFE preview recipe — run the checkout's server with HOME=<tmp>/home (plus temp DASHBOARD_DB_PATH/DATA_DIR/SETTINGS_FILE, DASHBOARD_PORT other than 4820/4899, DASHBOARD_RUN_HEAL_MS=0, AGENTHUB_PRICING_SYNC=0, AGENTHUB_AI_TOOLS_SYNC=0) so installHooks/refreshScript write into the fake home, never ~/.claude or ~/.codex. Build first: `cd client && NODE_ENV=production npx vite build`. No playwright here: screenshot with `google-chrome --headless=new --screenshot=...` or a small CDP script (Node has WebSocket) to set localStorage / click. A leftover smoke server from an earlier session listens on :4899 (DB /tmp/ahsmoke) — not the user's. Write memory files with a QUOTED heredoc (<<'EOF'): an unquoted one executed the backticks in the text.
2026-10-02: the pre-commit hook exports GIT_INDEX_FILE (and possibly GIT_DIR) into the test suites. A test git helper that inherits them acts on AgentHub's own repo, so strip every `GIT_*` variable from its env.
**Runaway vitest workers (2026-10-03):** killing a hung `vitest run` parent left its `node (vitest N)` workers spinning (load avg 60), which made the pre-commit hook fail on unrelated 5 s timeouts and made the user's dashboard lag. After any killed/timed-out vitest, `pgrep -af "node (vitest"` and kill the workers too. Run the full client suite BEFORE committing — the hook aborts on a snapshot change (Settings snapshot caught me once).
2026-10-05: `git commit -- <paths>` (partial commit) gives the hook a temp ABSOLUTE `GIT_INDEX_FILE`, so the two `POST /api/lanes/worktree` tool tests fail with "invalid object … .agents/skills/release-guard" — stage with `git add` and commit plainly. The hook also tests the WORKING TREE, not the index: with another session's WIP in the tree it fails on their files. Then verify the exact snapshot in a temp worktree (`git worktree add --detach /tmp/x HEAD`, `git apply --index` the staged patch, symlink root + client node_modules, NODE_ENV=test vitest + tsc), re-check the index is unchanged (`git diff --cached --binary | cmp - patch`), commit `--no-verify`, and say so to the user.
2026-10-07: NEVER let `.husky/pre-commit` run inside a LINKED worktree (`git worktree add`). There git exports an absolute `GIT_DIR` to the hook; `lanes-api.test.js`'s bare `execSync("git init")` then reinitialises the SHARED repo and sets `core.bare = true` in the main checkout's `.git/config` — every status/commit/pull breaks ("must be run in a work tree"). It also left stray "init" commits on the worktree HEAD. Commit in a scratch worktree only with `--no-verify`, or repro in a plain `git clone --local` (safe: GIT_INDEX_FILE is relative there).
2026-10-06: `.husky/pre-commit` now runs only RELATED tests for a small commit (≤ 10 code files, no package/config/hook/deleted file): `vitest related` for client/, server tests naming the staged module; docs-only runs nothing; `AGENTHUB_FULL_TESTS=1` forces both full suites (use it for a release commit). Its frontend run sets NODE_ENV=test itself. A locale JSON change still pulls ~50 client test files (everything imports i18n).
- Something on this host listens on :3000 (seen 2026-10-07), so 3 lane-profile tests (checkProfile, "end to end: init -> check -> real boot") fail with EADDRINUSE — environmental, not a regression. AlertsNotifications.spend.test can flake under full-suite load; passes alone.
2026-10-09: a session started from a server-mode AgentHub pane inherits `AGENTHUB_MODE=server` (+ AGENTHUB_LANE_ID/PANE_TOKEN/RUN_ID/USERS_ROOT/FILE_KEYS). Server tests then answer 401 everywhere (lanes-api: ~200 failures, log says "Server mode: every page and API call needs a login"). Run as `env -u TMUX -u AGENTHUB_MODE -u AGENTHUB_LANE_ID -u AGENTHUB_PANE_TOKEN -u AGENTHUB_RUN_ID -u AGENTHUB_USERS_ROOT -u AGENTHUB_FILE_KEYS npm run test:server`. The full server suite can exceed 15 min when other sessions test in parallel — don't wrap it in `timeout 900`. Client full-suite under that load failed 16 tests in CcConfig/AddLaneModal/DiffEditor/AiProxyConfig; all 80 passed alone.
@@ -0,0 +1,45 @@
---
name: agenthub-multi-user-goal
description: Multi-user AgentHub server — built as a server MODE inside AgentHub (no fork); plan in docs/plans/server-mode/ (AgentHub-Server repo deleted 2026-10-09)
metadata:
type: project
---
Goal (user, 2026-10-02): AgentHub as a shared web server — login, one folder per account on the shared disk, each user sees only their own stats/tokens/prompts; admin sees and manages all; data analysts analyse token use and prompts; a shared AI Router (key exposure is not a concern); every user can switch the shared Claude native / Codex accounts and use every installed tool without reinstalling or logging in again. Company is on Claude Enterprise, one seat per person.
The plan was first kept in a separate AgentHub-Server repo. The user deleted that repo on 2026-10-09, and its README now lives in AgentHub as docs/plans/server-mode/README.md (branch s3-followups). There is one source now: AgentHub.
**Why:** the local app is still moving fast; a fork now would mean merging every change twice.
**How to apply:** build the server features as a server MODE inside the AgentHub codebase, off by default. Deployment pieces live in AgentHub too (scripts/server/, docs/SERVER-MODE.md). Fork only from a tagged stable release. User said "từ từ" — do the local work first.
**Progress:** 2026-10-06 the user confirmed one codebase + an install-time choice (`agenthub server setup`) over a separate add-on package, and S1 was built UNCOMMITTED: `server/lib/auth.js`, `/api/auth`, `users`/`auth_sessions`, `AuthGate.tsx`, `agenthub server|users`, docs/SERVER-MODE.md. 2026-10-07 the user chose: admin signs every Claude account in, each new session auto-balanced on usage/quota/$ — built the Claude account pool (server/lib/claude-pool.js, setup-tokens via CLAUDE_CODE_OAUTH_TOKEN, `agenthub accounts`), also uncommitted; user said "commits sau". 2026-10-07 S2 ownership + S6 basics + review fixes built (server/lib/scope.js, audit.js, routes/users.js, pane tokens); checklist docs/plans/server-mode/CHECKLIST.md; still uncommitted. Left: S0 spike, S3 (Linux user per account), S4 — all need sudo on a host.
**2026-10-08 scope decided** (user's 7 asks): own workspaces/sessions/stats (S2 done) + own Linux user (S3) + own skills/plugins = admin baseline + user adds own + own AI Proxy = per-user store PLUS admin's shared proxies visible to all (no key leak) + shared tool binaries (/opt, S4) + shared Claude native pool (done) + NEW Codex multi-account pool (like claude-pool). User allowed the S0 spike with sudo ON THIS MACHINE (test users agh-test1/agh-test2; log every command for undo). Checklist: docs/plans/server-mode/CHECKLIST.md.
**2026-10-08 plan review decisions** (full plan: docs/plans/server-mode/S3-PLAN.md): hidepid=invisible mandatory; HIDE shared proxy keys via an AgentHub loopback gateway (pool OAuth tokens excluded); Codex ChatGPT accounts used CONCURRENTLY (user overrode the safe 1-pane default → P7 starts with a real-account spike; report back if codex self-refresh logs others out); members get NO managed-worktree mode and NO runtime layer (EMEMBERLANE). Read access = system unit + CAP_DAC_READ_SEARCH, but NOT NoNewPrivileges/CapabilityBoundingSet (they break sudo -u). Hooks auth = peer uid via /proc/net/tcp (verified). Code waits on branch `server-s3`; commits only on ask.
**2026-10-08 progress:** worktree `.claude/worktrees/server-s3` (branch server-s3, node_modules symlinked to main's, UNCOMMITTED). P0 (ai-tools config staff-only, member cc-config cwd scoped), P1 (personal proxies `u<id>_<slug>`), P1b (proxy key gateway /api/proxy-gw, server mode only; real claude+codex verified) DONE. Next P2 needs sudo + a decision on how far to touch this dev box (prod dashboard runs here as user unit on 4820). Single-suite runner: /tmp/agh-spike/t1.sh (REPORTER=spec).
**2026-10-08 P2 INSTALLED on this machine** (user chose full install): prod dashboard :4820 now = SYSTEM unit agenthub.service running the server-s3 WORKTREE code (env file ~/.claude/agenthub/runtime/agenthub.system.env); user unit disabled; hidepid=invisible on /proc; /etc/sudoers.d/agenthub; /etc/claude-code/managed-settings.json (member-hook); ah-admin + ah-vinnt exist. Undo: /tmp/agh-spike/UNDO.sh (step 0 = `install-system --uninstall`). A plugin update while this runs may race (old bootstrap doesn't know the system unit).
**2026-10-08 P3–P5 + P8 review fixes done & redeployed on this box** (still UNCOMMITTED on server-s3): 4-lens review found the host acting on member-owned paths (tmux client on member socket, writes into handoff, cap reads via swapped links) → fixed: all member tmux via sudo -u (+ pane-launch launch file), all home writes via write-as, fd+uid-checked reads, setpriv drops ambient cap for children. Live e2e as s3probe passed (pane, WS attach, Claude via gateway "pong", stage-hunk, partial commit, drop, symlink-swap refused). P7 spike done (free ChatGPT acct now in host ~/.codex): an OLD refresh token still refreshes after rotation → concurrent panes OK. Left: P6 (seed ~/.claude.json onboarding/trust, managed plugin baseline), P7 build, user's :4830 dev server still abandons member runs.
**2026-10-08 role rename hazard:** another session's UNCOMMITTED main-checkout work renamed role `member`→`developer` and migrated the SHARED dashboard.db (users CHECK now admin/analyst/developer). server-s3 bridges it in auth.js (`roleIn`/`roleOut`, ponytail) — before that, a developer on :4820 saw everything. At merge: take main's rename, drop the bridge. Also done 10-08: per-account first-run wizard + spotlight tour (`/api/me/prefs`, docs/plans/onboarding), P6 provision seed.
**2026-10-09 S3 code-complete and on origin/main (84e2a9f0, not released):** P4 per-member quota, P6 plugin baseline (managed-settings spike script written, NOT run), P7 Codex pool, and five review rounds F1–F49, each fix with a regression test. All of it was verified with fake sudo only. Still open:
- a live test on real accounts/sudo;
- the P6 spike;
- async tmux/copy (two ponytail ceilings);
- an Express-5 upgrade must drop the Layer.handle_request patch in server/index.js.
Work branch s3-next (worktree kept). Round-3 findings: ~/.cache/agenthub-s3/r3/.
**2026-10-09 follow-ups (branch s3-followups → released in v2.6.0):**
- plan README moved in;
- Express patch guarded to 4.x;
- P6 spike RUN on agh-test1: managed settings work from the first interactive session (onboarding must be seeded); `claude plugin list` stays [] because no user-scope record is written; details in S3-PLAN P6. Log: ~/.cache/agenthub-s3/LIVE-LOG.md;
- all of it RELEASED in v2.6.0 (fa156d6a) on 10-09; async member tmux listing and async snapshot copy included; server suite 2840/2843 (3 = port 3000 env). Remaining ceiling: a click/hasSession on a frozen member still blocks ≤3 s once per back-off.
**2026-10-12 prod box update:** the system unit still runs `.claude/worktrees/server-s3`, which had been left on a WIP commit over v2.5.12, so the dashboard's Update failed (`merge --ff-only` on a diverged branch; that old code predates the v2.6.1 `diverged_from_release` guard). Fixed by moving branch server-s3 to v2.7.1 (`reset --keep`; WIP pinned as branch `server-s3-wip-87903d47`), then `NODE_ENV=development npm run setup`, `NODE_ENV=production npm run build`, `sudo -n systemctl restart agenthub.service` (sudo -n works here). Future updates of this box should fast-forward cleanly.
**2026-10-12 live e2e as `test` (developer, pw 123456789, provisioned ah-test by the user):** scoping, WS, AI proxy, git as member, shell pane, isolation all OK. Root cause of "user's :4830 dev server abandons member runs" found and fixed in v2.7.2 (`linux-accounts.unseenMemberFolder`) — the OLD :4830 process still breaks member panes until restarted. Left to test after prod updates to 2.7.2: Claude via 9router gateway, Codex, member quota, skills in session. Open UX findings: ensure/start accept a missing folder (pane falls back to home), no mkdir for a new member, `--allow-dangerously-skip-permissions` always passed → Trust + Bypass consent prompts on first run. Auto-mode classifier blocks: sudoers log tweaks (audit tampering), `users provision` (permission grant). Leftovers: lane 49, proxy u5_e2e-probe, ~/proj in ah-test home, ~/.cache/agenthub-e2e.
**2026-10-12 v2.7.3 on prod (:4820 system unit, worktree server-s3 = 5d8fc9bb):** full member e2e as `test` PASSED — Claude + Codex via 9router gateway (pong), runs stay running, tokens recorded, home prompt box -> reply, Chat UI -> reply, no API >=400 for a developer, plugin baseline sg-all in member cache. Root causes fixed: (1) self-restart under the system unit crash-looped it (detached replacement held the port; recover = SIGTERM the orphan); (2) :4830 dev server runs in SERVER MODE (settings.env AGENTHUB_MODE=server) without CAP_DAC_READ_SEARCH -> EACCES on member 0700 tmux dir -> ended member runs; (3) cross-process stale tmux cache -> 20 s young-run grace. Known/left: trust prompt per member project (Claude doesn't inherit home trust), first-run Bypass consent (by design), 404 /api/pricing/cost for a brand-new session, developer System page shows host paths/DB size. test's workspace #49 + ~/proj kept as a demo.
**2026-10-12 v2.7.4 LOCAL (branch release-2.7.4 = c1241123, tag v2.7.4 local only, NOT pushed — push/release was classifier-blocked after the user asked to limit Gitea pushes):** prod :4820 runs it. Added: makeMemberFolder (start makes a missing folder in a member's home, as them), bypass flag only when skipDangerousModePermissionPrompt or a bypass run, developer /api/settings/info + /api/updates/status carry no paths (transcript_cache.keys leaked every user's transcript paths). Verified live: admin Users page (add analyst w/ step-up, EREAUTH, disable/enable, role, ESELF), analyst reads all/writes own, new analyst folder + first Claude session with no dialogs, load 12 viewers p95 ~95 ms 0 errors. Test accounts: testadmin (random pw in ~/.cache/agenthub-e2e/testadmin.cred), testanalyst (.cred there too), test/123456789. Live Update-button test still needs a pushed release newer than prod.
@@ -0,0 +1,21 @@
---
name: agenthub-no-launchd-on-macos
description: "macOS auto-start: LaunchAgent BUILT 2026-09-25 (launchd-service.js + service-manager.js), uncommitted/untested on a real Mac until the tester reports"
metadata:
node_type: memory
type: project
originSessionId: 149814b6-3a00-4df5-9c93-06f8c0700f5e
modified: 2026-09-25T04:32:05.978Z
---
2026-09-14: no launchd equivalent of the systemd unit was built — no Mac to test on, and the startup area already produced two self-kill fix releases (v1.5.7, v1.5.8). On macOS `systemctlAvailable()` is false, so the bootstrap falls back to a detached spawn from SessionStart: no reboot persistence, no auto-restart, `agenthub service install` says unavailable.
2026-09-25: REOPENED. A user reported "auto-start still doesn't work on macOS"; the user confirmed they mean start-at-login without opening Claude Code, and that someone can test builds on a Mac.
**Why:** the original blocker (no way to test) is gone.
**How to apply:** proposed design = LaunchAgent `~/Library/LaunchAgents/io.smartgift.agenthub.plist` behind the same API as `scripts/systemd-service.js` (KeepAlive ≈ Restart=always, AbandonProcessGroup, bootout+bootstrap as the deferred restart because kickstart does not re-read the plist, marker comment for "ours", every launchctl failure falls back to the detached spawn). Ship with a Mac checklist for the tester. The #22 macOS fixes from branch ah-release-1823 were cherry-picked onto main 2026-09-25 (not the superseded UI commits).
2026-09-25 later: BUILT as designed — `scripts/launchd-service.js`, `scripts/service-manager.js` (all callers require it), tests in `server/__tests__/launchd-service.test.js` (stubbed launchctl, faked platform). Mac tester checklist = INSTALL.md § macOS items 1–11. Not yet committed when written; never run on a real Mac.
Other macOS caveats (code review only): needs Node ≥ 22.5, `brew install tmux`, `~/.local/bin` on PATH by hand. See [[agenthub-release-state]].
@@ -0,0 +1,23 @@
---
name: agenthub-plugin-update-chicken-egg
description: AgentHub installs at v1.5.9 or older cannot self-detect updates; each machine needs one manual plugin-update command
metadata:
node_type: memory
type: project
originSessionId: f057b0e3-5a9e-433e-aebb-a992d5681dbc
modified: 2026-09-14T06:58:35.390Z
---
Until v1.5.10 (2026-09-14), **no** plugin-cache install of AgentHub could ever see a published release — `pluginMarketplaceUrl` rejected this repo's own `"source": "./"` marketplace entry, so the status endpoint answered `release_check: "no_remote"` and the UI showed no version at all.
The fix ships *in* v1.5.10, so an install running 1.5.9 or earlier carries the broken check and cannot detect it. Every such machine needs the update run by hand exactly once:
```
claude plugin marketplace update claude-code-agent-monitor-plugins && claude plugin update agenthub@claude-code-agent-monitor-plugins -y
```
**Why:** a broken update-detector cannot deliver its own fix; nothing on that machine will ever offer the newer version.
**How to apply:** when someone reports "Check for updates shows nothing" on AgentHub, ask for their version first. ≤1.5.9 ⇒ it is this, hand them the command; ≥1.5.10 ⇒ it is a real new bug, investigate `server/lib/update-check.js`.
Related: [[agenthub-release-state]], [[agenthub-no-launchd-on-macos]].
@@ -0,0 +1,152 @@
---
name: agenthub-release-state
description: "v2.7.4 RELEASED 2026-10-12 (b3fe10a4, release 571: #72 MM-reverted hidden, #73 trust-prompt chat, Safari Telex, + server-s3 3 commits cherry-picked); v2.7.3 RELEASED 2026-10-12 (5d8fc9bb, release 570: self-restart via unit, mayHaveTmux EACCES, young-run 20 s, ENOCWD, member list TTL 5 s); v2.7.2 RELEASED 2026-10-12 (3a8be55b, release 569, whole tree: #67 own agent instructions, Settings tab, chat⇄terminal prompt, S3 unseenMemberFolder fix); v2.7.1 RELEASED 2026-10-10 (2fd0c903, release 568, hotfix: v2.7.0 failed `tsc -b` in a test → every update broke at npm run build); v2.7.0 RELEASED 2026-10-10 (f6f1bf4a, release 567, whole tree: tabs from every workspace, interrupted-session resume, chat drafts, edited-files drag, chat panel in every split); v2.6.2 RELEASED 2026-10-10 (f0dc1445, release 566, psmux ignores list-sessions -F → panes read dead; setup `(cd client …)` broke under cmd.exe; execNpm error tail + 20 min); v2.6.1 RELEASED 2026-10-09 (96e4d28f, release 565, #69 tmux deleted-cwd fix + parallel sessions' Changes stacking/chat links/diverged update-check); v2.6.0 RELEASED 2026-10-09 (fa156d6a, release 564: Chat composer/Stop/permission chip, #70 extra-folder git, #68 long paste as file, #54, S3 experimental); origin/main 84e2a9f0 (2026-10-09) = S3 squash, pushed; v2.5.13 RELEASED 2026-10-08 (b7f3735b, release 563, Chat UI + shared terminal size + roles + backup + uninstall); v2.5.12 RELEASED 2026-10-08 (a9c71cd9, release 562, plan+quota for every AI tool, Grok/Kimi in, Gemini/Hermes/OpenClaw out, Quit #65); v2.5.10 RELEASED 2026-10-07 (9a54978e, release 560, perf for 10+ users + SERVER MODE + file drops/tab joins; git management held back); v2.5.9 RELEASED 2026-10-07 (8fdda668, release 559, UTF-8 locale for tmux #62 + slash list plugins/bundled skills + Claude account by token owner); v2.5.8 RELEASED 2026-10-07 (7543b8d6, release 558, Windows attach tmux.exe); v2.5.7 RELEASED 2026-10-06 (4163f431, release 557, psmux targets); v2.5.6 RELEASED 2026-10-06 (fcf8d801, release 556, Windows panes w/o sh + UI build w/o node on PATH); v2.5.5 RELEASED 2026-10-06 (5fe5d51b, release 555, AI Router→AI Proxy + tab reload on new build + update verdict); v2.5.4 RELEASED 2026-10-06 (dd9b2310, release 554, Query Explorer → Sessions Agents tab + Windows picker AttachThreadInput); v2.5.3 RELEASED 2026-10-06 (af014d98, release 553, Windows D:\\ cwd + picker TopMost owner + windowsHide); v2.5.2 RELEASED 2026-10-06 (f8acd5fc, release 552, fixes 2.5.1 bootstrap crash); v2.5.1 RELEASED 2026-10-06 (be755729, release 551, Windows npm.cmd bootstrap fix); v2.5.0 RELEASED 2026-10-06 (03ecc9e2, release 550, autostart switch + #61); v2.4.0 RELEASED 2026-10-06 (4aae6129, release 549, analytics parity 2–7 + another session's staged sidebar-resize/pet/draft/hook work); v2.3.1 RELEASED 2026-10-06 (837da6e5, release 548) fixing v2.3.0 (7ca1134c/547) self-reporting 2.2.1; v2.2.0 RELEASED 2026-10-06 (f0500dc, release 546); v2.1.0 RELEASED 2026-10-06 (6c60584, forge release 545; workspace aliases = rename step R); v2.0.1 = c067abc/544"
metadata:
node_type: memory
type: project
originSessionId: 149814b6-3a00-4df5-9c93-06f8c0700f5e
modified: 2026-09-29T00:00:00.000Z
---
**2026-10-12 v2.7.4 RELEASED:** b3fe10a4 on main, tag v2.7.4 (annotated), release 571 (EN/VI, server-mode items left out). Another session had tagged v2.7.4 LOCALLY (unpushed) on branch release-2.7.4/server-s3 (c1241123, 3 server fixes); user chose to merge: cherry-picked those 3 onto main (CLAUDE.md marker conflict only) and moved the local tag. Worktree server-s3 / branch release-2.7.4 still sit at c1241123 — same content, different shas; rebase them onto main. Always `git tag -l v<next>` before tagging.
**2026-10-12 v2.7.3 RELEASED:** 5d8fc9bb pushed from a scratch worktree branch (`release-2.7.3:main`), tag v2.7.3, release 570 (EN/VI, server items phrased generically). Full suites: server 2887/2887, client 1250/1250. LOCAL main left at c8ea18f5 (one commit behind origin: docs LANES/SERVER-MODE + run.test fix) because other sessions had uncommitted docs/LANES.md (line 397) — moving the ref was classifier-blocked ("git destructive"); they must `git pull --ff-only`/rebase after committing.
**2026-10-12 v2.7.2 RELEASED:** 3a8be55b (whole tree, user's choice: another session's #67 agent instructions + Settings tab + chat⇄terminal prompt + chat tinting; mine: a server without S3 skips runs/lanes under server.conf USERS_ROOT in reconcileOrphans/healRunId). Annotated tag v2.7.2, release 569 created via Gitea API with `git credential fill` creds (EN then VI; the S3 fix left OUT of the notes). .claude/launch.json left untracked (local dev config). --no-verify after tsc -b + touched suites.
**2026-10-10 v2.7.0 RELEASED:** f6f1bf4a (whole tree; peers agenthub-c4/-52 idle, nothing edited for 10+ min), annotated tag v2.7.0, forge release 567 (EN then VI, no server mode/roles). Mine: Appearance "Tabs from every workspace" (paneKey = lane×10+slot, layout stored under `all`), Chat drafts per session (lib/chatDraft.ts), Edited-N-files rows draggable. Others': interrupted-session resume dialog, chat activity panel in every split, session image preview, long-text transcript, psmux paste hold. Prettier fixed 9 of the others' files by hand (root .prettierrc covers client too). `npm run openapi:yaml` must run with `env -u DASHBOARD_PORT` — this shell exports 4830 and the generator writes it into `servers:` (drift test then fails). OPEN: chat view lost when two Chat-UI tabs join into a combo on :5174 (stored view flips to false, survives F5) — NOT reproduced in a sandbox; debug logging was removed before release; waiting for the user's console output.
**2026-10-09 v2.6.1 RELEASED:** 96e4d28f (whole tree, user's choice), tag v2.6.1, forge release 565 (EN then VI). #69 root cause: released tmux skips a pane's `-c` when the SERVER's own cwd is gone (spawn.c `if (getcwd(...) != NULL)`); server forked from plugin cache dir, outlives updates, prune deletes it → panes in deleted cwd, claude dies. Fix: tmux EXEC_OPTS cwd "/", paneArgv cds into `$1`. Committed --no-verify: 6 server tests fail on clean HEAD too (lane-profile x3, openapi.yaml, 2 server-mode). Not verified on a real Mac; issue #69 not commented/closed.
**2026-10-09 v2.6.0 RELEASED:** fa156d6a (fast-forward from 84e2a9f0), annotated tag v2.6.0, forge release 564 (EN then VI; no server mode/roles). User asked 2.5.14 first, then "lên 2.6.0". Built in worktree s3-followups: S3 follow-ups (async member tmux/snapshot, Express-4 guard, P6 spike result, plan README moved in) + main's WIP from parallel sessions (74e55c95, 9c881234, 3cb4408d: Chat UI composer, #54, #70 by agenthub-ec, chat Stop) + s3-docs onboarding patch; main moved with `git reset --keep`. Merge fixes: drop GET used dropDir() without req; capturePane/sendKey → onServerOf; userPrefs.hydrate paints theme (loadAccountTheme removed). Found: GET /api/agents ignores `status` when `session_id` is given (PaneChat's Stop always on). Issues #54 #68 #70 closed with VI comments. Prod :4820 still runs server-s3 2.5.12 (not touched); :4830 dev needs restart for S3 code.
**2026-10-09 S3 pushed, not released:** origin/main 84e2a9f0 "feat(server-s3): one Linux user per account (S3) — experimental" = s3-next (ba5129cf) squashed onto b7f3735b, pushed from a scratch worktree. User asked for: no tag, no release, they test on their own machine. Local `main` in the shared checkout was left at b7f3735b, because other sessions' 82 uncommitted files are there. Prod :4820 still runs the server-s3 worktree (87903d47, with the old holes); per the user, don't touch it unless asked. The AgentHub-Server repo's s3-docs branch (7d2f3df) is NOT pushed. When releasing later: the S3 commit message says EXPERIMENTAL (not verified on real sudo/accounts), and the notes must not mention server mode.
**2026-10-08 v2.5.13 RELEASED:** b7f3735b (whole tree, user's choice), annotated tag v2.5.13, forge release 563 (EN then VI; NO server/roles items — user: release notes list nothing server-related). Mine: Chat UI = ONE switch in Settings → Appearance (user rejected a per-pane toggle), saved per account via /api/me/prefs using server-s3's EXACT user_prefs schema (user_key/prefs JSON) — the server-s3 worktree shares the DB and already had that table; when it merges, add `agenthub.chatUi` to its PREF_KEYS. Plus Claude-Desktop conversation layout, pty-attach driver/follower sizing. agenthub-9e's roles admin/analyst/developer shipped in the same commit. --no-verify (:3000 EADDRINUSE, 3 server fails); both suites run by hand.
**2026-10-08 v2.5.12 RELEASED:** a9c71cd9 (whole tree), annotated tag v2.5.12, forge release 562 (EN on top, VI below; no "server" anywhere in the notes). Mine: Usage panel plan names + quota for Cursor (cookie `WorkosCursorSessionToken=<id>::<token>` to cursor.com/api/usage-summary — verified live: pro, 100%), Antigravity (`agy --print /usage --output-format json`, verified live; AGENTHUB_AGY_USAGE=0), Grok/Kimi/OpenCode Go (Orca's readers, NOT verified live — none installed/logged in); catalog + grok.json, kimi.json (Kimi bypass = `--auto`, not Orca's `--yolo`), − gemini/hermes/openclaw. Other sessions' WIP shipped too (Quit #65, tray icon, Add to Chat, Settings 3 groups/System, Changes panel ticks/blame/history, terminal font, Users page). --no-verify again (:3000 Next.js); prettier is NOT installed at the repo root — ran `npx prettier` (3.9.9) on staged files by hand.
**2026-10-07 v2.5.11 RELEASED:** commits f0656603 + 1619954f + 6ef9a5d4, tag v2.5.11 → 6ef9a5d4 (tag was force-moved twice before the release existed — user chose to keep 2.5.11), forge release 561 (EN on top, VI below; user: NEVER mention server mode in notes). Contents: git cherry-pick/revert/undo/amend + confirms (push/publish/branch delete/pick/revert/amend), JetBrains curved side by side in BOTH views (splitDiff.ts replaced MergeView; checked in headless Chrome via a temp Vite harness + CDP script, harness deleted), #64 (--untracked-files=all in laneStatus; issue CLOSED 10-07 with a VI comment, id 820), Open terminal in AI menu, Repo default, commit box wraps only when narrow, README.md = Vietnamese default + README.en.md with per-section cross-link table (ids shared: #requirements, #install-claude-code, #install-terminal, #more-docs), long overview moved to docs/OVERVIEW(.vi).md, update-check npm fix (Windows/NODE_ENV). Discard all was REMOVED (user: too dangerous — never re-add a bulk discard). --no-verify (:3000).
**2026-10-07 v2.5.10 RELEASED:** ca821008 (perf) + 9a54978e (server mode, file drops in prompt, tab joins, useSpin, metric tooltips, light palette), tag v2.5.10, release 560 (EN+VI). User chose to SHIP server mode this time; GIT MANAGEMENT (cherry-pick/revert/undo-commit/amend, other-branch history, "vs base" fallback in git-ops/git-diff/worktree/LaneChangesPanel/LaneGitBar/api/types/lanes.json/routes lanes + docs) held back for the next release — still WIP in the tree, another session is still editing it. Built in worktree /tmp/ahperf/wt, main moved with update-ref + read-tree. LESSON: the pre-commit hook in a LINKED WORKTREE exported GIT_DIR to the tests → junk "init" commits on the worktree HEAD + core.bare=true; fixed in scripts/test-server.js (drops GIT_DIR family). --no-verify for 9a54978e (user's tri-vi-portfolio next dev on :3000; both suites run by hand: server 2557/2560, client 1086/1086). LEFT IN MAIN TREE (auto-mode denied `git checkout HEAD --`): stale copies showing reverse diffs — package.json/lock + snapshot say 2.5.9, scripts/test-server.js lacks the GIT_DIR fix, prettier formatting of LaneCard/LaneGitHeader/TerminalView(+test)/run.test.js, openapi.yaml version, CLAUDE.md marker v2.5.9; a careless `git add` of those would revert them.
**2026-10-07 v2.5.9 RELEASED:** 8fdda668, tag v2.5.9, release 559 (EN+VI). #62 macOS `_` in terminal = tmux client with no UTF-8 locale (LaunchAgent sets none) → ensureUtf8Locale sets LC_CTYPE at start. Slash list + plugin skills/bundled skills. Thắng's Mac (verified from screenshots): keychain held Victor's (personal, pro) token while .claude.json said thangpq (team) → billed to Victor; fix = login decided by token owner (GET /api/oauth/profile), switch snapshots into OWNER's profile, EMISMATCH on save. Claude Code 2.1.291 re-reads creds store on change (~30 s), so running sessions follow a switch. Released ONLY my hunks via a `git clone --local` in /tmp (tested there: server 2474, client 1071), then main moved with update-ref + read-tree (index was empty) + version bump carried into the WIP copies of CLAUDE.md/openapi/snapshot. Other sessions' WIP (server mode, Sagi, TerminalView, useSpin StatusBar) left uncommitted. OPEN: Codex quota is read from rollouts (stale after a limit reset/account switch) — asked user whether to fetch it live from ChatGPT's undocumented usage endpoint.
**2026-10-07 v2.5.8 RELEASED:** 7543b8d6, tag v2.5.8, release 558 (EN+VI). node-pty on Windows never adds .exe ("File not found" in conpty.node) → attachBinary uses which("tmux")||"tmux.exe"; websocket.js logs `[WS] attach <run> failed`. Again released ONLY my hunks (websocket.js and CLAUDE.md built from HEAD + my edit via hash-object/update-index); server-mode WIP (auth, claude-pool, accounts) still uncommitted, user: "đừng gom server". USER CONFIRMED on the Windows box (2026-10-07): terminal attaches and works on v2.5.8 (psmux + node-pty OK).
**2026-10-06 v2.5.7 RELEASED:** 4163f431, tag v2.5.7, release 557 (EN+VI). Windows tmux is PSMUX (WinGet; `tmux -V` = 3.3.2): no `=name` targets ("no server running on session '=t4'"), sessions were alive the whole time. tmux.js probes once and uses bare names there. Released ONLY my files while another session's SERVER MODE (auth, AGENTHUB_MODE=server) stayed uncommitted in the tree — user: "bản server update riêng". Technique: stage CLAUDE.md/openapi.yaml as HEAD+my edits via `git hash-object -w` + `update-index --cacheinfo`, test the index via `git checkout-index -a --prefix=/tmp/x/` + symlinked node_modules (repo-links/updates/statusline tests fail there only because it's not a git repo). rtk rewrites `git diff` output — use /usr/bin/git for raw diffs.
**2026-10-06 v2.5.6 RELEASED:** fcf8d801, tag v2.5.6, release 556 (EN+VI). Windows box (kingg) facts: tmux.exe from WinGet (C:\Users\kingg\AppData\Local\Microsoft\WinGet\Links), NO sh; claude works inside it by hand. Fixes: paneArgv (no sh -c on win32, Terminal = tmux default shell), buildClient --ignore-scripts + tsc/vite via process.execPath (esbuild postinstall "'node' is not recognized" when the chain ran from the server env — root cause of node missing from that PATH still UNKNOWN), Atomics.wait instead of sleep. Not verified on Windows; user told to run /agenthub-open once if stuck on an old UI.
**2026-10-06 v2.5.5 RELEASED:** 5fe5d51b, tag v2.5.5, release 555 (EN+VI). Whole tree: agenthub-83's AI Router→AI Proxy rename (dashboard_runs.router RENAMED in place to proxy — user chose it; older build on same DB fails, so dev+prod update together) + my newBuildReload/UpdateNotifier verdict/EPANEEXITED + someone's PaneGrid drop-preview fix. Prettier fixed 5 of agenthub-83's files by hand; --no-verify (:3000). Still open: Windows tmux (pane command exits at once) + Windows update logs never received.
**2026-10-06 v2.5.4 RELEASED:** dd9b2310, tag v2.5.4, release 554 (EN+VI). User chose to fold Query Explorer into /sessions (History.tsx tabs Sessions · Events(ActivityFeed) · Agents(AgentsTable.tsx, ex-QueryExplorer, agents only); /query redirects). Windows picker: -EncodedCommand, throwaway ShowWindow + AttachThreadInput foreground (2.5.3's owner was hidden by windowsHide). Client owningLane/sessionWorktreeName accept "\". OPEN: asked user whether their Windows box has tmux — panes (Resume/Fork/New session) need it; native Windows has none → would need a ConPTY pane backend (big, plan first). --no-verify (:3000).
**2026-10-06 v2.5.3 RELEASED:** af014d98, annotated tag v2.5.3, release 553 (EN+VI). User asked "release 2.5.1" — already taken, user chose 2.5.3 + the whole tree (another session's windows-hide.js + modal scroll fixes). Windows cwd fix (createLane/canonicalCwd path.isAbsolute, resolveLaneByCwd either separator) + native picker invisible TopMost owner form. NOT verified on Windows; asked the user to retest Browse and report what happens if it still fails. --no-verify (:3000 next-server).
**2026-10-06 v2.5.2 RELEASED:** f8acd5fc, tag v2.5.2, release 552. v2.5.1 BROKE every plugin update ("boot.npmCommand is not a function"): plugin-bootstrap.js run as entry → bootstrap() → plugin-open requires it back → module.exports still {} (assigned below the entry block). Fix: exports moved above entry block + order test for both entry scripts. Lesson: a new export used across the bootstrap↔plugin-open cycle must be checked via the ENTRY path (repro: --require preload stubbing spawnSync, HOME=tmp, `--worker`). Committed WITH the hook (all green, :3000 free).
**2026-10-06 v2.5.1 RELEASED:** be755729, tag v2.5.1, forge release 551 (EN+VI). A Windows user's plugin update failed at "bootstrap": 'npm.cmd' is not recognized (server env PATH lacked npm). Fix: npmCommand() in plugin-bootstrap.js runs node's bundled npm-cli.js (beside process.execPath), no shell; used by installDeps, plugin-open buildClient, doctor npmStatus. NOT verified on a real Windows box; that machine must run /agenthub-update once (2.5.0's bootstrap still buggy). (Checkout path fixed 10-07, uncommitted: execNpm → npmInvocation = npmCommand + NODE_ENV dropped.) --no-verify again (:3000).
**2026-10-06 v2.5.0 RELEASED:** 03ecc9e2, annotated tag v2.5.0, forge release 550 (EN+VI). Settings → About "Start AgentHub automatically" (start-at-login opt-in, OFF by default for new installs; switch = unit's enabled state, existing enabled units stay on; bootstrap no longer auto-installs the unit) + agenthub-fa's #61 Workspace.tsx fix (user asked to fold it in). Committed --no-verify (next-server still on :3000 → lane-detect); prettier by hand. openapi.yaml is GENERATED from server/openapi.js + server/openapi-extra/*.js (`npm run openapi:yaml`, repo-links.test.js checks) — never hand-edit it.
**2026-10-06 v2.4.0 RELEASED:** 4aae6129, annotated tag v2.4.0, forge release 549 (EN+VI). Analytics parity phases 2–7 ported from ../agenthub-analytics onto v2.3.1 in a throwaway worktree, PLUS (user's choice) another session's STAGED work found in the main tree (resizable sidebar, pet run/wave, workspace-home draft, pre-commit hook running only related tests). Its old analytics-parity README (names the upstream repo — repo-links.test.js forbids it) was replaced by the port's. That session's later UNSTAGED Workspace.tsx edit was left in the tree (backup /tmp/ap/Workspace.other-unstaged.patch). Committed --no-verify after both full suites (client 1061/1061, server 2439/2442 — the 3 fails = :3000 held by a next-server); prettier step run by hand. Main tree moved by `git checkout <commit> -- <their staged files>` + `merge --ff-only`.
**2026-10-06 v2.3.1 RELEASED:** 837da6e5, tag v2.3.1, forge release 548 (EN+VI): version 2.3.1 everywhere, failureText (plugin-update + Update all), updates.test.js skip guard, 0206a523's gitignored files in Files (orange) + change-tree indent. The "Display abbreviations and account info" session (2be81da3) had nothing uncommitted in this tree (its quota work went out in v2.3.0; its later work is in ../agenthub-analytics and ../agenthub-port). WorkspaceHome.tsx edits appeared after the commit — left out. Committed with the hook (~5 min: backend then frontend, each retried once). smartgiftdev's bootstrap failure (f0500dc5920e) root cause still unknown — asked for plugin-update.json / plugin-update.log / bootstrap.log from that machine; likely `locked` or `superseded` (both stdout-only, both refuse before stopping the server).
**2026-10-06 v2.3.0 MIS-VERSIONED:** its tree says 2.2.1 everywhere (package.json/lock, openapi, CLAUDE.md marker, snapshot), so every v2.3.0 install reports "update available" forever and a checkout's `POST /api/updates/apply` really applies (npm run setup under NODE_ENV=production pruned all dev deps in the checkout once — reinstalled with `env -u NODE_ENV npm install --include=dev`; updates.test.js now skips when the checkout is behind a release). Cause: a REWOUND branch of the same session ("Hãy pump 2.2.1 nhé", then rewound to "Hãy tiếp tục") had already rewritten the files — a rewind keeps disk edits. User decided: no retag; working tree set to 2.3.1; push ONCE as v2.3.1 after the other sessions finish, leaving "Display abbreviations and account info" for the push after. Also pending in that push: failureText in plugin-update-helper.js + cc-update-all-helper.js (bootstrap's reason is on STDOUT, was lost). **How to apply:** right before every release commit, re-read the version in package.json/openapi/marker/snapshot — never trust an earlier bump.
**2026-10-06 v2.3.0 RELEASED:** daf5b7be (whole tree: Changes-panel CodeMirror editor + side by side + blue/green/red diff colours, #58 git-graph history, never-stage list drawn orange, plan-quota status bar, Appearance merge, Ctrl+Shift+C copy, compact sidebar) + 7ca1134c (DiffEditor test flake fix), tag v2.3.0, forge release 547 (EN+VI). Committed WITH the hook this time (`NODE_ENV=test git commit`, run in background; :3000 was free). Another session's uncommitted tree-indent tweak in LaneChangesPanel.tsx left OUT. #58 not closed on Gitea (not asked). analytics-parity plan still untracked.
**2026-10-06 v2.2.0 RELEASED:** f0500dc, tag v2.2.0, forge release 546 (EN+VI). Other sessions' WIP (change tree, AI commit message, router behavesAs #56, forget closed terminal, WAIT_FOR_CLIENT for every CLI) + my sidebar times on session rows (user asked). Committed --no-verify again: next-server on :3000 broke lane-detect tests; full suite green before. analytics-parity README had been STAGED by someone — unstaged again.
**2026-10-06 v2.1.0 RELEASED:** 6c60584 (whole tree after a 4-agent review + fixes: pick-path EREMOTE on X-Forwarded-For/Forwarded, abort on close, display failure = ENODIALOG; plugin commands resolve ROOT via supersededBy; REPL help alias-aware; parseGroups active index; OpenAPI gaps), tag v2.1.0, forge release 545 (EN+VI). User asked 2.0.2 first, then took my 2.1.0 advice. Committed --no-verify: 3 lane-detect tests need :3000 free and the user's tri-vi-portfolio `next dev` held it; rest of the suite green. This is R of docs/plans/workspace-rename (old `lanes`/`--lane` removable from the 3rd release after it). Known left: SSH-tunnel browser indistinguishable from local for pick-path.
**2026-10-05 v2.0.1 RELEASED:** b0cf213 Windows AI-CLI detection (which() tries PATHEXT, skips npm sh shim; spawnTarget = shell:true + quoted path for .cmd in ai-tool-jobs/versions) + c067abc bump, tag, forge release 544. NOT verified on a real Windows box — user (machine kingg, Win11) must /agenthub-update then Refresh in Settings → Agents.
**2026-10-05 v2.0.0 RELEASED:** 198fbb7 (all pending work) + 094d9c4 bump pushed to origin main, tag v2.0.0, forge release 543 (EN+VI notes). docs/plans/analytics-parity/ deliberately left UNTRACKED: it names Claude-Code-Agent-Monitor, which repo-links.test.js forbids in tracked files. Pre-commit hook runs the full suite (~4 min) — run git commit in background.
**2026-10-05 (65fe680 daily cost by spend day — token_usage_hourly; ad6e801 right-click menus everywhere + status bar Workspace $/Session $ + long-term DB safety; unpushed):** user first chose to keep all event data; on 2026-10-05 (later) REVERSED for payloads only: trim events.data at insert + one-time sweep (whole files/long output dropped, kept in transcripts), still no row prune and no VACUUM, transcript snapshots kept. See [[analytics-parity-plan]]. Live DB 1.2 GB (events 1.08 GB) + 346 MB WAL until a dashboard runs ad6e801.
**2026-10-03 later (326dfa9 split panes, 8098f44 new-tab/row fix, ed1bf20 custom pets; unpushed):** VS Code split tree (PaneGrid/paneLayout), edge-to-edge chrome on surface-1; sidebar "New session" rows + row opens last-focused tab + Home button; Sagi pets via /api/pets (.codex-pet.zip, image upload, 4 featured downloaded from codex-pets.net — user picked goku/bac-ho/border-collie/11; NOT bundled: no licence, I flagged it). Open: user has not said whether to bundle anyway.
**2026-10-03 (b7efba8, e5762a5, 8f6360f, 1597c11, unpushed):** 1597c11 = session view + right panel on the page with no cards (user wants flat, no raised cards), terminal bg back to --surface-0, refit on document.fonts loadingdone. Visual checks: run the test server with `env -u TMUX` or its panes land on the real tmux. tab bar = session view's only header (RunHistory removed); fix: .xterm-viewport scrollbar-hide rule moved OUT of @layer utilities (Tailwind purged it — runtime-only class).
**2026-10-02 (d9511ea, unpushed):** session view console became TABS (ConsoleTabs.tsx, max 4 = slots 0-3, + menu: New terminal via `shell: true` / bare AI tool / Agent settings); split view removed. User chose: tabs replace split, 4-tab limit, tab types = AI tool + plain shell only (no browser/markdown tabs yet). Not browser-checked.
**2026-10-02 (c507d37, unpushed):** AI Router chosen PER SESSION (Claude --settings=<data dir>/router-settings/<name>.json, Codex -p; workspace router + /router/apply removed; clearLaneRouters strips old keys at start); Settings + collapse toggle at sidebar foot; shipped SVG icons in client/public/ai-tools/. Open question to user: Native session does not blank a user-level router in ~/.claude/settings.json.
**2026-10-02 (earlier):** 379f7ee was amended to a6bd33b to take the multi-user plan out (that plan is now in the AgentHub-Server repo, see [[agenthub-multi-user-goal]]). Phase 6 (a session in its own `claude --worktree`, the Claude way) is committed as 5084334. Nothing is pushed to AgentHub origin.
**2026-10-02 (later) COMMITTED 379f7ee on main, NOT pushed/released:** desktop-parity phases 1-5+7 (sessions.lane_id ownership, archive/rename/state dot, Fork, Ctrl+click split, diff comment → pane), dashboard_runs fix (archive-on-replace, abandon only when tmux session gone), sidebar cleanup (no footer/lang/theme; update check in connection modal; language in Settings → General), one Switch + Checkbox. User decided: a workspace lists ONLY its own sessions (no "other sessions in folder" fold). Pending: phase 6 (worktree per session = child workspace) — user asked for my opinion, not yet decided; multi-user server plan docs/plans/multi-user-server/ — "từ từ", do other parts first. Plans now tracked in git.
**2026-10-02 COMMITTED on main, NOT pushed, NOT released (after v1.8.13):** ba2c4e1..2e051e2 workspace redesign + sidebar, d0535af workspace home (Phase C: instructions/sources/memory, run↔session binding), 5b26969 plan leftovers (tool filter, session search, transcript Resume, repo facts, Recents cost). Whole workspace-sessions plan done; docs/plans/ deliberately untracked. Push/release only when asked.
**2026-10-01 v1.8.13 RELEASED:** f887c16 feature + e01cb26 bump pushed to main, tag v1.8.13, forge release 542 (bilingual EN+VI notes), issues #52 and #40 closed with Vietnamese comments. Open: agy --model ids vs display names unverified.
**2026-10-01 models/pricing/per-tool settings (user approved 3 parts):** Part 1 pricing-sync adds+follows (source sync/user, dismissed table) DONE; Part 2 model lists (ai-tool-models.js, GET /api/ai-tools/:id/models, catalog `model` field, defaultModel, run-form picker fetches) DONE — server suite + client 797 green, docs + marker done. Part 3 generic per-tool tab (AiToolConfig.tsx, ai-tool-config.js, /usage, /config routes; AntigravityConfig deleted) DONE + browser-checked on isolated :4870. All 3 parts + review fixes + dead-status fix + cross-server lane sync (broadcastForeignLaneChanges, data_version) + retired-Claude sync guard UNCOMMITTED; server 2172, client 803 green. Open: whether agy --model takes ids or display names (needs user to run `agy models`).
**2026-10-01 COMMITTED (not pushed, not released): 058c574 update-detection fix (installed_not_running, "Could not check" in sidebar) + c5aba09 UI rework/md preview.** Was: AI Tools modal (tab-bar button), Update button for every tool with an updater (no version detection, user's choice), Add-lane one-button tool picker, Claude/Codex AgentHub sub-tab merged into Overview, markdown Preview/Raw toggle (react-markdown + remark-gfm) in config FileViewer + Changes whole-file view. All browser-checked; client 789, server 2141 green. Awaiting the user's commit ask; push/release only when asked.
**2026-09-29 whole-change review:** 4 Code Reviewer agents over all uncommitted work; fixes applied + docs updated. Notable behaviour changes: settings precedence is now real env > repo `.env` (counts as env_owned) > ~/.config/agenthub/settings.env; reset-pricing `{scope:"claude"}`; GET /api/sessions `?tool=`; Codex child-thread hooks no longer move root/lane status; Codex hooks own status only while current (hooksCurrent); agy quiet window 10 min whenever the session has hook events. Deliberately NOT fixed: Codex fork session_meta >1 MB, child hook before its rollout line, poll overwriting a user rename, cc-watcher on old CLAUDE_HOME until restart, pane on old CODEX_HOME, lane stuck running if agy .db never appears. Server 2140, client 779.
**2026-09-29 C1+C2+D:** all implemented, reviewed (Code Reviewer agent per part, findings fixed), e2e-verified on isolated servers; UNCOMMITTED, user has not asked to commit/release. C1 = codex-usage.js (rollouts → sessions/tokens); C2 = codex-hooks.js (trust-gated, exact-command match, sameOriginGuard); D = antigravity-usage.js (agy conversations/*.db protobuf ModelUsageStats) + antigravity-hooks.js (named hook `agenthub` in ~/.gemini/config/hooks.json, NEVER PreToolUse — `{}` answer denies the tool) + Settings → Antigravity tab. Limits: no permission event in agy; no Stop on API error/headless deny (poll releases lane after 2 min quiet, 10 min if last hook was not a Stop). D review (09-29) fixed empty-WAL-as-activity, poll undoing hook running, error Stop, EFOREIGN + mode keep in both hook installers; server 2126, client 778. Spike side effect: agy auto-updated user's ~/.local/bin/agy 1.0.0→1.2.13 ([[agy-auto-updates-on-run]]).
**2026-09-29 persistence:** done, uncommitted, reviewed + browser-checked. Settings saved to ~/.config/agenthub/settings.env (server/lib/settings-env.js, AGENTHUB_SETTINGS_FILE; AGENTHUB_FILE_KEYS marks file-loaded keys), first CLAUDE_HOME change pins DASHBOARD_DATA_DIR, CODEX_HOME editable in Codex → AgentHub. Server 2050, client 763. Known limit: discovery file .agenthub.json still follows CLAUDE_HOME. Part C findings: Codex rollouts carry token_count (input incl. cached, output incl. reasoning), forks COPY parent history (dedupe by parent's total vectors), subagent threads have session_id=root; Codex 0.155 hooks stable but trust-gated (/hooks review), AgentHub never emits --dangerously-bypass-hook-trust.
**2026-09-29 B:** implemented, uncommitted (not asked to commit). Pricing/Hooks/CLAUDE_HOME moved to Claude Code tab's "AgentHub" sub-tab (ClaudeAgentHubSettings.tsx); setClaudeHome EBADHOME guard; codex pane gets CODEX_HOME via -e. Scope agreed: NO tabs for other tools (Antigravity tab → D), NO editable CODEX_HOME yet. Server 2030/2030, client 758/758. Not browser-checked.
Agreed follow-up (own design): writeEnvFile writes repo-root .env = plugin cache dir, wiped every update; storage can't live under CLAUDE_HOME (data dir/DB is CLAUDE_HOME/agenthub, so changing CLAUDE_HOME also silently switches DB on restart). Editable CODEX_HOME comes after that fix.
**2026-09-29 UPDATE:** A1 (3 commits cherry-picked, 0aa7fc2..fcfebe4) and A2 (7ec5a7c) are on main and PUSHED to origin; stash dropped. User said do NOT release yet (still v1.8.12). Server 2023/2023, client 755/755. Branches a1-ai-tools-local / removal-on-a1 deleted 09-29. Next: part B.
As of **2026-09-28** AgentHub is at **v1.8.12** (see below); v1.8.11 was (`3c238bc`, tag `v1.8.11`,
forge release created via the API with the token from `git credential fill`).
It adds Antigravity lanes (`agy`), #50 per-change-block Undo/Keep, codex lanes
without a pipeline, the macOS LaunchAgent, the exited-pane heal sweep, and the
fresh-Codex-start fix. v1.8.10 (`3f6e903`) carried #45 git login/merge and the
#22 macOS fixes.
#40 A1 is IMPLEMENTED and committed locally on main (spec 46f6d27, server
fbe95a3, client+docs 6ede4d2) — NOT pushed, no release yet. Browser-checked 2026-09-28 on an isolated
server (:4850, temp DASHBOARD_DATA_DIR + TMUX_TMPDIR): AI Tools list/enable/
default/Refresh, Add-lane Default+Other…, codex lane created, Bypass checkbox
sends bypass:true — all OK, no console errors. A real bypassed codex start was
not run (auto-mode denied it).
#40 A2 (install/update, remote catalog sync, favicons) implemented 2026-09-28,
spec docs/superpowers/specs/2026-09-28-ai-tools-a2-design.md, plan
docs/superpowers/plans/2026-09-28-ai-tools-a2.md — UNCOMMITTED, parked in
`git stash` as "#40 A2 — AI Tools install/update…" (backup:
/tmp/ah-a1/a2-backup.patch + a2-untracked.tgz). User wants A1+A2 committed and
pushed on 2026-09-29 at real time (I declined to fake commit dates); A1's 3
local commits may be reset --soft and re-committed then. Server 2051/2051, client 756/756 green.
No real install was ever run (browser check intercepted the POSTs). Remote
sync can only be proven after a release that ships server/data/ai-tools/.
Next after A2: B.
v1.8.12 RELEASED 2026-09-28 (pushed main 887dc46, tag + forge release id 541):
the workflow-layer removal (ship-feature skills, 18 commands, 4 agents,
skills/agents install, ship-full|quick, Superpowers auto-install) with
pipelines DORMANT (templates deleted, stage code kept, test templates in
server/__tests__/fixtures/pipelines/). It was cherry-picked onto origin/main
WITHOUT A1. Local main == origin/main. A1's 3 commits now live only on local
branch `a1-ai-tools-local` (6ede4d2); `removal-on-a1` (2d1e181) = the same
removal on top of A1 (reference for conflict resolution). A2 is still
stash@{0}, based on 6ede4d2. Tomorrow: rebase A1 onto main (conflicts in
CLAUDE.md marker + docs/LANES.md; take removal-on-a1's resolution), pop A2,
commit at real time, push, release.
Issue #40 "AI Tools" — decomposed into A1 (catalog, detection,
enable/default, lanes for any tool, bypass switch, UI), A2 (install/update,
remote catalog sync from the newest release, server-cached favicons), B (move
per-tool settings into tool tabs), C (Codex token usage/pricing + hooks),
D (Antigravity parity, spike first). Design decisions were agreed in chat on
2026-09-28 before the spec was written.
Not done / not verified:
- #45, #22, #50 are NOT closed on Gitea (user has not asked).
- LaunchAgent untested on a real Mac; see [[agenthub-no-launchd-on-macos]].
- Never exercised by hand in a browser: git login form against real Gitea,
merge/conflict UI, AI Router end-to-end, an Antigravity lane.
See [[agenthub-plugin-update-chicken-egg]] for why older installs cannot
self-detect a release, and [[agenthub-flaky-codex-ingest-tests]] for test env quirks.
@@ -0,0 +1,14 @@
---
name: agenthub-remote-clients-plan
description: 2026-10-09 new direction — users run AgentHub local on own machines, hub keeps accounts + all records; plan docs/plans/remote-clients/README.md
metadata:
type: project
---
2026-10-09 the user worried the shared hub (server mode, S3) won't carry >10 concurrent users. Decided: each user installs AgentHub LOCAL; full conversation uploads to the hub, but only for sessions AgentHub started; shared accounts (Claude pool, shared AI Proxies) usable ONLY through AgentHub (no AgentHub → no account); branch server-s3 kept until this is settled. Plan R0 user page → R1 devices → R2 upload → R3 remote gateway (checks `x-claude-code-session-id`, verified sent by Claude Code 2.1.295) → R4 managed-settings/marketplace. 10-10 review: ownership via `source=device:` does not work with scope.js (owner comes from lanes.owner_id), mirrored lanes collide on (cwd,tool); suggested sessions.owner_id + hub as a local AI Proxy profile. Not built yet. Follow-ups 10-09: hub stays plain HTTP on LAN (http://10.1.13.7:4820); seats ≥ people, a seat may serve several people (user's call — don't re-raise terms); gate = warn by default, admin can switch to block; per-session ahrs_ token dropped (device token + session-must-be-uploading check); new R0 = one-click per-user activity page from Users (owner= filter).
**Why:** compute moves off the hub; the hub stays the single place to manage and audit.
**10-09 guarantee question:** guaranteed only "no hub account → no issued credential" (credential never leaves hub; needs admin-only seat logins). NOT guaranteed: that the AgentHub app was used. Proposed R3b: gateway records conversation itself from request bodies → no pool use invisible.
**How to apply:** the gating is detection, not prevention (the user owns the machine) — never claim otherwise. Related: [[agenthub-multi-user-goal]].
@@ -0,0 +1,21 @@
---
name: agenthub-sandbox-browser-repro
description: "How to reproduce an AgentHub UI bug in a real browser without the user's login or tmux — isolated server + build + playwright-core"
metadata:
node_type: memory
type: reference
originSessionId: 67840be0-27b2-4b05-b307-a9a883ff5be9
modified: 2026-10-13T08:22:48.426Z
---
Both live dashboards (:4820, :4830) need a login, and the user's tmux must never be touched (see [[never-tmux-kill-server]]). Recipe used 2026-10-10:
- `~/.cache/agenthub-repro/env.sh`: HOME, DASHBOARD_DATA_DIR, TMUX_TMPDIR, AGENTHUB_SETTINGS_FILE, XDG_* all under that dir, DASHBOARD_PORT=4899, `DISABLE_AUTOUPDATER=1` (a sandboxed `claude` must not update the real install), unset TMUX/TMUX_PANE/AGENTHUB_MODE/AGENTHUB_*/CLAUDECODE. Local mode = no login.
- **`mkdir -p` the TMUX_TMPDIR first.** A missing TMUX_TMPDIR makes tmux silently fall back to the REAL default socket (2026-10-13: sandbox panes landed beside the user's `agenthub-lane-2/3`, slot numbers interleaved with theirs). After the first start, verify `<TMUX_TMPDIR>/tmux-<uid>/default` exists and `tmux -S /private/tmp/tmux-501/default ls` gained nothing. Keep it SHORT (`mktemp -d /tmp/ahp.XXXX`): a socket path over ~104 chars (the session scratchpad is) fails every `new-session`.
- macOS (this Mac): playwright-core installed in the session scratchpad; Chrome at `~/Library/Caches/ms-playwright/chromium-1228/chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing`. Route `/api/lanes/pick-path` to 403 EREMOTE in the page, or a loopback browser opens a real osascript dialog.
- Log redirects need ABSOLUTE paths (after `source env.sh`, `~` is the sandbox HOME).
- vite dev hits EMFILE (inotify) here: build instead, `vite build --outDir ~/.cache/agenthub-repro/dist`, serve with `DASHBOARD_CLIENT_DIST`.
- Workspace: `POST /api/lanes/ensure {cwd}`; panes: `POST /api/lanes/1/start {slot:"auto"}` (needs `Origin` header) → bare unauthenticated `claude` with a real `--session-id`, so Chat UI works and no quota is spent.
- Browser: `require("~/.npm/_npx/e41f203b7505f1fb/node_modules/playwright-core")` + `executablePath` `~/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome`; HTML5 drag works with `locator.dragTo`.
- A production-mode sandbox server spawns a TRAY ICON (`scripts/tray.js`) that outlives the server by design → extra icons in the macOS menu bar (2026-10-13: user saw 3). Start the sandbox with `<data dir>/runtime/tray-off` created first, or on teardown kill tray.js pids whose environ has `DASHBOARD_PORT=4899`.
- Teardown: `tmux -S <sandbox socket> kill-session -t =name` per session (list first), kill the 4899 pid only after checking its environ's DASHBOARD_DATA_DIR. Never `pkill -f` a string your own command line contains.
@@ -0,0 +1,19 @@
---
name: agenthub-server-box-hardware
description: "This dev box becomes the team AgentHub server — 4-core/15 GB, SSD+HDD; lag was the HDD, not AgentHub; measured server capacity"
metadata:
node_type: memory
type: project
originSessionId: 3e920c96-dcc6-48df-945b-419d9705015b
modified: 2026-10-08T07:04:34.801Z
---
Box (measured 2026-10-08): Intel 100-series (Skylake) 4 cores, 15 GB RAM, SSD `sdb` 224 GB (/), HDD `sda` 500 GB with bind mounts for `~/.nvm`, `~/.local`, `~/.config` (Chrome profile), `~/.cache`, Docker, /var/log, /mnt/hdd. That HDD sat at 93–96 % util, 15–24 % iowait — the cause of the user's "lag", not AgentHub.
AgentHub measured: 4820 p99 4.8 ms with 3 sessions; peak real load 7–11 hooks/s; isolated copy of the 1.25 GB DB handled 100 hooks/s + 10 viewers at p99 ~40 ms, saturates ~200 hooks/s + 20 viewers (one Node thread, viewer refetches dominate). Real multi-user limit is RAM (~400 MB per `claude` process).
User plan: reinstall the OS, everything on SSD, HDD only for backups (/mnt/hdd), keep the GUI (they watch the box), move personal data to their Mac first; 4830 dev runs here until then, then only 4820. Daily DB backup to the HDD = Settings → Data → Daily backup (server/lib/db-backup.js, built 10-08, uncommitted on main).
**Why:** the user asked about a Rust/TS rewrite for speed; the numbers say no.
**How to apply:** answer perf/scaling questions from these numbers; suggest RAM (32 GB) before any rewrite; don't recreate HDD bind mounts for hot dirs. See [[agenthub-multi-user-goal]].
@@ -0,0 +1,16 @@
---
name: agy-auto-updates-on-run
description: "Running `agy` (Antigravity CLI) even with an isolated HOME auto-updates the real ~/.local/bin/agy binary"
metadata:
node_type: memory
type: feedback
originSessionId: c4043107-b649-4aaa-915a-0dd4a0a169cd
modified: 2026-09-29T04:39:33.876Z
---
Any `agy` run spawns a background self-updater that replaces `~/.local/bin/agy` in place (keeps `agy.<n>.old`), even with `HOME=/tmp/...`. Login is in the OS keyring, so an isolated HOME still runs as the user's account. On 2026-09-29 a spike run updated the user's agy 1.0.0 → 1.2.13 unintentionally.
**Why:** a spike is not supposed to change the user's installed tools.
**How to apply:** before running agy in a spike, tell the user it will self-update, or find/disable the updater setting first; always report it if it happened.
2026-10-08: one `agy --print /usage --output-format json` (user approved) updated 1.2.17 → 1.3.1 ~2 s after it exited. AgentHub v2.5.12 now runs that command for the Usage panel (every 5 min while a tab polls), so agy on a user's machine may self-update from AgentHub; `AGENTHUB_AGY_USAGE=0` turns it off. Tests never run the real agy (quota.test.js + scripts/test-server.js set it to 0).
@@ -0,0 +1,19 @@
---
name: analytics-parity-plan
description: Analytics parity (CCAM 523170e) phases 2–7 SHIPPED in v2.4.0 (4aae6129); deviations and what is left
metadata:
node_type: memory
type: project
originSessionId: 2be81da3-a042-4711-a022-329e454923fd
modified: 2026-10-06T09:50:28.294Z
---
Phases 1–7 were built 2026-10-05 in worktree `../agenthub-analytics` (branch `analytics-parity`, base 138e706, never committed). Phase 1 (event payload trim) shipped in main on its own (215cae7).
2026-10-06: ported onto 837da6e5 (v2.3.1) in a throwaway worktree from the dangling snapshot commit `597b20e` (parent 138e706), then committed as 4aae6129 — see the SHIPPED line below.
Port decisions: Phase 1 hunks resolved to main's version (+ Phase 6 redaction chained in); workflow tool/range filters moved into `server/lib/workflow-stats.js` (main's read worker), not the old in-route code; `/api/pricing/cost` keeps main's `?date=` beside `computeCost`; Push ingest + Privacy cards on Settings → **Data** (main split General); Snapshot/Query pages lazy like main's; i18n merged 3-way by key; the spend-rule test lives in `AlertsNotifications.spend.test.tsx`.
Verified: tsc clean, client 1055/1055, server 2438/2439 (only `updates.test.js` "must run from a git checkout" — fails in ANY linked worktree, v2.3.0 too); boot on fresh DB, on a backup of the real 1.2 GB DB, and the same with better-sqlite3 blocked — same row counts, integrity ok. `/api/analytics` first call ~1.6–2.4 s cold on the real DB (main too), ~160–220 ms warm.
SHIPPED 2026-10-06 as v2.4.0 (4aae6129, release 549); the port worktree and branch are deleted, ../agenthub-analytics (uncommitted, old base) is now redundant. Left undone: OpenAPI entries for the new routes, live Codex overlay (deliberate), Cursor tokens/cost (no source), long-context pricing (deferred). Budgets are alert rules (no budgets table/page). Related: [[agenthub-release-state]], [[agenthub-dev-prod-ports]].
@@ -0,0 +1,50 @@
---
name: claude-code-changelog-2-1-293
description: "Claude Code changelog 2.1.285–2.1.295 (to 2026-10-08) — items that touch AgentHub's hooks, plugins, resume, MCP, CLI, Workflow"
metadata:
node_type: memory
type: reference
originSessionId: f2f2cbeb-6ac1-4876-8b8a-f8dc6cd3a17b
modified: 2026-10-09T03:58:51.151Z
---
Source: https://code.claude.com/docs/en/changelog (re-read 2026-10-09). Installed on this box: 2.1.295 = latest (auto-updated). The local ~/.claude/cache/changelog.md is stale (stops at 2.1.139); always read the web page.
AgentHub-relevant changes:
- **2.1.295**:
- Hooks get `onFailure: "block"` for command/HTTP hooks: a hook that fails, times out or exits oddly BLOCKS the action. AgentHub's own hooks must keep the default (fail-open), per CLAUDE.md "Hooks: keep fail-safe and non-blocking". Never set it in plugin.json or the installer.
- **Program Status Protocol (OSC 7501)**: Claude Code reports working / waiting / done to the terminal. TESTED 2026-10-09: it cannot replace hooks and does not work through tmux; see [[osc7501-vs-hooks]].
- `claude -p` prints on stderr what it is waiting for when it stays open.
- Subagents preload at most 32 skills.
- claude.ai connectors default to MCP protocol 2026-07-28 (`MCP_PROTOCOL_NEGOTIATION=legacy` opts out).
- Fixes:
- Background sessions no longer inherit `FORCE_COLOR=3`.
- Subagents in a linked worktree no longer see the parent's git branch/status.
- An async SessionStart hook's context is no longer re-added on every resume.
- `CLAUDE_ENV_FILE` vars now survive `/resume` and `/branch`.
- `--tools`/`--restricted` now cover late-registered tools.
- An Edit is no longer treated as a full read when the file changed without its mtime advancing.
- Grep accepts `-l`/`-c`/`-r`.
- **2.1.294**: `prompt`/`agent` hooks written as instructions ("Block commands that…") no longer let through what they should block, and Stop/SubagentStop prompt hooks are judged better.
- **2.1.293**: `subagentStatusLine` payload gains `agentType`; mods' `classic.*` hooks no longer skipped during plugin-hooks-worker restart; `claude plugin test` gets `mock.session`.
- **2.1.292**: `claude plugin install --marketplace <source>` (adds marketplace + installs in one step — could simplify the manual install command); stdio MCP negotiates protocol 2026-07-28 by default (`MCP_PROTOCOL_NEGOTIATION=legacy` opts out — relevant to `agenthub mcp`); `/loop` wakeups survive process restart.
- **2.1.290**: `claude attach <name>` / `claude logs <name>` accept partial session names; plugin hook `tool.check` has `agentId`; permission rules re-applied after a PreToolUse hook rewrites input; `CLAUDE_CODE_DISABLE_ATTACHMENTS` no longer settable from repo `.claude/settings*.json`.
- **2.1.289**: `agent.spawn` for teammates, one agent id across plugin hook events, idle/waiting in `$.agent.list()`; fixed stale local-folder-marketplace plugin copies and mods not loading in first session after upgrade.
- **2.1.288**: resume/transcript-loss fixes; InstructionsLoaded hook now carries `agent_id`/`agent_type`; PreToolUse/PermissionRequest now BLOCK the call if matching fails or input isn't JSON-serializable; `claude project purge` → `claude purge` (old name still works).
- **2.1.287**: **Claude Mods** (plugins modifying deeper behavior, function hooks); OTel `user_prompt` gains `prompt_text` (mask like `prompt`); MCP `alwaysLoad: false` defers all that server's tools behind tool search; "N hooks ran" no longer double-counts internal callbacks; SessionStart from synced plugins runs in cloud sessions.
- **2.1.286**: `--bare` connects only CLI-named MCP servers, no system reminders, no background tasks; `/hooks` is one grouped list; plugin installs refuse npm sources that are git repos/folders.
- **2.1.285**: `claude --desktop`; `claude plugin configure <plugin>` (+ `--values-stdin`); `claude plugin install --config <server>.<key>=<value>`; managed `allowedProviders`; `CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`.
Nothing in this range changes `--session-id`, `--worktree`, `/reload-plugins` or tmux behavior that AgentHub relies on (see [[update-never-kills-panes]]).
Useful for the user's own workflow (beyond AgentHub):
- Skill evals (`learned:writing-agent-context` → `claude plugin eval`): 2.1.292 makes a failed `expect` in a test-registered hook, or a refused stub answer, FAIL `claude plugin test` instead of passing silently, so a suite that was green before may now go red for a real reason.
- `claude purge` is the new name of `claude project purge`.
- `/loop` and scheduled tasks now survive resume, compaction and process restart (2.1.290/2.1.292).
- `claude --desktop` opens the current dir/session in the desktop app.
- Workflow tool (2.1.295):
- `scriptPath` is only accepted for a path the tool returned or a readable dir. The refusal now says to pass the script inline via `script`.
- Workflow scripts are persisted under ~/.claude/projects/<cwd-slug>/…; copy one into an added dir (not /tmp, see [[tmp-wiped-on-reboot]]) to resume it.
- "May have been stopped by TaskStop" on resume was a false notice and is fixed.
- Forked skills inside workflow subagents now return to the invoking agent.
- `CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS` caps unattended 429/529 retry waits.
@@ -0,0 +1,10 @@
---
name: claude-code-line-mention-syntax
description: Claude Code CLI attaches a line range only for @path#L<a>-<b>; @path#a-b silently attaches the whole file
metadata:
type: reference
---
Verified in the 2.1.293 binary on 2026-10-08. The parser is `^([^#]+)(?:#L(\d+)(?:-(\d+))?)?(?:#[^#]*)?$`, and Claude Code's own IDE builder emits `@path#L5-10 ` (with a leading space if the previous character is not whitespace). A `#5-10` fragment without the `L` is ignored, so the whole file is read. The VS Code docs show `@app.ts#5-10`, but that is only the extension's chat panel. The `@` must start the prompt or follow whitespace, and a path with spaces needs `@"path#L1-2"`. Codex treats `@path` as plain text.
AgentHub's Add to Chat (`LaneChangesPanel.tsx`) was fixed on 2026-10-08 to paste ` @path#La-b `.
+23
View File
@@ -0,0 +1,23 @@
---
name: claude-haiku-5-5
description: "Claude Haiku 5.5 (2026-10-07) facts + its 100k-token price tier, which AgentHub's pricing does not model"
metadata:
node_type: memory
type: reference
originSessionId: f2f2cbeb-6ac1-4876-8b8a-f8dc6cd3a17b
modified: 2026-10-08T03:58:14.256Z
---
Source: https://www.anthropic.com/claude-haiku-5-5 (read 2026-10-08).
- Model id `claude-haiku-5-5`, released 2026-10-07. Cheapest/fastest small model; first Haiku with effort levels (low/med/high/xhigh/max); computer/browser use in beta; new tokenizer uses slightly more tokens per task.
- Per MTok, split at a **100k-token prompt**: input $0.10/$0.50, output $0.50/$2.50, cache write $0.125/$0.625, cache read $0.01/$0.05. (Haiku 4.5: $1/$5/$1.25/$0.10, flat.)
- Same day: **Sonnet 5.5 cache read was halved, $0.20 → $0.10** (input $2, output $10 unchanged).
- Anthropic positions it for summaries, compaction, classification, subagents; Sonnet/Opus 5.5 still better for complex agentic coding (Terminal-Bench 4.0: 39.2% vs Sonnet 70.6%).
- Platforms: Claude API, AWS, Google Cloud, Azure.
AgentHub status 2026-10-08: the >100k tier is now modelled (uncommitted), as SUBSET columns `long_*_tokens` on token_usage/token_usage_hourly plus `model_pricing.long_input_per_mtok`/`long_output_per_mtok`, synced from LiteLLM's `*_above_100k_tokens`. It was deliberately NOT done as a new primary-key dimension: prod (4820) and dev (4830) share one DB, so a PK rebuild would break the older build's `ON CONFLICT`, and splitting rows would double-count under the high-water-mark baselines. Threshold is the single `LONG_CONTEXT_TOKENS` = 100k.
Useful for the user's own work:
- A good cheap model for subagents doing exploration, summaries or classification. AgentHub's AI commit message (`server/lib/commit-message.js`, `--model haiku` alias) now gets it automatically and costs about 10× less. Nothing needs to change.
- Its cyber safeguards still BLOCK pentest/attacker techniques, so it is the wrong model for Strix pentest work. Use Sonnet/Opus there.
+18
View File
@@ -0,0 +1,18 @@
---
name: fast-bump-release
description: Bump + release must be quick — no full test suites at release time; run only the tests for what changed
metadata:
node_type: memory
type: feedback
originSessionId: 9476633f-af74-42b1-bcd5-99cf5cc82821
modified: 2026-10-10T05:01:24.067Z
---
When the user asks to bump/push/release AgentHub, do it fast: bump version (package.json, package-lock.json lines 3+9, screens snapshot "UI build vX"), commit `--no-verify`, tag, push, forge release (EN then VI, see [[agenthub-release-state]]). Do NOT rerun both full suites at release time — the related tests already ran during the fix.
**Why:** 2026-10-10 the user said bump/release takes too long because of excessive testing (full server+client runs ~5–10 min, plus the pre-commit hook's full run that fails on 6–7 pre-existing tests).
**How to apply:** at release, at most rerun the test files touched by the change set if they were edited after their last run; never the full suites unless the user asks or the change set is large/unverified.
**Exception — always run the real build gate:** before tagging, run `cd client && node_modules/.bin/tsc -b` (exactly what `npm run build` runs; it type-checks TEST files too). v2.7.0 (2026-10-10) shipped a test missing required props: vitest and `tsc --noEmit -p .` were green, `tsc -b` failed, and every user's update stopped at "npm run build failed" → hotfix v2.7.1. Fast release still means skipping the full suites, never skipping `tsc -b`.
@@ -0,0 +1,13 @@
---
name: instructions-other-tools
description: Why AgentHub's agent/workspace instructions reach only Claude and Codex — Cursor CLI and agy have no per-session way (tested 2026-10-12)
metadata:
type: project
---
Tested 2026-10-12 (cursor-agent 2026.10.01, agy binary strings only — never ran agy, see [[agy-auto-updates-on-run]]):
- **Cursor CLI**: no system-prompt flag. `--plugin-dir` is honoured only when Cursor's server flag `enableUserLocalPlugins` is on (off for this account — an always-apply rule in a plugin was ignored); `--add-dir` loads no rules. Rules load only from the cwd's `.cursor/rules`/AGENTS.md (control run confirmed) = the user's repo, forbidden.
- **agy**: no per-session flag (`/add-dir` is a slash command); rules only from global `~/.gemini/GEMINI.md`, `~/.gemini/config/rules/` (shared with the Antigravity IDE) or repo files.
- Not installed here, unverified: copilot, grok, kimi, omp, opencode.
**How to apply:** `GET /api/me/instructions` returns `tools` (= `SUPPORTED_TOOLS` in server/lib/lane-sources.js) and the Settings card shows "Applies to" only for those, installed and enabled. Recheck Cursor's plugin-dir if they ungate it. Writing agy's global rules folder was offered to the user as an opt-in, not built.
@@ -0,0 +1,15 @@
---
name: link-means-learn-and-remember
description: "When the user pastes a docs/news/changelog URL, read it, pick what is useful for them, and save that to memory"
metadata:
node_type: memory
type: feedback
originSessionId: f2f2cbeb-6ac1-4876-8b8a-f8dc6cd3a17b
modified: 2026-10-08T03:58:35.212Z
---
When the user sends a bare URL (a changelog, a model announcement, docs), or writes something like "cập nhật kiến thức", they want me to read it, keep only what is new and useful for them or their work, and write that to memory. They do not want code changes, and they do not want a full summary.
**Why:** On 2026-10-08 the user clarified this after sending the Claude Code changelog and the Haiku 5.5 page ("hãy xem có thông tin/kiến thức nào mới … có thể sử dụng được cho tôi … thì hãy ghi nhớ lại").
**How to apply:** Filter each item against their work: AgentHub (hooks, plugins, pricing, MCP, CLI), their `learned` skills and `claude plugin eval` workflow, Strix pentest skills, and cost. Save that filtered set and say where it went. If an item points at a gap in AgentHub, say so and ask before fixing it. Examples: [[claude-code-changelog-2-1-293]], [[claude-haiku-5-5]].
@@ -0,0 +1,15 @@
---
name: never-tmux-kill-server
description: "Never run `tmux kill-server` (or any tmux kill) from this session — $TMUX overrides TMUX_TMPDIR and it kills the user's real server, including this session's pane"
metadata:
node_type: memory
type: feedback
originSessionId: 0ffc9ffc-1268-4f68-8d99-85f48962dfdb
modified: 2026-10-05T01:25:20.401Z
---
Never run `tmux kill-server`, even as `env TMUX_TMPDIR=<tmp> tmux kill-server`. This session runs inside tmux (`TMUX=/tmp/tmux-1001/default,…`), and tmux uses the `$TMUX` socket in preference to `TMUX_TMPDIR`. So that command killed the user's REAL default tmux server: every lane pane and the pane hosting this conversation. It happened twice on 2026-10-05 while cleaning up an isolated test server.
**Why:** It destroys the user's live agent sessions and stops this conversation; that is irreversible.
**How to apply:** To clean up a private test tmux server, either leave it alone (it dies with its temp dir/processes), or address its socket explicitly: `env -u TMUX tmux -S <tmpdir>/tmux-<uid>/default kill-server`, after checking with `ls` that the socket path is under the temp dir. `npm run test:server` already cleans up its own server; never add a manual kill. Kill test processes only by verified PID (check `/proc/<pid>/environ`). Never use `pkill -f <pattern>`: it also matches the shell running it. Related: [[agenthub-flaky-codex-ingest-tests]].
@@ -0,0 +1,15 @@
---
name: no-agenthub-agents-skills
description: "Do not use agenthub:* agents or agenthub:* skills (ship-feature, reviewers, update-project-docs…) — too quota-heavy"
metadata:
node_type: memory
type: feedback
originSessionId: 7d8f0767-2ebe-4082-af4a-bb47a9104695
modified: 2026-09-24T04:39:18.244Z
---
Do not dispatch `agenthub:*` agents (frontend-reviewer, backend-reviewer, qc-local, senior-gate-reviewer) or invoke `agenthub:*` skills (ship-feature, ship-feature-lane, update-project-docs, …), even where CLAUDE.md says to prefer them.
**Why:** the user said (2026-09-24) they cost too much quota for what they deliver.
**How to apply:** do the review, docs and pipeline steps directly. A single non-agenthub reviewer is OK only when it's clearly worth it. The `agenthub stage` CLI calls are cheap reporting, and those are still fine.
@@ -0,0 +1,12 @@
---
name: no-git-stash-shared-checkout
description: Another Claude session may be editing/staging in the same agenthub checkout at the same time — never git stash to compare against HEAD
metadata:
type: feedback
---
On 2026-10-06 a parallel session committed v2.5.6 and staged new tmux/package changes in this checkout while I was working; my `git stash`/`stash pop` (to rerun a test on clean code) briefly hid whatever was in the tree.
**Why:** stash/pop is checkout-wide; it can swallow or unstage another session's in-flight work.
**How to apply:** to test against clean code use `git worktree add /tmp/<x> HEAD` instead. Before reporting, check `git status` for staged changes that are not yours and leave them alone. See [[agenthub-multi-user-goal]].
+27
View File
@@ -0,0 +1,27 @@
---
name: osc7501-vs-hooks
description: "Claude Code's OSC 7501 Program Status cannot replace AgentHub hooks — tested 2026-10-09 on 2.1.295; works only on a terminal that answers its startup probe, and not through tmux"
metadata:
node_type: memory
type: reference
originSessionId: 0b101e16-e1e6-4423-9539-49ddea37ddf0
modified: 2026-10-09T04:16:29.852Z
---
Tested on 2026-10-09 with Claude Code 2.1.295, using a Python pty fake terminal and a private `tmux -L` server.
**Format.** Claude probes `ESC ] 7501 ; ? ST` once at startup. It reports only if the terminal answers with an OSC 7501 whose data starts with `?`. Each report looks like `ESC ] 7501 ; state=<s>:app=claude-code[:id=][:kind=][:progress=][:title=<b64>][:msg=<b64>] ST`.
- `state` takes the values idle, working, blocked, done, failed and clear.
- `blocked` comes with `kind=permission` and `msg` = "approve Bash: <cmd>".
- `working` comes with `msg` = a one-line description of what it is doing.
- There is no session id, no tool events, no subagents and no tokens.
**Results.**
1. Direct pty, probe answered: idle → working → (blocked:permission) → done. This works.
2. Probe not answered: nothing is ever reported.
3. Inside tmux: the probe never reaches an attached client, with or without `allow-passthrough on`, and whether the pane started detached (like AgentHub) or attached. So nothing is reported.
4. tmux `pipe-pane` DOES see the raw probe. Replying with `send-keys -H` did NOT turn reporting on. Likely cause, unverified: tmux answers the DA1 sentinel first, so Claude has already given up on the probe.
**Conclusion:** OSC 7501 cannot replace hooks, and does not even work in AgentHub's tmux panes. Hooks give session id binding, tool events, subagents and transcript paths, and OSC 7501 has none of these. The only route that would work is a small pty proxy wrapped around `claude` in each pane, which answers the probe itself and forwards states. That is a new process in every pane, for a coarse live state that hooks (Notification/Stop) already give. Not worth it unless a tool with no hooks ever speaks OSC 7501.
Related: [[claude-code-changelog-2-1-293]].
@@ -0,0 +1,17 @@
---
name: remove-ineffective-skills
description: "User wants skills that don't help (or that lower output quality) removed, not kept around"
metadata:
node_type: memory
type: feedback
originSessionId: f869a50f-0ba0-4b91-8720-1c7b1788f68c
modified: 2026-10-08T04:46:33.637Z
---
Skills that have no effect, or that make Claude's work worse (over-broad triggers, outdated advice, contradictions), should be deleted, not just reported.
**Why:** said 2026-10-08 after the prompt audit; unused skills still cost listing tokens and misroute requests.
**How to apply:** judge with evidence: Skill invocations in `~/.claude/projects/*/*.jsonl`, `learned` eval results (with vs without), audit findings. Keep the user's own skills that beat baseline (`learned:*`) or see real use (`daily-report`). For a skill symlinked from `~/.agents/skills/`, remove only the link in `~/.claude/skills/` (Codex reads `~/.agents/skills`). The auto-mode classifier blocked an `rm` there on 2026-10-08, so hand the user the command. Related: [[no-agenthub-agents-skills]].
Roles the user set (2026-10-08): `sg-all:sg-md-writing` = THE skill for maintaining project knowledge (CLAUDE.md/AGENTS.md/rules/skills/subagents; `learned:writing-agent-context` was folded into it); `sg-all:sg-prompt-sharpening` = turn the team's terse natural-language asks into a complete prompt, show it, then act. Source is the company repo `~/MyDrive/Projects/ResearchAndDevelopment/smartgift-claude-skills` (master, evals under `plugins/*/evals/`); v0.2.0 was pushed there on 2026-10-08 at the user's request; ask again before any later push.
+25
View File
@@ -0,0 +1,25 @@
---
name: s3-main-merge-notes
description: "Exact edits to apply when merging s3-next (S3 server mode) into main — agenthub-26's chat/drop/permission-mode work on main needs S3 routing"
metadata:
node_type: memory
type: project
originSessionId: 0b101e16-e1e6-4423-9539-49ddea37ddf0
modified: 2026-10-09T02:21:46.744Z
---
On 2026-10-09, agenthub-26 left uncommitted work on main. It covers the chat UI, drop images and permission-mode. These files overlap with S3 (see [[agenthub-multi-user-goal]]). When s3-next merges into main, do the following:
1. `server/lib/tmux.js`: `capturePane` and `sendKey` call `execImpl` on main. Change both to member routing:
- `capturePane = onServerOf(name, ["capture-pane","-p","-t",pane(name)])`
- `sendKey = onServerOf(name, ["send-keys","-t",pane(name),key])`
Check that only ONE `function onServerOf` survives the merge. In CommonJS a second declaration silently wins and turns member routing off. `server/lib/pane-mode.js` only goes through those two helpers, so it inherits the routing.
2. `GET /api/run/drop/:name` (`server/routes/run.js`): on main it opens with O_NOFOLLOW|O_NONBLOCK, then fstats the descriptor, and requires `uid === process.getuid()`. The name regex accepts only ids the server made. Under S3:
- use `dropDir(req)`, the requester's own account;
- compare `st.uid` to the member's uid, or call run-as `openSafe`.
Agreed trade-off: an admin viewing a member's session sees the file-name chip, not the image.
3. `GET|POST /api/run/:id/permission-mode` is already covered by `scope.canSeeRun` and the `/run/:id` PATH_RULES. It types only through `tmux.sendKey`, so point 1 covers it.
**Why:** under S3 the host must never use a member's tmux socket or member files directly (P8 F1/F3). A plain merge would silently keep host-side calls.
**How to apply:** do this at the s3-next → main merge. Message agenthub-26 (if it is still alive) before committing on main.
+15
View File
@@ -0,0 +1,15 @@
---
name: tmp-wiped-on-reboot
description: "/tmp on this box is cleared on reboot; keep multi-hour work artifacts (scripts, renders, notes) in ~/.cache/<project>/ instead"
metadata:
node_type: memory
type: feedback
originSessionId: 6ed0a760-0a89-4a3e-b474-326390ae4048
modified: 2026-10-09T03:29:54.984Z
---
/tmp is wiped when this machine reboots. On 2026-10-09 a reboot mid-task erased every helper script, render and review note of the tri-vi-portfolio 3D house work, and they had to be rewritten.
**Why:** the box reboots without warning (kernel updates), and sessions get cut.
**How to apply:** put anything that must outlive the session outside both /tmp and the repo. The tri-vi house pipeline lives in `~/.cache/tri-vi-bake/` (bpy venv, scripts/, out/, study.glb). Keep running notes there too, not only in context. Related: [[agenthub-server-box-hardware]].
@@ -0,0 +1,17 @@
---
name: update-never-kills-panes
description: Updating AgentHub must never kill existing tmux lane panes; only Quit AgentHub closes them
metadata:
node_type: memory
type: feedback
originSessionId: f681ac06-d81e-4a3d-bd50-0679b1bcf18a
modified: 2026-10-08T01:47:38.004Z
---
Updating AgentHub (plugin update, checkout self-update, bootstrap `--force`, systemd/launchd restart) must NEVER kill the existing tmux panes (`agenthub-lane-*`). Panes are closed only by **Quit AgentHub** (`POST /api/settings/quit`, `agenthub stop`, issue #65), plus the user's own per-lane stop/reset/remove.
**Why:** the user said so directly (2026-10-08). Running agents live in those panes, and an update that kills them throws away work in progress.
Beyond AgentHub's control (the user has not signed off on these, so report them): Linux logout without linger, systemd-oomd under memory pressure, Windows psmux (unverified).
**How to apply:** never add `killRun`/`killSession`/`kill-server` to any update, restart or shutdown path. Keep `KillMode=process` in `scripts/systemd-service.js`, the `systemd-run --user --scope` start of the tmux server in `server/lib/tmux.js` (Linux), and `AbandonProcessGroup` in the launchd plist. tmux can be forked into the `agenthub.service` cgroup, and systemd's default `control-group` would kill every pane on restart. When reviewing update or restart changes, check this. Related: [[never-tmux-kill-server]].
@@ -0,0 +1,17 @@
---
name: workspace-rename-step4
description: "Removing the old `agenthub lanes`/`--lane` CLI names is deferred to ≥3 releases after the aliases ship; never touch stored data"
metadata:
node_type: memory
type: project
originSessionId: 47dc0201-8e49-4fce-9407-f087d3107588
modified: 2026-10-06T04:07:56.796Z
---
On 2026-10-06 the user had steps 1–3 of the lane→workspace rename built (aliases `/api/workspaces`, `agenthub workspace`, `--workspace`; help/docs on the new name; a stderr deprecation note for `agenthub lanes`/`--lane`). Step 4 (removing the old CLI names, moving client+CLI requests to `/api/workspaces`) is deferred until the THIRD release after the first one that ships the aliases (the first release after v2.0.1). The plan, checklist and "never touch" list are in `docs/plans/workspace-rename/README.md`.
**Why:** the user wants existing installs to update gradually and NOT lose any data — DB tables/columns, response keys, tmux names `agenthub-lane-<id>`, env vars, on-disk paths and browser storage keys must never be renamed.
**How to apply:** when cutting a release, check whether it is ≥ R+3 (R is recorded in that plan file — fill it in when R is cut) and remind the user that step 4 is due; keep `/api/lanes` unless the user decides otherwise (step 4c, default keep).
R = v2.1.0 (released 2026-10-06), so step 4 is allowed from the 3rd release after v2.1.0.