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
5 changes: 5 additions & 0 deletions .cursor/rules/planning.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ alwaysApply: true
Every implementation plan includes concrete Tests, Documentation, and UI/UX
sections. Use `N/A` only with a specific reason. Plans that touch Dex must name
the required skill references and visualization evidence.

Plans that touch Agent conversation UI or a public API must answer: which
shared package or OpenAPI surface owns the change, and which extension points
(`sa-*`, slots, constructor injection) Studio or other embedders use. Do not
plan portal-only UI with a later-extraction step.
10 changes: 10 additions & 0 deletions .cursor/rules/project-core.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,15 @@ semantically synchronized.
- Domain packages prohibit `any`, dynamic maps, and raw string states.
- Never export Dex resource getters solely to expose descriptors.
- Keep provider, MCP, Dex, application, transport, and UI boundaries separate.
- Assume a second consumer (SuperVerse Studio / agent-server). Application-
visible conversation UI, merge/sort helpers, and Tool presentation belong in
`@superdurable/superagent-ui` with `sa-*` / slots; portal `web/src` stays
transport, orchestration, branding, and thin mappers. Do not ship portal-only
UI to extract later. Public Go/OpenAPI surfaces stay in `agent` / `model`.
- Never commit or log `.env` or credentials.
- Every changing turn ends with a meaningful commit and clean worktree.
- `@superdurable/superagent-ui` GitHub Release tags and npm publishes must
target a commit already on `origin/main`. Never tag or publish from a
feature branch or PR head. Merge to `main` first, then tag `vX.Y.Z`. If a
tag was cut from a feature branch by mistake, supersede it with the next
patch from `main`.
3 changes: 3 additions & 0 deletions .cursor/rules/typescript-react.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ alwaysApply: false
- Keep components focused and preserve accessibility, keyboard, responsive,
reconnecting, stale, terminal, and failure states.
- Do not suppress type-aware, Hooks, or accessibility lint failures.
- Agent conversation presentation, ToolCall cards, and view-model merge/sort
logic live in `@superdurable/superagent-ui` with transport-free props and
render slots. Portal code maps generated types into those view models.
50 changes: 49 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,45 @@ execution history.
vulnerability checks, generated-code drift, TypeScript strict checking,
type-aware lint, component tests, and browser E2E.

## Embedder and SuperVerse reuse

Assume a second consumer (SuperVerse Studio / agent-server) for application-
visible behavior. Do not implement that behavior only in the portal `web/src`
tree or only under `internal/`.

### Frontend

- New or changed Agent conversation presentation, interaction controls, and
pure view-model merge or sort logic belong in `@superdurable/superagent-ui`
first.
- Portal `web/src` keeps transport, Snapshot and stream orchestration, product
shell or branding, and thin mappers into package view models.
- Shared components must be extensible: transport-free props, default `sa-*` /
`--sa-*` styling, and render slots or equivalent extension points so Studio
can customize row markup without forking sort or pairing logic.
- Plans and PRs that touch Agent conversation UI must state the shared package
surface and how Studio consumes or customizes it. Do not ship portal-only UI
with a promise to extract later.

### Backend

- Application-visible APIs, types, and constructors go through the public
`agent` / `model` packages and OpenAPI.
- Embedder extension points use constructor injection, interfaces, or
configuration. Do not require copying Flows or hand-rolling parallel HTTP.
- Do not hide SuperVerse-needed semantics behind portal-only side paths.

### Documentation

When changing the public UI package or public Go/OpenAPI surface, update
`ARCHITECTURE.md` and `web/packages/superagent-ui/README.md` in the same change.

## Plans and documentation

Every implementation plan includes concrete `Tests`, `Documentation`, and
`UI/UX` sections. Use `N/A` only with a specific reason.
`UI/UX` sections. Use `N/A` only with a specific reason. Plans that touch Agent
conversation UI or a public API must also answer the shared-surface and
extension-point checklist under Embedder and SuperVerse reuse.

