amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136) - #20

Merged
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel
Jul 14, 2026
Merged

amicode: widget-kernel — home dashboard, in-chat widget authoring, Amico presence, clipboard/model bridges (fork half of amicode#136)#20
Rchari1 merged 70 commits into
local/amicodefrom
wip/stage1-widget-kernel

Conversation

@Rchari1

Copy link
Copy Markdown
Member

Aaron's widget-kernel program, opened as a PR so CI runs and it's reviewable. 70 commits, +7,953/−382 across 111 files — 0 behind local/amicode, merges clean. All commits are Aaron's; it adds alongside the already-merged amicode fork work (solver-toggle #13, chat-fixes#18) without reverting any of it.

The load-bearing bit for amicode#136

The fork half of the bidirectional bridges whose extension-side listeners are in amicode#136 — without this PR + a vendored-binary bump, those three features are dead listeners:

  • packages/app/src/components/prompt-input/clipboard-bridge.ts → sends clipboard-write (copy-back) + clipboard-image-request, consumes the clipboard-image reply (image paste). Has a test.
  • packages/app/src/components/amicode-default-model.tsx → sends set-default-model (drives amicode's amicode.defaultModel).

The rest of the program

  • Home dashboard = WidgetGrid (legacy cards as fallback): panel-first chrome strip, sessions flyout, responsive grid.
  • In-chat widget authoring (Stage 2): author tool + live in-chat preview + pin; widgets served as documents with their own CSP (srcdoc inheriting the app CSP was killing the inline runtime — fixed here).
  • Amico third-actor presence wired into the chat flow (packages/ui/src/amicode/amico-presence.*, with stories + test).
  • Durable default-model pin — pin slot in the models store + fallback chain + control rebind.
  • Server-side: dashboard.ts, widgets.ts + widgets-src/*, widget-*.ts, toml-lite.ts (all new under server/amicode/); problems.ts bumps the log tail 8→24 (a smaller window can blank the filtered mid-solve view).

Before this lights up in shipped amicode

  1. This PR reviewed + merged to the fork default.
  2. Cut a fork release + bump the vendored binary in the amicode extension.
  3. Merge amicode#136 (the extension half).

One verification I want a reviewer to confirm

The bridge senders live in packages/app; Kate's original paste bridge was in packages/ui. Worth confirming a binary built from this branch actually serves the packages/app code (a strings check on the built binary), so the senders don't just exist in-tree but ship. I can run this once we're at the release-cut step.

🤖 Generated with Claude Code

aarontrowbridgeand others added 30 commits July 8, 2026 20:24
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.
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>
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>
New facets.ts (pure). receipt.ts short()/problem.ts shortValue() delegate
to compactValue — arrays/objects render as compact summaries, never raw
JSON blobs. Spec §4 / plan Task 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 4)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §6.1 / plan Task 5. Thin SolidJS over systemProjection + system-render
models; theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spec §5,§6.1 / plan Task 6. entity-view routes system→SystemComposite
(generic field-row path retired for system; Hamiltonian moved to the hero).
card.tsx renders systemReceiptPieces (semantic +/−/change, or post-state
compositeChip on creation/large/elided) instead of JSON diff pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ey) + shared corpus
spec §6.2,§9 / plan Task 12. Defensive legacy/structured projection (never
throws, raw passthrough on unknown enums), derives primaryKey from
type+free_phase+time_mode, synthesizes derivedFinalFidelity for min_time.
Re-implements the §10 mapping in place (no cross-repo import), locked to the
amicode corpus by a byte-identical fixture mirror. 9 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m problem_type (spec §6.3 / Task 13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + constraints)
spec §6.2 / plan Task 14. Mode-badge header via modeBadges; derived primary
objective headline + OBJECTIVE_LATEX (keyed by primaryKey, distinct from
ObjectiveKind); added-terms + typed-constraint rows (incl. the synthesized
min-time final_fidelity row); solve scalars. Theme-aware --v2-* CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ask 15)
entity-view routes formulation→FormulationView (generic field-rows gated off
for both hero kinds). card.tsx generalizes the system receipt path to a
hero path (system|formulation): formulationReceiptPieces renders mode
transitions / flag +/− / objective+constraint setDiff, or the post-state
mode-chip on creation/large/elided. 107 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk grid/flex children
Grid/flex children defaulted to min-width:auto, so long history notes / table
params forced the dialog content wider than its frame and clipped the right
edge (timestamps). Add min-width:0 + overflow-wrap:anywhere on the offending
children (history summary, system table params, formulation constraints/solve)
and overflow-x:auto on the LaTeX blocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bulletproof dialog overflow
- systemHamiltonianLatex: derive an illustrative Hamiltonian for ANY composite
(drift per role + interaction per coupling kind + drive) so the System hero
shows math for cavity+qubit/etc., not just transmon/rydberg ("show the system").
- param symbols (ω/δ/χ/J) in the component table; unit-suffixed keys kept.
- formatTs: compact ISO ("07-10 15:53") for history + Updated — cleaner, no clip.
- overflow: container overflow-x:hidden + min-width:0 down the timeline/event
chain + nowrap compact timestamp → history no longer bleeds past the frame.
110 fork tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el bleed)
The fit Dialog sizes to content; the wrapper only set overflow-y, so a wide
child (long history line) bled past 680px, grew the panel, and clipped both
edges. Set overflow:auto + min-width:0 + max-width:90vw so the 680px box holds
and content wraps within it. Root cause of the "still cut off" reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fit-panel growth)
The fit Dialog was measuring the scroll-width of a nowrap child (the katex
Hamiltonian) through the wrapper's overflow-x:auto, growing the panel to ~1170px
and clipping both edges. Switch to a definite 620px width with overflow-x:hidden
(+ overflow-y:auto for history) so there's no scroll-width to leak — content
wraps within, the Hamiltonian scrolls inside its own box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull Raghav's "bunch of bug fixes just landed" (2026-07-10) into the
composite-system work. 13 commits from the local/amicode integration branch:
#13 High-Performance Solver toggle + brand typeface (Racing Sans One) restore
#16 entity-view + problem-switcher modal padding, remove card-family gold tint
#17 chat paste via extension clipboard bridge (⌘V intercept)
#18 chat prose no longer clips + AMICO signature on every assistant turn
Conflict resolutions (4 files), all preferring the landed, reviewed fixes:
- message-timeline.tsx: took the team wrapper (width:100%); dropped my
untested 620px definite-width workaround. The katex Hamiltonian is now
contained by the auto-merged amicode.css hardening (entity-view
overflow-x:hidden + .amc-ev-formula overflow-x:auto), so width:100%
against the v1 dialog's definite max is sufficient.
- logo.tsx: took Racing Sans One (team brand decision, straight-sans
reverted per review). Dropped the Aero face — it is license-pending
donationware and cannot ship.
- prompt-input.tsx / attachments.ts: took the canonical paste-bridge impl
(readClipboardViaBridge, resolves "" not null).
Verify: packages/ui amicode suite 112 pass / 0 fail; packages/app paste-bridge
43 pass. The 1 pre-existing submit.test.ts failure (Toast export via
Object.assign, bun ESM quirk) is untouched by this merge on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the merge's Racing Sans One resolution back to Aero per Aaron —
matches wordmark-v2.tsx (already 'Aero', 'Racing Sans One' fallback). Aero
@font-face + asset survived the sync (index.css, public/assets/Aero-Regular.ttf).
NOTE: Aero is license-pending donationware (preview-only, USD 25+ to the
author). Racing Sans One (OFL) remains the CSS fallback. Must be licensed or
replaced before any release ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch #18)
anthropic.txt "Tone and style" -> "Communicating with the user": output
renders as rich GFM (headings/bold/lists/tables/inline code), match
structure to content, lead with the outcome, readable-beats-brief in
complete sentences. "interactive CLI tool" -> "interactive coding agent".
Companion patch in amicode AGENTS.md covers custom-prompt agents
(pulse-designer) that bypass this file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ha 3c26d8d9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#18 addendum)
Live test showed no change: the model pin is opencode/deepseek-v4-flash-free
(no anthropic creds), so sessions load default.txt — whose "fewer than 4
lines / one word answers are best" rules steamroll everything. Same
"Communicating with the user" section as anthropic.txt, terse examples
replaced with structure-matching ones; gemini.txt minimal-output bullets
replaced likewise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… model (patch #18 addendum 2)
One canonical "Communicating with the user" section (communicating.txt)
appended in provider() for all model families, with a supersede clause
that outranks per-model CLI/terseness rules. Inlined copies in
anthropic/default/gemini slimmed back to near-stock. Custom-prompt
agents still bypass by design (subagents return model-directed data);
pulse-designer is covered via amicode AGENTS.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…for user-facing custom-prompt agents
system-render.ts: role-aware driveTerm — atoms get Ω(t)/2(|r><1| + h.c.)
instead of the hardcoded bosonic ε(t)(â+â†); atom drift -Δ n̂ → -Δ|r><r|.
+3 tests (115 pass).
request.ts: custom-prompt agents append PROMPT_COMMUNICATING unless
mode === "subagent" — covers pulse-designer interview sessions at the
system-prompt level; subagent output stays style-free (model-directed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two-finger / right-click on a tab now opens a context menu:
· Close (mirrors the × / middle-click)
· Close other tabs (disabled when only one tab)
· Close tabs to the right (disabled when it's the last tab)
- context/tabs.tsx: two bulk actions (closeOthers, closeToRight) living
alongside removeTab/removeSessions. Both are navigation-safe — closeOthers
activates the kept tab; closeToRight re-navigates to the anchor only if the
active tab was among those removed (via a new currentTabIndex helper that
matches session tabs by href and draft tabs by draftId). Index-shift safe:
single splice under produce/startTransition, not a removeTab loop.
- titlebar.tsx: wrap TabNavItem's root in the existing Kobalte ContextMenu
(Trigger as="div", modal={false}), mirroring sidebar-project.tsx. Wired from
the <For> where the index is in scope; enablement flags from tab count/index.
- i18n/en.ts: common.closeOtherTabs + common.closeTabsToRight (other locales
are Partial and fall back to en).
Scope: session tabs (TabNavItem). Draft "new session" tabs unchanged.
Verify: packages/app tsgo -b exit 0, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e above not below (patch #20)
Upstream styled all h1-h6 identical to body text (14px medium, same
color as the container) with the margin below the title instead of
above — section titles read as unrendered prose. strong/b 500 -> 600
(500 vs the 400 body was near-invisible).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aarontrowbridgeand others added 27 commits July 12, 2026 01:13
…+ 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
…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>
@Rchari1
Rchari1 marked this pull request as ready for review July 14, 2026 22:54
@Rchari1
Rchari1 merged commit 3afee91 into local/amicodeJul 14, 2026
0 of 4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Rchari1@aarontrowbridge