Skip to content

feat: add the execution-history plugin - #13

Merged
aryasaatvik merged 5 commits into
devfrom
feat/history-plugin
Jun 13, 2026
Merged

aryasaatvik merged 5 commits into
devfrom
feat/history-plugin

Conversation

@aryasaatvik

@aryasaatvik aryasaatvik commented Jun 13, 2026 •

Copy link
Copy Markdown
Owner

Adds @executor-js/plugin-execution-history — an opt-in execution-history sink built on the observer foundation.

  • Records every run (plus its tool calls and interactions) into three owner-scoped pluginStorage collections via a buffered-batch writer — no new tables, no migrations; works on D1/libSQL/sqlite/postgres.
  • ./api: a scoped read API (list/get/listToolCalls) over HttpApi (executionHistoryHttpPlugin).
  • ./client: a Runs page at /plugins/executionHistory/ (table, status filter, pagination, 4-tab detail drawer) — mounts via the existing plugins catch-all with zero router changes.

The base . entry never loads the API or React layers. Fully opt-in (not registered in any default config).

Stacked on the execution-observer foundation. Gates: format:check, lint, full-monorepo typecheck, unit + handler tests green. Runs-page live render still to verify.

Stack

  1. feat: add the execution-observer foundation #12
  2. feat: add the execution-history plugin #13 👈 current
  3. feat: add the execution-metrics plugin #14

@aryasaatvik
aryasaatvik marked this pull request as ready for review June 13, 2026 19:06
@greptile-apps

greptile-apps Bot commented Jun 13, 2026 •

Copy link
Copy Markdown

Greptile Summary

Adds @executor-js/plugin-execution-history — an opt-in, observer-backed sink that records every execution run, tool call, and interaction into three owner-scoped pluginStorage collections with a buffered-batch write model, along with a scoped HTTP read API and a React Runs page.

  • SDK (./src/sdk): makeExecutionHistoryStore buffers per-execution data in memory until ExecutionFinished flushes it to storage in one batch; two eager writes (running, waiting_for_interaction) provide restart durability. All previous review issues (buffer leak on StorageFailure, ExecutionFinished fallthrough, unsafe statusFilter cast, empty-page pagination label, compact prettyJson) are resolved.
  • API (./src/api): Three read endpoints (list, get, listToolCalls) over HttpApiGroup; statusFilter is validated against RunStatus literals via Schema.is before reaching the storage facade.
  • React (./src/react): Runs page with status filter, pagination, and a 4-tab detail drawer; mounts via the plugin catch-all route with no router changes needed.

Confidence Score: 5/5

Safe to merge — all blocking issues from the prior review round are addressed and no new defects were found in the changed code.

The buffer-cleanup guarantee, the ExecutionFinished fallthrough fix, the RunStatus validation, and the pagination display fix are all correctly implemented. The two remaining findings are both non-blocking suggestions (interaction kind defensive guard and a spurious "none" atom fetch on initial render).

No files require special attention — the core write path in store.ts and the HTTP handler wiring are solid.

Important Files Changed

Filename Overview
packages/plugins/execution-history/src/sdk/store.ts Buffered-batch writer + read surface; all previously flagged issues (buffer leak, ExecutionFinished fallthrough) are now resolved via Effect.ensuring and an explicit tag guard
packages/plugins/execution-history/src/sdk/collections.ts Effect Schema definitions for RunRow/ToolCallRow/InteractionRow with indexed collections; looks correct
packages/plugins/execution-history/src/api/handlers.ts HTTP handlers for list/get/listToolCalls; statusFilter now correctly filtered through Schema.is(RunStatus) guard, resolving the previous unsafe cast
packages/plugins/execution-history/src/react/RunsPage.tsx Runs table with status filter, pagination, and detail drawer; prettyJson and empty-page pagination bugs from prior review are fixed; one minor sentinel atom call on initial render
packages/plugins/execution-history/src/api/handlers.test.ts Handler integration tests covering CSV param mapping, no-filter case, get with null, and listToolCalls; well structured
packages/plugins/execution-history/src/sdk/store.test.ts End-to-end store test through a real sqlite backend; covers started→tool call→finished lifecycle and verifies run/toolCall/interaction queries
packages/plugins/execution-history/src/react/atoms.ts Atom family definitions for runs list, run detail, and tool calls; the "runDetailAtom" key of "none" passed from DetailDrawer may trigger a spurious network request on initial render
packages/plugins/execution-history/src/sdk/plugin.ts Plugin definition wiring storage, extension, and observer together; straightforward and correct

