agentgui 1.0.1065 → 1.0.1066

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.
Files changed (3) hide show
  1. package/.gm/prd.yml +0 -30
  2. package/AGENTS.md +4 -0
  3. package/package.json +1 -1
package/.gm/prd.yml CHANGED
@@ -3076,33 +3076,3 @@
3076
3076
  - gm-plugkit/playwriter browser verb dom=/capture eval context defect - requires an upstream tool fix outside agentgui/design
3077
3077
  status: completed
3078
3078
  witness: 'External tool defect, not resolvable from this repo/session: the gm-plugkit/playwriter browser verb''s dom= and capture prefixes evaluate in a Node vm context with no page/document binding (ReferenceError on every attempt this session), unlike the screenshot= and url=<target> paths which do reach the real page. This is a defect in the upstream gm-plugkit/playwriter tool package itself, outside agentgui and design repo scope. Recorded per the false-completion rule as blockedBy:external rather than marked done - screenshots remain the working witness fallback and were used for all browser verification in this sweep.'
3079
- - id: cwd-validation-realtime-existing-probe-review
3080
- subject: Audit the existing debouncedCwdProbe/onCwdDraft validation - confirm it still races correctly with the new browse/recent/autocomplete affordances (no double state writes, no stale error surviving a valid pick)
3081
- status: pending
3082
- - id: practicality-sweep-composer-ergonomics
3083
- subject: 'Beyond cwd: sweep the chat composer and immediate surrounding controls for other practicality gaps (agent/model switching friction, draft persistence edge cases, file attach friction) via a workflow dispatch'
3084
- status: pending
3085
- - id: practicality-sweep-files-surface
3086
- subject: Sweep the Files tab for practicality gaps beyond the cwd-picker integration (navigation friction, bulk-op discoverability, missing shortcuts)
3087
- status: pending
3088
- - id: practicality-sweep-history-settings
3089
- subject: Sweep History and Settings surfaces for practicality gaps (search ergonomics, settings organization, discoverability of power-user features)
3090
- status: pending
3091
- - id: practicality-sweep-live-dashboard
3092
- subject: Sweep the Live dashboard for remaining practicality gaps beyond the 40th/41st run fixes
3093
- status: pending
3094
- - id: practicality-verify-buildesk-live
3095
- subject: Live-verify all cwd-practicality and general-practicality findings on https://buildesk.acc.l-inc.co.za/gm via browser witness
3096
- status: pending
3097
- - id: practicality-kit-build-vendor
3098
- subject: Build+test the design kit, re-vendor dist into site/app/vendor/anentrypoint-design
3099
- status: pending
3100
- - id: practicality-push-ci-green
3101
- subject: Push kit and agentgui changes, verify CI green on both repos
3102
- status: pending
3103
- - id: practicality-agents-md-record
3104
- subject: Record this run's findings in AGENTS.md following the existing run-log convention
3105
- status: pending
3106
- - id: docstudio-cue-session-group-eyebrow
3107
- subject: Verify ConversationList's session-group headers (Today/Yesterday/etc) use the --tr-label token + --fg-3 tone consistently, matching docstudio's uppercase letter-spaced low-opacity eyebrow label idiom
3108
- status: pending
package/AGENTS.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # AgentGUI — Agent Notes
2
2
 