Keep these documents current with the code:

Expand All @@ -238,3 +273,16 @@ Keep these documents current with the code:
and OpenAPI files use the repository Apache-2.0 header.
- Generated files and the vendored Dex skill follow their own recorded license
and are excluded from header rewriting.

## @superdurable/superagent-ui releases

GitHub Release tags and npm publishes for `@superdurable/superagent-ui` must
target a commit that is already on `origin/main`.

- Never create a `vX.Y.Z` tag, GitHub Release, or npm publish from a feature
branch, PR head, or any commit that is not an ancestor of `origin/main`.
- Merge the change to `main` first. Only then tag `vX.Y.Z` on that `main`
commit and publish the Release so `npm-release.yml` and
`github-release-ui.yml` can pass their main-ancestor checks.
- If a tag was created from a feature branch by mistake, do not reuse it.
Delete or supersede it and cut the next patch version from `main`.
5 changes: 4 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Agent state. Streams reduce latency but never become recovery state.
| `internal/model` | Provider routing, protocol adapters, in-memory credential lookup | Dex resources or HTTP API responses |
| `internal/mcp` | Trusted server config, discovery, policy, single-attempt sessions, brokers | Agent state transitions, retry loops, or exported Dex resources |
| `web` | React portal and generated Fetch client | Handwritten API response types or durable-state reconstruction |
| `web/packages/superagent-ui` | Transport-free React conversation components and local interaction behavior | Dex/API clients, routing, durable state, or product workflows |
| `web/packages/superagent-ui` | Transport-free React conversation components, timeline merge/sort, ToolCall cards, and local interaction behavior | Dex/API clients, routing, durable state, or product workflows |

Interfaces live at their consuming boundary. Concrete single-use components do
not receive speculative interfaces, and there is no general-purpose helpers
Expand All @@ -42,6 +42,9 @@ The Web application maps generated domain objects into the plain view models
accepted by `@superdurable/superagent-ui`. The shared package never imports the
generated client or reconstructs application state; this keeps it reusable by
other products without coupling their transport or orchestration to this portal.
Conversation chronology (`buildConversationTimeline`), ToolCall pairing, and
shared chrome such as `ToolCallCard` / `ActivityRow` / `planActionPresentation`
live in the package. Portal and Studio supply slots or thin mappers only.

The public `agent` package is a thin façade over `internal/agent`. It aliases the
stable application types and delegates constructors, so embedders share the
Expand Down
50 changes: 49 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,45 @@ execution history.
vulnerability checks, generated-code drift, TypeScript strict checking,
type-aware lint, component tests, and browser E2E.

## Embedder and SuperVerse reuse

Assume a second consumer (SuperVerse Studio / agent-server) for application-
visible behavior. Do not implement that behavior only in the portal `web/src`
tree or only under `internal/`.

### Frontend

- New or changed Agent conversation presentation, interaction controls, and
pure view-model merge or sort logic belong in `@superdurable/superagent-ui`
first.
- Portal `web/src` keeps transport, Snapshot and stream orchestration, product
shell or branding, and thin mappers into package view models.
- Shared components must be extensible: transport-free props, default `sa-*` /
`--sa-*` styling, and render slots or equivalent extension points so Studio
can customize row markup without forking sort or pairing logic.
- Plans and PRs that touch Agent conversation UI must state the shared package
surface and how Studio consumes or customizes it. Do not ship portal-only UI
with a promise to extract later.

### Backend

- Application-visible APIs, types, and constructors go through the public
`agent` / `model` packages and OpenAPI.
- Embedder extension points use constructor injection, interfaces, or
configuration. Do not require copying Flows or hand-rolling parallel HTTP.
- Do not hide SuperVerse-needed semantics behind portal-only side paths.

### Documentation

When changing the public UI package or public Go/OpenAPI surface, update
`ARCHITECTURE.md` and `web/packages/superagent-ui/README.md` in the same change.

