refactor: professionalize pass — gates in CI, deep seams, component extractions#181
Merged
Conversation
The check:contracts and check:structure gates only ran when someone remembered npm run check locally — three contributors independently hit stale gate failures. Also prunes the validator's reference to the removed shared/contracts/environments.ts and corrects AGENTS.md's test-runner note (tsx --test is long gone). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- frontend depcheck ignore-list moves from a 300-char inline --ignores flag to .depcheckrc.json, the same mechanism controller already uses - controller jscpd minTokens 400 -> 200, matching frontend (0 clones at the stricter threshold, so the alignment is free) - delete PROGRESS.md: a session work-log snapshot duplicating git history; docs/ carries the durable design notes Closes #146. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n root check tests/frontend/e2e ran node:test module regressions, not end-to-end tests — the name promised browser coverage that doesn't exist. Scripts, CI step, README, and AGENTS.md now say what actually runs. Root check:frontend additionally runs the frontend unit suites; previously the root gate ran controller tests but never frontend's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The feature-side copy silently omitted cwd/provider/archived/archivedAt fields the /api/agent/sessions/all route actually returns; the route re-declared the shape locally. One definition in shared/agent extends SessionSummary where it lives. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…me/:backend/upgrade Five copy-paste handlers (differing only in a backend literal) become one parameterized route validated against RUNTIME_JOB_BACKENDS. URLs are unchanged for existing callers; sglang/llamacpp/cuda/rocm now honor targetId/version/prefer_bundled and receive runningProcess exactly like the generic /runtime/jobs path, and mlx gains the same endpoint. The frontend mirror collapses five upgrade methods into upgradeRuntime() and drops the RuntimeCommandPayload type whose command/args fields the controller has rejected since the security hardening. Closes #145. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Runner seam Three independent ps parsers (listProcesses, buildProcessTree, and process-manager's listProcessTable) each ran and parsed their own ps invocation with their own regex — and only one sat behind the injectable ProcessRunner seam, so the other two were untestable. listProcessInventory() returns the superset row (pid/ppid/stat/ command/args) and all three derive from it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tatus union The status enum was 'idle | starting | running | loading | done | string' — the string arm voided type checking entirely, 'done' was a tool-block status that leaked into the session union, and session-index re-derived 'is working' from raw string comparisons that would silently misclassify any new status as running. settleTurn/settleTurnFinalizingTools replace five hand-rolled copies of the idle-settle transform (engine abort, failed-turn, agent_end, runtime poll, runtime-idle); SessionTab.status now shares the tightened union (persistence already coerces hydrated tabs to idle). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lder into their specs backend-builder advertised itself as engine-agnostic while carrying the vLLM extra-args allowlist filter, the vLLM Docker JIT wrapper, and the llama.cpp binary resolution/serialization rules. Those now live in specs/vllm-spec.ts and specs/llamacpp-spec.ts where the EngineSpec docstring says they belong; backend-builder keeps the generic serialization seam (appendSerializedArguments + ExtraArgumentSerializer) and the shared docker-run shape. Adding an engine no longer means editing the shared builder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AGENTS.md pointed at frontend/src/features/agent/pi-runtime*.ts; the runtime moved to services/agent-runtime/src/ months ago - the RTX 3090 left the remote box in June - controller README claimed Zod config validation (it's Effect Schema) and a CLI consumer (cli/ was deleted) - frontend README diagrammed /api/voice/* (voice feature removed) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
/v1/chat/completions only had an invalid-JSON assertion; the actual proxy behavior (upstream forwarding, SSE pass-through with the keepalive-first-byte contract, and the model_not_running 503 gate for managed recipes) was untested. Three tests against a stub upstream now pin all of it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ed stages The 220-line straight-line handler becomes parseChatBody / resolveChatUpstream / gateOnRunningModel / normalizeCompletionChoices closure functions plus a ~90-line dispatch, with behavior pinned by the new chat-proxy-forwarding tests. Also: malformed JSON on the recipe CRUD routes now 400s via parseJsonObjectBody instead of escaping as a 500 (ctx.req.json() threw outside the try). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
750-line modal becomes a 240-line composition over three verbatim-moved sections (runtime overview, voice creator, preview player); non-view helpers join the existing chatterbox-voice-model.ts per the model/view split. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
548-line shell sidebar becomes a 212-line composition; markup verified byte-identical (className/aria/role multiset diff) across the move. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
routes.ts carried recipe CRUD, launch lifecycle, model downloads, and the runtime-management surface in one 387-line file. It becomes a 12-line aggregator over recipe-routes / lifecycle-routes / download-routes / runtime-routes, with the shared observed-process closure extracted to a factory. Handler bodies verbatim; registration order preserved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One term per concept, grounded in current file paths — recipes, engines/specs, runtime targets, launch-state vs process-scan vs failure budget, the chat proxy stages, session/turn/pane vocabulary, and the contracts/gates conventions. Future reviews and agents should use these names. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sections 544-line panel becomes a 173-line container; DiffViewMode alias replaces a union repeated six times across props; pairDiffLines joins the model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ry, footer 526-line modal becomes a 126-line view over useRecipeModalModel (hook order preserved), pure source/format helpers, and two section views. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ToolSelection wire shape was known in two modules — tools/ owned the live selection while workspace/store.ts hand-rolled its serialization (and wrote promptTemplates past its own type via spread). selection-persistence.ts is now the single owner; persisted JSON is byte-identical and PersistedSessionMeta's type is honest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oad-state sections 501-line modal becomes a 263-line container; response schema and external-open helpers join a google-account-model per the sibling convention. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… use-setup 512-line hook becomes 309 lines over setup-load.ts and setup-actions.ts (verbatim moves; hook order unchanged). Completed after the extraction agent was cut off mid-verification; all gates re-run green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…feature, drop marketing clone features/marketing was a ~90% clone of the newer features/landing-page (same scaffolding, nav, screenshot frames). The unique content — the agents DLTL setup page — moves into landing-page/agents-page.tsx reusing the landing nav/frames/styles (agent CSS + responsive rules ported); /download now redirects to /landing; features/marketing is deleted. Also fixes two stale strings in DocsPage (test:e2e rename, dead CLI ref). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # frontend/package.json
|
🎉 This PR is included in version 1.65.3 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overnight professionalization loop (~24 commits, ledger with per-iteration rationale in
docs/professionalize-loop.md).Bugs fixed
ctx.req.json()threw outside the try).SessionStatusunion was voided by| string— zero type safety;session-indexre-derived "working" from strings incl. a status that doesn't exist.AggregatedSessionclient contract omitted four fields the server actually sends, and was defined twice.Gates & tests
check:contractsfailures).npm run check; the misnamed "e2e" suites are honestly namedregression.model_not_running503 gate.Deepened seams (controller)
process-inventoryparser behind the ProcessRunner seam replaces three independentpsparsers.backend-builderinto theirEngineSpecfiles;backend-builderis engine-agnostic (413→279)./runtime/{backend}/upgraderoutes → one validated/runtime/:backend/upgrade(closes Collapse redundant runtime upgrade routes into /runtime/jobs #145); frontend mirror collapsed too.Deepened seams (frontend)
session-status.ts: canonicalsettleTurn/isWorkingStatusreplaces five hand-rolled settle copies;SessionStatusandSessionTab.statusshare the tightened union.tools/selection-persistence.tssingle-owns the ToolSelection wire shape (workspace store delegated; persisted JSON byte-identical).Docs & config
CONTEXT.mdseeds the repo's domain language. README/AGENTS.md corrected (stale pi-runtime paths, removed 3090, Zod→Effect Schema, dead CLI/voice refs)..depcheckrc.json, jscpd thresholds aligned at the stricter bar (closes Hoist duplicated per-package cleanup tool configs #146);PROGRESS.mdscratch removed.Deliberate skips (rationale in the ledger — please don't re-request blind)
/runtime/<backend>info-path unification (two discovery mechanisms can disagree; needs design + live verification).setActiveRecipe(the machinery keeping models alive; not an autonomous-hours change).Validation
Full
npm run check(contracts, structure, frontend quality incl. build, controller checks) andnpm run test:integration(117 controller + 236 frontend regression) green at head. Every push ran the pre-push quality gate.🤖 Generated with Claude Code