Repository navigation
refactor: rename stax plans to stax work-items - #40
Merged
Merged
Conversation
Rename the artifact noun and CLI surface concept-wide: the `.stax/*.md`
files the binary tracks are now called "work items" everywhere. Hard cut;
no `stax plans` alias.
- CLI: `stax plans <verb>` → `stax work-items <verb>`; usage table,
error messages ("unknown work-items subcommand"), and `-h` output
all updated.
- Go: scope.go → work_items.go (the file was a misnomer — it held the
work-item tooling, not anything scope-related). Symbol renames:
runPlans, printPlansUsage, planList, lintPlanFile, planRow,
planDetail, plansListOverflowThreshold, defaultMaxPlanLines,
reviewPerPlan, planFileExt, parsePlan, listPlans, writePlansScaffold,
promptMaxPlanLines, et al. → workItem/workItems/WorkItem variants.
- On-disk schema: `_config.lock` `max_plan_lines` → `max_work_item_lines`;
`review_per` value "plan" → "work-item". Existing files with the old
key/value silently fall back to defaults (hard cut, no migration).
- HTTP API: `/api/systems?id=` response field `plans` → `workItems`;
Go struct `planDetail` → `workItemDetail`. Frontend updated to
consume the new key. `/api/scopes` keeps its existing naming.
- Frontend: type `Plan` → `WorkItem`; DOM ids `#system-plans`/`tpl-plan`
→ `#system-work-items`/`tpl-work-item`; user-visible strings
("Loading plans…", "No plans for this system yet.") updated.
- Bundled skills: scope/SKILL.md + ship/SKILL.md rewritten to use
"work item" for the artifact; hook commands (`stax plans lint` →
`stax work-items lint`) in agents/claude/settings.json and
agents/codex/hooks.json. The proposal-pattern wording ("plan-first
protocol", "sub-plan", "## Plan" approval-prompt heading, "Build
the plan", "Present the plan") is preserved as English usage,
distinct from the renamed artifact.
- Docs: AGENTS.md, CLAUDE.md, README.md, docs/public/reference.md,
docs/internal/*.md — artifact noun renamed; reference.md gains a
new `.stax/_config.lock` schema subsection covering all three keys
+ the post-rename migration note.
- Scripts: scripts/e2e_test.sh + scripts/e2e_test.ps1 — every `plans`
invocation routed through `work-items`; shell constant
`PLANS_LIST_OVERFLOW_THRESHOLD` → `WORK_ITEMS_LIST_OVERFLOW_THRESHOLD`
with matching update in constants_e2e_test.go's drift check; PS1
helpers `Add-ManyPlans`/`Write-PlanWithBody` → `Add-ManyWorkItems`/
`Write-WorkItemWithBody`; fixture slug stems `-plan{NNN}` →
`-work-item{NNN}` with all assertions following.
- Skills-evals: `test_*_plan_extends.py` → `test_*_work_item_extends.py`;
`plan_judge.py` → `work_item_judge.py`; fixture loaders/judgments
updated to match.
- Sample data: `.stax.example/_config.lock` schema key updated. Sample
work-item bodies that use "plan" in a billing/subscription sense
(e.g. "subscription plan changes") left untouched — domain English,
not the renamed artifact.
Verified locally: go vet + go test clean, npm run check + frontend
build clean, scripts/e2e_test.sh 624/624 cases pass.
Signed-off-by: Tanzim Saqib <[email protected]>
The committed lock file was missing node_modules/@emnapi/core and node_modules/@emnapi/runtime — peer deps that oxc-parser bindings pull in on Linux x64. Locally npm install on macOS ARM64 doesn't notice because the local platform binding doesn't need them, but GitHub Actions runs npm ci on linux/amd64 and rejects the lock as out-of-sync. Regenerated the lock file with `npm install --include=optional` from a clean state so all platform-specific bindings + their transitive peer deps are recorded. No package.json changes. Signed-off-by: Tanzim Saqib <[email protected]>
6 of 7 tasks
tsaqib
added a commit
that referenced
this pull request
May 29, 2026
Aligns the web UI with the renamed artifact noun (PR #40 moved the CLI from `stax plans` to `stax work-items`). The user-visible URLs, nav rail labels, page identifiers, and the HTTP API the page TS consumes all migrate together so the naming axis is one consistent "work item" everywhere. Frontend: - Page files: scopes.html → work-items.html, scope.html → work-item.html; scopes.ts → work-items.ts, scope.ts → work-item.ts. Layout block-helper args (title/page/active) updated to match. - Nav rail (header.html + mobile-nav.html): "Scopes" → "Work items"; href /scopes → /work-items; data-active-key follows. Flag icon kept. - Detail page back-link, list-page empty-state, home-page card + Latest section, /search results section, and all DOM ids that embedded "scope" (`#scope-icon`, `#scope-title`, `#scope-body`, `#scopes-list`, `#latest-scopes`, `tpl-scope`, `tpl-scope-link`) renamed to the work-item equivalents. - Page dispatcher in bundle.ts uses bracketed keys for the kebab-cased page names; vite.config.ts pages array follows. - Internal hrefs `/scope?id=…` → `/work-item?id=…` across home.ts, search.ts, system.ts. - CSS: `.scope-body` → `.work-item-body`. HTTP API + Go server: - /api/scopes → /api/work-items, /api/scope → /api/work-item; apiScopesPath/apiScopePath constants renamed. - Handler renames: handleAPIScopes → handleAPIWorkItems, handleAPIScope → handleAPIWorkItem; readScopesForAPI → readWorkItemsForAPI. - Struct renames (with collision resolution): scopeListItem → workItemListItem, scopesListResponse → workItemsListResponse, scopeRelation → workItemRelation, scopeDetail → workItemDetail. The previous `workItemDetail` (per-system-row inner type used by /api/systems?id=) renames to `systemWorkItem` to free the better name for the detail response. - JSON wire keys: `"scopes"` → `"workItems"` on statsResponse, workItemsListResponse, searchResponse, and systemEntry. Frontend TS types follow. Tests / docs: - server_test.go: clean-URL fallback expects /work-items and /work-item; every fixture/assertion updated to body.WorkItems and `"workItems":` wire shape. - scripts/e2e_test.sh + e2e_test.ps1: curl + assert_contains paths and JSON-key substring assertions updated. - AGENTS.md: frontend hard rules now reference /work-item URL, #work-item-body, active="work-items", and {workItems: [...]}. - frontend/package-lock.json: regenerated with `npm install --include=optional` (same pre-existing @emnapi gap PR #40 hit). Verified locally: go vet + go test clean, npm run check clean, scripts/e2e_test.sh 624/624 cases pass. Signed-off-by: Tanzim Saqib <[email protected]>
1 of 5 tasks
tsaqib
added a commit
that referenced
this pull request
May 29, 2026
* refactor(frontend): rename /scopes route to /work-items Aligns the web UI with the renamed artifact noun (PR #40 moved the CLI from `stax plans` to `stax work-items`). The user-visible URLs, nav rail labels, page identifiers, and the HTTP API the page TS consumes all migrate together so the naming axis is one consistent "work item" everywhere. Frontend: - Page files: scopes.html → work-items.html, scope.html → work-item.html; scopes.ts → work-items.ts, scope.ts → work-item.ts. Layout block-helper args (title/page/active) updated to match. - Nav rail (header.html + mobile-nav.html): "Scopes" → "Work items"; href /scopes → /work-items; data-active-key follows. Flag icon kept. - Detail page back-link, list-page empty-state, home-page card + Latest section, /search results section, and all DOM ids that embedded "scope" (`#scope-icon`, `#scope-title`, `#scope-body`, `#scopes-list`, `#latest-scopes`, `tpl-scope`, `tpl-scope-link`) renamed to the work-item equivalents. - Page dispatcher in bundle.ts uses bracketed keys for the kebab-cased page names; vite.config.ts pages array follows. - Internal hrefs `/scope?id=…` → `/work-item?id=…` across home.ts, search.ts, system.ts. - CSS: `.scope-body` → `.work-item-body`. HTTP API + Go server: - /api/scopes → /api/work-items, /api/scope → /api/work-item; apiScopesPath/apiScopePath constants renamed. - Handler renames: handleAPIScopes → handleAPIWorkItems, handleAPIScope → handleAPIWorkItem; readScopesForAPI → readWorkItemsForAPI. - Struct renames (with collision resolution): scopeListItem → workItemListItem, scopesListResponse → workItemsListResponse, scopeRelation → workItemRelation, scopeDetail → workItemDetail. The previous `workItemDetail` (per-system-row inner type used by /api/systems?id=) renames to `systemWorkItem` to free the better name for the detail response. - JSON wire keys: `"scopes"` → `"workItems"` on statsResponse, workItemsListResponse, searchResponse, and systemEntry. Frontend TS types follow. Tests / docs: - server_test.go: clean-URL fallback expects /work-items and /work-item; every fixture/assertion updated to body.WorkItems and `"workItems":` wire shape. - scripts/e2e_test.sh + e2e_test.ps1: curl + assert_contains paths and JSON-key substring assertions updated. - AGENTS.md: frontend hard rules now reference /work-item URL, #work-item-body, active="work-items", and {workItems: [...]}. - frontend/package-lock.json: regenerated with `npm install --include=optional` (same pre-existing @emnapi gap PR #40 hit). Verified locally: go vet + go test clean, npm run check clean, scripts/e2e_test.sh 624/624 cases pass. Signed-off-by: Tanzim Saqib <[email protected]> * chore(ci): rename test workflows to E2E test naming User-driven rename of the test workflow names — the two top-level workflows (Linux and Windows) now share an E2E test prefix for visual grouping in the GitHub Actions sidebar. Signed-off-by: Tanzim Saqib <[email protected]> --------- Signed-off-by: Tanzim Saqib <[email protected]>
tsaqib
added a commit
that referenced
this pull request
May 29, 2026
Commit 8ed25f9 (#40) renamed the artifact concept project-wide but the text-substitution pass missed three classes of identifiers in `skills-evals/`, all of which break the pytest run end-to-end: 1. A list-comprehension f-string `[p.slug for p in plans]` got rewritten to `[p.slug for p in work items]` — two tokens with a space, so Python aborts at parse time. Twelve test files all share this identical pattern (every backend's `*_reminders_supersedes_todo.py` and `*_work_item_extends.py`), so every workflow that runs pytest hits the same collection-time SyntaxError on the first import. 2. `skills-evals/src/skills_evals/workspace.py` still exports `load_all_plans` / `ParsedPlan` / `collect_plan_files` / `_parse_plan`. Every test file already imports `load_all_work_items` from that module, so once the SyntaxError is fixed the next collection error is an `ImportError` of the same shape — i.e. all twelve workflows would still fail. 3. `skills-eval-cline.yml`, `skills-eval-cline-user-scope.yml`, `skills-eval-copilot.yml`, and `skills-eval-copilot-user-scope.yml` still pass `tests/test_<agent>_plan_extends.py` to pytest, but the rename moved that file to `tests/test_<agent>_work_item_extends.py`. With pytest's default selector (`--strict-config`) a missing path is a hard failure, so all four cline/copilot workflows fail before collection even starts. Single bundled fix because the three layers are coupled — fixing any one alone still leaves CI red. Verified locally that `uv run pytest --collect-only` collects 25 tests with zero errors (20 deselected by the existing agent filter, 5 collected for `STAX_AGENT_KEY=claude`). The judges' user-facing label (`name="PlanQuality"` in `work_item_judge.py`) is intentionally left alone — it appears in DeepEval output, not the wire, and renaming it would also drift the historical score series. Signed-off-by: Tanzim Saqib <[email protected]>
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.
Summary
Renames the artifact noun and CLI surface concept-wide. The
.stax/*.mdfiles the binary tracks are now called work items everywhere — CLI verb, Go identifiers, on-disk schema, HTTP API, frontend, bundled skills, docs, e2e harness, and skills-evals. Hard cut;stax plansis removed (no alias).The
/scopeand/shipskill names, the/api/scopesHTTP route, and the web UI's "scope" terminology are intentionally unchanged — those are a separate naming axis from the artifact noun.What changed
stax plans <verb>→stax work-items <verb>. Help table, usage panel, and unknown-subcommand error all updated.scope.go→work_items.go,scope_test.go→work_items_test.go(the old names were misnomers — both files held the work-item tooling, not anything scope-related).runPlans,printPlansUsage,planList,lintPlanFile,parsePlan,listPlans,planRow,planDetail,plansListOverflowThreshold,defaultMaxPlanLines,reviewPerPlan,planFileExt,writePlansScaffold,promptMaxPlanLines, et al. →workItem/workItems/WorkItemvariants._config.lockmax_plan_lines→max_work_item_lines;review_pervalue"plan"→"work-item". Existing files with the old key/value silently fall back to defaults (hard cut, no migration)./api/systems?id=response fieldplans→workItems; Go structplanDetail→workItemDetail. Frontend updated to consume the new key./api/scopeskeeps its existing naming.Plan→WorkItem; DOM ids#system-plans/tpl-plan→#system-work-items/tpl-work-item; user-visible strings ("Loading plans…", "No plans for this system yet.") updated.agents/skills/scope/SKILL.mdandship/SKILL.mdrewritten — artifact noun renamed throughout; hook commandsstax plans lint→stax work-items lintinagents/claude/settings.jsonandagents/codex/hooks.json. The proposal-pattern wording (plan-first protocol,sub-plan,## Planapproval-prompt heading,Build the plan,Present the plan) is preserved as English usage — distinct from the renamed artifact..stax/_config.lockschema subsection covering all three keys + the post-rename migration note.scripts/e2e_test.shandscripts/e2e_test.ps1— everyplansinvocation routed throughwork-items; shell constantPLANS_LIST_OVERFLOW_THRESHOLD→WORK_ITEMS_LIST_OVERFLOW_THRESHOLDwith matching update inconstants_e2e_test.go's drift check; PS1 helpersAdd-ManyPlans/Write-PlanWithBody→Add-ManyWorkItems/Write-WorkItemWithBody; fixture slug stems-plan{NNN}→-work-item{NNN}with all assertions following.test_*_plan_extends.py→test_*_work_item_extends.py;plan_judge.py→work_item_judge.py; fixture loaders and judgments updated..stax.example/_config.lockschema key updated. Sample work-item bodies that use "plan" in a billing/subscription sense (e.g. "subscription plan changes") left untouched — domain English, not the renamed artifact.Test plan
go vet ./...cleango test ./...cleannpm run check(typecheck + Biome + Knip) cleannpm run build(Vite production build) cleanscripts/e2e_test.sh624/624 cases pass locallystax init→/scopeauthor a work item →stax work-items lint→/shipexecute → confirm hook firesstax work-items lint