## Plans and documentation

Every implementation plan includes concrete `Tests`, `Documentation`, and
`UI/UX` sections. Use `N/A` only with a specific reason.
`UI/UX` sections. Use `N/A` only with a specific reason. Plans that touch Agent
conversation UI or a public API must also answer the shared-surface and
extension-point checklist under Embedder and SuperVerse reuse.

Keep these documents current with the code:

Expand All @@ -238,3 +273,16 @@ Keep these documents current with the code:
and OpenAPI files use the repository Apache-2.0 header.
- Generated files and the vendored Dex skill follow their own recorded license
and are excluded from header rewriting.

## @superdurable/superagent-ui releases

GitHub Release tags and npm publishes for `@superdurable/superagent-ui` must
target a commit that is already on `origin/main`.

- Never create a `vX.Y.Z` tag, GitHub Release, or npm publish from a feature
branch, PR head, or any commit that is not an ancestor of `origin/main`.
- Merge the change to `main` first. Only then tag `vX.Y.Z` on that `main`
commit and publish the Release so `npm-release.yml` and
`github-release-ui.yml` can pass their main-ancestor checks.
- If a tag was created from a feature branch by mistake, do not reuse it.
Delete or supersede it and cut the next patch version from `main`.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ strict `vX.Y.Z` tag on `main`. The release workflows derive the package version
from the tag in the temporary runner checkout. The committed workspace version
does not require a manual release bump.

Never create the release tag from a feature branch or PR head. Merge to
`origin/main` first, then tag that main commit. Both `npm-release.yml` and
`github-release-ui.yml` reject tags whose commit is not an ancestor of
`origin/main`. A mistaken feature-branch tag must not be reused; cut the next
patch version from `main` instead.

The npm package must trust the `superdurable/superagent` GitHub repository with
workflow filename `npm-release.yml`, no environment, and direct `npm publish`
permission. The workflow uses npm trusted publishing and GitHub OIDC. Do not add
Expand Down
30 changes: 0 additions & 30 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions web/packages/superagent-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,53 @@ remain unchanged.

```tsx
import {
ActivityRow,
ApprovalCard,
ConversationComposer,
ConversationTimeline,
MarkdownContent,
PendingMessageQueue,
PendingQuestionBatch,
PlanPanel,
TimerCard,
ToolCallCard,
ToolRecoveryPanel,
buildConversationTimeline,
pairToolCallsById,
planActionPresentation,
useTimelineFollow,
} from "@superdurable/superagent-ui";
import "@superdurable/superagent-ui/styles.css";
```

## Conversation timeline

`buildConversationTimeline` merges durable messages, consumed-user projections,
reasoning, activities, and the live assistant into one chronologically ordered
list. `ConversationTimeline` applies that order and renders through slots
(`renderMessage`, `renderActivity`, `renderReasoning`, `renderAssistant`,
`renderConsumedUser`) so Studio can keep its own markup while sharing sort
logic.

## Tool call cards

`pairToolCallsById` joins assistant `toolCalls` to `role=tool` messages by call
id. `ToolCallCard` collapses request and result by default:

- `apply_patch` → red/green patch diff from the request `patch` field
- `exec_short_command` / `exec_long_command` → highlighted `$` command plus grey
stdout/stderr (ANSI stripped)
- other tools → generic JSON request/result

Override with `renderToolCall` when a product needs a custom row.

## Shared chrome and helpers

Also exported: `ActivityRow`, `PlanPanel` / `planActionPresentation`,
`ApprovalCard`, `TimerCard`, `mergeSequencedMessages`, `mergeActivityEvent`,
live-text helpers, and `useTimelineFollow` (optional element scroll root for
panel scrollers).

`ConversationComposer` is controlled. `PendingMessageQueue` receives plain view
models and reports semantic actions by item ID, so it has no knowledge of Dex,
HTTP, generated clients, or product-specific stores. `MarkdownContent` renders
Expand Down
Loading