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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ the resolved app appearance automatically.
one grouped control (expand a row for bounded command and output). Model
pickers follow the provider CLI, including Claude Fable 5.1 and GPT-6 Astra
when advertised. Its compact thread rail and bottom command deck keep chat
primary, with **Open review** routing to Strand's Review surface. Declarative
primary, with **Open review** routing to Strand's Review surface. **Agent
Session Recap** summarizes files touched, risky paths, and leftover TODOs
in the active worktree and can sit next to Review. Declarative
plugins render from validated manifests; third-party JavaScript does not
execute in the privileged webview.
The bundled **Quick Notes** plugin provides an editable scratchpad for each
Expand Down
9 changes: 8 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2200,7 +2200,8 @@ the audit does not mark these fixes or proposals shipped.
registries, shared hosts, and resilient layout-v2 references shipped
2026-08-28; declarative manifest validation, permission broker, bundled
marketplace, Heroi dogfood plugin, and `docs/plugin-creation.md` shipped
2026-08-29. Typed services/resource leases, quotas, remote install, and
2026-08-29; Agent Session Recap and `docs/plugin-marketplace-backlog.md`
shipped 2026-10-01. Typed services/resource leases, quotas, remote install, and
isolated community execution remain open.
- AI features (writing suggestions, conflict hints) — PRD Q3
- ☑ Commit message suggestions from staged diffs, or all unstaged changes
Expand Down Expand Up @@ -2723,6 +2724,12 @@ sample is now an editable repository-scoped Workbench plugin. Notes are saved
under a repository-path key in Strand's app-config `strand.db`, never in the
working tree. The placeholder Repo Status marketplace plugin was removed.

**Agent Session Recap shipped (2026-10-01):** bundled builtin
`daniels.session-recap` summarizes files touched, risky paths, and leftover
TODOs in the active repository or worktree. It reuses Review's Open-review
bridge and degrades to a clear empty state with no repo or no changes. Design
note: `docs/plugin-marketplace-backlog.md`. Remote marketplace stays deferred.

