Skip to content

feat: park/unpark and amend UI, defect fixes, Baseline standard (v0.4.0) - #6

Merged
TadMSTR merged 2 commits into
mainfrom
feat/park-amend-v04
Aug 2, 2026
Merged

TadMSTR merged 2 commits into
mainfrom
feat/park-amend-v04

Conversation

@TadMSTR

@TadMSTR TadMSTR commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Requires task-queue-mcp v0.4.0 — the park/unpark/amend routes do not exist on earlier versions. Merge that first.

Park replaces Quarantine

Quarantining was a one-way trip from the only interface that shows the queue: listTasks() and findTaskFilePath() read only the queue dir and never quarantine/, there was no Restore button anywhere in the UI, and the backend's POST /tasks/:id/restore route was unreachable — while the confirm dialog told the operator the task "can be restored". It had never bitten anyone only because the feature had never been used.

Because parked is now a status upstream and the file never moves, listTasks() picks a parked task up with no reader change — that's the payoff of the status design. It renders muted and dashed with an Unpark button; the detail view carries a banner naming the status it will return to.

Amend

Amendments render directly below the description, highlighted, headed "read these, the description above is unchanged". An amendment nobody reads is no better than the note-in-a-file workaround it replaces. The history timeline now labels non-status actions by action instead of repeating the task's status, which read as a redundant transition.

Fixes

  • Stale reported version. server.ts hardcoded VERSION = '0.2.0' while package.json and manifest.json said 0.3.0, so /health and the WebSocket connected event under-reported by two releases. Now read from package.json at startup, so it can't drift again. (deploy.sh already copies package.json alongside dist/, so the read resolves in both the repo and deployed layouts.)
  • WebSocket origin check could be skipped entirely. if (origin && !allowed.includes(origin)) — a client sending no Origin header bypassed it. Browsers always send one; non-browser clients don't, which is precisely the case the check exists for. A missing origin is now rejected.
  • previewFile symlink escape. path.resolve normalises .. but follows nothing, so a symlink inside an allowed prefix pointing anywhere on disk passed the check. fs.realpathSync first, and the prefix compare uses the platform separator.
  • Bare npx in the build script. With devDependencies absent, npx tsc silently downloads an unrelated registry package named tsc and the typecheck gate becomes a stranger's binary. Hit live during this build — npm audit fix --omit=dev pruned the dev tree and the next npm run build printed "This is not the tsc command you are looking for". Both tools now resolve from node_modules/.bin.

Security

js-yaml 4.2.0 → 4.3.1 — GHSA-52cp-r559-cp3m, high, on a production dependency sitting on the hot path: yamlLoad() parses every task file on every list and detail request. Real-world exploitability is low (the YAML is written by trusted local writers, not attacker-controlled), but the fix was in the declared range and non-breaking. npm audit --omit=dev is now clean and enforced in CI.

The one remaining advisory is a low, dev-only esbuild finding — arbitrary file read via its dev server on Windows. We never run esbuild's dev server, and clearing it needs a breaking major bump. CI audits production dependencies only, for that reason.

Baseline standard

LICENSE (MIT), AGENTS.md, .github/workflows/ci.yml + release.yml (SHA-pinned, matching the fleet), README badges, and a Mermaid architecture diagram.

README rewritten for a public audience. It now leads with what the plugin is — a UI for task-queue-mcp — and that the MCP server is a hard requirement, which a reader landing on this repo cold previously could not tell at all. Adds Requirements, the diagram showing the reads-direct / writes-proxied asymmetry, and Non-goals. The five-agent project-dir table (host topology) is replaced by a description of the mapping mechanism with a generic example; host-specific paths and log locations genericized.

Verification

  • npm ci && npm run build && npm test — 8 tests pass, typecheck clean.
  • New tests cover the park/unpark/amend actions, the explicit-status unpark body, the operator-actor default, and pass-through of the MCP's authorization rejection.

🤖 Generated with Claude Code

developer-agent added 2 commits August 2, 2026 17:16
Requires task-queue-mcp v0.4.0 — park/unpark/amend routes do not exist
on earlier versions.

Park replaces Quarantine
  Quarantining was a one-way trip from the only interface that shows the
  queue: no reader listed `quarantine/`, there was no Restore button
  anywhere in the UI, and the backend restore route was unreachable —
  while the confirm dialog told the operator the task "can be restored".
  Because `parked` is now a status upstream, a parked task stays in the
  list with no reader change; it renders muted and dashed with an Unpark
  button, and the detail view names the status it will return to.

Amend
  Amendments render below the description, highlighted and headed to say
  the description above is unchanged. An amendment nobody reads is no
  better than the note-in-a-file workaround it replaces.

Version drift
  server.ts hardcoded VERSION = '0.2.0' while package.json and
  manifest.json said 0.3.0, so /health and the WebSocket connected event
  under-reported by two releases. Now read from package.json at startup.

WebSocket origin bypass
  The guard read `if (origin && !allowed.includes(origin))`, so a client
  sending no Origin header skipped it entirely. Browsers always send one;
  non-browser clients don't — exactly what the check is for.

previewFile symlink escape
  path.resolve normalises `..` but follows nothing, so a symlink inside
  an allowed prefix pointing anywhere on disk passed. realpath first.

Bare npx in the build script
  With devDependencies absent, `npx tsc` silently downloads an unrelated
  registry package named `tsc` and the typecheck gate becomes a
  stranger's binary. Hit live during this build. Resolves from
  node_modules/.bin now.

js-yaml 4.2.0 -> 4.3.1 (GHSA-52cp-r559-cp3m, high) — a production
dependency on the hot path, parsed on every list and detail request.
`npm audit --omit=dev` is clean and now enforced in CI.

Baseline standard: LICENSE, AGENTS.md, CI + release workflows, badges,
and a README rewritten for a public audience — it now says the plugin is
a UI for task-queue-mcp and that the server is a hard requirement, which
a reader landing cold previously could not tell at all.

agent-id: developer
The new CI failed on its first run: `npm test` runs `node --test`
directly against the .ts test files, which relies on Node's built-in
type stripping (unflagged from 22.18). On Node 20 every test fails with
ERR_UNKNOWN_FILE_EXTENSION.

Latent, not new — the repo had no CI at all, so `npm test` had never run
on anything but a developer's local interpreter. Adding CI is what
surfaced it.

Runtime requirement is unchanged at Node 20+; dist/ is bundled plain JS,
so only the test script cares. Documented the split in README and
AGENTS.md so the two versions don't look like an inconsistency.

agent-id: developer
@TadMSTR
TadMSTR merged commit 25318c1 into main Aug 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant