Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions packages/app-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@ The M2 artifact: the Amicode app surface, carried as an **overlay** on a
pinned **canonical opencode** base — the mechanism that retires the fork at
cutover while keeping every Amicode surface.

## Slice (b) — the complete app-graph delta — SHIPPED

**Scope (corrected mid-slice)**: the complete fork-vs-base delta of the
app's build graph — `packages/{app,ui,session-ui,schema,core,sdk}` — 422
files (per-package: app 94A/105M/1D, ui 142A/22M, session-ui 8A/16M,
schema 2A/5M, core 3A/23M, sdk 0A/2M).

The planned additive-only scope **does not typecheck** — the finding that
drove the correction: ~10 additive app files depend on symbol-level
additions in modified files (`settings.developer`, `tabs.openPath`,
`model.pin`, `QuestionInfo.kind` — the typed question cards spanning
schema/core/sdk), and the fork's debug-bar deletion forces `layout.tsx`
into the overlay (base layout imports the deleted module). The fork delta
is a cross-cutting FEATURE delta, not an app-layer delta.

**The M3 cutover port inventory is machine-derived** (manifest:
`server_coupled_port_inventory`, 35 files in schema/core/sdk): every app
feature whose types or runtime live in the fork's server-side packages.
At cutover the canonical server ships NONE of these — the bundle will hit
exactly these gaps — so each is a port-upstream / extension-service /
drop decision. Recorded, not resolved.

**The true overlays** (big M-files upstream still evolves: home.tsx,
session-header, message-part, timeline, …) ride wholesale — correct for
the one-push cutover. The compose-vs-fork decomposition is deliberate
POST-cutover maintenance (`manifest.true_overlays` is the worklist).

### Proofs (all green, 2026-08-21)

1. **Equivalence** — every overlay file byte-identical to the fork's at the
pin (round-trip verified at extraction; manifest hash-verified at
materialization). Symlink-aware (`app/public/amico.svg` → ui asset).
2. **Composition** — `bun install` (4,695 pkgs) → `schema` typecheck →
`session-ui` typecheck + `ui` tsc build → `app` `tsgo -b` typecheck →
`app` **vite production build** (14.3s, 1,587 assets, Amicode surfaces
present in the emitted bundle) → **103/103 session-ui unit tests**.

## Slice (a) — the complete `packages/ui` delta — SHIPPED

**Scope**: every file under `packages/ui` the fork changed vs the upstream
Expand Down
749 changes: 740 additions & 9 deletions packages/app-bundle/manifest.json

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions packages/app-bundle/overlay/packages/app/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Amicode App — UI Structure

The SolidJS surface of the Amicode extension. This context covers how the window is
laid out and how a researcher moves between chat and the supporting surfaces. It is a
glossary only — no implementation details, no routing tables, no component names.

For the conversation/session runtime context, see the repo-root `CONTEXT.md`.

## Language

### The shell

**Landing**:
What the window shows on launch. The Landing is always a fresh, empty chat — a new
composer awaiting a first prompt — never a dashboard or a resumed session. Prior
sessions and setup are one interaction away in the **Rail**, never in the way.
_Avoid_: Home, Home page, Dashboard, Start screen

**Chat**:
The single persistent hub of the window — the composer and its conversation. Every
other surface opens beside or in front of the Chat; the Chat is never replaced by
another surface, only overlaid. There is no view in which the Chat is absent.
_Avoid_: Main view, editor, session pane (as the whole hub)

**Context tree**:
The organic graph of what the agent is actually holding in mind, rendered inside the
**context side panel** (opened from the progress-circle ring button in the session
header). Root = amico at center, the session's turns orbiting it (one per user prompt,
however many assistant messages it spans), and the markdown, source, skills, and agents
each turn pulled into context clustering around their turn. Shared context sits between
the turns that recall it. Interactive: clicking a file node opens the real file (project
files as a session tab, vault files in the **Vault panel**). One per session view; absent
until the session holds context. On-demand — visible only when the context panel is open,
never persistent. See ADR 0004 (relocated from the former top panel of ADR 0003).
_Avoid_: Brain (that was the ambient, non-interactive strip), knowledge graph, minimap

**Vault panel**:
The dismissible drawer that puts the vault — every attached mount and every file inside
it — in the interface. Read-only browsing with inline markdown/source rendering; opened
from the titlebar vault button, the command palette, or a **Context tree** click on a
vault node.
_Avoid_: Vaults tab (that is the mount *list* in status), file manager, explorer

