Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8a676d8
feat(code-mode): add session contract scaffolding
ian-pascoe Jun 17, 2026
3888c84
feat(core): add reusable Code Mode QuickJS sessions
ian-pascoe Jun 17, 2026
668872b
feat(core): route Code Mode through managed sessions
ian-pascoe Jun 18, 2026
c7aa991
feat(code-mode): add session recovery journal
ian-pascoe Jun 18, 2026
a0270b0
docs(code-mode): document session reuse contract
ian-pascoe Jun 18, 2026
a734245
test(benchmarks): add repeated workflow Code Mode eval
ian-pascoe Jun 18, 2026
cd41030
chore(code-mode): harden session release contract
ian-pascoe Jun 18, 2026
cf96c64
fix(code-mode): harden stale session recovery
ian-pascoe Jun 18, 2026
062dcc4
docs(agents): strategy and plan docs
ian-pascoe Jun 18, 2026
3f66b34
test(code-mode): cover inferred session var diagnostics
ian-pascoe Jun 18, 2026
ff42acd
fix(code-mode): infer reused var diagnostics types
ian-pascoe Jun 18, 2026
a5292a3
test(code-mode): harden inferred var diagnostics
ian-pascoe Jun 18, 2026
8f6bb6b
fix(code-mode): validate persisted var diagnostic types
ian-pascoe Jun 18, 2026
0720f12
docs: update session reuse guidance
ian-pascoe Jun 18, 2026
897b5e6
chore: ce config
ian-pascoe Jun 18, 2026
b95daae
fix(pi): expose Code Mode run metadata
ian-pascoe Jun 18, 2026
ecb8de5
test(opencode): cover Code Mode run metadata
ian-pascoe Jun 18, 2026
e28e103
fix(opencode): omit blank Code Mode session ids
ian-pascoe Jun 18, 2026
c798edd
fix(opencode): make Code Mode reuse opt-in
ian-pascoe Jun 18, 2026
1013a92
fix(opencode): keep session id top-level
ian-pascoe Jun 18, 2026
f2b73c0
fix(native): separate remote attach configuration
ian-pascoe Jun 18, 2026
2ce5e9c
fix(code-mode): address repl session review feedback
ian-pascoe Jun 18, 2026
9eed48a
fix(code-mode): resolve remaining repl review threads
ian-pascoe Jun 18, 2026
a34e856
fix(code-mode): preserve session return cleanup
ian-pascoe Jun 18, 2026
ea36892
fix(pi): reject malformed legacy remote settings
ian-pascoe Jun 18, 2026
5e4dc36
fix(docs): use caplets favicon
ian-pascoe Jun 18, 2026
c1ef5d2
refactor: remove `recoveryCommand` from returned meta
ian-pascoe Jun 18, 2026
35d0fc4
fix(code-mode): address remaining session review feedback
ian-pascoe Jun 18, 2026
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
14 changes: 14 additions & 0 deletions .changeset/code-mode-repl-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@caplets/core": minor
"@caplets/opencode": patch
"@caplets/pi": patch
"caplets": patch
---

Expand the Code Mode tool contract with optional `sessionId` reuse, `meta.sessionId` run metadata, and recovery history lookup through `recoveryRef`.

Sessions are live reuse affordances for iterative Code Mode runs; this does not provide durable heap persistence across host restarts.

OpenCode now accepts the optional `sessionId` argument on Code Mode tools so agents can reuse live sessions there too.

Native integrations and remote CLI control now use `CAPLETS_REMOTE_*` exclusively for attach/client behavior. `CAPLETS_SERVER_*` remains reserved for serving/self-hosting configuration.
49 changes: 49 additions & 0 deletions .compound-engineering/config.local.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Compound Engineering -- local config
# Copy to .compound-engineering/config.local.yaml in your project root.
# All settings are optional. Invalid values fall through to defaults.

# --- Work delegation (Codex) ---