**Heroi repository agent chat shipped (2026-08-30):** Heroi is now a focused
Workbench chat surface: it filters persisted conversations to the active
repository and leaves Files, git changes, diffs, and other tools to composable
Expand Down
11 changes: 10 additions & 1 deletion TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1474,13 +1474,18 @@ community plugins, performance and platform certification from Git feature gaps.
permission broker, quotas, diagnostics, and isolated execution boundary;
do not load third-party code into Strand's privileged webview.
(manifest validation, capability broker, bundled marketplace, Heroi
builtin plugin, `docs/plugin-creation.md` — 2026-08-29; quotas,
builtin plugin, `docs/plugin-creation.md` — 2026-08-29; Agent Session Recap
and `docs/plugin-marketplace-backlog.md` — 2026-10-01; quotas,
remote install, and isolated custom UI remain open.)
- ☑ Bundled plugin marketplace in Settings → Plugins with user-level install
persistence (`plugins.installed`, `ui/src/plugins/marketplace.ts`).
- ☑ Repository-scoped Quick Notes plugin with debounced persistence in
Strand's app database; removed the Repo Status sample plugin
(`QuickNotesView`, `quick-notes:<repo-path>` — 2026-08-30).
- ☑ Agent Session Recap plugin (`daniels.session-recap`, `AgentSessionRecapView`,
`buildAgentSessionRecap`) — bundled builtin summarizing files touched, risky
paths, and TODOs in the active worktree next to Review; empty/unavailable
without repo or changes (`docs/plugin-marketplace-backlog.md` — DAN-77).
- ☑ Heroi Workbench surface (`daniels.heroi.workspace`, `HeroiView`,
`heroi_agent_send`, `heroi_provider_models` — active-repository-only chat
with streaming, resumable, cancellable Claude/Codex/Cursor Agent sessions;
Expand All @@ -1500,6 +1505,10 @@ community plugins, performance and platform certification from Git feature gaps.
Claude Fable 5.1 (`claude-fable-5-1`) plus GPT-6 Astra (`gpt-6-astra`)
(`heroi.rs`, `heroi/models.rs`, `HeroiView`, `attachments.ts` — DAN-70).
- ☑ Plugin-creation guide for AI/manifest authors (`docs/plugin-creation.md`).
- ☐ Risk Radar plugin after a declarative `list`/`badge` view (or tree-row
slot) exists; do not invent those types in Recap (`docs/plugin-marketplace-backlog.md`).
- ☐ Remote plugin marketplace / signed index only after isolation is proven,
in the order recorded in `docs/plugin-marketplace-backlog.md`.
- ☐ Run native workspace-scoped Workbench persistence and live-terminal continuity E2E on
macOS, Windows, and Linux builds (browser QA covers layout, focus, resizing,
module moves, and overflow; native SQLite/PTYS require packaged app passes).
Expand Down
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ Project documentation.
- [`git-client-feature-audit-2026-09-06.md`](./git-client-feature-audit-2026-09-06.md)
— current code-backed list of 19 missing/partial Git-client feature families,
priorities, workarounds, and completion criteria.
- [`plugin-marketplace-backlog.md`](./plugin-marketplace-backlog.md) — Tier 1–4
plugin ideas vs today's declarative model; remote marketplace is deferred.
- [`learnings.md`](./learnings.md) — durable rules learned while building
Strand. Read before touching the UI; append when you discover something
future work has to respect.
- [`plugin-creation.md`](./plugin-creation.md) — how to author a declarative plugin.
- [`pull-request-improvements.md`](./pull-request-improvements.md) — competitive
research and the prioritized UX/UI proposal for the hosted PR workspace.
- [`release-checklist.md`](./release-checklist.md) — fail-closed 1.0 automated,
Expand Down
19 changes: 19 additions & 0 deletions docs/learnings.md
Original file line number Diff line number Diff line change
Expand Up @@ -2979,3 +2979,22 @@ membership; cached libgit2 indexes can survive external Git writes. Preserve
sparse expansion through its existing reader. git2 0.19 `Index::get_path`
already normalizes Windows separators through `path_to_repo_path`; do not add
lossy string conversion to fix a raw-libgit2 issue the Rust binding handles.

## Agent Session Recap is a Strand builtin, not static markdown (2026-10-01)

**Rule.** Community plugins stay data-only (`markdown` / `status`,
`repository.read` / `ai.invoke`). Live worktree, review-baseline, and loaded
diff context cannot be expressed as static declarative content, so Agent
Session Recap ships as `daniels.session-recap` with `render.kind = "builtin"`,
the same reservation used by Heroi and Quick Notes. It may read the active
repository store and a bounded local/review diff retainer while visible. It
must not add `list`/`badge` view types, enable `network.fetch`, duplicate
Review's diff viewer, or become a background whole-tree patch loader. Empty
and no-repository states are required. Remote marketplace stays deferred
(`docs/plugin-marketplace-backlog.md`).

**Why.** Claude research mapped Recap onto today's primitives, but the
manifest views are snapshots. Pretending a static markdown surface can follow
an agent worktree would either lie about the API or pollute the privileged
webview with third-party JS.

16 changes: 9 additions & 7 deletions docs/plugin-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ the trust boundary this format implements.
- Namespaced surface contributions merged into the Workbench `SurfaceRegistry`
- Permission-checked capability broker (`repository.read`, `ai.invoke`, `network.fetch`)
- Declarative surfaces rendered by Strand (`markdown`, `status`)
- One built-in dogfood plugin: **Heroi** (`daniels.heroi`) — Strand-hosted
repository-scoped coding-agent chat with native, streaming Claude, Codex,
and Cursor Agent sessions. Files, diffs, git changes, and other tooling stay
in their own Workbench surfaces.
- Strand-maintained builtins: **Heroi** (`daniels.heroi`) for repository-scoped
coding-agent chat, **Agent Session Recap** (`daniels.session-recap`) for a
files/risky/TODO summary of the active worktree next to Review, and
**Quick Notes** (`example.quick-notes`).

Community plugins cannot load arbitrary React, touch Zustand, call Tauri directly,
or access the DOM. Those capabilities require future isolated runtimes.
Expand Down Expand Up @@ -107,9 +107,10 @@ Strand renders both view types with first-party components and theme tokens.

### Built-in renderers (Strand-maintained only)

Only Strand may ship `render.kind = "builtin"`. Today the allowed module is
`daniels.heroi.workspace` for the Heroi dogfood plugin. Third-party manifests
that declare `builtin` are rejected at validation time.
Only Strand may ship `render.kind = "builtin"`. Today the allowed modules are
`daniels.heroi.workspace`, `daniels.session-recap.workspace`, and
`strand-tools.quick-notes.workspace`. Third-party manifests that declare
`builtin` are rejected at validation time.

## Validation checklist

Expand Down Expand Up @@ -178,6 +179,7 @@ pnpm --filter ./ui test
| `ui/src/plugins/marketplace.ts` | Bundled catalog |
| `ui/src/plugins/renderSurface.tsx` | Declarative + builtin render routing |
| `ui/src/plugins/builtins/heroi/` | Heroi dogfood plugin |
| `ui/src/plugins/builtins/agentSessionRecap/` | Agent Session Recap dogfood plugin |
| `ui/src/workbench/SurfaceHost.tsx` | Host lifecycle contract |

## Non-goals (this phase)
Expand Down
106 changes: 106 additions & 0 deletions docs/plugin-marketplace-backlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Plugin marketplace backlog

**Status:** Design note for DAN-77. Grounded in `docs/plugin-creation.md` and
`docs/extensibility-architecture.md`. Does not ship new permissions, view
types, or a remote catalog.

**Today's model.** Community and bundled plugins are data-only. Strand
validates a manifest (`apiVersion: "1"`), registers namespaced Workbench
surfaces, and renders them itself. Third-party JavaScript does not run in the
privileged webview. The capability broker exposes three named permissions:

| Permission | Ships today |
| --- | --- |
| `repository.read` | Read-only snapshot: path, name, branch, HEAD, dirty flag. |
| `ai.invoke` | Existing provider CLI orchestration (`repoSuggestCommitMessage`). |
| `network.fetch` | Reserved; the broker does not enable it. |

Declarative view types are `markdown` and `status`. `render.kind = "builtin"`
is reserved for Strand-maintained modules (Heroi, Quick Notes, Agent Session
Recap). Remote downloads, arbitrary React, and direct Tauri invoke remain
non-goals until isolation is proven.

Static `markdown` / `status` content cannot follow the active worktree, review
baseline, or loaded diffs. Anything that must read that context is a
Strand-hosted builtin that still requests only real permissions and degrades
to an empty state when context is missing.

## Suggested marketplace order (deferred)

Do not start a remote catalog in this phase. Architecture already lists
marketplace, signed indexes, and monetization as non-goals before local
permission and isolation hold. When that work is justified, suggested order:

1. **JSON Schema + "load unpacked"** — author against the existing manifest
schema; install from a local folder for dogfood.
2. **Registry CI** — validate manifests in Strand's repo (what the bundled
catalog already does at install time).
3. **Signed index** — hashed, signed catalog; no unsigned remote execute.
4. **Re-consent / revocation** — changing permissions re-prompts; revoke
without plugin cooperation (broker already fails closed).
5. **Site / deep links** — install URLs after signing and consent exist.
6. **Non-verified publishers** — last, and only behind isolation plus
explicit user consent.