**Rail**:
The one narrow vertical strip of icons along the window's leading edge. Collapsed to
icons by default; each icon reveals its text label on hover. The Rail is the only
persistent navigation chrome — it replaces the former top chrome strip and the former
project-avatar strip, which no longer exist.
_Avoid_: Sidebar (the Rail is not the Panel), toolbar, activity bar

**Rail surface**:
One thing the Rail can open, represented by a single icon. The navigation surfaces are
Chats, Projects, Run gallery, Pulse bank, and Library. A Rail surface is a destination,
not a document — it lists or collects things the researcher then acts on.
_Avoid_: Widget, card, tab

**Panel**:
The dismissible drawer a **Rail surface** opens beside the **Chat**. Exactly one Panel
is open at a time; opening another replaces it; dismissing it returns the window to
Chat-only. Selecting an item inside a Panel acts in the Chat rather than navigating
away from it.
_Avoid_: Modal, page, route, flyout

**Account zone**:
The cluster at the foot of the **Rail** for identity and configuration, distinct from
the navigation surfaces above it. Holds the researcher profile (About You), backend
Connections, solver/model Defaults, and Settings. These are set-and-forget surfaces,
not places a researcher browses.
_Avoid_: Settings menu (the zone is broader), footer

### Ambient surfaces

**Live-solve indicator**:
The always-visible readout that a solve is running, shown in the titlebar so it
survives every Chat and Panel change. Reports progress at a glance and, on click, jumps
to the Chat that owns the running solve. Its absence means nothing is solving.
_Avoid_: Now-solving card, status bar, progress toast

**Setup nudge**:
The non-blocking prompt, shown alongside the first-run **Landing**, that reflects the
app-visible onboarding signal (profile completeness plus a dismiss flag today; richer
per-step progress — vault, Julia, connection — would require an extension→app bridge).
It persists until onboarding is complete and then disappears; it never gates the Chat.
_Avoid_: Onboarding modal, wizard (the wizard is the conversational interview; the nudge
only surfaces its state), setup wall

## Relationships

- The **Landing** is a **Chat**; the window never opens on anything else.
- The **Context tree** lives inside the context side panel and belongs to one session;
the **Vault panel** belongs to the window and opens beside whatever Chat is showing. A
Context-tree click on a vault node opens the Vault panel on that file — the two surfaces
reference each other but neither owns the other.
- Every **Rail surface** opens as a **Panel** beside the **Chat**; the Chat is never
replaced, only overlaid, and at most one Panel is open at a time.
- The **Rail** carries navigation surfaces above and the **Account zone** below; both
live in the same strip but are different in kind — one is browsed, one is configured.
- The **Live-solve indicator** and the **Setup nudge** are ambient: they belong to no
single Chat or Panel and persist across navigation until their condition clears
(nothing solving; onboarding complete).
- A **Setup nudge** reflects onboarding state; it does not own the onboarding flow,
which is the conversational overture interview conducted in the **Chat** itself.

## Retired concepts

These were real surfaces before the chat-first redesign and are intentionally gone. A
reader meeting them in older code or notes should map them forward:

- **Home / Dashboard** (the aggregate widget page) → dissolved. Its widgets became
**Rail surfaces**, **Account zone** entries, in-Chat context, or first-run affordances.
- **Home top chrome strip** (the Home page's brand mark + defaults capsule + projects
flyout + connections + gear) → replaced by the **Rail** and **Account zone**.
- **Titlebar Home affordance** — the titlebar's `/`-pointing Home button is repurposed to
"new chat" once `/` is itself a Chat. The titlebar session/draft **tab strip** stays
(it tracks *open* sessions); the Chats **Rail surface** is full history — the overlap is
intentional, not a duplicate.
- **Project-avatar strip** (the always-visible `w-16` avatar rail in `sidebar-shell`) →
legacy-only; it is already absent when the redesign flag is on. Project switching lives
in the Projects **Rail surface**.
- **User-authored widget subsystem** (`amicode_author_widget`, "pin to dashboard",
the widget grid, `/amicode/dashboard`) → retired with the dashboard. Authoring and
pinning are removed, not re-homed; re-homing authored widgets as in-Chat artifacts is
a possible future, not part of this redesign. See ADR 0001.
- **Home cards** "Meet Amico" and "Jump back in" → folded into the first-run Landing and
the Chats surface respectively; they are no longer standalone surfaces.
- **Brain** (the ambient session map — first an inline timeline strip, then ADR 0002's
proposed chat-wide background) → superseded by the **Context tree** top panel. The
background direction was parked (ADR 0003); the strip row is deleted; the ambient engine
survives as a library only. **Glass** (the frosted card surface of the background design)
retires with it.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 0001 — Chat is the landing; the dashboard dissolves into a rail