# work_delegate: codex # codex | false (default: false)
# work_delegate_consent: true # true | false (default: false)
# work_delegate_sandbox: yolo # yolo | full-auto (default: yolo)
# work_delegate_decision: auto # auto | ask (default: auto)
# work_delegate_model: gpt-5.4 # any valid codex model (omit to use ~/.codex/config.toml default)
# work_delegate_effort: high # minimal | low | medium | high | xhigh (omit to use ~/.codex/config.toml default)

# --- Product pulse ---
# Settings written by /ce-product-pulse first-run interview. Re-run the skill with
# argument `setup` or `reconfigure` to edit interactively.

# pulse_product_name: "Spiral" # used in report titles (no default)
# pulse_lookback_default: 24h # 1h | 24h | 7d | 30d (default: 24h)
# pulse_primary_event: "session_started" # the event that means "user showed up"
# pulse_value_event: "task_completed" # the event that means "user got value"
# pulse_completion_events: "onboarded,first_purchase" # comma-separated, 0-3 events
# pulse_quality_scoring: false # true | false (default: false; AI products only)
# pulse_quality_dimension: "answer accuracy" # dimension scored 1-5 when pulse_quality_scoring is true
# pulse_analytics_source: posthog # posthog | mixpanel | custom (no default)
# pulse_tracing_source: sentry # sentry | datadog | custom (no default)
# pulse_payments_source: stripe # stripe | custom (no default)
# pulse_db_enabled: false # true | false (default: false; read-only DB if true)
# pulse_metric_sources: "retention_d7=posthog,nps=delighted" # strategy-metric -> source overrides; comma-separated 'metric=source' pairs; unlisted metrics fall back to pulse_analytics_source
# pulse_pending_metrics: "retention_d7,nps" # comma-separated strategy metrics awaiting instrumentation; render as 'no data'
# pulse_excluded_metrics: "north_star" # comma-separated strategy metrics intentionally not in pulse

# --- Output format ---
# Per-skill output format default. Selects the exclusive format the artifact
# is written in: `md` produces a markdown file, `html` produces a single
# self-contained HTML file. The two are mutually exclusive -- there is no
# sibling artifact. See DESIGN.md or your agent instructions to influence
# HTML styling. CLI arguments override these defaults; pipeline contexts
# (e.g., LFG, disable-model-invocation) always force `md` regardless.

# plan_output: html # md | html (default: md)
# brainstorm_output: html # md | html (default: md)
# ideate_output: md # md | html (default: html -- ideation docs are human-facing, so HTML is the default; set md to opt out)

# --- ce-promote ---
# Written automatically when you decline the Spiral setup offer in /ce-promote.
# Suppresses that one-time setup nudge in this project. Remove the key to re-enable.

# ce_promote_spiral_optout: true # true | (absent) (default: absent -- offer once)
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ benchmark-results/

# autoresearch
.auto/

