The first write path. Read, forecast, and calibration were all real — now you can manage CommiTea from CommiTea. Estimates/priority are exclusive label axes, so a change is a label swap: proposed, approved, then written. Nothing assumed. (Branch cut from main, targets main — no stacking, per the lesson from the #38/#39 gap.)
Core (@commitea/core)
planIssueChange(current, change) — pure diff planner: swaps the est/*|p/* axis, clears on null, dedups a doubled axis; returns the resulting label set + before/after diff + noop. describeChange() → est/2d → est/5d.
request() seam extended for writes (method/body, JSON, 204). Client gains listLabels() (name→id) and setIssueLabels() (PUT /issues/{n}/labels).
App
main bridge gitea:applyChange — resolves plan.labels → ids (cached, refetch on miss), PUTs, returns the plan + fresh issue. Token never leaves main.
preload + global.d.ts expose applyChange; useBacklog returns a refetch so a write re-reconciles the board + forecast.
Issue screen — an Adjust button (only when configured) opens a propose-approve Dialog: estimate/priority pickers, live est/3d → est/8d consequence, Apply/Cancel. AppShell wires it, reflects the new labels on the open issue immediately, and refetches.
The live spec exercises propose + Cancel (so CI never mutates the real repo); the actual PUT was verified once manually — changed #2est/3d → est/8d (200 OK), confirmed, then reverted clean. Screenshot: the dialog on real issue #2.
Not in this slice (later)
The write path currently surfaces as a direct control; routing it through Reginald's chat (apply_changes as an LLM tool call, with the same engine) is the agent-integration slice.
capture_work (create issue) and record_directive (append to the pm-state ledger) are the other two write tools.
The **first write path**. Read, forecast, and calibration were all real — now you can *manage* CommiTea from CommiTea. Estimates/priority are exclusive label axes, so a change is a label swap: **proposed, approved, then written. Nothing assumed.** (Branch cut from `main`, targets `main` — no stacking, per the lesson from the #38/#39 gap.)
## Core (`@commitea/core`)
- **`planIssueChange(current, change)`** — pure diff planner: swaps the `est/*`|`p/*` axis, clears on null, dedups a doubled axis; returns the resulting label set + before/after diff + `noop`. `describeChange()` → `est/2d → est/5d`.
- `request()` seam extended for writes (method/body, JSON, 204). Client gains `listLabels()` (name→id) and `setIssueLabels()` (`PUT /issues/{n}/labels`).
## App
- **main bridge `gitea:applyChange`** — resolves `plan.labels` → ids (cached, refetch on miss), PUTs, returns the plan + fresh issue. **Token never leaves main.**
- preload + `global.d.ts` expose `applyChange`; `useBacklog` returns a `refetch` so a write re-reconciles the board + forecast.
- **Issue screen** — an *Adjust* button (only when configured) opens a propose-approve **Dialog**: estimate/priority pickers, live `est/3d → est/8d` consequence, Apply/Cancel. AppShell wires it, reflects the new labels on the open issue immediately, and refetches.
## Verified
83 core tests green (7 `apply-changes` + 2 client-write new) · desktop typecheck clean · 14 fixture e2e green.
The live spec exercises **propose + Cancel** (so CI never mutates the real repo); the actual PUT was verified once manually — changed #2 `est/3d → est/8d` (200 OK), confirmed, then reverted clean. Screenshot: the dialog on real issue #2.
## Not in this slice (later)
- The write path currently surfaces as a **direct control**; routing it through Reginald's chat (`apply_changes` as an LLM tool call, with the same engine) is the agent-integration slice.
- `capture_work` (create issue) and `record_directive` (append to the pm-state ledger) are the other two write tools.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
christian
added 1 commit 2026-07-09 00:15:06 +00:00
The first write path. Read, forecast, and calibration were all real; now you can
*manage* CommiTea from CommiTea. Estimates/priority are exclusive label axes, so
a change is a label swap — proposed, approved, then written. Nothing is assumed.
core (@commitea/core):
- planIssueChange(current, change): pure diff planner — swaps the est/*|p/* axis,
clears on null, dedups a doubled axis; returns the resulting label set + a
before/after diff + noop flag. describeChange() renders "est/2d → est/5d".
- request() seam extended for writes (method/body, JSON, 204). client gains
listLabels() (name→id) and setIssueLabels() (PUT /issues/{n}/labels).
app:
- main bridge gitea:applyChange — resolves plan.labels → ids (cached, refetch on
miss), PUTs, returns the plan + fresh issue. Token never leaves main.
- preload + global.d.ts expose applyChange; useBacklog returns a refetch so a
write re-reconciles the board + forecast.
- Issue screen: an Adjust button (shown only when configured) opens a
propose-approve Dialog — estimate/priority pickers, live "est/3d → est/8d"
consequence, Apply/Cancel. AppShell wires it, reflects new labels on the open
issue immediately, and refetches.
Verified: 83 core tests green (7 apply-changes + 2 client-write new), desktop
typecheck clean, 14 fixture e2e green. Live spec exercises propose + CANCEL (no
mutation); the real PUT was verified once manually (change #2 est/3d→est/8d→200,
reverted clean). Icon: pencil (no sliders-horizontal in the set).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The first write path. Read, forecast, and calibration were all real — now you can manage CommiTea from CommiTea. Estimates/priority are exclusive label axes, so a change is a label swap: proposed, approved, then written. Nothing assumed. (Branch cut from
main, targetsmain— no stacking, per the lesson from the #38/#39 gap.)Core (
@commitea/core)planIssueChange(current, change)— pure diff planner: swaps theest/*|p/*axis, clears on null, dedups a doubled axis; returns the resulting label set + before/after diff +noop.describeChange()→est/2d → est/5d.request()seam extended for writes (method/body, JSON, 204). Client gainslistLabels()(name→id) andsetIssueLabels()(PUT /issues/{n}/labels).App
gitea:applyChange— resolvesplan.labels→ ids (cached, refetch on miss), PUTs, returns the plan + fresh issue. Token never leaves main.global.d.tsexposeapplyChange;useBacklogreturns arefetchso a write re-reconciles the board + forecast.est/3d → est/8dconsequence, Apply/Cancel. AppShell wires it, reflects the new labels on the open issue immediately, and refetches.Verified
83 core tests green (7
apply-changes+ 2 client-write new) · desktop typecheck clean · 14 fixture e2e green.The live spec exercises propose + Cancel (so CI never mutates the real repo); the actual PUT was verified once manually — changed #2
est/3d → est/8d(200 OK), confirmed, then reverted clean. Screenshot: the dialog on real issue #2.Not in this slice (later)
apply_changesas an LLM tool call, with the same engine) is the agent-integration slice.capture_work(create issue) andrecord_directive(append to the pm-state ledger) are the other two write tools.🤖 Generated with Claude Code
The first write path. Read, forecast, and calibration were all real; now you can *manage* CommiTea from CommiTea. Estimates/priority are exclusive label axes, so a change is a label swap — proposed, approved, then written. Nothing is assumed. core (@commitea/core): - planIssueChange(current, change): pure diff planner — swaps the est/*|p/* axis, clears on null, dedups a doubled axis; returns the resulting label set + a before/after diff + noop flag. describeChange() renders "est/2d → est/5d". - request() seam extended for writes (method/body, JSON, 204). client gains listLabels() (name→id) and setIssueLabels() (PUT /issues/{n}/labels). app: - main bridge gitea:applyChange — resolves plan.labels → ids (cached, refetch on miss), PUTs, returns the plan + fresh issue. Token never leaves main. - preload + global.d.ts expose applyChange; useBacklog returns a refetch so a write re-reconciles the board + forecast. - Issue screen: an Adjust button (shown only when configured) opens a propose-approve Dialog — estimate/priority pickers, live "est/3d → est/8d" consequence, Apply/Cancel. AppShell wires it, reflects new labels on the open issue immediately, and refetches. Verified: 83 core tests green (7 apply-changes + 2 client-write new), desktop typecheck clean, 14 fixture e2e green. Live spec exercises propose + CANCEL (no mutation); the real PUT was verified once manually (change #2 est/3d→est/8d→200, reverted clean). Icon: pencil (no sliders-horizontal in the set). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>