- Status: Proposed
- Date: 2026-07-23
- Deciders: Kate Bonner (Head of Product)

## Context

The Amicode window opened on a **Home** page: a top chrome strip plus an aggregate grid
of widgets (run gallery, pulse bank, library, "about you", "now solving", "meet amico",
"jump back in"). Chat lived on a separate route the researcher navigated to. Reaching a
new chat therefore cost a step, and the first thing a researcher saw was a dashboard of
everything rather than an invitation to act.

The redesign already in flight on `kate/chat-redesign` had been pulling the new-session
screen toward a composer-as-hero, and auto-draft machinery to open an empty chat without
a session id already existed behind the `newLayoutDesigns` feature flag — though only
*inside* the directory-scoped session route, not at the root. The open question was
whether to keep the dashboard as a peer destination or commit to chat as the single hub.

## Decision

**The window lands on a fresh new chat on every launch, and the aggregate dashboard is
removed.** Chat becomes the one persistent hub. The widgets that earned a place are
re-homed onto a single vertical **Rail** of navigation surfaces (Chats · Projects · Run
gallery · Pulse bank · Library), with identity/config in an **Account zone** at the
Rail's foot. Each Rail surface opens a dismissible **Panel** beside the chat; the chat
is overlaid, never replaced, and at most one Panel is open at a time. Two widgets become
ambient: the running-solve readout becomes a **Live-solve indicator** in the titlebar,
and onboarding becomes a non-blocking **Setup nudge** on the first-run landing.

The change is shipped as a single coherent cutover under the existing `newLayoutDesigns`
flag — not behind a new flag and not sliced for incremental rollout. The flag remains
the fallback to the legacy shell.

See `packages/app/CONTEXT.md` for the vocabulary (Landing, Rail, Rail surface, Panel,
Account zone, Live-solve indicator, Setup nudge) and the retired concepts.

## Consequences

- The **Home** page, its **top chrome strip**, and the aggregate **Dashboard** are
retired. The titlebar's `/`-pointing Home button is repurposed to "new chat"; the
titlebar session tab strip stays (open sessions) alongside the Chats Rail surface
(history). The `w-16` **project-avatar strip** is legacy-only and already absent when
the flag is on. Older code and notes must map forward per `CONTEXT.md`.
- **The landing runs at `/`, which has no directory context**, unlike the existing
session-route auto-draft. The root landing must resolve a working directory first —
reusing the server-cwd fallback on a fresh install with no tracked project.
- **A shipped capability is retired:** dissolving the dashboard removes the home for the
user-authored-widget subsystem (`amicode_author_widget`, pin-to-dashboard, the widget
grid, `/amicode/dashboard`), so authoring and pinning are removed rather than re-homed.
Existing pinned widgets stop appearing. Re-homing authored widgets as in-Chat artifacts
is a possible future enhancement, deliberately out of this cutover.
- Fastest path to value: a researcher can type a prompt the instant the window opens.
- Discoverability of the collections (gallery, pulse bank, library) drops from
"on screen by default" to "one Rail click away." Accepted, because the Rail's
hover labels keep them nameable and the dashboard's density worked against focus.
- The server-driven widget data (`/amicode/*` routes) is reused; widgets are re-homed
into Panels, not rebuilt.
- Onboarding must be usable ambiently — the conversational overture interview plus a
Setup nudge — because there is no dashboard to host a setup wall.
- A single cutover means no partial state to maintain, but the whole shell changes at
once under the flag; review and QA happen against the flag as one unit.

## Alternatives considered

- **Keep an optional Dashboard surface** (a Rail icon reopening the grid). Rejected:
two ways to reach the same widgets, and it preserves the "dashboard of everything"
the redesign is trying to shed.
- **Grid as the default rail panel** (a soft home beside the chat). Rejected: leaves a
widget wall adjacent to the composer, undercutting "chat is the hero."
- **Resume the last chat on launch** instead of a fresh one. Rejected: makes the
landing inconsistent (sometimes chat, sometimes stale context) and diverges from the
reference; in-flight solves are recovered via the Live-solve indicator and the Chats
surface instead.
- **Two-tier rail** (Slack-style persistent project avatars beside the function rail).
Rejected: heavier chrome competing with the chat; the Projects surface covers fast
switching at one click.
- **New `chatFirstLayout` flag with a 3-slice rollout**, or a **prototype-first**
validation pass. Rejected for now in favor of one cutover under `newLayoutDesigns`;
revisit if the single cutover proves too large to review.
Loading
Loading