Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
48e718c
feat(core): add remote profile storage
ian-pascoe Jun 19, 2026
29fc529
feat(core): add remote credential pairing store
ian-pascoe Jun 19, 2026
aa8f7c5
fix(core): complete self-hosted remote profiles
ian-pascoe Jun 19, 2026
ad24f16
feat(core): add unified remote login cli
ian-pascoe Jun 19, 2026
aa5ae18
feat(core): resolve attach from remote profiles
ian-pascoe Jun 19, 2026
084b898
feat(core): remove legacy attach credential flags
ian-pascoe Jun 19, 2026
50ba917
feat(core): require remote credentials for http serve
ian-pascoe Jun 19, 2026
ba94486
feat(core): remove server basic auth resolution
ian-pascoe Jun 19, 2026
53bea80
docs(core): teach remote login setup
ian-pascoe Jun 19, 2026
fd70b21
feat(core): finish remote login runtime migration
ian-pascoe Jun 19, 2026
67065d7
fix(pi): drop remote credential settings
ian-pascoe Jun 19, 2026
3df841d
fix(core): harden remote profile auth flows
ian-pascoe Jun 19, 2026
9e5c429
fix(review): harden remote auth edge cases
ian-pascoe Jun 19, 2026
38ce2fb
fix(core): refresh native remote background auth
ian-pascoe Jun 19, 2026
a533def
docs: document unified remote attach auth
ian-pascoe Jun 19, 2026
00416c9
test(core): isolate remote control route config
ian-pascoe Jun 19, 2026
8a47014
fix(core): address remote auth review feedback
ian-pascoe Jun 19, 2026
65532d3
fix(core): handle remote auth review edge cases
ian-pascoe Jun 20, 2026
108cdd3
fix(core): adapt daemon auth tests after rebase
ian-pascoe Jun 20, 2026
5b44870
test(core): make daemon validation exit test deterministic
ian-pascoe Jun 20, 2026
b5a4439
fix(core): address remote auth review feedback
ian-pascoe Jun 20, 2026
88d2ab7
fix(core): guard native remote replacement close race
ian-pascoe Jun 20, 2026
3a06512
fix(core): guard profile-backed native close race
ian-pascoe Jun 20, 2026
60d58b0
fix(core): address remote login review followups
ian-pascoe Jun 20, 2026
5235de2
fix(core): address cloud login review followups
ian-pascoe Jun 20, 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
5 changes: 5 additions & 0 deletions .changeset/native-remote-background-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@caplets/core": patch
---

Refresh native remote credentials before background polling, attach event reconnects, tool invokes, and stale-manifest retries so long-lived Remote Profile integrations do not reuse expired authorization headers.
8 changes: 8 additions & 0 deletions .changeset/unified-remote-login.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@caplets/core": minor
"caplets": minor
"@caplets/opencode": minor
"@caplets/pi": minor
---

Replace self-hosted remote env-token and Basic Auth setup with unified Remote Login profiles. Remote attach, hosted Cloud, OpenCode, and Pi now resolve Caplets-owned credentials from `caplets remote login <url>` and use `CAPLETS_REMOTE_URL` only as a non-secret selector.
26 changes: 26 additions & 0 deletions CONCEPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,29 @@ Recovery References are separate from session handles. Possessing a session hand
### 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.

## Remote Attach

### Remote Attach

The process where a local agent-facing Caplets runtime connects to a trusted Caplets host and exposes that host's capabilities through local or native agent integrations.

Remote Attach uses Remote Profiles for trust and credentials. Long-lived attach traffic treats credentials as refreshable runtime state rather than fixed startup state.

### Remote Login

The provider-neutral flow that trusts a local Caplets client to a Caplets host, whether the host is self-hosted or Caplets Cloud.

Remote Login stores host credentials in Caplets-owned credential storage so agent configs can launch `caplets attach --remote-url ...` without carrying remote secrets.

### Pairing Code

A short-lived, one-time code minted by a self-hosted Caplets host and exchanged by a client during Remote Login.

Pairing Codes are bootstrap material only. They are not reusable client credentials.

### Remote Profile

The stored local record for a trusted Caplets host, including the normalized host URL, host kind, selected workspace when applicable, and redacted credential status.

Remote Profiles are the source of truth for request credentials. Long-lived clients resolve current profile state when sending remote traffic instead of copying credentials into agent config or one-time startup state.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,14 @@ Native integrations expose `caplets__code_mode` for multi-step TypeScript workfl
generated `caplets.<id>` handles. Progressive exposure adds `caplets__<id>` tools; direct
exposure adds operation-level tools such as `caplets__<id>__<operation>`.

Remote mode is available with `caplets attach`, self-hosted HTTP service settings, or
Caplets Cloud auth:
Remote mode uses Remote Login for both self-hosted Caplets and Caplets Cloud. Trust the
host once, then launch attach or a native integration with only non-secret selectors:

```sh
export CAPLETS_MODE=remote
export CAPLETS_REMOTE_URL=https://caplets.example.com/caplets
export CAPLETS_REMOTE_TOKEN=...
caplets remote login https://caplets.example.com/caplets
caplets attach --remote-url https://caplets.example.com/caplets

caplets cloud auth login
caplets remote login https://cloud.caplets.dev
CAPLETS_MODE=cloud CAPLETS_REMOTE_URL=https://cloud.caplets.dev opencode
```

Expand Down
37 changes: 21 additions & 16 deletions apps/docs/src/content/docs/remote-attach.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Caplets native integrations use the same mode names as `caplets attach`:
| -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `local` | The agent should start Caplets against local user and project config. |
| `remote` | The agent should connect to a self-hosted Caplets service. |
| `cloud` | The agent should connect to Caplets Cloud with explicit `CAPLETS_REMOTE_*` or `CAPLETS_CLOUD_*` environment values. |
| `cloud` | The agent should connect to Caplets Cloud through a saved Remote Profile. |
| `auto` | Caplets should use Cloud for Cloud URLs, self-hosted remote for non-Cloud URLs, and local mode when no remote URL is set. |

## MCP client config
Expand All @@ -24,7 +24,7 @@ Codex:
```toml
[mcp_servers.caplets]
command = "caplets"
args = ["attach"]
args = ["attach", "--remote-url", "https://caplets.example.com/caplets"]
```

Generic MCP JSON:
Expand All @@ -34,40 +34,45 @@ Generic MCP JSON:
"mcpServers": {
"caplets": {
"command": "caplets",
"args": ["attach"]
"args": ["attach", "--remote-url", "https://caplets.example.com/caplets"]
}
}
}
```

## Environment
## Remote Login

For a self-hosted remote:
For a self-hosted remote, first create a short-lived Pairing Code on the server:

```sh
export CAPLETS_MODE=remote
export CAPLETS_REMOTE_URL=https://caplets.example.com/caplets
export CAPLETS_REMOTE_TOKEN=...
caplets remote host pair --host-url https://caplets.example.com/caplets
```

If the server uses a non-default credential state directory, pass the same directory with
`--state-path` that the server uses for `caplets serve --remote-state-path`.

caplets attach
Then log in once on the client and configure the agent to launch attach:

```sh
caplets remote login https://caplets.example.com/caplets
caplets attach --remote-url https://caplets.example.com/caplets
```

Use `CAPLETS_REMOTE_USER` and `CAPLETS_REMOTE_PASSWORD` instead of
`CAPLETS_REMOTE_TOKEN` when the remote uses Basic Auth.
Enter the Pairing Code at the hidden prompt from `caplets remote login`. Use
`--code-stdin` for automation instead of putting Pairing Codes in shell history.

For Caplets Cloud native integrations, set the Cloud URL plus a workspace and token:
For Caplets Cloud native integrations, log in once and then set the Cloud URL selector:

```sh
caplets remote login https://cloud.caplets.dev
export CAPLETS_MODE=cloud
export CAPLETS_REMOTE_URL=https://cloud.caplets.dev
export CAPLETS_REMOTE_WORKSPACE=...
export CAPLETS_REMOTE_TOKEN=...

opencode
```

Saved Cloud auth from `caplets cloud auth login` is used by the `caplets attach` CLI path.
Native integrations do not read the saved auth store directly.
Saved Remote Profiles are used by `caplets attach` and native integrations. Agent configs
should not contain Caplets remote tokens or passwords.

Run a finite Project Binding smoke path before wiring an agent:

Expand Down
16 changes: 5 additions & 11 deletions apps/docs/src/content/docs/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -123,24 +123,18 @@ Expected symptom: remote mode starts, but attach cannot reach the runtime or aut
Confirm the remote environment:

```sh
export CAPLETS_MODE=remote
export CAPLETS_REMOTE_URL=https://caplets.example.com/caplets
export CAPLETS_REMOTE_TOKEN=...
caplets remote login https://caplets.example.com/caplets
caplets doctor
caplets attach
caplets attach --remote-url https://caplets.example.com/caplets
```

If the remote requires auth, set either `CAPLETS_REMOTE_TOKEN` or
`CAPLETS_REMOTE_USER` plus `CAPLETS_REMOTE_PASSWORD`. If the URL belongs to Caplets Cloud,
check whether your environment expects `CAPLETS_REMOTE_*` or `CAPLETS_CLOUD_*` values and
keep the family consistent for that shell. Cloud-native integrations also need the selected
workspace:
If the URL belongs to Caplets Cloud, log in through Remote Login and keep the Cloud URL
selector consistent for that shell:

```sh
caplets remote login https://cloud.caplets.dev
export CAPLETS_MODE=cloud
export CAPLETS_REMOTE_URL=https://cloud.caplets.dev
export CAPLETS_REMOTE_WORKSPACE=...
export CAPLETS_REMOTE_TOKEN=...
caplets attach --once
```

Expand Down
Loading