agentleFS
talayashtalayash/agentrium/.claude/skills/local-qa/SKILL.md

local-qa

Skill48 starsChanged 20 days agoMITView on GitHub

How to run Agentrium locally for QA/manual verification alongside the user's running production client. Use whenever asked to run, start, launch, QA, smoke-test, or screenshot the desktop app. Contains the hard rule about never touching the running production instance or port 5173.

5 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    NEVER, under any circumstances, for any reason:

    line 13
  2. Distinctive:

    Ask the user to close their client so your build can launch.

    line 19
  3. Very specific:

    Run bare npm run tauri dev or npm run dev in this repo.

    line 20
  4. Distinctive:

    If something still will not run after following this file, report that and stop.

    line 28
  5. Very specific:

    Do NOT use APPDATA / LOCALAPPDATA redirection instead.

    line 58
  6. Very specific:

    Run from agentrium/. Pick a QA port that is not 5173 (5174 is the default choice.

    line 76
  7. Very specific:

    Before picking the port, confirm nothing is listening on it: Get-NetTCPConnection -LocalPort 5174 -State Listen -ErrorAction …

    line 88
  8. Distinctive:

    Before driving anything, confirm there are now two processes and that you know which is which:

    line 108
  9. Very specific:

    Stop ONLY the background task you started (TaskStop with your own task id), or close the Agentrium QA window.

    line 121

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Running Agentrium locally for QA

The hard rule (never violate)

The user runs their real Agentrium client on this machine, all day, with live Claude Code sessions in it. It is production. It is their actual work.

NEVER, under any circumstances, for any reason:

  • Kill, stop, close, Stop-Process, CloseMainWindow, taskkill, or otherwise terminate a running claude-terminal.exe / Agentrium process.
  • Take, free, or kill whatever is holding port 5173. That is the production client's dev port.
  • Ask the user to close their client so your build can launch.
  • Run bare npm run tauri dev or npm run dev in this repo. Both default to 5173 and to the production app identifier, which collides.

There is no exception. Not "just this once", not "it's only a dev build", not "the app restores sessions anyway", not if a launch fails and killing it would be the quick fix. If QA seems to require stopping their client, you are using the wrong recipe - use the one below instead.

If something still will not run after following this file, report that and stop. Do not escalate to touching their process.

Why a plain tauri dev cannot work here

Three separate collisions, all of which must be solved at once:

CollisionCauseFix
App never launches, exits code 0tauri-plugin-single-instance (src-tauri/src/main.rs) keys on the app identifier; a second launch just focuses the first and quitsoverride identifier
Port in use / hijacks their dev servervite.config.ts pins port: 5173, strictPort: trueoverride port AND build.devUrl
Shares the production SQLite DB and keychain sign-indata dir and keychain service default to the prod namesset AGENTRIUM_INSTANCE_ID=.qa

Fixing only one of the first two is what causes the damage. Fix both.

Isolating the database (know this before you QA)

Always export AGENTRIUM_INSTANCE_ID=.qa before launching. Rust reads it through crate::instance_suffix() (src-tauri/src/main.rs) and appends it to:

  • the SQLite data dir: ClaudeTerminal.qa\claudeterminal.db instead of the prod ClaudeTerminal\claudeterminal.db (database.rs), so profiles, workspaces, agents and session history start empty and stay separate;
  • the keychain service: com.claudeterminal.agentrium.auth.qa (credentials.rs), so signing in or out in QA never touches the prod refresh token.

Without the variable the QA window opens on the user's real database. If you forget it, close the QA window you launched and relaunch with it.

Do NOT use APPDATA / LOCALAPPDATA redirection instead. directories resolves folders through SHGetKnownFolderPath, which ignores those variables, so the redirect silently does nothing.

What is still shared with prod even with the suffix (all low risk, but know it):

  • Terminal log files in ClaudeTerminal\logs (commands.rs hard-codes the unsuffixed dir). QA writes new, uniquely named files there and only deletes paths that its own DB points at, so prod logs are not touched.
  • error_reporter / feedback queues and the LSP download cache also use the unsuffixed dir.
  • Real outside state: git repos, worktrees, files on disk, and Claude Code's own ~/.claude sessions. A QA terminal pointed at a real repo is a real terminal. Use a scratch folder for destructive flows (worktree removal, force push, session purge).

The recipe

Run from agentrium/. Pick a QA port that is not 5173 (5174 is the default choice; step up if it is taken).

QA_PORT=5174
export AGENTRIUM_INSTANCE_ID=.qa

npm run tauri dev -- \
  --features devtools \
  --config "{\"identifier\":\"com.claudeterminal.desktop.qa\",\"productName\":\"Agentrium QA\",\"build\":{\"devUrl\":\"http://localhost:$QA_PORT\",\"beforeDevCommand\":\"npm run dev -- --port $QA_PORT --strictPort\"}}"

Before picking the port, confirm nothing is listening on it: Get-NetTCPConnection -LocalPort 5174 -State Listen -ErrorAction SilentlyContinue returning nothing means it is free. If it is taken, use 5175, 5176, and so on. Never 5173.

What each override buys you:

  • AGENTRIUM_INSTANCE_ID=.qa - own SQLite DB and own keychain entry (see "Isolating the database" above).
  • identifier -> ...desktop.qa - single-instance no longer hands off, so a second window actually opens beside theirs.
  • productName -> Agentrium QA - the window title tells you at a glance which one you are looking at. Always check the title before interacting.
  • devUrl + beforeDevCommand --port - both halves must change together, or Tauri loads 5173 and you are driving their app's server. First run recompiles Rust for the changed identifier - budget a few minutes.

Verifying you are on the QA instance, not theirs

Before driving anything, confirm there are now two processes and that you know which is which:

Get-Process claude-terminal | Select-Object Id,MainWindowTitle,StartTime

The QA one is titled Agentrium QA and has the newer StartTime. If only one process exists, the overrides did not take - re-read the recipe, do not kill anything.

Cleaning up

Stop ONLY the background task you started (TaskStop with your own task id), or close the Agentrium QA window. Never target a PID you did not launch, and never Stop-Process -Name claude-terminal - that name matches theirs too.

Driving the update sheet and notification banner

Both are frontend-only, so DevTools (--features devtools is already in the recipe) can drive them without any app source changes. Vite serves the store modules in dev:

const u = (await import('/src/store/updaterStore.ts')).useUpdaterStore;
const { toast, useToastStore } = await import('/src/store/toastStore.ts');

// update sheet: available / downloading / ready / error
u.setState({ status: 'available', notifiedVersion: '2.4.0',
  updateInfo: { version: '2.4.0', date: '2026-09-15', body: 'Release notes' },
  bannerDismissedVersion: null, bannerSnoozedUntil: null, skippedVersion: null });

u.setState({ status: 'downloading', downloadProgress: 61,
  downloadedBytes: 11200000, totalBytes: 18400000, bannerDismissedVersion: null });

u.setState({ status: 'ready', bannerDismissedVersion: null });   // Relaunch really relaunches
u.setState({ status: 'error', error: 'connection closed', bannerDismissedVersion: null });

// notifications - 4 at once crosses the collapse threshold
toast.success('Pushed to origin/master', '14 files changed across 2 commits');
toast.error('Push rejected', 'The remote has commits you do not have locally');
toast.warning('Worktree has uncommitted work', 'Switching branches may stash 6 files');
toast.info('Session restored', '4 terminals reattached');
useToastStore.getState().clearAll();

Do not bother with a plain browser

http://localhost:<port> in an ordinary browser hits the error boundary: useWindowFocused.ts calls getCurrentWindow(), which needs window.__TAURI_INTERNALS__. Stubbing it is not worth the effort - use the real window from the recipe above.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.