3
+ ## GUI practicality sweep (2026-07-17) — forty-second run
4
+
5
+ User-driven ask ("setting the cwd is not nearly practical enough... go over every possible aspect of the app's practicality") plus a mid-run docstudio design-cue directive. Started narrow (cwd-setting) and expanded into the widest sweep yet, surfacing a real infrastructure bug and a real kit crash along the way. cwd practicality (`site/app/js/app.js`, `design/src/components/agent-chat.js`, `design/src/components/files-modals.js`): the cwd editor was a bare text input requiring an exact remembered absolute path with no discoverability at all — added an inline browse popover (reusing the existing confined `/api/list`, writing to an independent `state.cwdBrowse` so it never disturbs the Files tab's own state), always-visible allowed-roots chips (prefetched on editor open, not gated behind first clicking "browse"), a small localStorage-backed recent-cwd MRU (`CWD_RECENT_KEY`, capped at 6), relative-subpath resolution against the current cwd (`onCwdSave`/`debouncedCwdProbe` both resolve a bare name like `myproject` against `state.chatCwd`), and fixed a real bug where Escape did nothing to close the cwd editor (the global keydown handler's typing-guard blurred the focused input and returned before ever reaching the Escape ladder — added a targeted exception plus a nested browse-popover-then-editor ladder). History's directory `SessionMeta` fact gained the same one-click "use as chat cwd" action Files already had (kit `SessionMeta` gained a generic `onAction`/`actionLabel`, alongside the existing `onCopy`). **Real infrastructure bug found+fixed** (`lib/http-handler.js`, `site/app/js/backend.js`): the new cwd browse popover inherited an existing, previously-undiscovered production bug — this env's nginx `proxy_pass` URI normalization silently collapses an encoded `%2F` path-segment slash back into a literal `/` before forwarding, so any `/api/list/<abs-path>`-shaped request from a path SEGMENT lost its leading slash and 403'd, which also meant the **pre-existing Files tab's own drill-down navigation had been broken in production this whole time**, not just the new picker. Fixed by switching `/api/list`, `/api/stat`, `/api/file`, `/api/download`, `/api/image` to a `?dir=`/`?path=` query param (immune to that proxy normalization) via a new shared `resolveConfinedPath()` helper, keeping the legacy path-segment form for compatibility. `scripts/validate-mutations.mjs` (29 checks) confirmed the confinement contract is byte-identical before/after. Files/completion sweep (`gui-completion` workflow wf_bcf46a89-739, 29 agents, 28 done/1 lens crashed on a StructuredOutput retry cap, 17 confirmed findings): rename/mkdir 409 collisions now prefill a suggested alternate name (`suggestAlternateName`, "name"→"name (2)"→"name (3)"); bulk-move destination gained a one-click roots picker (kit `PromptDialog` gained an optional `roots`/`onPickRoot` prop); **delete is now soft** — moves into a confined per-root `.agentgui-trash/` instead of unlinking (`moveToTrash`/`restoreFromTrash`, new `POST /api/restore`, 10-minute retention with purge-on-delete + a 200-entry eviction cap) with a real undo toast, not just the pre-existing confirm-before dialog; search-hit event anchors (`focusEventI`/`focusEventTs`) are now carried in the URL hash (`ets=`) so reload/Back reproduces the same scrolled+flashed position a live click gives, previously lost; Settings gained a scroll-position scrollspy (manual scrolling now updates `state.settingsSection`/the URL, previously deep-link-in only); truncation confirm banners now state the actual turn count + cost about to be discarded instead of "the later turns"; the cross-tab "reload it" banner now warns about + confirms discarding an unsent draft; History event list gained persistent next/prev error navigation (`jumpToNextError`), not just jump-to-first; the History session header now shows agent/model (reading `sess.model` directly — a first attempt reading a nonexistent `sess.agent` field silently rendered nothing, caught and corrected); `backend.js` exported `onSessionExpired()` but nothing ever subscribed to it — a mid-session 401 failed every fetch completely silently; now surfaces a persistent "Session expired, reload to sign in again" banner; the offline banner gained a manual "retry now" button; search-term highlighting now extends into expanded event bodies (`Row`'s `detail` field), not just the collapsed title; History search results gained an export button (JSON of title/project/snippet/timestamp/sid); Settings gained a `navigator.storage.estimate()` browser-storage breakdown. **Real kit crash found+fixed mid-implementation**: an initial attempt to add the search-results export button by passing a VElement (or an extra `captionAction` prop) through `ConversationList`'s `caption` prop caused an intermittent webjsx "Cannot read properties of undefined (reading 'key')" page crash — root-caused by tracing `caption`'s only other use site (`aria-label: caption || 'Conversations'`, which needs a plain string) and confirmed via 3 independent before/after browser runs (crash present with the VElement version, absent 3/3 times after reverting). Re-implemented as a fully separate sibling element outside `ConversationList` entirely (`.agentgui-search-rail-wrap`, replicating `.ds-sessions`' own flex-column layout), re-verified crash-free across 3 more independent runs. docstudio design-cue pass (a fresh subagent surveyed `/config/docstudio`'s vanilla-ESM Material/Gemini-styled chat UI against the kit): docstudio turned out architecturally LESS mature than the kit in every systemic dimension (typography scale, color tokens, spacing, motion) — the 6 concrete candidate cues it found were mostly already-implemented (streaming caret, soft-tint error bubbles, dark-aware skeleton shimmer, filled-contrast destructive dialogs, suggestion-chip semantics — inapplicable here since agentgui's chips send-immediately rather than fill-then-edit) except session-group eyebrow labels, which were using the generic `--tr-caps` tracking token instead of the more emphatic `--tr-label` token `.t-label`/`.t-micro` already establish as the canonical section-eyebrow convention — fixed both `.ds-session-group-label` and `.ds-dash-group-label`. Two upstream-diverged rebases handled cleanly mid-session (one single-conflict, one 35-commits-diverged including new upstream a11y/motion/visual-regression work) by rebuilding `dist/` fresh from merged sources per the standing discipline rather than hand-merging generated code — `bun test.js` confirmed 0 regressions both times. Kit pushed `7c27e9c`→`fb11176`→`acd5fd2` (three pushes across the run's phases), agentgui pushed `71d7352`→`56b865f`→`2fecd75`→`a1a394a`, all CI green throughout. **Standing lesson: a kit component prop with an established narrow contract (here, `ConversationList`'s `caption` being read as `aria-label: caption || 'Conversations'` elsewhere in the same function) can silently break when a caller passes a richer value (a VElement) than the prop was ever designed for — the failure surfaces as a webjsx "reading key" crash far from the actual mismatch. When extending what a caller passes through an existing prop, grep every OTHER use site of that prop inside the component first, not just the one you're touching.**
6
+
3
7
  ## GUI logic+predictability sweep (2026-07-12) — forty-first run