# Compound Engineering local config
.compound-engineering/*.local.yaml
27 changes: 17 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Commands

- Use `pnpm` only; the repo pins `pnpm@11.5.0` and requires Node `>=24`.
- Use `pnpm` only; the repo pins `pnpm@11.7.0` and requires Node `>=22`.
- Install with `pnpm install --frozen-lockfile` when matching CI.
- Full local gate and pre-push hook: `pnpm verify` (`format:check -> lint -> code-mode:check-api -> typecheck -> schema:check -> test -> benchmark:check -> build`).
- Full local gate and pre-push hook: `pnpm verify` (`format:check -> lint -> code-mode:check-api -> schema:check -> docs:check -> typecheck -> test -> benchmark:check -> build`).
- Fast focused checks: `pnpm format:check`, `pnpm lint`, `pnpm typecheck`, `pnpm test`, `pnpm build`.
- Run one package: `pnpm --filter @caplets/core test`, `pnpm --filter caplets build`, or replace the filter with `@caplets/opencode`, `@caplets/pi`, `@caplets/benchmarks`.
- Run one Vitest file by passing it after the package script, e.g. `pnpm --filter @caplets/core test -- test/config.test.ts`.
Expand All @@ -17,13 +17,20 @@
- `packages/opencode` and `packages/pi` are native agent integrations that wrap `@caplets/core/native`; keep integration-specific schema/adapter code there.
- `packages/benchmarks` owns deterministic and opt-in live coding-agent benchmarks; deterministic benchmark docs are generated from `pnpm benchmark`.

## Generated And Checked Files
## Agent skills

- Source code is the source of truth. Keep long-lived product docs in `docs/product/`, architecture docs in `docs/`, and ADRs in `docs/adr/`. Avoid committing short-lived implementation plans or design specs unless explicitly requested; if they are needed, put them in `docs/plans/` or `docs/specs/` and delete or repurpose them once they are superseded. Do not use `docs/superpowers/` in this repo.
- Config schema source of truth is Zod in `packages/core/src/config.ts`; update `schemas/caplets-config.schema.json` with `pnpm schema:generate` and verify with `pnpm schema:check`.
- Code Mode runtime API declaration source of truth is `packages/core/src/code-mode/runtime-api.d.ts`; update `packages/core/src/code-mode/runtime-api.generated.ts` with `pnpm code-mode:generate-api` and verify with `pnpm code-mode:check-api`.
- `pnpm benchmark` updates `docs/benchmarks/coding-agent.md`; `pnpm benchmark:check` fails if the committed report is stale.
- Live benchmarks are opt-in only: build first, then run `CAPLETS_BENCH_LIVE=1 pnpm benchmark:live:opencode` or `CAPLETS_BENCH_LIVE=1 pnpm benchmark:live:pi`; results are local/model-dependent and not deterministic product claims.
- Issues and PRDs live in GitHub Issues for `spiritledsoftware/caplets`; use `gh` with `--repo spiritledsoftware/caplets`. Details: `docs/agents/issue-tracker.md`.
- Triage labels are documented in `docs/agents/triage-labels.md`; current live labels include `question` for `needs-info` and `wontfix` for `wontfix`.
- This is a single-context repo. Start with `CONTEXT.md`, relevant ADRs in `docs/adr/`, and `docs/agents/domain.md`; use `STRATEGY.md`, `CONCEPTS.md`, and `docs/solutions/` when the task touches product direction, vocabulary, or documented patterns.

## Docs And Generated Files

- Source code is authoritative. Keep durable product docs in `docs/product/`, architecture docs in `docs/`, ADRs in `docs/adr/`, specs/plans in `docs/specs/` or `docs/plans/`, and solution patterns in `docs/solutions/`.
- Avoid committing short-lived plans unless explicitly requested. Do not use `docs/superpowers/` in this repo.
- Config schema source: `packages/core/src/config.ts`. Generate with `pnpm schema:generate`; check with `pnpm schema:check`.
- Code Mode API sources: `packages/core/src/code-mode/runtime-api.d.ts` and `packages/core/src/code-mode/platform-entry.ts`. Generate with `pnpm code-mode:generate-api`; check with `pnpm code-mode:check-api`.
- Benchmark report: `pnpm benchmark` updates `docs/benchmarks/coding-agent.md`; `pnpm benchmark:check` checks staleness.
- Live benchmarks are opt-in and local/model-dependent: build first, then run `CAPLETS_BENCH_LIVE=1 pnpm benchmark:live:opencode`, `CAPLETS_BENCH_LIVE=1 pnpm benchmark:live:pi`, or `CAPLETS_BENCH_LIVE=1 pnpm benchmark:live:pi-eval`.

## Config And Runtime Gotchas

Expand All @@ -34,7 +41,7 @@

## PR And Release Checks

- CI runs `pnpm verify` plus `pnpm changeset status --since=origin/main` on PRs unless the PR has the `no changeset` label.
- CI runs `pnpm verify` plus `pnpm changeset status --since=origin/main` on PRs unless the PR has the `[no changeset]` label.
- User-facing package changes usually need a changeset; current versioning is handled by Changesets and `pnpm version-packages`/`pnpm release`.
- Pre-commit only runs `pnpm lint-staged` (`oxfmt --check` and `oxlint` on staged JS/TS/config/docs files); pre-push runs the full `pnpm verify`.
- Core Alchemy deploys the public landing page only from `apps/landing`; it does not deploy Cloud Worker or dashboard paths.
- Alchemy deploy workflows are in `.github/workflows/deploy.yml` and `.github/workflows/pr-preview-deploy.yml`; check `alchemy.run.ts` and `infra/` before changing deploy behavior.
35 changes: 35 additions & 0 deletions CONCEPTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Concepts

Shared domain vocabulary for this project -- entities, named processes, and status concepts with project-specific meaning. Seeded with core domain vocabulary, then accretes as ce-compound and ce-compound-refresh process learnings; direct edits are fine. Glossary only, not a spec or catch-all.

## Code Mode

### Caplet

A configured capability surface that exposes a backend to agents through a stable handle, progressive wrapper tools, or direct tool operations.

### Code Mode

The Caplets execution surface where an agent runs a bounded TypeScript workflow against generated Caplet handles and receives compact structured output.

### Code Mode Session

A reusable live Code Mode execution context that lets adjacent calls share variables, functions, and cached setup while the runtime remains alive and compatible.

Code Mode Sessions are intentionally runtime state, not durable saved workflows. A caller starts a fresh session by omitting the previous session handle rather than resetting or replacing it in place.

### Recovery Journal

A retained, redacted record of Code Mode calls for a session, used to help reconstruct setup after the live Code Mode Session is no longer available.

Recovery Journals support auditability and reconstruction, but they do not restore heap state. They store bounded setup evidence and avoid treating persisted runtime identifiers as reusable credentials.

### Recovery Reference

A capability-style reference that authorizes reading a Recovery Journal.

Recovery References are separate from session handles. Possessing a session handle may identify a live Code Mode Session, but reading retained recovery history requires the recovery-specific reference or a known cleaned-up session that can be mapped back to the same retained journal.

### Progressive Exposure

The Caplets exposure mode where agents discover and call backend operations through a small set of wrapper tools instead of receiving every downstream operation as a separate top-level tool.
67 changes: 67 additions & 0 deletions STRATEGY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: Caplets
last_updated: 2026-06-17
---

# Caplets Strategy

## Target problem

Coding agents get slower, more expensive, and less reliable when real backend surfaces are exposed as flat tool lists: large MCP/API setups flood context with hundreds of operations, create duplicate generic names, and force repeated model/tool round trips for discovery, schema inspection, execution, and synthesis. The hard part is preserving exact backend power, auth state, schemas, resources, prompts, results, and errors across local, remote, Cloud, and native agent setups without making the agent reason over the whole tool wall up front.

## Our approach

Caplets wins by being a Code Mode-first capability layer for coding agents, not a general tool catalog. It turns heterogeneous backends into typed, scoped handles so agents can discover, inspect, execute, filter, and summarize with a small decision surface, while preserving exact backend semantics and keeping auth, direct I/O, and project-local context behind Caplet-controlled boundaries.

## Who it's for

**Primary:** Agent power-users/builders - They're hiring Caplets to turn sprawling MCP/API/CLI surfaces into typed capabilities their coding agents can inspect, call, filter, and synthesize without a giant tool wall.

## Key metrics

- **Initial tool surface compression** - Reduction in initially visible tools, serialized payload bytes, approximate context tokens, and duplicate top-level names versus direct flat MCP; measured by `pnpm benchmark:check`.
- **Code Mode workflow efficiency** - Reduction in model/tool round trips, external calls, and payload tokens while preserving required evidence fields; measured by deterministic Code Mode benchmark fixtures.
- **Live task parity at lower token cost** - Live eval pass rate must match baselines before claiming token efficiency, then compare request+output tokens and tool-surface tokens.
- **Release readiness** - Full verification, CI, changeset, release, and deploy paths pass for package-impacting work; measured through `pnpm verify` and GitHub workflows.
- **Runtime diagnosability and health** - Users and agents can verify server health, remote auth, Project Binding state, exposure readiness, and Code Mode health through finite diagnostics; measured through `caplets doctor`, `/v1/healthz`, and `caplets attach --once`.

## Tracks

### Capability backends and shared contracts

Expand and harden backend families, auth, schemas, media artifacts, and Caplet source handling so many tool ecosystems can enter Caplets as focused capability domains.

_Why it serves the approach:_ The product only works if heterogeneous MCP/API/CLI surfaces keep their fidelity while presenting as inspectable Caplets instead of a flat tool wall.

### Code Mode runtime and native agent surfaces

Make Code Mode the dependable default surface across MCP clients, OpenCode, and Pi, with typed handles, lean generated declarations, persistent workflow affordances, and practical non-I/O platform globals.

_Why it serves the approach:_ Code Mode is the mechanism that lets agents discover, call, filter, join, and summarize in one bounded workflow while keeping direct I/O and raw tool sprawl out of the prompt.

### Remote runtime and Project Binding

Make local, self-hosted remote, and Cloud-backed execution behave as one capability model, with attach, workspace routing, auth refresh, diagnostics, and safe project sync.

_Why it serves the approach:_ The same Caplet semantics need to survive where the work runs; remote and Cloud only help if project files, credentials, attach state, and recovery paths remain explicit and trustworthy.

### Public proof, docs, and release confidence

Keep public docs, generated references, landing proof, deterministic benchmarks, and repo verification aligned with implementation truth.

_Why it serves the approach:_ Caplets asks users to trust a smaller visible surface, so public claims need reproducible evidence and drift checks.

## Not working on

- Flattening every downstream tool into the initial tool list by default.
- Making progressive discovery the main product frame; it remains a supported mode.
- Requiring hosted Cloud for local usage.
- Exposing arbitrary shell access or direct Code Mode host/network access.
- Treating live benchmark runs as deterministic product claims.
- Returning binary or oversized media inline as blobs or base64.

## Marketing

**One-liner:** Give your agent capabilities, not giant tool walls.

**Key message:** Caplets turns MCP servers, APIs, and commands into focused capability handles for compact coding-agent workflows. The proof point is not just that Caplets connects to more backends; it is that agents can complete real multi-step backend work with a smaller decision surface, fewer round trips, and claims that are checked against reproducible benchmarks.
1 change: 1 addition & 0 deletions apps/docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default defineConfig({
integrations: [
starlight({
title: "Caplets Docs",
favicon: "/icon.png",
logo: {
src: "./src/assets/caplets-icon.png",
alt: "Caplets",
Expand Down
Binary file added apps/docs/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions apps/docs/src/content/docs/code-mode.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,46 @@ uses handles such as `caplets.osv.searchTools(...)` and `caplets.osv.callTool(..
For most tasks, keep bulky raw payloads inside the Code Mode script and return compact
JSON with the evidence the user needs.

## Reuse a live session

Code Mode accepts an optional `sessionId`. Omit it to create a fresh session. Successful
fresh runs and reused runs include `meta.sessionId`; pass that value to a nearby follow-up
call when you want to reuse helper functions, variables, or cached discovery results in the
same QuickJS heap.

```ts
const first = await caplets__code_mode({
code: `
var pickNames = (items) => items.map((item) => item.name);
return pickNames((await caplets.osv.searchTools("package")).items);
`,
});

const sessionId = first.meta?.sessionId;

const second = await caplets__code_mode({
sessionId,
code: `
const tools = await caplets.osv.searchTools("version");
return { names: pickNames(tools.items) };
`,
});
```

Unknown or expired session IDs fail before submitted code runs, using structured session
errors such as `SESSION_NOT_FOUND`. Heap state is live runtime state only; it is not durable
across process restarts or TTL eviction. Ordinary CLI calls such as `caplets code-mode
'return 1'` are one-shot and do not share heap with later CLI invocations.

## Recovery history

When a Code Mode session is created, successful metadata can include a `recoveryRef`.
Agents that already possess that reference can call `caplets.debug.readRecovery(...)` to read
redacted, bounded summaries of prior session runs. Recovery history helps reconstruct safe
setup code manually; it does not restore heap values, closures, timers, promises, or host
handles. A stale or unknown `sessionId` alone does not grant access to recovery history, and
there is no recent-session lookup.

## Platform globals

Code Mode also installs standard JavaScript platform globals at runtime so scripts can
Expand Down
Loading