Open the Run Inspector from a button inside the Amicode chat - #22
Closed
kateebonner wants to merge 107 commits into
Closed
Open the Run Inspector from a button inside the Amicode chat#22kateebonner wants to merge 107 commits into
kateebonner wants to merge 107 commits into
Conversation
…ion-lookup.ts — shared by the About-You card and the onboarding wizard; card keeps debounce/sequencing/race guards Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… about-you with live institution/logo lookup → profile preview + open chat); saves through POST /amicode/profile so the home page autofills affiliation + logo; shows exactly once (fresh profile, dismiss remembered) + tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… the starter chips (Open chat owns 'start something'); PDFs upload via POST /amicode/library into ~/.amico/library (sanitized basename, %PDF- magic check, 30MB cap), GET lists newest-first; 'Discuss latest →' hands the agent the paper path + tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…jects On a fresh browser profile against a bare `opencode serve`, the home page's primary CTA (Meet-Amico card / "Open chat") did nothing: the persisted client-side project list is empty, so startWithPrompt fell through to openNewSession(), which needs the same newSessionProject() that just came back empty and silently returns. Fall back to the focused server's own working directory, synced from GET /path (.directory; "" until loaded, so the guard holds). Open and touch it as a project — self-healing: the home page tracks it from then on — and start the draft with the prompt preserved. Deliberately not sync.data.project: the server's "global" record has worktree "/". Regression spec drives the real UI against a mocked server with no localStorage seed; verified failing on the unfixed code and passing with the fix. tsgo -b clean; bun test:unit 376 pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
amicode(home): fix silent dead-end on 'Open chat' with no tracked projects
Prepend 'Aero' to the AMICODE wordmark/logo font-family chain (logo.tsx, wordmark-v2.tsx), matching each file's current fallback stack. Additive only. Re-applied fresh after the branch fast-forwarded 57 commits to current origin/local/amicode — this had been uncommitted WIP on the old base. Aero is donationware (Nirmal Biswas / Picatype, $25+) — bundled preview- only, must be licensed or replaced before any release. See AMICODE- PATCHES.md #15.
The chat composer's handlePaste bailed out silently whenever event.clipboardData was empty — which it always is inside the sandboxed cross-origin webview iframe (navigator.clipboard is denied there too). Cmd/Ctrl+V into the composer was a no-op. The extension side of this bridge already ships on main (chat_panel.ts answers clipboard-request), and home-cards.tsx already proved the pattern for a different input. This wires the same bridge into the main composer: platform.readClipboardText (new, mirrors readClipboardImage) -> entry.tsx implements it via the postMessage bridge when framed -> attachments.ts falls back to it when clipboardData yields no text. See AMICODE-PATCHES.md #16 for the full trace + build/verify evidence.
Live test (Aaron) found the prior commit's fix was composer-only: pasting into a generic "Connect <provider>" API-key dialog (dialog-connect- provider.tsx - one of many such plain-input settings forms) was still a silent no-op, since that input has no knowledge of the bridge. Same root cause, generalized properly: one document-level paste listener (installGlobalPasteFallback, entry.tsx) covers every form field and contenteditable in the app, activating only when the native paste event gave no text (the sandboxed-iframe symptom) - a no-op everywhere clipboardData already works. The composer's own handler stopPropagation()s on every paste it handles, so it never double-fires there. See AMICODE-PATCHES.md #16 addendum for the full trace + build evidence.
…' (upload PDFs between about-you and the finish; ✓-list of uploads, continue-without-papers path; step skipped when upload isn't wired); home Library card stays; shared fileToBase64 util Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mo udd hit exactly this) + trunk Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… demoted to the quiet secondary — the autofilled home is the payoff shot Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
amicode: first-run onboarding wizard — welcome UI that autofills home-page affiliation + logo
…99 The fork rendered the old "digi" pixel-H mark in four independent copies while amicode redesigned its mark (PR #99). This unifies them to a single MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox 0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier draft of this branch had copied, which #99 itself later abandoned. - logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square. MarkDetailed = amico.svg's full mark (bracket + internal accents), viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only. - spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now import MARK_PATH instead of carrying their own copies — run-card was a fourth private copy of the old glyph; its transform is recalibrated (scale 0.55 → 0.011) for the 3600-unit space. - favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600, path kept byte-identical to MARK_PATH. - logo.css: aspect-ratio 8/7 → 1/1 (mark is square now). - Small contexts use the reduced mark, the Meet Amico card uses the detailed one — matching amicode's own small/large split. Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict resolved, entry 15 rewritten for the final geometry). Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass; app vite build clean — new mark path in the bundle, old geometry and the 64x56 viewBox gone (0 chunks), favicon carries the new path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reduced bracket is right for small chrome (titlebar, footer, tiny fallbacks), but the large brand-hero contexts should show the full mark. Switch to MarkDetailed at: - the new-session / main chat landing hero (both the v2 design view, 144px, and the classic view, 112px) - the onboarding wizard welcome step (56px) The wizard's tiny 36px affiliation-logo fallback stays on the reduced Mark (below where the internal accents resolve). Checks: typecheck (ui+app) green; ui bun test src 99 pass; app build clean with the detailed-mark accents present in the bundle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consolidate brand mark to one geometry; fix drift from amicode's redesign
Adds an "Inspect Run" button on the amicode problem-header rail, beside
the live run chip, that opens the VS Code Run Inspector on demand instead
of relying on auto-launch. It fires the existing host bridge —
postAmicode("amicode.openInspector") — which chat_panel.ts relays to the
already-allowlisted vscode command; no new bridge, allowlist, or route.
- entity-rail.tsx: new optional onInspectRun prop + button, gated on a run
existing (hasRun) so it shows alongside the run chip, not before any
solve. packages/ui stays bridge-agnostic (fires a callback only).
- message-timeline.tsx: wires onInspectRun to the bridge, passed only when
framed in Amicode (inAmicode()), so the public web/share build shows
nothing.
- use-amicode-commands.tsx: export postAmicode + inAmicode for reuse.
Pairs with harmoniqs/amicode#116 (stops the inspector auto-launching);
reaches amicode users after this is re-vendored into the extension binary.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The message timeline had three independent systems writing scrollTop to the bottom on the same content update, reading scroll geometry at slightly different instants from a virtualizer whose item heights are estimates. When virtua corrected a measured height a frame later, the writers had already landed on slightly different positions -> visible bounce. - session.tsx: gate createAutoScroll on the session's real working state instead of a hard-coded `true`. The auto-scroller's ResizeObserver was force-following the bottom on *any* reflow (image load, accordion expand, font swap), which read as the chat jumping on its own. Send-to-bottom and the jump button are unaffected (they use the force path). - message-timeline.tsx: only realign via virtua's estimate-based scrollToIndex(align:"end") when the row set changes or status flips, not on every streamed token. Pure intra-row growth is left to the measured-bottom rAF lock, which pins against the real DOM height, so the two mechanisms stop disagreeing frame-to-frame. Safe because timelineRowKeys is memoized with `equals: sameKeys`. - message-part.tsx: honor prefers-reduced-motion in the imperative ShellSubmessage reveal (the CSS already does; this JS animate() did not, and its initial render collapses width to 0 / blurs the value). Verified: app + ui typecheck clean; message-part, scroll-view, layout-scroll, file-tab-scroll, use-session-hash-scroll unit tests pass (16/16). Perceptual smoothness during live streaming still wants a visual pass against a real model. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 3px accent-colored border-left (and the onboarding wizard's 4px accent border-top) read as a heavy yellow outline on every amicode card. Drop the rail from the home dashboard hero cards, the in-chat receipt/entity/ask/run cards, the problem rail, and the onboarding wizard — each keeps its neutral 1px hairline. The H-mark, live dots, hover tints, and focus outlines (keyboard a11y) are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Locks the contract the entity-rail "Inspect Run" button depends on:
postAmicode posts exactly {source:"amicode", kind:"command",
command:"amicode.openInspector"} (the command chat_panel.ts allowlists),
never throws if the parent frame rejects the post, and inAmicode()
reports false when unframed so the button stays hidden on the public web
build. Solid components can't be DOM-rendered under this repo's bun test
harness, so this covers the button's observable contract at the bridge.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold the full AMICO receipt redesign into the rail removal: instead of just dropping the accent bar, give the whole family one visual language. - receipt card (card.tsx): the H-mark doubles as the working spinner, diffs render structured (dimmed old -> new) instead of a run-on string, a green check settles the done state, failure tints the card red, and it is a real <button> with a focus ring (was a click-only <div>, invisible to keyboard) - entity view (entity-view.tsx): raw keys lead with a human label and keep the technical name beneath (params.drive_max -> "Drive max"), nested fields get a subhead, the arrived-from change is highlighted, the edit-in-chat affordance is always visible, and a footer states the read-only / edit-in-chat contract - rail / ask-card / run-window share the surface + H-mark signature - identity via an accent-tinted wash + gold hairline, no side rail - new pure helpers receiptParts / humanizeKey / fieldGroup (receiptText output unchanged); interaction/animation styles in new amicode.css Typecheck clean; 66/66 amicode tests pass; app build succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
QNode {id, prereqs, relevant?(value predicate), optionsFrom?, batchable};
frontier(graph, answers) returns answerable-now nodes (prereqs met AND
optionsFrom answered AND relevant AND not-yet-answered). Value-dependent and
relevance-pruning guardrails both covered. v1 = tested reference the SCORE
batching policy mirrors (not runtime-wired; spec §4.1). 6/6 bun test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(amicode): "Inspect Run" button on the entity rail
Fix chat scroll jitter during streaming; respect reduced motion
redesign amico entity component
chipText (system): composite branch -> compositeChip (N=1 matches the legacy flat chip; N>1 = "platform · N×role · kind · arch"); entityRows: composite branch -> compositeSystemRows (component-table + coupling-list, not a JSON blob); new systemProjection (composite read-through; flat collapses to N=1 with isComposite flag). All parse BOTH shapes defensively in place -- the fork repo cannot import the plugin normalizeSystem (spec §3 cross-repo). Never throws. +5 tests; 73/73 amicode-ui bun suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring the fork mainline up to date with the merged upstream stack (PRs #6–#12): onboarding wizard, Library upload, brand-mark consolidation, receipt-card + entity-view redesign, Inspect Run button, chat-jitter/reduced-motion fix, accent-rail removal. Conflicts resolved: - logo.tsx: auto-merged; the local 'Aero' font-family prepend survived origin's brand-mark rewrite (verified line 112 + wordmark-v2 intact). - AMICODE-PATCHES.md: kept both sides. Local Aero (#15) + composer paste bridge (#16) preserved; origin's mark-drift entry renumbered 15 -> 17 to sit after them. Local Aero + paste-bridge commits (a4fd244/c811798/b868a59) retained — still local-only WIP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… Piccolissimo + Altissimo PRO] segmented control on home (spec-20260709-093000); selection persists in localStorage, changes nothing about solves (future wiring: executor cloud-altissimo seam + issimo entitlement as the subscription gate) + tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… restore the <Logo> component and its Racing Sans One face (straight-sans experiment reverted per review) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…iew: keep trunk's MarkDetailed (redesign) + this branch's Logo typeface wordmark (Racing Sans One restore) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…+ preview The conflict-safe core of spec-20260712-014749 (all NEW files; no edits to the message-part.tsx / entity-rail.tsx / run-window.tsx surfaces the dashboard agent is actively changing): - amico-presence.ts: pure presence state machine (dormant/stepping_in/on/ settling/idle) — classify + transition; the shared brain rail+flow read. 14 tests. - amico-presence.css: offset accent lane + rail wake/settle motion (v2 tokens, reduced-motion gated); new file, not the hot amicode.css. - amico-presence.stories.tsx: self-contained Storybook preview of all 5 states + an auto-playing pop-in/out sequence (mock data). Deferred (dashboard-agent file contention): the invasive wiring — stamp scrub in message-part/card/ask-card/run-window, thinking-line decouple, rail wake/settle hookup. Fully specified in the approved spec; needs a coordinated pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…inherits the app CSP and kills the inline runtime
…ock; about-you failures render loud
…ce (spec stage1.5)
…fallback chain, control rebind (T3.2)
…e grid (spec stage1.5 T3.1/T3.3/T3.4)
…pill
The old edit mode floated a heavy row of five bordered buttons above every
card with a truncated label, drowning the content and reading as its own UI.
Rebuild: cards stay visible under a light scrim + dashed ring ("arranging,
not using"), each gets one compact grouped control pill in its top-right
corner (↑↓ reorder / ⚙ config / fork / ×), a banner orients, the add-back
tray only appears when something is hidden. Reorder ↑/↓ disable at row ends;
move buckets by hero/tile row (matches what the user sees). Overlay is
click-safe over the iframe; scrim blocks accidental widget clicks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…the frame Moving display:none onto the frame wrapper left the cell holding an empty grid column. Hide the whole cell when not editing and there's nothing to render; keep the frame mounted under display:none so its amc:empty signal keeps flowing and the cell re-appears if the widget later has content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Realizes the approved spec (identity rule + working lane) — the conflict-scoped pass (rail wake via CSS only; NO edit to entity-rail.tsx, which the widget kernel is editing): - message-part.tsx: drop the per-turn AMICO signature (data-slot= amicode-turn-signature); repurpose the amicode_* check as the in-domain signal; mount the thinking line in an offset accent lane BELOW the streamed parts, gated on inDomainTurn && working (decouples it from the old card-suppression so it now shows on in-domain turns — the reviewer's issue 5). - card.tsx / ask-card.tsx / run-window.tsx: drop the 'AMICO' wordmark (keep the H-mark glyph as a subtle leading icon); remove orphaned separators. - amico-presence.css: rail wakes on entry via [data-component=amicode-entity-rail] (session-sticky mount => plays once, no entity-rail.tsx edit). - styles/index.css: load amico-presence.css in the components layer. Verified: 20 tests pass, 0 typecheck errors. NOT visually run (heavy fork build; main checkout held by widget agent). Deferred: grouping amicode cards INTO the offset lane (open-question-2) + rail livedot-while-working — visual-iteration follow-ups. Not merged/pushed; reconciles with wip/stage1-widget-kernel at merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el build Disjoint from the widget kernel (UI chat flow vs dashboard widgets); brings the presence lane + un-stamped cards into the current build for live review. Stage 2 widget-author WIP left uncommitted in the working tree, untouched.
…n-chat preview + pin
Prompt Amico to build a home widget; it renders a live preview in the chat and
you pin it to the dashboard. Rides the existing /^amicode_/ tool-name seam — no
stock-code, no new part type, no new route.
Server (opencode):
- authorWidget() in widgets.ts: validate structured manifest fields + js, assemble
the manifest TOML, round-trip through parseManifest, write ~/.amico/widgets/<id>/;
re-authoring an id overwrites (new content hash = hot-reload). Never throws.
- amicode_author_widget built-in tool (Tool.define + registry) whose description IS
the authoring contract (mount signature, --amc-* tokens, fetch allowlist,
empty-state). Output carries an AMICODE_WIDGET {json} sentinel for the preview.
- mergeDashboard: BUILT-IN widgets still auto-surface; USER/authored/forked widgets
are now opt-in via pin (no home clutter while iterating in chat).
UI:
- widget-preview.ts: pure parseWidgetSentinel (mirrors parseDiffSentinel).
- WidgetPreviewCard: live WidgetFrame (reuses the kernel) + Pin button + warnings;
reads a widgetHost transport off the ui-bridge; degrades to a note with no host.
- AmicodeToolCard: new <Match> for amicode_author_widget.
- ui-bridge: AmicodeWidgetHost {frameSrc, callbacks, pin}; entity-rail passes it in.
App:
- message-timeline provides widgetHost (frame src, fetch/prompt callbacks, pin =
GET+append+POST /amicode/dashboard).
Tests: authorWidget 5, sentinel parser 4, dashboard opt-in 1 (ui 178 / server 40 green).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…or.clipboard.read in the outer webview + copy-back The webview half of the bidirectional clipboard bridge (extension half is in amicode#136): image paste answered client-side in the outer webview where navigator.clipboard.read is granted (the sandboxed iframe + text-only vscode.env.clipboard can't); copy writes back to the OS clipboard; text-paste fallback on any failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)
…in the chat A persistent, breathing visualization of amico's neural pathways rendered over the vault/skill/agent graph, living in the conversation flow as a permanent timeline row (stable key, kept mounted, riding the timeline's own row-measurement and bottom-lock machinery). Behavior - Auto-breathe: a 72px living slice at rest (close-up centered on amico's current position), expanding to a 224px whole-network view while a turn thinks (the amico core anchors dead center, zoom fits the farthest node); lingers 5s past completion, then collapses. Click/Enter toggles manually until the next turn reclaims auto. Folds entirely while a question dock is open — render loop paused, amico is waiting on the user. - Live telemetry: every tool call of the session streams into the brain. Reads, edits, skills, tasks and amicode_* verbs COMMIT — a pulse travels the skeleton and the node claims its category color (skill names map onto real skeleton node ids; unknown files graft beside the current position); greps/globs/lists flash as considered scouts that may leak back to dark; the interview's question tool rings the pulse-designer node per question. - Session persistence: completed messages arrive replay-flagged and restore the atlas instantly; the busy message animates live — every turn resumes the session's accumulated path. Turns with ≥2 commits chart a quiet constellation named "plate N · <prompt excerpt>". - Spreading activation: each live commit charges up to 4 skeleton neighbors sub-threshold, so one event ripples like tissue instead of blipping. - Cross-links: hovering a tool row (or an Explored/shell group chip) rings its node on the map via the amicode:brain-hover event; in the collapsed close-up the camera turns briskly to look at the glanced node. Rendering - Natively wide force layout for the strip (stretch-then-relax: locally isotropic distances inside a wide envelope — no projection squash), all pathways drawn clearly, untraversed tissue receded so the traversed path owns the contrast, where-we-are cursor ring legible in both themes. - Assets ship CSP-split (the server forbids inline scripts and data: fonts in served HTML): public/brain.html + brain.js + brain-font.woff2, GENERATED from the canonical design artifact in amicode media/brain — re-split to update, do not hand-edit. - The card wears the message cards' surface token, hairline border, 12px radius, and the centered content-column constraint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
amicode: the amico brain — a live map of the session's thought in the chat
The Run Inspector could only be opened from the VS Code status bar item or
the command palette — nothing inside the chat itself. Adds a framed-panel
button (new 'pulse' icon: a zero-order-hold staircase, matching the
terminal/review framed idiom) to the session header's right titlebar
cluster, beside the terminal toggle so it stays visible in narrow embeds.
Wiring is the existing bridge, end to end: the button posts the already-
allowlisted {source:"amicode", kind:"command", command:"amicode.openInspector"}
via postAmicode(); chat_panel.ts relays it to revealInspector(). Framed-only
(inAmicode() gate) — hidden in the public web/desktop builds where no
extension host exists. No V2-actions mirror: the desktop V2 layout is never
framed, so the gate would keep it permanently hidden there.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jack-champagne
force-pushed
the
local/amicode
branch
from
July 20, 2026 12:59
c05d2e3 to
e9b6951
Compare
Member
|
Closing as superseded — this one genuinely is. This PR adds an "Open Run Inspector" button to
The one thing here with no equivalent on the default branch is the cc @kate |
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.
What
The Run Inspector had no affordance inside the chat — only the VS Code status-bar item and the command palette. This adds a titlebar button to the session header's right action cluster (beside the terminal toggle, so it survives narrow embeds where the
md:cluster is hidden).pulseicon in the framed-panel idiom (terminal/review wear the same frame): a zero-order-hold staircase — the very thing the inspector plotsamicode.openInspectorthrough the existing bridge (postAmicode), whichchat_panel.tsrelays torevealInspector()— zero extension-side changes neededinAmicode()gated: hidden in the public web/share and desktop builds, where there is no extension hostVerification
bun turbo typecheck(app + ui) clean;bun test: ui 221 pass, app 388 pass, 0 fail🤖 Generated with Claude Code