@knpkv/relay 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY.md +29 -0
- package/README.md +110 -2
- package/dist/backends.d.ts +26 -0
- package/dist/backends.d.ts.map +1 -0
- package/dist/harness.d.ts +132 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12210 -0
- package/dist/index.js.map +7 -0
- package/dist/messages.d.ts +44 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/model.d.ts +207 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/registry.d.ts +47 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/turn.d.ts +68 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/wire.d.ts +214 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +145 -0
- package/dist/wire.js.map +7 -0
- package/package.json +73 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
`dist/index.js` bundles code from these packages of [Pi](https://github.com/earendil-works/pi), each published
|
|
4
|
+
under the MIT licence below: `@earendil-works/pi-durable`, `@earendil-works/chord` and `@earendil-works/pi-ai`
|
|
5
|
+
(version 1.0.4).
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2025 Mario Zechner
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
```
|
package/README.md
CHANGED
|
@@ -1,3 +1,111 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @knpkv/relay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Relay agent harness every knpkv product mounts. One durable conversation per product object, model
|
|
4
|
+
turns through the user's own Claude Code or Codex CLI login, product capabilities behind one permission
|
|
5
|
+
gate, and one event stream for the dock.
|
|
6
|
+
|
|
7
|
+
## Mental model
|
|
8
|
+
|
|
9
|
+
- **One session per object.** A session is keyed by an `ObjectRef` (`{ product, kind, id }`), so a
|
|
10
|
+
question about the same pull request finds its history again, across restarts.
|
|
11
|
+
- **Durable by construction.** Sessions run on [Pi Durable](https://github.com/earendil-works/pi) over
|
|
12
|
+
SQLite (`@libsql/client`, so Node and Bun both work). Every input, model turn and tool call is committed
|
|
13
|
+
before it is shown. A process killed mid-run continues from its last checkpoint when the store is next
|
|
14
|
+
opened, and a `write` that was interrupted is never run twice; the model is told it was interrupted.
|
|
15
|
+
- **Capabilities are the only way in.** A product declares each action once as a `@knpkv/capability`
|
|
16
|
+
contract (Schema input, output and declared failures, plus its access) and binds a handler with
|
|
17
|
+
`implement`; `register` hands it to Relay. The model sees a declared failure's reason and fix, never a
|
|
18
|
+
defect's internals.
|
|
19
|
+
- `read` runs when the model calls it, and reruns after a crash.
|
|
20
|
+
- `write` waits for the person to confirm the exact action (`ConfirmationRequired` carries verb, target,
|
|
21
|
+
arguments and whether it is reversible). The decision is remembered per call, so a restart neither asks
|
|
22
|
+
again nor runs a declined action.
|
|
23
|
+
- `host` is refused until herdr Approvals are wired.
|
|
24
|
+
- **Your login, not ours.** Each turn runs `claude --print` or `codex exec` with every CLI tool withheld,
|
|
25
|
+
asking for one structured answer (a reply or tool calls). Relay never holds a provider credential and never
|
|
26
|
+
registers pi-ai's own providers, including its claude.ai and ChatGPT OAuth flows.
|
|
27
|
+
|
|
28
|
+
## Use
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { claudeCodeBackend, layer, register } from "@knpkv/relay"
|
|
32
|
+
import { Effect, Layer } from "effect"
|
|
33
|
+
|
|
34
|
+
const RelayLive = Layer.unwrap(
|
|
35
|
+
Effect.gen(function* () {
|
|
36
|
+
const claude = yield* claudeCodeBackend({ cwd })
|
|
37
|
+
return layer({
|
|
38
|
+
storePath, // e.g. <product data dir>/relay/sessions.sqlite
|
|
39
|
+
instructions: "You are Relay inside CodeCommit…",
|
|
40
|
+
capabilities: [register(getPullRequest), register(postComment)],
|
|
41
|
+
backends: [claude]
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`RelayHarness` then offers:
|
|
48
|
+
|
|
49
|
+
- `send(ref, text, requestId, { backend?, context? })`: `requestId` makes a retried send land once and names
|
|
50
|
+
the run that answers it. `backend` switches the session from its next turn on (`RelayBackendNotConfigured`
|
|
51
|
+
otherwise). `context` is what the person attached, as the product renders it (`{ label, body }`): it is
|
|
52
|
+
placed just before the message for the model, and never appears in the transcript or the Snapshot.
|
|
53
|
+
- `events(ref)`: a `Snapshot` first, with each message's `id`, the `runIds` of a run in flight and the
|
|
54
|
+
requestIds still `queued`. Then:
|
|
55
|
+
- `MessageQueued { requestId }`, then `MessagePlaced { id, requestId, text }` when a run takes it, or
|
|
56
|
+
`MessageWithdrawn { requestId }` when it is cancelled first.
|
|
57
|
+
- `RunStarted { runIds }` and `TextDelta`.
|
|
58
|
+
- `ToolStarted` and `ToolFinished`, each with a server-built, display-safe `summary`. A finished call carries
|
|
59
|
+
its citations, and a write whose product projects one carries a `receipt { summary, providerId, link? }`
|
|
60
|
+
(`register(capability, { receipt })`).
|
|
61
|
+
- `ConfirmationRequired`, then `ConfirmationResolved { decision: confirmed | declined | expired }`. A card
|
|
62
|
+
turns to past tense only on the latter.
|
|
63
|
+
- `RunFinished`, `RunFailed` or `Cancelled`, with the `runIds` the run answered.
|
|
64
|
+
- `decide(callId, allow)`: `RelayDecisionNotPending` says why an answer can't apply: `Decided`, `Expired` (the run
|
|
65
|
+
ended first) or `Unknown`. Kept for the process's lifetime.
|
|
66
|
+
- `cancel(ref, runId)`: withdraws a queued message alone, or stops the run in flight; `RelayRunNotActive` when no
|
|
67
|
+
run answers `runId`.
|
|
68
|
+
- `session(ref)`: the session's tools and the backend its next turn runs on.
|
|
69
|
+
- `backends`: `Unverified` (the CLI answered `--version`), `Ready` (a turn answered), or `Unavailable` with
|
|
70
|
+
`NotInstalled`, `SignedOut`, `Misconfigured` or `NoCapability` and a one-line fix. Observed, never persisted.
|
|
71
|
+
`SignedOut` comes from an `AuthenticationError` turn failure.
|
|
72
|
+
|
|
73
|
+
## In the browser: `@knpkv/relay/wire`
|
|
74
|
+
|
|
75
|
+
The contract a product's `/…/relay` routes speak, as a separate browser bundle that imports only
|
|
76
|
+
`effect` and `@knpkv/capability`. It holds the harness's event and session schemas, plus:
|
|
77
|
+
|
|
78
|
+
- `RelayStreamFrame`: one `data:` frame of `GET events`, a `RelayEvent`, `Unauthorized` or `StreamFailed`;
|
|
79
|
+
- `RelayMessageRequest`, `RelayCancelRequest` and `RelayDecisionRequest`, the write bodies, and `RelayMessageAccepted`;
|
|
80
|
+
- the typed refusals: `RelayUnavailableError` (503, with the fix), `RelayConflictError` (409, with the
|
|
81
|
+
`RelayConflictState` found) and `RelayBadRequestError` (400).
|
|
82
|
+
|
|
83
|
+
A product narrows `ref` to its own objects and may add a typed `context` to a message. The build fails if
|
|
84
|
+
the bundle reaches anything else, and `pnpm test:pack` checks the packed `dist/wire.js` again.
|
|
85
|
+
`@knpkv/relay-product/client` reads a conversation through it.
|
|
86
|
+
|
|
87
|
+
## Security boundaries
|
|
88
|
+
|
|
89
|
+
- The session store holds conversation content. Its directory is created `0700` and the database `0600`;
|
|
90
|
+
a store directory, database or SQLite sidecar (`-wal`, `-shm`) that is a symbolic link, even a dangling one, fails with `RelayStoreLinked` before anything is
|
|
91
|
+
re-permissioned or written;
|
|
92
|
+
it is never logged, never sent to telemetry, and never served on unauthenticated routes.
|
|
93
|
+
- One process owns a store: it holds an exclusive SQLite lock on `<store>.lock` (owner-only), so a second
|
|
94
|
+
owner fails with `RelayStoreLocked`. Closing the harness frees the store at once, so the same process can
|
|
95
|
+
open it again; the OS releases the lock if the owner dies. The lock is the runtime's own SQLite
|
|
96
|
+
(`node:sqlite` on Node, `bun:sqlite` on Bun), loaded when a store opens and used only through `exec`,
|
|
97
|
+
because libsql keeps a closed connection, and its locks, until its statements are garbage-collected.
|
|
98
|
+
- Provider credentials stay with the user's CLI. Relay only spawns `claude`/`codex` with all of their tools
|
|
99
|
+
withheld.
|
|
100
|
+
|
|
101
|
+
## Dependency note
|
|
102
|
+
|
|
103
|
+
Relay bundles the Pi modules it uses (pi-durable, chord, and pi-ai's core) into `dist/index.js`. Their MIT
|
|
104
|
+
notice ships in `LICENSE-THIRD-PARTY.md`. Pi's packages declare the Anthropic, OpenAI, Google and Bedrock SDKs
|
|
105
|
+
and esbuild as hard dependencies, but nothing Relay loads imports them. Bundling keeps all of that out of
|
|
106
|
+
every product that mounts Relay. The installed dependencies are `typebox`, `@libsql/client`, `effect` and
|
|
107
|
+
Relay's sibling `@knpkv` packages.
|
|
108
|
+
|
|
109
|
+
`pnpm test:pack` holds the package to that: the bundle may import only declared dependencies and Node
|
|
110
|
+
built-ins, and a dynamic import may reach nothing but a Node built-in. The bundle is temporary, until upstream
|
|
111
|
+
makes those dependencies optional (ADR-0009, amendment of 2026-10-07).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Effect, FileSystem, Layer } from "effect";
|
|
2
|
+
import { ChildProcessSpawner } from "effect/process";
|
|
3
|
+
import { RelayBackendUnavailable } from "./harness.js";
|
|
4
|
+
export interface CliBackendOptions {
|
|
5
|
+
/** Working directory the CLI starts in. It reads no files there: every tool is withheld. */
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
/** Model override; omitted means the CLI's configured default. */
|
|
8
|
+
readonly model?: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Claude Code on the user's own login. */
|
|
11
|
+
export declare const claudeCodeBackend: (options: CliBackendOptions) => Effect.Effect<{
|
|
12
|
+
id: "claude-code";
|
|
13
|
+
name: string;
|
|
14
|
+
model: Layer.Layer<import("effect/ai/LanguageModel").LanguageModel | import("effect/ai/Model").ModelName | import("effect/ai/Model").ProviderName, never, never>;
|
|
15
|
+
probe: Effect.Effect<string, RelayBackendUnavailable, never>;
|
|
16
|
+
signInFix: string;
|
|
17
|
+
}, never, ChildProcessSpawner.ChildProcessSpawner>;
|
|
18
|
+
/** Codex on the user's own ChatGPT login. */
|
|
19
|
+
export declare const codexCliBackend: (options: CliBackendOptions) => Effect.Effect<{
|
|
20
|
+
id: "codex-cli";
|
|
21
|
+
name: string;
|
|
22
|
+
model: Layer.Layer<import("effect/ai/LanguageModel").LanguageModel | import("effect/ai/Model").ModelName | import("effect/ai/Model").ProviderName, never, never>;
|
|
23
|
+
probe: Effect.Effect<string, RelayBackendUnavailable, never>;
|
|
24
|
+
signInFix: string;
|
|
25
|
+
}, never, ChildProcessSpawner.ChildProcessSpawner | FileSystem.FileSystem>;
|
|
26
|
+
//# sourceMappingURL=backends.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backends.d.ts","sourceRoot":"","sources":["../src/backends.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAGtD,MAAM,WAAW,iBAAiB;IAChC,4FAA4F;IAC5F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AA8BD,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB;;;;;;kDAgB5B,CAAA;AAEF,6CAA6C;AAC7C,eAAO,MAAM,eAAe;;;;;;0EAoB1B,CAAA"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Context, Crypto, Effect, FileSystem, Layer, Path, Schema, Scope, Stream } from "effect";
|
|
2
|
+
import type { LanguageModel } from "effect/ai";
|
|
3
|
+
import { RelayBackendId } from "./model.js";
|
|
4
|
+
import type { BackendStatus, ObjectRef, RelayEvent, SessionInfo, SessionTool } from "./model.js";
|
|
5
|
+
import type { RegisteredCapability } from "./registry.js";
|
|
6
|
+
declare const RelayStoreLocked_base: Schema.Class<RelayStoreLocked, Schema.TaggedStruct<"RelayStoreLocked", {
|
|
7
|
+
readonly path: Schema.String;
|
|
8
|
+
readonly message: Schema.String;
|
|
9
|
+
}>, import("effect/Cause").YieldableError>;
|
|
10
|
+
/** Another process already owns this Relay store. */
|
|
11
|
+
export declare class RelayStoreLocked extends RelayStoreLocked_base {
|
|
12
|
+
}
|
|
13
|
+
declare const RelayStoreLinked_base: Schema.Class<RelayStoreLinked, Schema.TaggedStruct<"RelayStoreLinked", {
|
|
14
|
+
readonly path: Schema.String;
|
|
15
|
+
readonly message: Schema.String;
|
|
16
|
+
}>, import("effect/Cause").YieldableError>;
|
|
17
|
+
/**
|
|
18
|
+
* The store directory or database is a symbolic link. Relay refuses it rather than re-permission and
|
|
19
|
+
* write conversation content wherever the link points.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RelayStoreLinked extends RelayStoreLinked_base {
|
|
22
|
+
}
|
|
23
|
+
declare const RelayStoreFailed_base: Schema.Class<RelayStoreFailed, Schema.TaggedStruct<"RelayStoreFailed", {
|
|
24
|
+
readonly operation: Schema.String;
|
|
25
|
+
readonly message: Schema.String;
|
|
26
|
+
}>, import("effect/Cause").YieldableError>;
|
|
27
|
+
/** The Relay store could not be opened or read. `message` names the operation and the fix. */
|
|
28
|
+
export declare class RelayStoreFailed extends RelayStoreFailed_base {
|
|
29
|
+
}
|
|
30
|
+
declare const RelayDecisionNotPending_base: Schema.Class<RelayDecisionNotPending, Schema.TaggedStruct<"RelayDecisionNotPending", {
|
|
31
|
+
readonly callId: Schema.String;
|
|
32
|
+
readonly state: Schema.TaggedUnion<{
|
|
33
|
+
readonly Decided: Schema.TaggedStruct<"Decided", {
|
|
34
|
+
readonly allow: Schema.Boolean;
|
|
35
|
+
}>;
|
|
36
|
+
readonly Expired: Schema.TaggedStruct<"Expired", {}>;
|
|
37
|
+
readonly Unknown: Schema.TaggedStruct<"Unknown", {}>;
|
|
38
|
+
}>;
|
|
39
|
+
}>, import("effect/Cause").YieldableError>;
|
|
40
|
+
/** No confirmation is waiting for this call; `state` says whether it was answered, withdrawn, or never asked. */
|
|
41
|
+
export declare class RelayDecisionNotPending extends RelayDecisionNotPending_base {
|
|
42
|
+
}
|
|
43
|
+
declare const RelayRunNotActive_base: Schema.Class<RelayRunNotActive, Schema.TaggedStruct<"RelayRunNotActive", {
|
|
44
|
+
readonly runId: Schema.String;
|
|
45
|
+
}>, import("effect/Cause").YieldableError>;
|
|
46
|
+
/** No run of this session answers `runId`: it finished, or never started. */
|
|
47
|
+
export declare class RelayRunNotActive extends RelayRunNotActive_base {
|
|
48
|
+
}
|
|
49
|
+
declare const RelayBackendNotConfigured_base: Schema.Class<RelayBackendNotConfigured, Schema.TaggedStruct<"RelayBackendNotConfigured", {
|
|
50
|
+
readonly backend: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
|
|
51
|
+
}>, import("effect/Cause").YieldableError>;
|
|
52
|
+
/** The session asked for a backend this product did not configure. */
|
|
53
|
+
export declare class RelayBackendNotConfigured extends RelayBackendNotConfigured_base {
|
|
54
|
+
}
|
|
55
|
+
declare const RelayBackendUnavailable_base: Schema.Class<RelayBackendUnavailable, Schema.TaggedStruct<"RelayBackendUnavailable", {
|
|
56
|
+
readonly cause: Schema.Literals<readonly ["NotInstalled", "SignedOut", "Misconfigured", "NoCapability"]>;
|
|
57
|
+
readonly fix: Schema.String;
|
|
58
|
+
}>, import("effect/Cause").YieldableError>;
|
|
59
|
+
/** A backend's CLI can't be used. `fix` is the one action that makes it usable. */
|
|
60
|
+
export declare class RelayBackendUnavailable extends RelayBackendUnavailable_base {
|
|
61
|
+
}
|
|
62
|
+
/** One backend the harness can run turns on, with the `LanguageModel` that reaches it. */
|
|
63
|
+
export interface RelayBackend {
|
|
64
|
+
readonly id: RelayBackendId;
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly model: Layer.Layer<LanguageModel.LanguageModel>;
|
|
67
|
+
/** The CLI's version, read without a model call; fails when it is missing or unusable. */
|
|
68
|
+
readonly probe: Effect.Effect<string, RelayBackendUnavailable>;
|
|
69
|
+
/** The one line that signs the CLI back in, shown when a turn is refused for its login. */
|
|
70
|
+
readonly signInFix: string;
|
|
71
|
+
}
|
|
72
|
+
export interface RelayHarnessOptions<Requirements> {
|
|
73
|
+
/** SQLite file of this product's Relay sessions. Owner-only; never on a shared path. */
|
|
74
|
+
readonly storePath: string;
|
|
75
|
+
/** The product's standing instructions for Relay. */
|
|
76
|
+
readonly instructions: string;
|
|
77
|
+
readonly capabilities: ReadonlyArray<RegisteredCapability<Requirements>>;
|
|
78
|
+
/** The first backend is the default for new sessions. */
|
|
79
|
+
readonly backends: readonly [RelayBackend, ...ReadonlyArray<RelayBackend>];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Context the person attached to one message, as the product renders it for the model: `label` names
|
|
83
|
+
* what it is, `body` is the text the model reads. It reaches the model's context, never the transcript.
|
|
84
|
+
*/
|
|
85
|
+
export interface MessageContext {
|
|
86
|
+
readonly label: string;
|
|
87
|
+
readonly body: string;
|
|
88
|
+
}
|
|
89
|
+
export interface SendOptions {
|
|
90
|
+
/** Switch the session to this backend from its next turn on. */
|
|
91
|
+
readonly backend?: RelayBackendId | undefined;
|
|
92
|
+
/** Attached context, placed just before the message. */
|
|
93
|
+
readonly context?: ReadonlyArray<MessageContext> | undefined;
|
|
94
|
+
}
|
|
95
|
+
export interface RelayHarnessService {
|
|
96
|
+
/**
|
|
97
|
+
* Send a message to the session about `ref`. `requestId` makes a retried send land once and names the run
|
|
98
|
+
* that answers it. `backend` switches the session to that backend from its next turn on.
|
|
99
|
+
*/
|
|
100
|
+
readonly send: (ref: ObjectRef, text: string, requestId: string, options?: SendOptions) => Effect.Effect<void, RelayStoreFailed | RelayBackendNotConfigured>;
|
|
101
|
+
/** The session's events: a `Snapshot` first, then every change. Ends when the scope closes. */
|
|
102
|
+
readonly events: (ref: ObjectRef) => Stream.Stream<RelayEvent, RelayStoreFailed>;
|
|
103
|
+
/**
|
|
104
|
+
* Answer a confirmation pending in `ref`'s session. A call raised in another session is `Unknown` here and
|
|
105
|
+
* stays pending. Outcomes are remembered for the harness's lifetime, not across restarts.
|
|
106
|
+
*/
|
|
107
|
+
readonly decide: (ref: ObjectRef, callId: string, allow: boolean) => Effect.Effect<void, RelayDecisionNotPending | RelayStoreFailed>;
|
|
108
|
+
/**
|
|
109
|
+
* Stop the run answering `runId`. A message still queued is withdrawn alone; a run in flight stops whole,
|
|
110
|
+
* with every message it took. Nothing already committed is undone.
|
|
111
|
+
*/
|
|
112
|
+
readonly cancel: (ref: ObjectRef, runId: string) => Effect.Effect<void, RelayStoreFailed | RelayRunNotActive>;
|
|
113
|
+
/** The tools the dock lists for a session, and the backend its next turn runs on. */
|
|
114
|
+
readonly session: (ref: ObjectRef) => Effect.Effect<SessionInfo, RelayStoreFailed>;
|
|
115
|
+
/** Every configured backend's status, in configuration order. */
|
|
116
|
+
readonly backends: Effect.Effect<ReadonlyArray<BackendStatus>>;
|
|
117
|
+
/** The tools the dock lists for a session. */
|
|
118
|
+
readonly tools: ReadonlyArray<SessionTool>;
|
|
119
|
+
}
|
|
120
|
+
declare const RelayHarness_base: Context.ServiceClass<RelayHarness, "@knpkv/relay/RelayHarness", RelayHarnessService>;
|
|
121
|
+
export declare class RelayHarness extends RelayHarness_base {
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build the harness for one product. One attempt's resources (the store lock, the store, the harness) live in
|
|
125
|
+
* their own scope: an attempt that fails releases them at once, so a retry in the same scope can take the
|
|
126
|
+
* store; one that succeeds keeps them until the caller's scope closes.
|
|
127
|
+
*/
|
|
128
|
+
export declare const make: <Requirements>(options: RelayHarnessOptions<Requirements>) => Effect.Effect<RelayHarnessService, RelayStoreFailed | RelayStoreLinked | RelayStoreLocked, Crypto.Crypto | FileSystem.FileSystem | Path.Path | Scope.Scope | Exclude<Requirements, Scope.Scope>>;
|
|
129
|
+
/** Build the harness as a scoped layer: the store closes, and the lock is released, with the scope. */
|
|
130
|
+
export declare const layer: <Requirements>(options: RelayHarnessOptions<Requirements>) => Layer.Layer<RelayHarness, RelayStoreFailed | RelayStoreLinked | RelayStoreLocked, Crypto.Crypto | FileSystem.FileSystem | Path.Path | Exclude<Exclude<Requirements, Scope.Scope>, Scope.Scope>>;
|
|
131
|
+
export {};
|
|
132
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relay: the agent harness every product mounts.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
export { claudeCodeBackend, codexCliBackend } from "./backends.js";
|
|
7
|
+
export type { CliBackendOptions } from "./backends.js";
|
|
8
|
+
export { layer, make, RelayBackendNotConfigured, RelayBackendUnavailable, RelayDecisionNotPending, RelayHarness, RelayRunNotActive, RelayStoreFailed, RelayStoreLinked, RelayStoreLocked } from "./harness.js";
|
|
9
|
+
export type { MessageContext, RelayBackend, RelayHarnessOptions, RelayHarnessService, SendOptions } from "./harness.js";
|
|
10
|
+
export { BackendStatus, BackendUnavailableCause, CapabilityAccess, DecisionState, ObjectRef, objectRefKey, RelayBackendId, RelayEvent, RelayProduct, SessionInfo, SessionTool, WriteReceipt } from "./model.js";
|
|
11
|
+
export { register } from "./registry.js";
|
|
12
|
+
export type { DisplayOptions, Gate, RegisteredCapability } from "./registry.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EACL,KAAK,EACL,IAAI,EACJ,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACvH,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,YAAY,EACZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA"}
|