Until an isolated runtime exists, Settings → Plugins stays a bundled
in-app list (`ui/src/plugins/marketplace.ts`).

## Tier 1 — fits today's primitives

Ideas that can ship with `markdown` / `status` and `repository.read` /
`ai.invoke`, or as a Strand-maintained builtin that uses those same
permissions and existing repo/review state.

| Idea | Today's model | Notes |
| --- | --- | --- |
| **Agent Session Recap** | Builtin (`daniels.session-recap`) | First dogfood for this note. Summarizes files touched, risky paths, and TODOs in loaded patches. `repository.read` only. Sits next to Review; does not grow a diff viewer. |
| Quick Notes | Builtin (`example.quick-notes`) | Already shipped. Scratchpad keyed by repository path. |
| Heroi | Builtin (`daniels.heroi`) | Already shipped. Chat only; Files/Review stay separate panes. |
| Static markdown checklists | Declarative `markdown` | No permissions. Fine for pinned runbooks. |
| Repo snapshot card | Declarative `status` | Branch/HEAD/dirty labels. The old Repo Status sample was removed; do not revive it unless it earns a pane. |
| AI one-liner of uncommitted work | `ai.invoke` | Already first-party via commit-message suggestion. Not a plugin. |

**Claude's other Tier-1 pick, Risk Radar,** is not shippable on today's
views. A useful radar wants a `list` / `badge` contribution (or tree-row
slots). That is a new surface type. Out of scope here.

