Generated by the improve skill on 2026-07-06, audited against commit 610a7b0.
Each plan is self-contained: an executor with zero prior context can run it from
the plan file + the repo. Read the plan fully before starting, honor its STOP
conditions, run its drift check first, and update your row below when done.
Breaking / behavior-changing plans are flagged
| Plan | Title | Cat | Priority | Effort | Depends on | Status |
|---|---|---|---|---|---|---|
| 001 | Add missing typecheck scripts (inspect + 5 examples) |
dx | P1 | S | — | DONE (partial — see note) |
| 002 | Clear the critical shell-quote advisory in the bundle |
security/deps | P1 | S | — | DONE |
| 003 | Reject cross-origin WebSocket upgrades |
security | P1 | S | — | DONE |
| 004 | Stop git argument injection via ref/hash |
security/bug | P1 | S | — | DONE |
| 005 | Don't cache a rejected RPC setup() promise |
bug | P1 | S | — | DONE |
| 006 | Bound SharedState.syncIds (memory leak) |
bug | P1 | S | — | DONE |
| 007 | Behavioral tests for the auth/OTP trust boundary | tests | P1 | S | — | DONE |
| 008 | Cap hub terminal buffer + reject restart-after-terminate | bug | P2 | S | — | DONE |
| 009 | Fix two server-side streaming lifecycle leaks | bug | P2 | S-M | — | TODO |
| 010 | Initialize client shared state once across trust flips | bug | P2 | S | — | DONE |
| 011 | Don't leak/drop when WS client posts on a closing socket | bug | P2 | S | — | DONE |
| 012 | Atomic, non-throwing createStorage writes |
bug | P2 | M | — | DONE |
| 013 | De-duplicate git parse helpers into node/git.ts |
tech-debt | P2 | S | 004 | TODO |
| 014 | Parallelize the git:show static dump |
perf | P2 | S-M | 004, 013 | TODO |
| 015 | Expire + bound the persisted trusted-token store | security | P2 | S | 007 (shared test) | TODO |
| 016 | Harden code-server: loopback bind + folder guard |
security | P2 | M | 003 (mitigates cookie) | TODO |
| 017 | Make allowArbitraryCommands govern preset overrides |
security | P2 | M | — | TODO |
| 018 | Persist a Turbo cache in CI (e2e job) | dx | P3 | S | — | TODO |
| 019 | RPC round-trip tests for the inspect plugin | tests | P3 | S | 001 (compl.) | TODO |
| 020 | Docs pages for the 15 plugin DP_* diagnostics |
docs | P3 | M | — | TODO |
| 021 | Document @devframes/plugin-messages |
docs | P3 | S | — | TODO |
| 022 | Memoize git commit-log rows | perf | P3 | M | — | DONE |
| 023 | Single-pass MessagesView filtering | perf | P3 | M | — | TODO |
| 024 | Batch stream-replay into one frame | perf | P3 | M | 009 | TODO |
| 025 | Cache falsy RPC results (presence check) | bug | P3 | S | — | DONE |
| 026 | Clear dev/docs-only dependency advisories | deps | P3 | S | 002 | TODO |
| 027 | Spike: @devframes/next host-integration package |
direction | P3 | M | — | DONE (shipped @devframes/next, experimental — see docs/helpers/next.md; hub + next-runtime-snapshot examples adopt it) |
| 029 | Bring @devframes/plugin-git to the host baseline |
direction/dx | P3 | S-M | — | TODO |
| 030 | Spike: server-side auth enforcement |
security | P2 | L | 003, 007, 015 | DONE |
| 031 | Agent-native MCP wave (bridges, core surface, connector) | direction | P2 | L | — | IN PROGRESS (phases 1–3 implemented on PR #145; DONE at merge) |
| 032 | Reduce the devframe + @devframes/hub public API surface for 0.9 |
direction/tech-debt | P2 | L | — | TODO |
| 033 | Swappable UI packages: renderer-module manifest + missing-renderer fallback |
direction | P1 | L | — | DONE (plan + implementation in one PR) |
Status values: TODO | IN PROGRESS | DONE | BLOCKED (one-line reason) | REJECTED (one-line rationale).
- First wave (P1, mostly non-breaking, quick, clean verification): 001, 002, 003, 004, 005, 006, 007. Do 001 early (it makes the inspect plugin + examples actually typecheck, catching regressions from later work). 003 is the single highest-leverage security fix and is the prerequisite mitigation for the code-server cookie disclosure (016) and the auth-enforcement spike (030).
- Second wave (P2): 008–017. Note the git chain: 004 → 013 → 014 all touch
show.ts/log.ts, so land them in that order. 015 sharesstate.test.tswith 007. - Third wave (P3 polish + docs + direction): 018–029. 024 depends on 009.
- Design spike: 030 (auth enforcement) after 003/007/015 — it only makes enforcement possible and tested, off by default; turning it on is a separate breaking follow-up.
- 013 depends on 004, 014 depends on 004 + 013 — same git files
(
show.ts,log.ts); serialize to avoid collisions. - 024 depends on 009 — both edit the streaming
subscribehandler. - 015 coordinates with 007 — both live in
node/auth/__tests__/state.test.ts. - 016's cookie-disclosure residue is mitigated by 003 (origin check) and fully addressed by 030 (auth); 016 itself ships the bind + folder hardening.
- 026 depends on 002 — 002 clears the one runtime-shipped critical; 026 mops up the dev/docs-only advisories.
- 019 / 001 — 001 hit a STOP condition on the inspect plugin itself (see
below) and did not add its
typecheckscript; 019's verification should runtsc --noEmitdirectly inplugins/inspectinstead.
- 001 shipped for 4 of the 6 in-scope packages (
files-inspector,streaming-chat,next-runtime-snapshot,minimal-vite-devframe-hub), fixing the small in-scope type errors each surfaced (a missing*.css/virtual:uno.cssambient shim, a superfluousasyncon a schema-typed RPC handler whose framework type requires a synchronous return, a missing destructure default matching a valibotv.optional(..., default), a badas never[]cast inplugins/inspect/src/rpc/functions/invoke.ts— the last one is an in-scope inspect-plugin fix and was kept even though the plugin's own script was not added, below). plugins/inspectdid not get the script (STOP condition): itstsconfig.jsonis the only one in the repo withcomposite: true, which makestsc --noEmitreject otherwise-valid cross-package imports (devframe/ utils/*,devframe/adapters/cli, etc.) with TS6307 "file not listed in the file list of project" errors — a tsconfig fix, which this plan's Scope marks out-of-bounds. The plugin also has a few genuine SPA-composable type bugs (src/spa/composables/{history,rpc}.ts) independent of that flag. Follow-up: a small dedicated plan to dropcomposite(auditing why it was set — see6bbe9d2, it looks like copy-paste from a template, unused elsewhere) and then fix the remaining composable bugs.minimal-next-devframe-hubdid not get the script (STOP condition):packages/hub/src/node/host-terminals.tstypes its child-processenvasNodeJS.ProcessEnv; Next.js's own ambient types (next/types/global.d.ts) augmentProcessEnvto require a literal-typedNODE_ENV, so the plain{ COLORS, FORCE_COLOR, ...env }object hub builds no longer satisfies it once a Next.js app is in the program (packages/hubtypechecks clean on its own). Fixing this means looseninghost-terminals.ts's env type inpackages/hub— out of scope here. Follow-up: type that field asRecord<string, string | undefined>(or similar) inpackages/hub.- CI guard added:
scripts/verify-typecheck-coverage.ts(wired intopnpm typecheck, and therefore into CI) now fails if any workspace package has atsconfig.jsonbut notypecheckscript, with the two exceptions above declared explicitly (and flagged stale the moment they're fixed) — closing plan 001's original "Maintenance notes" follow-up so the gap this plan fixed can't quietly reopen.
- Hub-bridge type import (TECH-DEBT-02) — terminals + code-server each
duck-type
ctx.terminalswith local interfaces (manager.ts:60-82,supervisor.ts:44-64). Importing the canonical types from@devframes/hub/typeswould remove the drift risk, but aimport typestill makes the plugins' emitted.d.tsreference@devframes/hub, adding a type-resolution dependency the plugins deliberately avoid (they must typecheck standalone without hub). Net negative; deferred unless the maintainer accepts a type-only hub peer. - h3 pinned to a release candidate (DEPS-02) —
pnpm-workspace.yaml:53pinsh3: 2.0.1-rc.22on the critical host path. This looks intentional (exact RC pin). No plan; watch for h3 GA and bump behind amountStaticHandler/upgrade characterization test then. - serve-static per-request
statfan-out (PERF-05) —serve-static.ts:61-95does up to ~5stats per request with no cache. For a dev tool this is acceptable, and a resolution cache risks serving stale files on rename/delete (MED risk for marginal gain). Rejected as not worth the staleness risk. - Shared-state RPC read/write not trust-gated (SEC-06) —
node/rpc-shared-state.ts:94-130exposes get/set/patch with no trust check. This is a real exposure but its root cause is the origin/auth gap; folded into plan 003 (origin check) as the immediate mitigation and plan 030 (per-key client-writable opt-in + trust) as the durable fix. No standalone plan. - Auth token carried in the WS URL query —
ws-client.ts:32-34appends?devframe_auth_token=…. WS URLs aren't sent asRefererand this is loopback, so impact is low; noted for awareness, not planned.
Audited across all nine categories (correctness, security, performance, tests,
tech-debt/architecture, dependencies, DX, docs, direction) over packages/*,
plugins/*, and the build/CI tooling. Not deeply audited: the plugins' SPA
render layers for DOM-XSS from untrusted repo content (flagged by the security
pass as a worthwhile dedicated follow-up — e.g. plugins/git/src/client/** diff/
commit views), packages/nuxt, storybook/, and the Playwright e2e specs
line-by-line.