Sequence Diagram

sequenceDiagram
    participant Engine as Execution Engine
    participant Observer as ExecutionObserver
    participant Store as ExecutionHistoryStore
    participant Buffer as RunBuffer (in-memory)
    participant Storage as PluginStorage (D1/sqlite)
    participant API as HTTP API
    participant UI as Runs Page (React)

    Engine->>Observer: ExecutionStarted
    Observer->>Store: handleEvent
    Store->>Buffer: buffers.set(executionId, ...)
    Store->>Storage: runsC.put(status: running)

    Engine->>Observer: ToolCallStarted / ToolCallFinished
    Observer->>Store: handleEvent
    Store->>Buffer: buffer.toolCalls.set(...)

    Engine->>Observer: InteractionStarted
    Observer->>Store: handleEvent
    Store->>Buffer: buffer.interactions.set(...)
    Store->>Storage: runsC.put(status: waiting_for_interaction)

    Engine->>Observer: InteractionResolved
    Observer->>Store: handleEvent
    Store->>Buffer: buffer.interactions.set(...updated)

    Engine->>Observer: ExecutionFinished
    Observer->>Store: handleEvent
    Store->>Storage: "runsC.put(terminal) + toolCallsC.put* + interactionsC.put*"
    Store->>Buffer: buffers.delete(executionId) via Effect.ensuring

    UI->>API: GET /execution-history/runs
    API->>Storage: runsC.query + runsC.count
    API-->>UI: runs + total

    UI->>API: GET /execution-history/runs/:id
    API->>Storage: runsC.get + toolCallsC.query + interactionsC.query
    API-->>UI: RunDetailResponse
Loading

Fix All in Codex Fix All in Cursor Cloud Agents Fix All in Claude Code Fix All in Cursor

Reviews (4): Last reviewed commit: "fix(plugin-execution-history): address G..." | Re-trigger Greptile

@aryasaatvik
aryasaatvik force-pushed the feat/observer-foundation branch from 08a80c1 to 11d40f4 Compare June 13, 2026 19:32
@aryasaatvik
aryasaatvik force-pushed the feat/history-plugin branch from 915777b to 2484437 Compare June 13, 2026 19:32
aryasaatvik added a commit that referenced this pull request Jun 13, 2026
- Buffer leak: wrap the ExecutionFinished flush in Effect.ensuring so the
  RunBuffer is always released, even when a write fails or is interrupted.
- Exhaustive dispatch: route ExecutionFinished by an explicit tag guard instead
  of a fallthrough, so a future ExecutionEvent variant isn't silently recorded
  as a finished run.
- statusFilter: keep only valid RunStatus literals (Schema.is) rather than
  casting, so ?status=bogus can't reach the storage where-clause.
- Runs page: fix the 'showing 1-0' label on an empty page; make prettyJson
  actually indent (decode via Schema, re-stringify with two-space indent — only
  JSON.parse is lint-banned).
@aryasaatvik
aryasaatvik force-pushed the feat/history-plugin branch from 2484437 to 1e981af Compare June 13, 2026 20:33
@aryasaatvik
aryasaatvik changed the base branch from feat/observer-foundation to dev June 13, 2026 20:50
aryasaatvik added a commit that referenced this pull request Jun 13, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->
### [Stack](https://github.com/kitlangton/stack)

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
…nd observer

New opt-in @executor-js/plugin-execution-history package. It contributes no
tools — only a pure execution-history sink built on the existing pluginStorage
collection facade (no new tables, no migrations; works on D1/libSQL/sqlite/
postgres uniformly, owner-scoped automatically).

Three indexed collections (runs, toolCalls, interactions) back the history. The
store consumes the engine's ExecutionEvent stream via runtime.executionObserver
with a buffered-batch write model: the run row is written eagerly on start and
on pause (durable while waiting), tool-call/interaction detail is buffered in
memory and flushed as one batch on ExecutionFinished — keeping per-run writes
to ~2 + one batch (important for D1's subrequest budget). The read surface
(executor.executionHistory.list/get/listToolCalls) pushes filters, ordering and
pagination down to SQL via the indexed query facade. code + trigger are retained
across the run's re-writes (with a fallback to the persisted row if the buffer
is lost).
Adds the ./api entry: an executionHistory HttpApiGroup (GET /execution-history/
runs with status/trigger/time/interaction/limit/offset/sort query params, plus
/runs/:executionId and /runs/:executionId/tool-calls), a handler layer that
reads the executor.executionHistory extension via an extensionService tag, and
executionHistoryHttpPlugin — the HTTP-augmented variant that layers routes/
handlers/extensionService onto the base plugin.