## Tier 2 — needs slots or new view types

Typed Workbench slots (header actions, tree badges, context menus, detail
panels, status items) are designed in the architecture doc and are not
implemented. Do not pretend they shipped.

| Idea | Gap |
| --- | --- |
| Risk Radar | New declarative `list` / `badge` view, or tree-row badges. |
| Ownership / CODEOWNERS badges | Tree-row slot + a read of CODEOWNERS (new capability or first-party). |
| Review-queue decorations | Slot inside `strand.review.workspace`, not a third-party React tree. |
| Header actions on Files / Review | Header/toolbar slot. |

## Tier 3 — needs `network.fetch` and/or isolated UI

`network.fetch` is named in the manifest and thrown as missing by the
broker. Enabling it is a separate trust-boundary project.

| Idea | Gap |
| --- | --- |
| CI status panels | Brokered network to GitHub/Azure/etc.; likely a `status`/`list` surface plus host auth that plugins must never see raw. |
| Extra hosted-PR widgets | Same network + slots inside Pull Requests. |
| Secret sniffer (remote rules) | Local heuristics can live in Recap's risky-path list; remote rule packs need fetch + quotas. |

## Tier 4 — needs isolation (webview or WASI)

Custom UI in the main webview is rejected. Isolated custom UI and backend
are architecture phases 7, not this ticket.

| Idea | Gap |
| --- | --- |
| Arbitrary React dashboards | Unprivileged webview + schema-validated RPC. |
| Community git helpers / WASM tools | Capability-limited WASI; no `dlopen` into Strand. |
| Remote marketplace client | Signing, consent, revocation, then isolation. |

## Follow-ups (not this PR)

- Risk Radar after a `list`/`badge` primitive exists.
- Enable `network.fetch` only with host allowlists and quotas.
- Remote marketplace only after isolation is proven, in the order above.
14 changes: 14 additions & 0 deletions ui/src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,20 @@ export const en = {
'plugins.heroi.imageType': 'Heroi can only attach PNG, JPEG, GIF, or WebP images.',
'plugins.heroi.imageSize': 'Each attached image must be 4 MiB or smaller.',
'plugins.heroi.imageReadFailed': 'Heroi could not read an attached image.',
'plugins.recap.title': 'Session Recap',
'plugins.recap.noRepository': 'No repository open',
'plugins.recap.noRepositoryHint': 'Open a repository or worktree to recap agent changes.',
'plugins.recap.empty': 'No agent session changes',
'plugins.recap.emptyHint': 'This worktree is clean. Pin a Review baseline or let an agent edit files, then return here.',
'plugins.recap.worktree': 'Worktree',
'plugins.recap.since': 'Session since {short}',
'plugins.recap.uncommitted': 'Uncommitted',
'plugins.recap.files': 'Files touched ({count})',
'plugins.recap.risky': 'Risky areas',
'plugins.recap.riskyEmpty': 'No auth, secret, or migration paths in this session.',
'plugins.recap.todos': 'TODOs left behind',
'plugins.recap.todosEmpty': 'No TODO, FIXME, HACK, or XXX markers in loaded patches.',
'plugins.recap.todosUnavailable': 'Patches are not loaded yet, so leftover TODOs cannot be scanned.',
'files.createEntry': 'New file or folder',
'files.newFile': 'New file',
'files.newFolder': 'New folder',
Expand Down
Loading
Loading