4
8
 
5
9
  `gui-logic-predictability` workflow wf_c645ba95-c6a (23 agents, 192 tool calls, 0 errors) — 10 confirmed findings, all implemented, plus one real kit bug found and fixed mid-verification (not from the workflow's own hunt). App (`site/app/js/app.js`): `runningPanel()`'s title read `'running · N'` with no scoping cue even though the panel always lists every in-flight session app-wide, not just ones related to the current chat — retitled `'all running sessions · N'`, and it now appends `'(refreshing…)'` while a backgrounded tab's poll is catching up after refocus (`refreshActive()` sets a `state._activeStale` flag while `document.hidden` skips the network call, cleared on the next real response) instead of silently painting stale data as fresh. `runningRowTitle()` fell straight to `UNTITLED_CONVERSATION` for a brand-new session with no index row yet, while the Live dashboard's `computeLiveSessions()` already had a 3s "indexing…" carve-out for the identical case — the same session read two contradictory identities in the same 0-3s window depending only on which panel you looked at; gave `runningRowTitle` the matching carve-out. Live dashboard cards sorted by `elapsed`/`activity` re-sort on every tick (both are continuously-changing values), which could reorder a card out from under a mid-click pointer (selecting a checkbox, clicking stop) — added a module-level `_livePointerDown` flag (set/cleared on document `pointerdown`/`pointerup`/`pointercancel`) that freezes the sort to the last-computed sid order while a pointer is held anywhere in the dashboard. agy's real `--continue` resume path (wired last run) had no composer disclosure the way claude-code's resume banner does — added a `'continues most recent conversation'` composerContext bit for agy past its first turn. History's `ConversationList` sessions mapper hardcoded `agent: undefined` while the Running-panel/Live-dashboard rows for the identical finished-vs-in-flight session both show an agent/model badge — traced to ccsniff's `Store.sessions()` never folding per-event `model` into the session record even though `flattenEvent` captures it; fixed upstream (see below) and wired `agent: agentById('claude-code').name + ' · ' + s.model` into the mapper (ccsniff only reads Claude Code's own JSONL, so the agent is always constant). Kit (`design/src/components/{chat,content}.js`, `design/chat.css`, `design/src/components/sessions.js`): per-message chat copy action (`ChatMessage`'s generic `actionRow`) had zero visible click feedback for sighted/mouse users — only an `aria-live` `announce()` — unlike the three sibling copy patterns already in the same file (code-block copy, `CodeNode`/`ToolCallNode` copy) which all self-manage a label/icon flip to "copied" for 1.6s; added the matching flip keyed off `a.label === 'copy'`. Follow-up chips (contextual, derived from the last turn) and empty-state seed chips (generic starter ideas) shared identical DOM shape/class with zero visual signal distinguishing them — `.agentchat-followup` gained a dashed border (same pill shape/size, no new color/shape language). `flashComposerNote`'s single shared DOM node silently overwrote an unread note if a second call landed before the first note's 2.6s timeout — now queues notes and drains them in order instead of dropping the first message. `SessionDashboard`'s filter `SearchInput` never forwarded `resultCount` to its `aria-live` region (the Live dashboard's own filtered session count was available but unused) — wired it through. **That last change surfaced a real, previously-latent kit bug independent of this run's own hunt: `SearchInput` (`design/src/components/content.js`) conditionally returned either a bare `<input>` VElement or a wrapping `<span>` VElement depending on whether `resultCount`/a clear button were present that render — since `resultCount` now toggles from `undefined` to a string as the Live filter's value changes, webjsx's `applyDiff` tried to morph one element type into another at the same keyed toolbar slot, producing a corrupted merged DOM node (a real `<select>` picked up `type=search`/`name=q`/`placeholder=...` attributes from the `SearchInput` render, and the actual `<input>` vanished entirely) — live-witnessed on buildesk before the fix (`hasInput:false` on the toolbar). Fixed by always returning the `.ds-search-input-wrap` shape (confirmed `display:contents` in CSS, so it's layout-transparent and safe for every existing call site).** ccsniff (separate repo, `github:AnEntrypoint/ccsniff#main`, cloned fresh to `/config/workspace/ccsniff-work`): `Store.sessions()` (`src/store.js`) folded in the most-recent-by-timestamp `model` per session (events aren't guaranteed in ts order since JSONL is read file-by-file); `index.js`'s assistant-event ingestion never actually populated `model` on pushed content blocks (only `system`/init events carried `e.model`) — real Claude Code JSONL carries the actually-used model at `message.model` on every assistant turn, so that's now inherited onto every block from that message. `node test.js`: ALL TESTS PASS both commits. Pushed `11f6c3b` then (after a remote-advanced rebase) `26bbfcc`/`beff5e7`, ccsniff CI (Publish/Auto-Declaudeify/Deploy GH Pages) green both pushes. Kit built+tested twice (once per round of edits — findings, then the SearchInput fix), re-vendored both times. Reinstalling the ccsniff dependency required removing `bun.lock`'s pinned commit hash entirely (`bun install ccsniff@github:...#main --force` alone kept resolving to the stale pinned sha even after a `rm -rf node_modules/ccsniff`) — deleting `bun.lock` and re-running `bun install` re-resolved `#main` to the actual latest commit. The local buildesk server process needed an explicit restart (`kill -TERM` on the `bun server.js` PID) for the new `node_modules/ccsniff` to load — Node/Bun caches modules in-process, so an npm/git dependency swap under a running process is invisible until restart; the env's custom Node supervisor (`/opt/gmweb-startup`, not a standard supervisord) auto-respawned it within ~20s of the health-check failing, re-launching via `bunx agentgui@latest` which correctly resolves to the local workspace's own `bin/gmgui.cjs` in this workspace-linked setup (confirmed by the "Workspace mode: skipping npm version checker" startup log line), not the published npm package. Browser-witnessed every finding live on buildesk: `.ds-dash-toolbar` filter input/select intact before AND after typing with the corruption fixed, `aria-live` region reading `'0 results'`; `.chat-msg-action.is-copied`/`.agentchat-followup` CSS rules present in the live CSSOM; History rail rows reading `'agentgui · 3s ago · Claude Code · claude-sonnet-5'` (18/18 sessions carrying a real model after the ccsniff fix + server restart); synthetic `pointerdown` dispatch confirmed no page error from the new listener. 0 pageErrors throughout.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.1065",
3
+ "version": "1.0.1066",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",