Follows the graphql/onepassword convention: the base SDK plugin (the '.' entry)
never loads @executor-js/api (held as a peer/dev dep); only hosts that compose
an HttpApi import the augmented plugin from /api. Routes are flat and plugin-
prefixed (no :scopeId) because the per-request executor is already owner-scoped.
Adds the ./react + ./client entries: an atom HTTP client over the
executionHistory API group, atoms for the runs list/detail/tool-calls, a
RunsPage (runs table with status/trigger/started/duration/tool-count columns,
a status filter, offset pagination, and a 4-section detail drawer — Properties,
Tool calls, Logs, Interaction), and a defineClientPlugin that registers it at
/plugins/executionHistory/ with a 'Runs' nav entry. Mounts through the existing
/plugins/$pluginId/$ catch-all with zero router changes.

Built on the existing @executor-js/react shadcn-style primitives (Table, Sheet,
Tabs, Badge, Select) — no new design system or charting dep. The branch's
keyboard-nav, live auto-refresh, and command-palette filter are deferred. React
deps are peer/optional, mirroring the graphql plugin.
- Buffer leak: wrap the ExecutionFinished flush in Effect.ensuring so the
  RunBuffer is always released, even when a write fails or is interrupted.
- Exhaustive dispatch: route ExecutionFinished by an explicit tag guard instead
  of a fallthrough, so a future ExecutionEvent variant isn't silently recorded
  as a finished run.
- statusFilter: keep only valid RunStatus literals (Schema.is) rather than
  casting, so ?status=bogus can't reach the storage where-clause.
- Runs page: fix the 'showing 1-0' label on an empty page; make prettyJson
  actually indent (decode via Schema, re-stringify with two-space indent — only
  JSON.parse is lint-banned).
@aryasaatvik
aryasaatvik force-pushed the feat/history-plugin branch from 1e981af to a06c2d6 Compare June 13, 2026 20:50
@aryasaatvik
aryasaatvik merged commit f0cf727 into dev Jun 13, 2026
7 of 12 checks passed
aryasaatvik added a commit that referenced this pull request Jun 13, 2026
Adds **`@executor-js/plugin-execution-metrics`** — an opt-in metrics
sink built on the observer foundation.

- Base plugin drives Effect Metric counters + an execution-duration
histogram from the event stream.
- `./api`: an auth-gated `GET /execution-metrics/metrics` Prometheus
scrape (`executionMetricsHttpPlugin`).
- `./cloudflare`: a Workers Analytics Engine sink (`writeDataPoint`) —
per-isolate Effect metrics being meaningless on a Worker fleet. Wired
opt-in on host-cloudflare, gated on the `ANALYTICS` binding.

Base `.` entry free of `@executor-js/api` and
`@cloudflare/workers-types`.

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, and metrics-render tests green (an
adversarial-verify pass caught + fixed a Prometheus histogram-bucket
bug).

<!-- stack:links:start -->
### [Stack](https://github.com/kitlangton/stack)

1. #12
2. #13
3. **#14** 👈 current
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->
### [Stack](https://github.com/kitlangton/stack)

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds **`@executor-js/plugin-execution-metrics`** — an opt-in metrics
sink built on the observer foundation.

- Base plugin drives Effect Metric counters + an execution-duration
histogram from the event stream.
- `./api`: an auth-gated `GET /execution-metrics/metrics` Prometheus
scrape (`executionMetricsHttpPlugin`).
- `./cloudflare`: a Workers Analytics Engine sink (`writeDataPoint`) —
per-isolate Effect metrics being meaningless on a Worker fleet. Wired
opt-in on host-cloudflare, gated on the `ANALYTICS` binding.

Base `.` entry free of `@executor-js/api` and
`@cloudflare/workers-types`.

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, and metrics-render tests green (an
adversarial-verify pass caught + fixed a Prometheus histogram-bucket
bug).

