@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.
@@ -0,0 +1,44 @@
1
+ export type MessageEvent = {
2
+ readonly _tag: "MessageQueued";
3
+ readonly requestId: string;
4
+ } | {
5
+ readonly _tag: "MessagePlaced";
6
+ readonly id: string;
7
+ readonly requestId: string;
8
+ readonly text: string;
9
+ } | {
10
+ readonly _tag: "MessageWithdrawn";
11
+ readonly requestId: string;
12
+ };
13
+ /** What the tracker reads of a stored message; Pi's messages fit it, and no Pi type leaves the bundle. */
14
+ export interface StoredMessage {
15
+ readonly role: string;
16
+ readonly content: string | ReadonlyArray<{
17
+ readonly type: string;
18
+ readonly text?: string;
19
+ }>;
20
+ }
21
+ /** What the tracker reads of a committed entry. */
22
+ export interface CommittedEntry {
23
+ readonly id: number;
24
+ readonly kind: string;
25
+ readonly model?: ReadonlyArray<StoredMessage>;
26
+ }
27
+ /** What the tracker reads of a submission record. */
28
+ export interface SubmissionState {
29
+ readonly id: number;
30
+ readonly type: "input" | "write";
31
+ readonly status: "queued" | "placed" | "done" | "unanswered";
32
+ readonly requestId?: string;
33
+ readonly entry?: number;
34
+ }
35
+ /** The visible text of a stored user or assistant entry. */
36
+ export declare const entryText: (messages: ReadonlyArray<StoredMessage> | undefined) => string;
37
+ /** One subscription's tracker: feed it each committed entry and submission record, in stream order. */
38
+ export declare const makeMessageTracker: () => {
39
+ /** A committed entry; only a person's message can place one. */
40
+ entry: (entry: CommittedEntry) => ReadonlyArray<MessageEvent>;
41
+ /** A submission record; Relay submits every input with the dock's requestId, its id is the fallback. */
42
+ record: (record: SubmissionState) => ReadonlyArray<MessageEvent>;
43
+ };
44
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1G;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAErE,0GAA0G;AAC1G,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5F;AAED,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;CAC9C;AAED,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAA;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,4DAA4D;AAC5D,eAAO,MAAM,SAAS,aAAc,aAAa,CAAC,aAAa,CAAC,GAAG,SAAS,KAAG,MAShE,CAAA;AAEf,uGAAuG;AACvG,eAAO,MAAM,kBAAkB;IAc3B,gEAAgE;IAChE,KAAK,UAAU,cAAc,KAAG,aAAa,CAAC,YAAY,CAAC;IAK3D,wGAAwG;IACxG,MAAM,WAAW,eAAe,KAAG,aAAa,CAAC,YAAY,CAAC;CAYjE,CAAA"}
@@ -0,0 +1,207 @@
1
+ import { Schema } from "effect";
2
+ /** The products Relay can be about. */
3
+ export declare const RelayProduct: Schema.Literals<readonly ["codecommit", "jcf", "agent-usage", "control-center", "herdr"]>;
4
+ export type RelayProduct = typeof RelayProduct.Type;
5
+ /** A product object a Relay session is about. Relay keeps sessions only for the products it knows. */
6
+ export declare const ObjectRef: Schema.Struct<{
7
+ readonly product: Schema.Literals<readonly ["codecommit", "jcf", "agent-usage", "control-center", "herdr"]>;
8
+ readonly kind: Schema.String;
9
+ readonly id: Schema.String;
10
+ }>;
11
+ export interface ObjectRef extends Schema.Schema.Type<typeof ObjectRef> {
12
+ }
13
+ /** The key a session is stored under. Unique per product, kind and id: JSON-encoded, so no field can contain the separator. */
14
+ export declare const objectRefKey: (ref: ObjectRef) => string;
15
+ /** Who must agree before a capability runs, as the dock lists it. */
16
+ export declare const CapabilityAccess: Schema.Literals<readonly ["read", "write", "host"]>;
17
+ export type CapabilityAccess = typeof CapabilityAccess.Type;
18
+ /** Why a backend can't answer yet, and the one action that fixes it. */
19
+ export declare const BackendUnavailableCause: Schema.Literals<readonly ["NotInstalled", "SignedOut", "Misconfigured", "NoCapability"]>;
20
+ export type BackendUnavailableCause = typeof BackendUnavailableCause.Type;
21
+ /** The backends Relay supports: each runs on the user's own CLI login, never on a token Relay holds. */
22
+ export declare const RelayBackendId: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
23
+ export type RelayBackendId = typeof RelayBackendId.Type;
24
+ /**
25
+ * What setup shows for one backend. `Unverified` (installed, version known, never answered yet) until a turn
26
+ * answers (`Ready`) or is refused for sign-in (`Unavailable` with `SignedOut`). Not persisted: every start is
27
+ * `Unverified` or `Unavailable` again. `fix` is one line the person can act on.
28
+ */
29
+ export declare const BackendStatus: Schema.TaggedUnion<{
30
+ readonly Ready: Schema.TaggedStruct<"Ready", {
31
+ readonly backend: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
32
+ readonly label: Schema.String;
33
+ readonly version: Schema.String;
34
+ }>;
35
+ readonly Unavailable: Schema.TaggedStruct<"Unavailable", {
36
+ readonly backend: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
37
+ readonly label: Schema.String;
38
+ readonly version: Schema.optionalKey<Schema.String>;
39
+ readonly cause: Schema.Literals<readonly ["NotInstalled", "SignedOut", "Misconfigured", "NoCapability"]>;
40
+ readonly fix: Schema.String;
41
+ }>;
42
+ readonly Unverified: Schema.TaggedStruct<"Unverified", {
43
+ readonly backend: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
44
+ readonly label: Schema.String;
45
+ readonly version: Schema.String;
46
+ }>;
47
+ }>;
48
+ export type BackendStatus = typeof BackendStatus.Type;
49
+ /** Why a confirmation can't be answered: answered already, withdrawn with its run, or never asked. */
50
+ export declare const DecisionState: Schema.TaggedUnion<{
51
+ readonly Decided: Schema.TaggedStruct<"Decided", {
52
+ readonly allow: Schema.Boolean;
53
+ }>;
54
+ readonly Expired: Schema.TaggedStruct<"Expired", {}>;
55
+ readonly Unknown: Schema.TaggedStruct<"Unknown", {}>;
56
+ }>;
57
+ export type DecisionState = typeof DecisionState.Type;
58
+ /** One tool as the dock lists it for a session. */
59
+ export declare const SessionTool: Schema.Struct<{
60
+ readonly name: Schema.String;
61
+ readonly access: Schema.Literals<readonly ["read", "write", "host"]>;
62
+ readonly available: Schema.Boolean;
63
+ readonly unavailableReason: Schema.optional<Schema.String>;
64
+ }>;
65
+ export interface SessionTool extends Schema.Schema.Type<typeof SessionTool> {
66
+ }
67
+ /**
68
+ * What the dock shows for a session: its tools, the backend its next turn runs on, and whether a run can
69
+ * be stopped (the dock offers Stop only when `cancel` is true).
70
+ */
71
+ export declare const SessionInfo: Schema.Struct<{
72
+ readonly tools: Schema.$Array<Schema.Struct<{
73
+ readonly name: Schema.String;
74
+ readonly access: Schema.Literals<readonly ["read", "write", "host"]>;
75
+ readonly available: Schema.Boolean;
76
+ readonly unavailableReason: Schema.optional<Schema.String>;
77
+ }>>;
78
+ readonly backend: Schema.Literals<readonly ["claude-code", "codex-cli"]>;
79
+ readonly cancel: Schema.Boolean;
80
+ }>;
81
+ export interface SessionInfo extends Schema.Schema.Type<typeof SessionInfo> {
82
+ }
83
+ /**
84
+ * What a confirmed write did, as the product projects it: a display-safe line, the provider's id for what
85
+ * was made, and where to see it.
86
+ */
87
+ export declare const WriteReceipt: Schema.Struct<{
88
+ readonly summary: Schema.String;
89
+ readonly providerId: Schema.String;
90
+ readonly link: Schema.optionalKey<Schema.String>;
91
+ }>;
92
+ export interface WriteReceipt extends Schema.Schema.Type<typeof WriteReceipt> {
93
+ }
94
+ /** Everything the dock renders. `seq` counts up within one subscription; a reconnect starts from a `Snapshot`. */
95
+ export declare const RelayEvent: Schema.TaggedUnion<{
96
+ readonly ApprovalPending: Schema.TaggedStruct<"ApprovalPending", {
97
+ readonly session: Schema.String;
98
+ readonly seq: Schema.Int;
99
+ readonly call: Schema.String;
100
+ readonly approvalId: Schema.String;
101
+ }>;
102
+ readonly Cancelled: Schema.TaggedStruct<"Cancelled", {
103
+ readonly session: Schema.String;
104
+ readonly seq: Schema.Int;
105
+ readonly runIds: Schema.$Array<Schema.String>;
106
+ }>;
107
+ readonly ConfirmationRequired: Schema.TaggedStruct<"ConfirmationRequired", {
108
+ readonly session: Schema.String;
109
+ readonly seq: Schema.Int;
110
+ readonly call: Schema.String;
111
+ readonly action: Schema.Struct<{
112
+ readonly verb: Schema.String;
113
+ readonly target: Schema.Struct<{
114
+ readonly product: Schema.String;
115
+ readonly kind: Schema.String;
116
+ readonly id: Schema.String;
117
+ }>;
118
+ readonly args: Schema.Codec<Schema.Json, Schema.Json, never, never>;
119
+ }>;
120
+ readonly reversible: Schema.Boolean;
121
+ }>;
122
+ readonly ConfirmationResolved: Schema.TaggedStruct<"ConfirmationResolved", {
123
+ readonly session: Schema.String;
124
+ readonly seq: Schema.Int;
125
+ readonly call: Schema.String;
126
+ readonly decision: Schema.Literals<readonly ["confirmed", "declined", "expired"]>;
127
+ }>;
128
+ readonly MessagePlaced: Schema.TaggedStruct<"MessagePlaced", {
129
+ readonly session: Schema.String;
130
+ readonly seq: Schema.Int;
131
+ readonly id: Schema.String;
132
+ readonly requestId: Schema.String;
133
+ readonly text: Schema.String;
134
+ }>;
135
+ readonly MessageQueued: Schema.TaggedStruct<"MessageQueued", {
136
+ readonly session: Schema.String;
137
+ readonly seq: Schema.Int;
138
+ readonly requestId: Schema.String;
139
+ }>;
140
+ readonly MessageWithdrawn: Schema.TaggedStruct<"MessageWithdrawn", {
141
+ readonly session: Schema.String;
142
+ readonly seq: Schema.Int;
143
+ readonly requestId: Schema.String;
144
+ }>;
145
+ readonly RunFailed: Schema.TaggedStruct<"RunFailed", {
146
+ readonly session: Schema.String;
147
+ readonly seq: Schema.Int;
148
+ readonly runIds: Schema.$Array<Schema.String>;
149
+ readonly cause: Schema.String;
150
+ readonly fix: Schema.String;
151
+ }>;
152
+ readonly RunFinished: Schema.TaggedStruct<"RunFinished", {
153
+ readonly session: Schema.String;
154
+ readonly seq: Schema.Int;
155
+ readonly runIds: Schema.$Array<Schema.String>;
156
+ }>;
157
+ readonly RunStarted: Schema.TaggedStruct<"RunStarted", {
158
+ readonly session: Schema.String;
159
+ readonly seq: Schema.Int;
160
+ readonly runIds: Schema.$Array<Schema.String>;
161
+ }>;
162
+ readonly Snapshot: Schema.TaggedStruct<"Snapshot", {
163
+ readonly session: Schema.String;
164
+ readonly seq: Schema.Int;
165
+ readonly messages: Schema.$Array<Schema.Struct<{
166
+ readonly id: Schema.String;
167
+ readonly role: Schema.Literals<readonly ["user", "relay"]>;
168
+ readonly text: Schema.String;
169
+ }>>;
170
+ /** The run in flight, empty when idle. */
171
+ readonly runIds: Schema.$Array<Schema.String>;
172
+ /** Messages accepted but not yet in the transcript, oldest first: they wait for the run in flight. */
173
+ readonly queued: Schema.$Array<Schema.String>;
174
+ }>;
175
+ readonly TextDelta: Schema.TaggedStruct<"TextDelta", {
176
+ readonly session: Schema.String;
177
+ readonly seq: Schema.Int;
178
+ readonly text: Schema.String;
179
+ }>;
180
+ readonly ToolFinished: Schema.TaggedStruct<"ToolFinished", {
181
+ readonly session: Schema.String;
182
+ readonly seq: Schema.Int;
183
+ readonly call: Schema.String;
184
+ readonly ok: Schema.Boolean;
185
+ readonly summary: Schema.String;
186
+ readonly cites: Schema.$Array<Schema.Struct<{
187
+ readonly product: Schema.String;
188
+ readonly kind: Schema.String;
189
+ readonly id: Schema.String;
190
+ }>>;
191
+ readonly receipt: Schema.optionalKey<Schema.Struct<{
192
+ readonly summary: Schema.String;
193
+ readonly providerId: Schema.String;
194
+ readonly link: Schema.optionalKey<Schema.String>;
195
+ }>>;
196
+ }>;
197
+ readonly ToolStarted: Schema.TaggedStruct<"ToolStarted", {
198
+ readonly session: Schema.String;
199
+ readonly seq: Schema.Int;
200
+ readonly call: Schema.String;
201
+ readonly capability: Schema.String;
202
+ readonly summary: Schema.String;
203
+ readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
204
+ }>;
205
+ }>;
206
+ export type RelayEvent = typeof RelayEvent.Type;
207
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAI/B,uCAAuC;AACvC,eAAO,MAAM,YAAY,2FAAmF,CAAA;AAC5G,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,sGAAsG;AACtG,eAAO,MAAM,SAAS;;;;EAIpB,CAAA;AACF,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC;CAAG;AAE1E,+HAA+H;AAC/H,eAAO,MAAM,YAAY,QAAS,SAAS,KAAG,MAAyD,CAAA;AAEvG,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,qDAA6C,CAAA;AAC1E,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;AAE3D,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,0FAAkF,CAAA;AACtH,MAAM,MAAM,uBAAuB,GAAG,OAAO,uBAAuB,CAAC,IAAI,CAAA;AAEzE,wGAAwG;AACxG,eAAO,MAAM,cAAc,wDAAgD,CAAA;AAC3E,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAIvD;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EASxB,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAA;AAErD,sGAAsG;AACtG,eAAO,MAAM,aAAa;;;;;;EAIxB,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAA;AAErD,mDAAmD;AACnD,eAAO,MAAM,WAAW;;;;;EAKtB,CAAA;AACF,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC;CAAG;AAE9E;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;EAItB,CAAA;AACF,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC;CAAG;AAE9E;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;EAIvB,CAAA;AACF,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC;CAAG;AAShF,kHAAkH;AAClH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAMnB,0CAA0C;;QAE1C,sGAAsG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxG,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Capabilities as the harness holds them: one list of `@knpkv/capability` capabilities with their
3
+ * types closed over, so the harness can run any of them from the model's JSON without `any`.
4
+ *
5
+ * Decoding, encoding and failure handling are the capability package's (`invoke`, `describeCall`);
6
+ * this module only erases types and records what the gate needs.
7
+ *
8
+ * @module
9
+ */
10
+ import { type Capability, type CapabilityEncodingFailed, type CapabilityFailed, type CapabilityInputInvalid, type FailureSchema, type InputSchema, type InvocationResult, type PendingAction, type PlainSchema } from "@knpkv/capability";
11
+ import { Schema } from "effect";
12
+ import type { Effect } from "effect";
13
+ import type * as JsonSchema from "effect/JsonSchema";
14
+ import type { WriteReceipt } from "./model.js";
15
+ /** What a person must agree to before a gated capability runs. */
16
+ export interface Gate {
17
+ readonly access: "write" | "host";
18
+ readonly reversible: boolean;
19
+ readonly describe: (args: Schema.Json) => Effect.Effect<PendingAction, CapabilityInputInvalid | CapabilityEncodingFailed>;
20
+ }
21
+ /** One registered capability, its types erased behind closures. */
22
+ export interface RegisteredCapability<Requirements> {
23
+ readonly name: string;
24
+ readonly description: string;
25
+ /** `undefined` for a read: it runs without anyone agreeing first. */
26
+ readonly gate: Gate | undefined;
27
+ /** A short display name, for activity rows. */
28
+ readonly label: string;
29
+ /** A display-safe line for one call: a write's action verb, or the label. */
30
+ readonly summarize: (args: Schema.Json) => string;
31
+ /** What a completed call made, for writes whose product projects a receipt. */
32
+ readonly receipt: (result: InvocationResult) => WriteReceipt | undefined;
33
+ /** JSON Schema of the input, for the model's tool list and argument validation. */
34
+ readonly parameters: JsonSchema.JsonSchema;
35
+ /** `args` is the model's JSON for this call; the capability decodes it at the boundary. */
36
+ readonly run: (args: Schema.Json) => Effect.Effect<InvocationResult, CapabilityInputInvalid | CapabilityFailed | CapabilityEncodingFailed, Requirements>;
37
+ }
38
+ /** How the dock shows a capability's calls. Every field has a default. */
39
+ export interface DisplayOptions<Output extends PlainSchema> {
40
+ /** Defaults to the capability name with spaces: `get_pull_request` is "get pull request". */
41
+ readonly label?: string;
42
+ /** A write's receipt, from its decoded output: a display-safe line, the provider's id, a link. */
43
+ readonly receipt?: (output: Output["Type"]) => WriteReceipt;
44
+ }
45
+ /** Register a capability for Relay, with how the dock shows its calls. */
46
+ export declare const register: <Name extends string, Input extends InputSchema, Output extends PlainSchema, Failure extends FailureSchema, Requirements>(capability: Capability<Name, Input, Output, Failure, Requirements>, display?: DisplayOptions<Output>) => RegisteredCapability<Requirements>;
47
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAElB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,KAAK,UAAU,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,kEAAkE;AAClE,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,CACjB,IAAI,EAAE,MAAM,CAAC,IAAI,KACd,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,sBAAsB,GAAG,wBAAwB,CAAC,CAAA;CACrF;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB,CAAC,YAAY;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,MAAM,CAAA;IACjD,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,YAAY,GAAG,SAAS,CAAA;IACxE,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAA;IAC1C,2FAA2F;IAC3F,QAAQ,CAAC,GAAG,EAAE,CACZ,IAAI,EAAE,MAAM,CAAC,IAAI,KACd,MAAM,CAAC,MAAM,CAChB,gBAAgB,EAChB,sBAAsB,GAAG,gBAAgB,GAAG,wBAAwB,EACpE,YAAY,CACb,CAAA;CACF;AAED,0EAA0E;AAC1E,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,WAAW;IACxD,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,kGAAkG;IAClG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,YAAY,CAAA;CAC5D;AAED,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,GACnB,IAAI,SAAS,MAAM,EACnB,KAAK,SAAS,WAAW,EACzB,MAAM,SAAS,WAAW,EAC1B,OAAO,SAAS,aAAa,EAC7B,YAAY,cAEA,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,YACzD,cAAc,CAAC,MAAM,CAAC,KAC9B,oBAAoB,CAAC,YAAY,CA0BnC,CAAA"}
package/dist/turn.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * One model turn over a CLI-backed `LanguageModel`, with tool calls carried in a JSON schema.
3
+ *
4
+ * **Mental model**
5
+ *
6
+ * - **The CLI never runs tools.** `claude --print` and `codex exec` are asked for one structured
7
+ * answer: either tool calls or a final reply. The harness runs the tools, behind its gate, and the
8
+ * next turn sees their results. That keeps the user's own CLI login as the only credential and the
9
+ * permission gate as the only path to a product.
10
+ * - **The transcript is rendered, not replayed into provider sessions.** Each turn gets the whole
11
+ * visible transcript, so switching backends mid-session needs no provider state.
12
+ *
13
+ * @module
14
+ */
15
+ import { Effect, Schema } from "effect";
16
+ import { LanguageModel } from "effect/ai";
17
+ /** A tool as the model is told about it. */
18
+ export interface TurnTool {
19
+ readonly name: string;
20
+ readonly description: string;
21
+ readonly parameters: Schema.Json;
22
+ }
23
+ /** One transcript line as the model reads it. */
24
+ export type TurnLine = {
25
+ readonly _tag: "User";
26
+ readonly text: string;
27
+ } | {
28
+ readonly _tag: "Relay";
29
+ readonly text: string;
30
+ } | {
31
+ readonly _tag: "ToolCall";
32
+ readonly id: string;
33
+ readonly name: string;
34
+ readonly arguments: Schema.Json;
35
+ } | {
36
+ readonly _tag: "ToolResult";
37
+ readonly id: string;
38
+ readonly name: string;
39
+ readonly text: string;
40
+ readonly isError: boolean;
41
+ };
42
+ export interface TurnRequest {
43
+ readonly instructions: string;
44
+ readonly tools: ReadonlyArray<TurnTool>;
45
+ readonly transcript: ReadonlyArray<TurnLine>;
46
+ }
47
+ /** What the model returns for one turn. An empty `toolCalls` means `reply` is the final answer. */
48
+ export declare const Turn: Schema.Struct<{
49
+ readonly reply: Schema.String;
50
+ readonly toolCalls: Schema.$Array<Schema.Struct<{
51
+ readonly name: Schema.String;
52
+ readonly arguments: Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>;
53
+ }>>;
54
+ }>;
55
+ export type Turn = typeof Turn.Type;
56
+ /** The prompt one turn sends: instructions, the tool list with schemas, the transcript, the answer rule. */
57
+ export declare const renderTurnPrompt: (request: TurnRequest) => string;
58
+ /** Run one turn on whatever `LanguageModel` is provided: the user's Claude Code or Codex CLI. */
59
+ export declare const runTurn: (request: TurnRequest) => Effect.Effect<{
60
+ readonly reply: string;
61
+ readonly toolCalls: readonly {
62
+ readonly name: string;
63
+ readonly arguments: {
64
+ readonly [x: string]: Schema.Json;
65
+ };
66
+ }[];
67
+ }, import("effect/ai/AiError").AiError, LanguageModel.LanguageModel>;
68
+ //# sourceMappingURL=turn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,4CAA4C;AAC5C,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAA;CACjC;AAED,iDAAiD;AACjD,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAA;CAAE,GAC1G;IACA,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B,CAAA;AAEH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;CAC7C;AAED,mGAAmG;AACnG,eAAO,MAAM,IAAI;;;;;;EAGf,CAAA;AACF,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAA;AAenC,4GAA4G;AAC5G,eAAO,MAAM,gBAAgB,YAAa,WAAW,KAAG,MAmB1C,CAAA;AAEd,iGAAiG;AACjG,eAAO,MAAM,OAAO;;;;;;;;oEAOlB,CAAA"}
package/dist/wire.d.ts ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Relay's wire contract: what a product's `/…/relay` routes accept and send, and what the browser decodes.
3
+ * Browser-safe: it imports only `effect` and `@knpkv/capability`, never the harness, Pi or SQLite, so a page
4
+ * can import `@knpkv/relay/wire` without pulling the server in.
5
+ *
6
+ * **Mental model**
7
+ *
8
+ * - **One stream per conversation.** `GET events?product&kind&id` sends `data: <RelayStreamFrame JSON>`
9
+ * frames: a `Snapshot` first, then live {@link RelayEvent}s. `Unauthorized` (the browser's session ended)
10
+ * and `StreamFailed` (the server could not read the session's events) end the stream.
11
+ * - **Writes answer with what happened.** `messages` is 202 {@link RelayMessageAccepted}; `cancel` and
12
+ * `decisions` are 204, or 409 {@link RelayConflictError} with the state they found. Every route can be 503
13
+ * {@link RelayUnavailableError} with the fix when Relay could not start in that process.
14
+ *
15
+ * A product narrows `ref` to its own objects and may add a typed `context` to a message; both are its own
16
+ * schema built on these.
17
+ *
18
+ * @module
19
+ */
20
+ import { Schema } from "effect";
21
+ export { BackendStatus, BackendUnavailableCause, CapabilityAccess, DecisionState, ObjectRef, objectRefKey, RelayBackendId, RelayEvent, RelayProduct, SessionInfo, SessionTool, WriteReceipt } from "./model.js";
22
+ /** One `data:` frame of the events stream: an event, or why the stream ended. */
23
+ export declare const RelayStreamFrame: Schema.Union<readonly [Schema.TaggedUnion<{
24
+ readonly ApprovalPending: Schema.TaggedStruct<"ApprovalPending", {
25
+ readonly session: Schema.String;
26
+ readonly seq: Schema.Int;
27
+ readonly call: Schema.String;
28
+ readonly approvalId: Schema.String;
29
+ }>;
30
+ readonly Cancelled: Schema.TaggedStruct<"Cancelled", {
31
+ readonly session: Schema.String;
32
+ readonly seq: Schema.Int;
33
+ readonly runIds: Schema.$Array<Schema.String>;
34
+ }>;
35
+ readonly ConfirmationRequired: Schema.TaggedStruct<"ConfirmationRequired", {
36
+ readonly session: Schema.String;
37
+ readonly seq: Schema.Int;
38
+ readonly call: Schema.String;
39
+ readonly action: Schema.Struct<{
40
+ readonly verb: Schema.String;
41
+ readonly target: Schema.Struct<{
42
+ readonly product: Schema.String;
43
+ readonly kind: Schema.String;
44
+ readonly id: Schema.String;
45
+ }>;
46
+ readonly args: Schema.Codec<Schema.Json, Schema.Json, never, never>;
47
+ }>;
48
+ readonly reversible: Schema.Boolean;
49
+ }>;
50
+ readonly ConfirmationResolved: Schema.TaggedStruct<"ConfirmationResolved", {
51
+ readonly session: Schema.String;
52
+ readonly seq: Schema.Int;
53
+ readonly call: Schema.String;
54
+ readonly decision: Schema.Literals<readonly ["confirmed", "declined", "expired"]>;
55
+ }>;
56
+ readonly MessagePlaced: Schema.TaggedStruct<"MessagePlaced", {
57
+ readonly session: Schema.String;
58
+ readonly seq: Schema.Int;
59
+ readonly id: Schema.String;
60
+ readonly requestId: Schema.String;
61
+ readonly text: Schema.String;
62
+ }>;
63
+ readonly MessageQueued: Schema.TaggedStruct<"MessageQueued", {
64
+ readonly session: Schema.String;
65
+ readonly seq: Schema.Int;
66
+ readonly requestId: Schema.String;
67
+ }>;
68
+ readonly MessageWithdrawn: Schema.TaggedStruct<"MessageWithdrawn", {
69
+ readonly session: Schema.String;
70
+ readonly seq: Schema.Int;
71
+ readonly requestId: Schema.String;
72
+ }>;
73
+ readonly RunFailed: Schema.TaggedStruct<"RunFailed", {
74
+ readonly session: Schema.String;
75
+ readonly seq: Schema.Int;
76
+ readonly runIds: Schema.$Array<Schema.String>;
77
+ readonly cause: Schema.String;
78
+ readonly fix: Schema.String;
79
+ }>;
80
+ readonly RunFinished: Schema.TaggedStruct<"RunFinished", {
81
+ readonly session: Schema.String;
82
+ readonly seq: Schema.Int;
83
+ readonly runIds: Schema.$Array<Schema.String>;
84
+ }>;
85
+ readonly RunStarted: Schema.TaggedStruct<"RunStarted", {
86
+ readonly session: Schema.String;
87
+ readonly seq: Schema.Int;
88
+ readonly runIds: Schema.$Array<Schema.String>;
89
+ }>;
90
+ readonly Snapshot: Schema.TaggedStruct<"Snapshot", {
91
+ readonly session: Schema.String;
92
+ readonly seq: Schema.Int;
93
+ readonly messages: Schema.$Array<Schema.Struct<{
94
+ readonly id: Schema.String;
95
+ readonly role: Schema.Literals<readonly ["user", "relay"]>;
96
+ readonly text: Schema.String;
97
+ }>>;
98
+ readonly runIds: Schema.$Array<Schema.String>;
99
+ readonly queued: Schema.$Array<Schema.String>;
100
+ }>;
101
+ readonly TextDelta: Schema.TaggedStruct<"TextDelta", {
102
+ readonly session: Schema.String;
103
+ readonly seq: Schema.Int;
104
+ readonly text: Schema.String;
105
+ }>;
106
+ readonly ToolFinished: Schema.TaggedStruct<"ToolFinished", {
107
+ readonly session: Schema.String;
108
+ readonly seq: Schema.Int;
109
+ readonly call: Schema.String;
110
+ readonly ok: Schema.Boolean;
111
+ readonly summary: Schema.String;
112
+ readonly cites: Schema.$Array<Schema.Struct<{
113
+ readonly product: Schema.String;
114
+ readonly kind: Schema.String;
115
+ readonly id: Schema.String;
116
+ }>>;
117
+ readonly receipt: Schema.optionalKey<Schema.Struct<{
118
+ readonly summary: Schema.String;
119
+ readonly providerId: Schema.String;
120
+ readonly link: Schema.optionalKey<Schema.String>;
121
+ }>>;
122
+ }>;
123
+ readonly ToolStarted: Schema.TaggedStruct<"ToolStarted", {
124
+ readonly session: Schema.String;
125
+ readonly seq: Schema.Int;
126
+ readonly call: Schema.String;
127
+ readonly capability: Schema.String;
128
+ readonly summary: Schema.String;
129
+ readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
130
+ }>;
131
+ }>, Schema.TaggedStruct<"Unauthorized", {}>, Schema.TaggedStruct<"StreamFailed", {}>]>;
132
+ export type RelayStreamFrame = typeof RelayStreamFrame.Type;
133
+ /** The text a message may carry. */
134
+ export declare const RelayMessageText: Schema.String;
135
+ /**
136
+ * `POST messages`. `requestId` is the client's: a retry with the same one lands once, and the run that
137
+ * answers carries it in `runIds`. `backend` switches the session from its next turn on.
138
+ */
139
+ export declare const RelayMessageRequest: Schema.Struct<{
140
+ readonly ref: Schema.Struct<{
141
+ readonly product: Schema.Literals<readonly ["codecommit", "jcf", "agent-usage", "control-center", "herdr"]>;
142
+ readonly kind: Schema.String;
143
+ readonly id: Schema.String;
144
+ }>;
145
+ readonly text: Schema.String;
146
+ readonly requestId: Schema.String;
147
+ readonly backend: Schema.optionalKey<Schema.Literals<readonly ["claude-code", "codex-cli"]>>;
148
+ }>;
149
+ export interface RelayMessageRequest extends Schema.Schema.Type<typeof RelayMessageRequest> {
150
+ }
151
+ /** `messages` answers 202 with the run id, which is the request id. */
152
+ export declare const RelayMessageAccepted: Schema.Struct<{
153
+ readonly runId: Schema.String;
154
+ }>;
155
+ export interface RelayMessageAccepted extends Schema.Schema.Type<typeof RelayMessageAccepted> {
156
+ }
157
+ /** `POST cancel`: withdraws a queued message, or stops the run in flight. */
158
+ export declare const RelayCancelRequest: Schema.Struct<{
159
+ readonly ref: Schema.Struct<{
160
+ readonly product: Schema.Literals<readonly ["codecommit", "jcf", "agent-usage", "control-center", "herdr"]>;
161
+ readonly kind: Schema.String;
162
+ readonly id: Schema.String;
163
+ }>;
164
+ readonly runId: Schema.String;
165
+ }>;
166
+ export interface RelayCancelRequest extends Schema.Schema.Type<typeof RelayCancelRequest> {
167
+ }
168
+ /** `POST decisions`: the person's answer to one confirmation card. */
169
+ export declare const RelayDecisionRequest: Schema.Struct<{
170
+ readonly ref: Schema.Struct<{
171
+ readonly product: Schema.Literals<readonly ["codecommit", "jcf", "agent-usage", "control-center", "herdr"]>;
172
+ readonly kind: Schema.String;
173
+ readonly id: Schema.String;
174
+ }>;
175
+ readonly callId: Schema.String;
176
+ readonly allow: Schema.Boolean;
177
+ }>;
178
+ export interface RelayDecisionRequest extends Schema.Schema.Type<typeof RelayDecisionRequest> {
179
+ }
180
+ /** What a 409 found instead: the run already over, or the confirmation decided, expired or never asked. */
181
+ export declare const RelayConflictState: Schema.Union<readonly [Schema.TaggedUnion<{
182
+ readonly Decided: Schema.TaggedStruct<"Decided", {
183
+ readonly allow: Schema.Boolean;
184
+ }>;
185
+ readonly Expired: Schema.TaggedStruct<"Expired", {}>;
186
+ readonly Unknown: Schema.TaggedStruct<"Unknown", {}>;
187
+ }>, Schema.TaggedStruct<"NotRunning", {}>]>;
188
+ export type RelayConflictState = typeof RelayConflictState.Type;
189
+ declare const RelayUnavailableError_base: Schema.Class<RelayUnavailableError, Schema.TaggedStruct<"RelayUnavailableError", {
190
+ readonly message: Schema.String;
191
+ readonly fix: Schema.String;
192
+ }>, import("effect/Cause").YieldableError>;
193
+ /** Relay could not start in this process: another one owns its store, or the store is unreadable. */
194
+ export declare class RelayUnavailableError extends RelayUnavailableError_base {
195
+ }
196
+ declare const RelayConflictError_base: Schema.Class<RelayConflictError, Schema.TaggedStruct<"RelayConflictError", {
197
+ readonly state: Schema.Union<readonly [Schema.TaggedUnion<{
198
+ readonly Decided: Schema.TaggedStruct<"Decided", {
199
+ readonly allow: Schema.Boolean;
200
+ }>;
201
+ readonly Expired: Schema.TaggedStruct<"Expired", {}>;
202
+ readonly Unknown: Schema.TaggedStruct<"Unknown", {}>;
203
+ }>, Schema.TaggedStruct<"NotRunning", {}>]>;
204
+ }>, import("effect/Cause").YieldableError>;
205
+ /** A run or confirmation is no longer in the state the request assumed; `state` says which it is in. */
206
+ export declare class RelayConflictError extends RelayConflictError_base {
207
+ }
208
+ declare const RelayBadRequestError_base: Schema.Class<RelayBadRequestError, Schema.TaggedStruct<"RelayBadRequestError", {
209
+ readonly message: Schema.String;
210
+ }>, import("effect/Cause").YieldableError>;
211
+ /** The request named a backend this server does not offer, or was otherwise malformed. */
212
+ export declare class RelayBadRequestError extends RelayBadRequestError_base {
213
+ }
214
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,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;AAInB,iFAAiF;AACjF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sFAI3B,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;AAE3D,oCAAoC;AACpC,eAAO,MAAM,gBAAgB,eAAuE,CAAA;AAEpG;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;EAK9B,CAAA;AACF,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,mBAAmB,CAAC;CAAG;AAE9F,uEAAuE;AACvE,eAAO,MAAM,oBAAoB;;EAA0C,CAAA;AAC3E,MAAM,WAAW,oBAAqB,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC;CAAG;AAEhG,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB;;;;;;;EAAiD,CAAA;AAChF,MAAM,WAAW,kBAAmB,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,CAAC;CAAG;AAE5F,sEAAsE;AACtE,eAAO,MAAM,oBAAoB;;;;;;;;EAAyE,CAAA;AAC1G,MAAM,WAAW,oBAAqB,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC;CAAG;AAEhG,2GAA2G;AAC3G,eAAO,MAAM,kBAAkB;;;;;;2CAAuE,CAAA;AACtG,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAA;;;;;AAE/D,qGAAqG;AACrG,qBAAa,qBAAsB,SAAQ,0BAI1C;CAAG;;;;;;;;;;AAEJ,wGAAwG;AACxG,qBAAa,kBAAmB,SAAQ,uBAIvC;CAAG;;;;AAEJ,0FAA0F;AAC1F,qBAAa,oBAAqB,SAAQ,yBAIzC;CAAG"}