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
8 changes: 8 additions & 0 deletions .changeset/bright-walls-refresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@caplets/core": patch
"@caplets/opencode": patch
"@caplets/pi": patch
"caplets": patch
---

Refresh expired downstream OAuth/OIDC tokens before calling MCP, OpenAPI, GraphQL, and HTTP backends, persisting rotated credentials when providers return them.
7 changes: 7 additions & 0 deletions .codex/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[mcp_servers.caplets-local]
command = "node"
args = ["./packages/cli/dist/index.js", "serve", "--transport", "stdio"]
env_vars = ["GH_TOKEN"]

[mcp_servers.caplets-local.env]
CAPLETS_MODE = "local"
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
## Package Map

- `packages/core` is the runtime/library source: config parsing, schema generation, MCP/OpenAPI/GraphQL/HTTP/CLI backends, native service exports.
- `packages/cli` publishes the `caplets` binary and delegates almost all behavior to `@caplets/core`; `serve`/no arg starts the stdio MCP server.
- `packages/cli` publishes the `caplets` binary and delegates almost all behavior to `@caplets/core`; `caplets serve` starts the MCP server, while no args print help.
- `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

- Put design specs in `docs/specs/`, implementation plans in `docs/plans/`, and product requirements documents in `docs/product/`; do not use `docs/superpowers/` in this repo.
- 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.
Expand All @@ -28,7 +28,7 @@
## Config And Runtime Gotchas

- Default user config path is resolved by core; tests commonly override with `CAPLETS_CONFIG`.
- Project config lives at `.caplets/config.json` and executable project config is intentionally restricted unless `CAPLETS_TRUST_PROJECT_CAPLETS` is enabled.
- Project config lives at `.caplets/config.json`; project Markdown Caplet files load by default, while executable backend maps in project config are intentionally rejected.
- Runtime config reload keeps the last known-good config on parse/validation errors; do not change this behavior without updating reload tests.
- Caplet tool names come from configured server IDs and expose progressive discovery operations (`get_caplet`, `list_tools`/`search_tools`, `get_tool`, `call_tool`) rather than flattening downstream tools.

Expand Down
1,276 changes: 95 additions & 1,181 deletions README.md

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions docs/adr/0001-code-mode-default-exposure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ADR 0001: Make Code Mode The Default Backend Exposure

## Status

Accepted

## Context

Early Caplets work centered on progressive disclosure: show one capability card first, then let the agent inspect and call downstream operations through scoped wrapper tools. That model reduced flat tool-list bloat, but larger workflows still required repeated model/tool round trips for discovery, schema inspection, execution, filtering, and synthesis.

The current implementation supports multiple exposure modes and defaults global config to `code_mode`. The landing page, benchmark report, native integrations, and runtime code all treat Code Mode as the main path for agents using configured backends.

Source code remains the source of truth for behavior. This ADR records the decision and rationale, not a substitute for `packages/core` or generated schemas.

## Decision

Code Mode is the default backend exposure for Caplets.

Configured backends should enter the primary agent surface as generated `caplets.<id>` handles inside a Code Mode TypeScript script. Agents should perform discovery, exact schema inspection, tool calls, filtering, joins, and compact synthesis inside that script.

Progressive wrapper tools remain supported through the `progressive` and `progressive_and_code_mode` exposure modes. Direct MCP exposure remains supported through `direct` and `direct_and_code_mode` when the downstream surface should be registered directly.

## Consequences

- Product docs should describe Caplets as Code Mode first, not only as a progressive disclosure gateway.
- Progressive disclosure remains an implementation and compatibility model, but not the primary product frame.
- Benchmarks should report Code Mode separately from progressive modes.
- Agent guidance should prefer compact one-pass Code Mode scripts for multi-step work.
- Long-lived docs should preserve progressive exposure details as an alternate mode, not as the main PRD.

## Evidence

- `packages/core/src/config.ts` defaults `options.exposure` to `code_mode`.
- `packages/core/src/serve/session.ts` registers a `code_mode` MCP tool when Code Mode Caplets are callable.
- `packages/core/src/native/tools.ts` defines `caplets__code_mode` for native integrations.
- `docs/benchmarks/coding-agent.md` records deterministic Code Mode workflow results and live benchmark guidance.
- `apps/landing/src/pages/index.astro` presents Code Mode as the primary evaluated mode.
120 changes: 120 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Caplets Architecture

Caplets is a Code Mode and capability gateway for coding agents. It turns configured backends into Caplet handles, optional progressive wrapper tools, and optional direct MCP surfaces.

Source code is authoritative. This document summarizes the architecture, but implementation details in `packages/core`, generated schemas, tests, and package entrypoints win when docs drift.

## Runtime Layers

### Configuration And Caplet Sources

The core config loader accepts user config, project config, and Markdown Caplet files. The schema source of truth is Zod in `packages/core/src/config.ts`, with generated JSON Schemas in `schemas/`.

Supported backend families are:

- `mcpServers`
- `openapiEndpoints`
- `graphqlEndpoints`
- `httpApis`
- `cliTools`
- `capletSets`

Project sources override user/global sources. Source-aware inspection reports where each Caplet came from and warns when one Caplet shadows another.

### Engine

`packages/core/src/engine.ts` owns the active config, backend managers, config reload behavior, and execution dispatch. Reload keeps the last known-good config if parsing or validation fails.

Backend managers provide a common shape for listing tools, searching tools, describing exact tools, calling tools, and checking readiness. MCP-backed Caplets additionally support resources, resource templates, prompts, and completion.

### Exposure Policy

`packages/core/src/exposure/policy.ts` resolves one exposure value into three booleans:

- `codeMode`
- `progressive`
- `direct`

The global default is `code_mode`. Per-Caplet config may choose `direct`, `progressive`, `code_mode`, `direct_and_code_mode`, or `progressive_and_code_mode`.

### MCP Server

`packages/core/src/serve/session.ts` registers the user-facing MCP surface.

- Code Mode exposure registers one `code_mode` tool that runs TypeScript against generated `caplets.<id>` handles.
- Progressive exposure registers one wrapper tool per Caplet.
- Direct exposure registers discovered downstream MCP tools, resources, resource templates, and prompts.

The HTTP server in `packages/core/src/serve/http.ts` exposes MCP, control, and health endpoints for self-hosting and remote clients. Stdio remains the local MCP transport for ordinary client config.

### Code Mode

Code Mode is implemented under `packages/core/src/code-mode/`.

The runtime generates TypeScript declarations from the current callable Caplets, statically checks the submitted script, runs it in the sandbox, bridges handle methods back to the native service, stores logs when configured, and returns JSON-serializable results with diagnostics.

The intended agent pattern is one compact script:

1. choose handles
2. inspect or check only when useful
3. search for candidate operations
4. describe exact operations when schemas are needed
5. call tools
6. filter, join, and summarize inside the script
7. return compact decision-ready evidence

### Native Service

`packages/core/src/native/service.ts` powers OpenCode and Pi. It uses the same engine and exposure policy as MCP serving, then exposes native tools with agent-specific prompt guidance.

`caplets__code_mode` is the native Code Mode entrypoint. `caplets__<id>` tools exist for progressive exposure. Direct native exposure registers operation-level tools named `caplets__<id>__<operation>`.

### Remote Control

Remote control under `packages/core/src/remote-control/` lets CLI and native integrations operate against a self-hosted or Cloud Caplets service. Remote mode uses server-owned config, auth, and execution, with local/project overlays where supported.

### Project Binding

Project Binding under `packages/core/src/project-binding/` connects a local project root to a remote runtime. The foreground attach loop owns session state, heartbeat, reconnect behavior, sync preflight, and terminal recovery commands.

`docs/project-binding.md` is the living operational contract for Project Binding.

## Backend Contracts

### MCP

MCP-backed Caplets preserve downstream tool results and expose resources, templates, prompts, and completion when the downstream server supports them. Direct exposure can register those downstream surfaces directly.

### OpenAPI, GraphQL, And HTTP

OpenAPI, GraphQL, and HTTP backends expose explicit operation/action tools. They do not synthesize MCP resources or prompts. HTTP-like backends enforce safe URL handling, bounded response bodies, timeouts, and redacted errors.

### CLI Tools

CLI-backed Caplets expose curated actions only. Actions spawn declared commands and args without shell interpolation. Inputs are validated before spawn, and outputs are bounded.

### Caplet Sets

Caplet sets expose another Caplets collection as a nested backend. This lets a team or repository share a Caplet catalog without flattening every child backend into the parent config.

## Auth And Secrets

Auth supports none, bearer, headers, OAuth2, and OIDC where the backend family supports them. OAuth/OIDC state is stored outside config. Errors and diagnostics redact configured secrets.

Cloud Auth stores hosted credentials and a selected workspace. `caplets attach` refreshes expired hosted credentials before creating Binding Sessions and fails closed when refresh credentials are revoked.

## Distribution And Deployment

The public CLI package is `caplets`. The native packages are `@caplets/opencode` and `@caplets/pi`.

The repo includes a source-build `Dockerfile` and `docker-compose.yml` for self-hosting the HTTP service. Release workflows publish npm packages and can publish the service image.

## Benchmark Architecture

`packages/benchmarks` owns deterministic and opt-in live benchmarks.

- Deterministic benchmarks are stable, credential-free, and committed through `docs/benchmarks/coding-agent.md`.
- Live benchmarks require local agents, credentials, selected models, and explicit `CAPLETS_BENCH_LIVE=1`.
- Pi eval modes include Code Mode, progressive Code Mode, direct Code Mode, vanilla MCP, and Executor MCP competitors.

Benchmark output is product evidence, not runtime configuration truth. Runtime truth lives in `packages/core`.
88 changes: 0 additions & 88 deletions docs/plans/2026-05-12-cli-inspection-polish.md

This file was deleted.

Loading