agentgui 1.0.1047 → 1.0.1049
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gm/prd.yml +5 -0
- package/AGENTS.md +1 -1
- package/package.json +1 -1
- package/AUDIT-PUNCHLIST.md +0 -62
package/.gm/prd.yml
CHANGED
|
@@ -2958,3 +2958,8 @@
|
|
|
2958
2958
|
notes: Both scripts' agent prompts say 'check PUNCHLIST-COMPLETION.md / PUNCHLIST-COHESION.md / AGENTS.md'; edit both prompts this session so they say 'check AGENTS.md' only, before the PUNCHLIST files are deleted, so no workflow prompt references a nonexistent file.
|
|
2959
2959
|
status: completed
|
|
2960
2960
|
witness: grep -rn PUNCHLIST .claude/workflows/*.js returns 0 matches after editing gui-logic-predictability.js (2 edits), gui-completion.js (1 edit), gui-claude-code-parity.js (2 edits), gui-screen-realestate.js (2 edits) to reference AGENTS.md alone.
|
|
2961
|
+
- id: delete-audit-punchlist
|
|
2962
|
+
subject: Delete AUDIT-PUNCHLIST.md - dead stale documentation, findings already resolved+merged
|
|
2963
|
+
notes: 'Confirmed via grep: no workflow script references AUDIT-PUNCHLIST.md (unlike the gui-*.js workflows that referenced PUNCHLIST-*.md). Only narrative past-tense mentions in AGENTS.md/rs-learn. All 44 findings landed in cf710c6/eb1eab3/951404e. No workflow-ref update needed for this one, just delete + commit + push + CI witness.'
|
|
2964
|
+
status: completed
|
|
2965
|
+
witness: git rm AUDIT-PUNCHLIST.md; git status --porcelain confirms D AUDIT-PUNCHLIST.md staged. Re-confirmed 0 workflow-script references.
|
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Punch-list document cleanup (2026-07-12) — 37th-run confirming pass
|
|
4
4
|
|
|
5
|
-
The 10 standing `PUNCHLIST-*.md` files (COHESION/COMPLETION/DENSITY/DESIGN/DESIGN-14/DESIGN-15/LOGIC/PARITY/POLISH/UX, ~440KB) are removed — all their findings landed and merged in earlier commits, and their content duplicated what AGENTS.md already records in denser, current form, violating the project's own Documentation Policy (history belongs in git log/CHANGELOG, never a standing doc). Four `.claude/workflows/*.js` scripts (`gui-logic-predictability.js`, `gui-completion.js`, `gui-claude-code-parity.js`, `gui-screen-realestate.js`) referenced the punch-list filenames by name in agent prompts as the "don't re-report already-fixed findings" grounding source — all four now point at `AGENTS.md` alone. **Standing rule for future sweeps: no new `PUNCHLIST-*.md` (or similarly-named) file should be checked into the repo as a durable artifact — a workflow's punch-list is a transient working document for that run's synthesis step; the run's outcome belongs in AGENTS.md (or drains to rs-learn), never a standing file.**
|
|
5
|
+
The 10 standing `PUNCHLIST-*.md` files (COHESION/COMPLETION/DENSITY/DESIGN/DESIGN-14/DESIGN-15/LOGIC/PARITY/POLISH/UX, ~440KB) plus `AUDIT-PUNCHLIST.md` (found in a follow-up confirming pass) are removed — all their findings landed and merged in earlier commits, and their content duplicated what AGENTS.md already records in denser, current form, violating the project's own Documentation Policy (history belongs in git log/CHANGELOG, never a standing doc). Four `.claude/workflows/*.js` scripts (`gui-logic-predictability.js`, `gui-completion.js`, `gui-claude-code-parity.js`, `gui-screen-realestate.js`) referenced the punch-list filenames by name in agent prompts as the "don't re-report already-fixed findings" grounding source — all four now point at `AGENTS.md` alone. **Standing rule for future sweeps: no new `PUNCHLIST-*.md`/`AUDIT-PUNCHLIST.md` (or similarly-named) file should be checked into the repo as a durable artifact — a workflow's punch-list is a transient working document for that run's synthesis step; the run's outcome belongs in AGENTS.md (or drains to rs-learn), never a standing file.**
|
|
6
6
|
|
|
7
7
|
## GUI logic+predictability sweep (2026-07-12) — thirty-seventh run
|
|
8
8
|
|
package/package.json
CHANGED
package/AUDIT-PUNCHLIST.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
All findings are pre-confirmed (isReal: true). Here is the deduped, prioritized punch-list grouped by fixLocation, ordered by severity then user impact.
|
|
2
|
-
|
|
3
|
-
## SERVER (lib/) — highest impact: security correctness
|
|
4
|
-
|
|
5
|
-
1. **[HIGH · security] /api/image broad arbitrary-file-read** — `lib/http-handler.js:144-162`: drop `os.homedir()` from `allowRoots` (restrict to `CLAUDE_PROJECTS_DIR` + `IMAGE_ROOTS`) and 403 any path whose extension isn't in the image `mimeTypes` map instead of falling back to `application/octet-stream`.
|
|
6
|
-
2. **[HIGH · security] ?token= credential leak, no Referrer-Policy/CSP** — `lib/http-handler.js:56-61`: always `res.setHeader('Referrer-Policy','no-referrer')`, add a CSP restricting img/connect/script-src to self + unpkg/jsdelivr, and migrate token→httpOnly SameSite=Strict cookie so the password leaves the URL/history/logs.
|
|
7
|
-
3. **[MEDIUM · robustness] cwd unvalidated before spawn** — `lib/ws-handlers-util.js:70`: when `p?.cwd` is set, `fs.statSync(cwd).isDirectory()` check and `err(400,'no such directory')` before `runClaudeWithStreaming`; optionally confine to an allowlist root.
|
|
8
|
-
|
|
9
|
-
## APP (site/app/) — chat correctness, then history, then settings
|
|
10
|
-
|
|
11
|
-
4. **[HIGH · chat] Live SSE event read flat but arrives nested** — `app.js:281-293`: unwrap `const ev = data.payload || data;` and use `ev` for `state.events.push` and the tool_use/isError counters (keep `data.sid` for routing). Core live-history regression.
|
|
12
|
-
5. **[MEDIUM · chat] resumeSid persists across agent switch** — `app.js:149-168`: clear `resumeSid`/`resumeNote` in `selectAgent` when `id !== 'claude-code'`, and gate the banner (474), status sub (527), and forwarded arg (662) on `selectedAgent === 'claude-code'` (stale sid wrongly triggers agy `--continue`).
|
|
13
|
-
6. **[MEDIUM · chat] scrollChatToBottom queries dead `.chat-thread`** — `app.js:133-142`: prefer `.agentchat-thread` (the kit's real scroller), keep `.chat-thread`/`#agentgui-main` as fallbacks.
|
|
14
|
-
7. **[MEDIUM · history] Live events not deduped vs snapshot** — `app.js:282-285`: after the unwrap (#4), guard `state.events.push` with `ev.i != null && state.events.some(e => e.i === ev.i)` and count each `ev.i` once via a per-session Set.
|
|
15
|
-
8. **[MEDIUM · settings] Schemeless backend URL validated-but-stored-raw** — `app.js:998-1013`: normalize on save (`new URL(...).origin`), validate/store/use the same canonical string so `localhost:3000` can't resolve against the page origin.
|
|
16
|
-
9. **[MEDIUM · settings] clear-local-data leaves in-memory state that re-persists** — `app.js:1090-1098`: zero `selectedAgent`/`selectedModel`/`chatCwd`/`backend`/`backendDraft`/`agentModels` (don't re-call `B.setBackend('')` which rewrites the key), or `location.reload()` after clearing.
|
|
17
|
-
10. **[LOW · chat] Aborted-empty turn not pruned from in-memory array** — `app.js:599-604`: in `cancelChat`, `state.chat.messages = state.chat.messages.filter(m => !isEmptyTurn(m))` so `messages.length`-derived UI isn't off-by-one (persist only filters its snapshot, never the live array).
|
|
18
|
-
11. **[LOW · history] Search-hit focus scroll races live append** — `app.js:1228-1234`: snapshot the target event's `.i`/`.ts`, re-derive `rowPos` inside the rAF from current `state.events`, bail if it moved.
|
|
19
|
-
12. **[LOW · history] Search results ignore subagent/project filters** — `app.js:904-921`: apply the same `showSubagents`/`projectFilter` gating as `visibleSessions` before slicing (or label the header "incl. hidden").
|
|
20
|
-
13. **[LOW · settings] preferencesPanel cwd "(current: X)" can misrepresent running chats** — `app.js:1108-1109`: relabel as "default for new chats" or derive the displayed cwd from in-flight `chat.active` ctrl.cwd.
|
|
21
|
-
|
|
22
|
-
## APP — consistency / vocabulary (low, batch together)
|
|
23
|
-
|
|
24
|
-
14. **[MEDIUM · consistency] Status bar says 'live' where crumb/health say 'connected'** — `app.js:387`: use `ok ? 'connected' : 'offline'`; reserve 'live' for the history SSE label (335).
|
|
25
|
-
15. **[MEDIUM · consistency] agentsPanel rail inverts purple=subagent contract** — `app.js:1152`: `rail: avail ? 'green' : 'flame'` (selection already shown via `active`); purple must stay subagent-only.
|
|
26
|
-
16. **[LOW · settings] db chip absent on partial /health + 'N active' is dead text** — `app.js:1022-1040`: always render `db unknown` when `hh.db` absent; make the active-executions chip a button routing to history's running panel.
|
|
27
|
-
17. **[LOW · consistency] Resume label noun vs gerund** — `app.js:527`: `'resuming…'` to match banner + sibling gerund statuses.
|
|
28
|
-
18. **[LOW · consistency] Literal '...' in resume banner** — `app.js:479`: drop the trailing `...` (it's a fixed 8-char slice, not a truncation) or use `…`.
|
|
29
|
-
19. **[LOW · consistency] ACP 'running·healthy' tight middot vs spaced separator** — `app.js:1144`: `'running healthy'` so `·` keeps one meaning.
|
|
30
|
-
20. **[LOW · consistency] db 'ok/down' reuses vocabulary the connection chip translated away** — `app.js:1037`: `db online/offline` to match the connection register.
|
|
31
|
-
|
|
32
|
-
## KIT (c:\dev\anentrypoint-design) — requires build + publish to unpkg
|
|
33
|
-
|
|
34
|
-
21. **[HIGH · perf] Streaming re-parses full growing markdown every rAF (O(n²))** — `chat.js:82-90` MdNode: parse markdown once on turn-complete; render the live turn as cheap inline/plain text while streaming (gate on `isStreaming`), promote to `{kind:'md'}` only when settled.
|
|
35
|
-
22. **[HIGH · responsive] Chat control cluster + cwd bar have no media queries** — `chat.css`: add `@media` breakpoints for `.agentchat-controls`/`.agentchat-cwd-text` (the 360/640/900 rules in index.html target dead `.chat-controls`/`.cwd-bar`; also delete that dead CSS in `index.html`).
|
|
36
|
-
23. **[MEDIUM · a11y] EventList Row toggle never emits aria-expanded** — `content.js:23,39-50`: add an `expanded` prop → `aria-expanded` on the button branch; app passes the boolean at `app.js:796-806`.
|
|
37
|
-
24. **[MEDIUM · responsive] cwd `max-width:60ch` overflows phones** — `chat.css:59-64`: `max-width: min(60ch, 60vw)` (+ optional 640px 42vw clamp).
|
|
38
|
-
25. **[MEDIUM · responsive] Hamburger 36px + drawer rows ~40px + send button under 44px** — `247420.css` source: raise `.app-side-toggle` and `.app-side a` and the small/landscape composer `send` to min 44×44 (WCAG 2.5.5).
|
|
39
|
-
26. **[MEDIUM · security] marked/dompurify imported from unpinned CDN** — `markdown.js:9-26`: vendor marked+dompurify locally (dynamic import can't carry SRI) and ship a `script-src 'self'` CSP; success/fallback sanitization paths are already safe.
|
|
40
|
-
27. **[LOW · perf] CodeNode highlight cache key uses code LENGTH not content** — `chat.js:95-97`: key on full `p.code` (or export+use `simpleHash`) so same-length blocks re-highlight.
|
|
41
|
-
28. **[LOW · a11y] `.agentchat-cwd-btn` has no :focus-visible** — `chat.css`: add `:focus-visible` ring mirroring `.agentchat-empty-suggestion`.
|
|
42
|
-
29. **[LOW · a11y] Native select pickers have title-only accessible name** — `agent-chat.js:36-48`: pass `label:` (visible or sr-only) to the agent/model `Select`.
|
|
43
|
-
30. **[LOW · consistency] Head sub-line re-derives 'streaming…' ignoring status prop** — `agent-chat.js:175`: derive from the same `status` prop (`busy ? (status||'streaming…') : …`) so reconnecting-while-streaming reads one word.
|
|
44
|
-
31. **[LOW · glyph] Box-drawing dividers in OS-kit comments** — `src/kits/os/app-panes.css:4,51,114`: replace `──` with `---` (comment-only; not the shipped AgentChat surface).
|
|
45
|
-
|
|
46
|
-
## BOTH (coordinated app + kit + publish)
|
|
47
|
-
|
|
48
|
-
32. **[HIGH · chat] Text and tool parts don't interleave — all prose renders before every tool card** — `app.js:673-675` + `agent-chat.js:114-124`: model the assistant turn as one ordered `parts[]` (append/extend `{kind:'md'}` segments and tool parts in arrival order; tool boundary closes the md segment); drop the forced `m.content` prepend in the kit and render `parts` strictly in order. This is the core chat-jank fix and supersedes the standalone perf concern in #21 about ordering.
|
|
49
|
-
33. **[MEDIUM · chat] Orphan tool_result renders as detached bottom card** — `app.js:446-457`: ids already match on both runner paths, so harden the client fallback — attach an unmatched result to the most recent running tool part (or insert after the last tool part) rather than pushing to array end. Compounds #32.
|
|
50
|
-
34. **[MEDIUM · history] Same event kinds render differently in chat vs history** — `app.js:773-808` + kit ToolCallNode: generalize the kit's ToolCallNode so EventList rows accept structured `{kind:'tool',...}` parts, then route history tool_use/tool_result through the same `toolPart`/`applyToolResult` pairing chat uses (preserve green/purple/flame rails).
|
|
51
|
-
|
|
52
|
-
## PERF — confirmed no-fix (mitigating context)
|
|
53
|
-
|
|
54
|
-
- `app.js:264,1306` relTime/resize full re-render: acceptable (rAF-coalesced); resolves once #36 row-build is lazy.
|
|
55
|
-
- `app.js` webjsx keying: stable, no collision — this is why the perf findings stay at vnode-build cost, not DOM teardown.
|
|
56
|
-
|
|
57
|
-
## APP — remaining perf (high/medium)
|
|
58
|
-
|
|
59
|
-
35. **[HIGH · perf] Full app tree re-renders per rAF during stream** — `app.js:78-86`: scope the streaming re-render to the active transcript/bubble rather than rebuilding Topbar/Crumb/Status/panels every token (pairs with kit #21).
|
|
60
|
-
36. **[HIGH · perf] EventList computes `full`+JSON.stringify for all ~300 rows every frame** — `app.js:790`: build `full` (and `JSON.stringify(e.toolInput,...)`) only when the row is `expanded`.
|
|
61
|
-
37. **[MEDIUM · perf] O(sessions) linear scan per live event** — `app.js:287-299`: build `state.sessionsBySid = new Map(...)` on each refresh, `.get(data.sid)` instead of `arr.find`.
|
|
62
|
-
38. **[MEDIUM · perf] scrollChatToBottom nests a 2nd rAF + re-querySelector per frame** — `app.js:133-142`: cache the scroller (re-query only if detached), drop the inner rAF (caller already in a frame). Folds into #6.
|