<!-- stack:links:start -->

1. #12
2. #13
3. **#14** 👈 current
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->
### [Stack](https://github.com/kitlangton/stack)

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
Adds **`@executor-js/plugin-execution-metrics`** — an opt-in metrics
sink built on the observer foundation.

- Base plugin drives Effect Metric counters + an execution-duration
histogram from the event stream.
- `./api`: an auth-gated `GET /execution-metrics/metrics` Prometheus
scrape (`executionMetricsHttpPlugin`).
- `./cloudflare`: a Workers Analytics Engine sink (`writeDataPoint`) —
per-isolate Effect metrics being meaningless on a Worker fleet. Wired
opt-in on host-cloudflare, gated on the `ANALYTICS` binding.

Base `.` entry free of `@executor-js/api` and
`@cloudflare/workers-types`.

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, and metrics-render tests green (an
adversarial-verify pass caught + fixed a Prometheus histogram-bucket
bug).

<!-- stack:links:start -->

1. #12
2. #13
3. **#14** 👈 current
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 18, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 18, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->
### [Stack](https://github.com/kitlangton/stack)

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 18, 2026
Adds **`@executor-js/plugin-execution-metrics`** — an opt-in metrics
sink built on the observer foundation.

- Base plugin drives Effect Metric counters + an execution-duration
histogram from the event stream.
- `./api`: an auth-gated `GET /execution-metrics/metrics` Prometheus
scrape (`executionMetricsHttpPlugin`).
- `./cloudflare`: a Workers Analytics Engine sink (`writeDataPoint`) —
per-isolate Effect metrics being meaningless on a Worker fleet. Wired
opt-in on host-cloudflare, gated on the `ANALYTICS` binding.

Base `.` entry free of `@executor-js/api` and
`@cloudflare/workers-types`.

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, and metrics-render tests green (an
adversarial-verify pass caught + fixed a Prometheus histogram-bucket
bug).

<!-- stack:links:start -->

1. #12
2. #13
3. **#14** 👈 current
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 23, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 23, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 27, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 27, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 28, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 28, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 29, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 29, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 31, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Aug 31, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Sep 13, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Sep 13, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Sep 18, 2026
Adds the **execution-observer foundation** — the seam the history and
metrics plugins build on.

- New `ExecutionObserver` contract in the SDK: six tagged lifecycle
events (`ExecutionStarted`/`Finished`, `ToolCallStarted`/`Finished`,
`InteractionStarted`/`Resolved`) + `composeExecutionObservers`, with a
`plugin.runtime.executionObserver` hook.
- The execution engine emits the events (re-derived onto the current
Queue-based pause model), exposes `Executor.owner`, and tags the run
span with the execution id + trigger.
- `makeExecutionStack` composes plugin observers — one seam covers every
HTTP host and the MCP Durable Objects; local's fixed-execution +
in-process MCP are wired directly.

**Behaviour-neutral / opt-in:** with no plugin observing, every path is
a no-op.

Gates: `format:check`, `lint`, full-monorepo `typecheck`, and observer
unit tests all green. Live app verification still to come.

<!-- stack:links:start -->

1. **#12** 👈 current
2. #13
3. #14
<!-- stack:links:end -->
aryasaatvik added a commit that referenced this pull request Sep 18, 2026
Adds **`@executor-js/plugin-execution-history`** — an opt-in
execution-history sink built on the observer foundation.

- Records every run (plus its tool calls and interactions) into three
owner-scoped `pluginStorage` collections via a buffered-batch writer —
**no new tables, no migrations**; works on D1/libSQL/sqlite/postgres.
- `./api`: a scoped read API (`list`/`get`/`listToolCalls`) over HttpApi
(`executionHistoryHttpPlugin`).
- `./client`: a Runs page at `/plugins/executionHistory/` (table, status
filter, pagination, 4-tab detail drawer) — mounts via the existing
plugins catch-all with zero router changes.

The base `.` entry never loads the API or React layers. Fully opt-in
(not registered in any default config).

Stacked on the execution-observer foundation. Gates: `format:check`,
`lint`, full-monorepo `typecheck`, unit + handler tests green. Runs-page
live render still to verify.

<!-- stack:links:start -->

1. #12
2. **#13** 👈 current
3. #14
<!-- stack:links:end -->
Sign up for free to 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.

1 participant