@get-bb/plugin-sdk 0.4.24 → 0.4.28
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/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +0 -25
- package/bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts +0 -200
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +1 -440
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +0 -665
- package/bundled-types/bb-plugin-sdk-testing.d.ts +0 -16
- package/bundled-types/bb-plugin-sdk.d.ts +37 -295
- package/dist/ai-services.js +5 -1
- package/dist/internal/host-policy.js +95 -108
- package/dist/provider-bridge-acp.js +74 -616
- package/dist/provider-bridge-testing.js +177 -580
- package/dist/provider-bridge-worker-entry.mjs +15 -9
- package/dist/provider-bridge.js +64 -558
- package/dist/testing/index.js +133 -114
- package/package.json +1 -1
|
@@ -17,26 +17,6 @@ declare const threadEventItemPresentationLabelSchema: z.ZodObject<{
|
|
|
17
17
|
pending: z.ZodString;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
19
|
type ThreadEventItemPresentationLabel = z.infer<typeof threadEventItemPresentationLabelSchema>;
|
|
20
|
-
/**
|
|
21
|
-
* The row's leading icon, by name. Two vocabularies share the one field:
|
|
22
|
-
*
|
|
23
|
-
* - a host glyph (`{ glyph: "FileText" }`), the same names the plugin
|
|
24
|
-
* branding and provider declaration icons use;
|
|
25
|
-
* - a plugin-declared icon (`{ glyph: "echo-provider/receipt" }`), the
|
|
26
|
-
* namespaced form `"<pluginId>/<name>"` that names an entry of the
|
|
27
|
-
* plugin's manifest map `bb.branding.experimental_icons`
|
|
28
|
-
* (`NAMESPACED_GLYPH_PATTERN` in plugin-icon.ts). The server rejects at
|
|
29
|
-
* ingest a namespaced glyph that is not the emitting plugin's own declared
|
|
30
|
-
* icon; clients resolve the name against the plugin inventory they hold
|
|
31
|
-
* and draw the SVG tinted with `currentColor`.
|
|
32
|
-
*
|
|
33
|
-
* Both are names, never bytes or paths: the row persists the name and
|
|
34
|
-
* follows the plugin's current map at render time. If the plugin is gone or
|
|
35
|
-
* the name is unknown when the row renders, the icon is simply not found and
|
|
36
|
-
* the per-kind fallback glyph draws instead — accepted, so a persisted row
|
|
37
|
-
* never depends on a file that may have moved. The schema stays a plain
|
|
38
|
-
* non-blank string on purpose: persisted rows must parse forever.
|
|
39
|
-
*/
|
|
40
20
|
declare const threadEventItemPresentationIconSchema: z.ZodObject<{
|
|
41
21
|
glyph: z.ZodString;
|
|
42
22
|
}, z.core.$strip>;
|
|
@@ -114,15 +94,6 @@ declare const threadEventWebFetchItemSchema: z.ZodObject<{
|
|
|
114
94
|
url: z.ZodString;
|
|
115
95
|
}, z.core.$strip>;
|
|
116
96
|
type ThreadEventWebFetchItem = z.infer<typeof threadEventWebFetchItemSchema>;
|
|
117
|
-
/**
|
|
118
|
-
* A file the agent read. The single most common generic tool in the
|
|
119
|
-
* production corpus (Claude `Read`: 7,568 calls across 141 threads rendered
|
|
120
|
-
* as an opaque `toolCall`), so it earns a core kind: clients show the path,
|
|
121
|
-
* the permission matrix treats it as a read, and no tool-name table is
|
|
122
|
-
* needed to recognise it. `cmd` carries the native shell form when the
|
|
123
|
-
* provider read through a command (`cat`, `sed -n`) rather than a structured
|
|
124
|
-
* tool, so the row can still show what actually ran.
|
|
125
|
-
*/
|
|
126
97
|
declare const threadEventFileReadItemSchema: z.ZodObject<{
|
|
127
98
|
cmd: z.ZodOptional<z.ZodString>;
|
|
128
99
|
id: z.ZodString;
|
|
@@ -153,16 +124,6 @@ declare const threadEventFileReadItemSchema: z.ZodObject<{
|
|
|
153
124
|
type: z.ZodLiteral<"fileRead">;
|
|
154
125
|
}, z.core.$strip>;
|
|
155
126
|
type ThreadEventFileReadItem = z.infer<typeof threadEventFileReadItemSchema>;
|
|
156
|
-
/**
|
|
157
|
-
* One kind for every exploration tool that is not a file read: grep, glob,
|
|
158
|
-
* and directory listing, discriminated by `mode`. Claude `Grep` + `Glob` and
|
|
159
|
-
* the shell `rg`/`ls`/`find` commands bridges already classify into
|
|
160
|
-
* `command` activity intents all fold into it. `query` is the pattern: text
|
|
161
|
-
* or a regex for `content`, a glob for `path`, and an optional filter for
|
|
162
|
-
* `list` (empty when the whole directory is listed). `path` is the root the
|
|
163
|
-
* search ran under when the provider named one. `cmd` carries the native
|
|
164
|
-
* shell form when the provider searched through a command.
|
|
165
|
-
*/
|
|
166
127
|
declare const threadEventSearchItemSchema: z.ZodObject<{
|
|
167
128
|
cmd: z.ZodOptional<z.ZodString>;
|
|
168
129
|
id: z.ZodString;
|
|
@@ -199,22 +160,6 @@ declare const threadEventSearchItemSchema: z.ZodObject<{
|
|
|
199
160
|
type: z.ZodLiteral<"search">;
|
|
200
161
|
}, z.core.$strip>;
|
|
201
162
|
type ThreadEventSearchItem = z.infer<typeof threadEventSearchItemSchema>;
|
|
202
|
-
/**
|
|
203
|
-
* The agent delegated work to a child agent. One kind replaces the three
|
|
204
|
-
* encodings in the production data — codex `spawnAgent`/`wait` tool calls,
|
|
205
|
-
* the Claude `Agent` tool call with nested child turns, and backgrounded
|
|
206
|
-
* `local_agent` background tasks — and the `thread/openWork` notification:
|
|
207
|
-
* an open delegation IS open work.
|
|
208
|
-
*
|
|
209
|
-
* `childRef` is the provider-native id of the child (a codex agent id, a
|
|
210
|
-
* Claude subagent id, a bb child thread id when the delegation became a bb
|
|
211
|
-
* thread); child turns link back through their `parentToolCallId`.
|
|
212
|
-
* `background: true` marks a delegation that outlives its spawning turn, in
|
|
213
|
-
* which case its progress and terminal state ride the thread-scoped
|
|
214
|
-
* `item/delegation/progress` and `item/delegation/completed` events exactly
|
|
215
|
-
* as `backgroundTask` does; a foreground delegation settles through the
|
|
216
|
-
* ordinary turn-scoped `item/completed`.
|
|
217
|
-
*/
|
|
218
163
|
declare const threadEventDelegationItemSchema: z.ZodObject<{
|
|
219
164
|
background: z.ZodBoolean;
|
|
220
165
|
childRef: z.ZodString;
|
|
@@ -247,14 +192,6 @@ declare const threadEventDelegationItemSchema: z.ZodObject<{
|
|
|
247
192
|
type: z.ZodLiteral<"delegation">;
|
|
248
193
|
}, z.core.$strip>;
|
|
249
194
|
type ThreadEventDelegationItem = z.infer<typeof threadEventDelegationItemSchema>;
|
|
250
|
-
/**
|
|
251
|
-
* A structured plan snapshot the agent maintains as an item: codex
|
|
252
|
-
* `update_plan` (its `turn/plan/updated` notification reaches 295 threads in
|
|
253
|
-
* the production corpus and the UI discards it today) and the Claude
|
|
254
|
-
* `TaskCreate`/`TaskUpdate`/`TodoWrite` family. Each snapshot carries the
|
|
255
|
-
* full step list; a later snapshot supersedes an earlier one. Distinct from
|
|
256
|
-
* the `plan` item, which is the free-text plan-mode document.
|
|
257
|
-
*/
|
|
258
195
|
declare const threadEventPlanStepsItemSchema: z.ZodObject<{
|
|
259
196
|
explanation: z.ZodOptional<z.ZodString>;
|
|
260
197
|
id: z.ZodString;
|
|
@@ -293,14 +230,6 @@ declare const threadEventPlanStepsItemSchema: z.ZodObject<{
|
|
|
293
230
|
type: z.ZodLiteral<"planSteps">;
|
|
294
231
|
}, z.core.$strip>;
|
|
295
232
|
type ThreadEventPlanStepsItem = z.infer<typeof threadEventPlanStepsItemSchema>;
|
|
296
|
-
/**
|
|
297
|
-
* A plugin-defined item kind outside the core vocabulary
|
|
298
|
-
* (`"<pluginId>/<name>"`, see provider-extension-kind.ts). The payload is
|
|
299
|
-
* opaque JSON here; the server validates it against the owning plugin's
|
|
300
|
-
* declared schema at ingest. `presentation` is REQUIRED — an
|
|
301
|
-
* extension item has no core renderer to fall back on, so the declarative
|
|
302
|
-
* base is the only thing every client can show.
|
|
303
|
-
*/
|
|
304
233
|
declare const threadEventExtensionItemSchema: z.ZodObject<{
|
|
305
234
|
id: z.ZodString;
|
|
306
235
|
kind: z.ZodString & z.ZodType<`${string}/${string}`, string, z.core.$ZodTypeInternals<`${string}/${string}`, string>>;
|
|
@@ -331,13 +260,6 @@ declare const threadEventExtensionItemSchema: z.ZodObject<{
|
|
|
331
260
|
type: z.ZodLiteral<"extension">;
|
|
332
261
|
}, z.core.$strip>;
|
|
333
262
|
type ThreadEventExtensionItem = z.infer<typeof threadEventExtensionItemSchema>;
|
|
334
|
-
/**
|
|
335
|
-
* A materialized provider background task. Dynamic workflows (taskType
|
|
336
|
-
* "local_workflow"), backgrounded shell commands (taskType "local_bash"), and
|
|
337
|
-
* backgrounded subagents (taskType "local_agent" / "local_subagent") become
|
|
338
|
-
* items. The item id is derived from the provider task id and stays stable
|
|
339
|
-
* across the started → progress* → completed lifecycle.
|
|
340
|
-
*/
|
|
341
263
|
declare const threadEventBackgroundTaskItemSchema: z.ZodObject<{
|
|
342
264
|
description: z.ZodString;
|
|
343
265
|
error: z.ZodOptional<z.ZodString>;
|
|
@@ -982,7 +904,6 @@ declare const threadEventItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
982
904
|
type: z.ZodLiteral<"extension">;
|
|
983
905
|
}, z.core.$strip>], "type">;
|
|
984
906
|
type ThreadEventItem = z.infer<typeof threadEventItemSchema>;
|
|
985
|
-
/** All thread events — provider-originated or system-originated. */
|
|
986
907
|
declare const threadEventSchema: z.ZodPipe<z.ZodUnknown, z.ZodUnion<readonly [z.ZodIntersection<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
987
908
|
threadId: z.ZodString;
|
|
988
909
|
type: z.ZodLiteral<"thread/started">;
|
|
@@ -2950,6 +2871,7 @@ declare const threadEventSchema: z.ZodPipe<z.ZodUnknown, z.ZodUnion<readonly [z.
|
|
|
2950
2871
|
turnId: z.ZodOptional<z.ZodString>;
|
|
2951
2872
|
type: z.ZodLiteral<"system/manager/user_message">;
|
|
2952
2873
|
}, z.core.$strip>, z.ZodObject<{
|
|
2874
|
+
cause: z.ZodOptional<z.ZodLiteral<"host-connection-lost">>;
|
|
2953
2875
|
reason: z.ZodEnum<{
|
|
2954
2876
|
"host-daemon-restarted": "host-daemon-restarted";
|
|
2955
2877
|
"manual-stop": "manual-stop";
|
|
@@ -3394,12 +3316,6 @@ declare const promptInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3394
3316
|
}, z.core.$strip>], "type">;
|
|
3395
3317
|
type PromptInput = z.infer<typeof promptInputSchema>;
|
|
3396
3318
|
|
|
3397
|
-
/**
|
|
3398
|
-
* The inclusive `[min, max]` range of `thread/delta` grammar versions a bridge
|
|
3399
|
-
* speaks. Distinct from the JSON-RPC `protocolVersion`: the envelope can stay
|
|
3400
|
-
* put while the delta vocabulary grows, and a bridge that speaks both v2 and
|
|
3401
|
-
* v3 says so here instead of forcing a daemon bump.
|
|
3402
|
-
*/
|
|
3403
3319
|
declare const bridgeGrammarVersionsSchema: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
3404
3320
|
type BridgeGrammarVersions = z.infer<typeof bridgeGrammarVersionsSchema>;
|
|
3405
3321
|
|
|
@@ -4185,15 +4101,6 @@ declare const threadDeltaSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
4185
4101
|
}, z.core.$strip>], "kind">;
|
|
4186
4102
|
type ThreadDelta = z.infer<typeof threadDeltaSchema>;
|
|
4187
4103
|
|
|
4188
|
-
/**
|
|
4189
|
-
* The `thread/delta` grammar range this assembler speaks, reported to every
|
|
4190
|
-
* bridge in the `initialize` params so the two sides negotiate a version
|
|
4191
|
-
* (see `negotiateGrammarVersion` in the protocol). `[3, 3]`: the v2 dialects
|
|
4192
|
-
* (`message.*`, `usage.turn`/`usage.exact`) are deleted, so a bridge whose
|
|
4193
|
-
* range lacks 3 — including one that predates `grammarVersions` and reads as
|
|
4194
|
-
* `[2, 2]` — is refused at the handshake with a legible error instead of
|
|
4195
|
-
* connecting to an assembler that would drop its every stream.
|
|
4196
|
-
*/
|
|
4197
4104
|
declare const ASSEMBLER_GRAMMAR_VERSIONS: BridgeGrammarVersions;
|
|
4198
4105
|
interface DiffCumulativeTextArgs {
|
|
4199
4106
|
nextText: string;
|
|
@@ -4205,35 +4112,10 @@ interface DiffCumulativeTextResult {
|
|
|
4205
4112
|
reset: boolean;
|
|
4206
4113
|
}
|
|
4207
4114
|
interface CreateDeltaAssemblerOptions {
|
|
4208
|
-
/** Provider id stamped onto provider/unhandled events. */
|
|
4209
4115
|
providerId: string;
|
|
4210
|
-
/**
|
|
4211
|
-
* Entropy prefix for minted turn/item ids. Defaults to fresh per-assembler
|
|
4212
|
-
* entropy so ids never collide across assembler (process) restarts; tests
|
|
4213
|
-
* inject a fixed prefix for determinism.
|
|
4214
|
-
*/
|
|
4215
4116
|
entropyPrefix?: string;
|
|
4216
|
-
/**
|
|
4217
|
-
* Minimum gap between emitted `item.progress` events per item key
|
|
4218
|
-
* (`flush: true` bypasses it; `item.close` always emits). 500ms default —
|
|
4219
|
-
* the cadence the claude bridge hand-rolled for background-task snapshots,
|
|
4220
|
-
* now the central policy for every provider's progress stream.
|
|
4221
|
-
*/
|
|
4222
4117
|
progressThrottleMs?: number;
|
|
4223
|
-
/**
|
|
4224
|
-
* Coalescing window for streamed-text events (assistant/reasoning/plan
|
|
4225
|
-
* deltas and command/fileChange output deltas) per stream. Within the
|
|
4226
|
-
* window consecutive deltas concatenate into one emitted event of the same
|
|
4227
|
-
* type; the buffer flushes trailing-edge with no timers — on the thread's
|
|
4228
|
-
* next traffic once the window elapsed, on stream close, and before ANY
|
|
4229
|
-
* non-batchable event for the thread (the ordering barrier: coalescing
|
|
4230
|
-
* never reorders text relative to item opens/closes, turn events, errors,
|
|
4231
|
-
* or other streams' flushes). The first delta of a fresh stream always
|
|
4232
|
-
* emits immediately, keeping time-to-first-token unchanged. 100ms default;
|
|
4233
|
-
* 0 disables batching (one event per delta).
|
|
4234
|
-
*/
|
|
4235
4118
|
textDeltaFlushMs?: number;
|
|
4236
|
-
/** Clock override for tests. */
|
|
4237
4119
|
now?: () => number;
|
|
4238
4120
|
}
|
|
4239
4121
|
interface AssembleDeltasArgs {
|
|
@@ -4242,87 +4124,37 @@ interface AssembleDeltasArgs {
|
|
|
4242
4124
|
}
|
|
4243
4125
|
interface DeltaAssembler {
|
|
4244
4126
|
assemble(args: AssembleDeltasArgs): ThreadEvent[];
|
|
4245
|
-
/** bb item id minted for a provider item id (command-plane lookup). */
|
|
4246
4127
|
getBbItemId(threadId: string, providerItemId: string): string | undefined;
|
|
4247
|
-
/** Provider item id behind a bb item id (reverse command-plane lookup). */
|
|
4248
4128
|
getProviderItemId(threadId: string, bbItemId: string): string | undefined;
|
|
4249
|
-
/** bb turn id minted for a vouched provider turn id. */
|
|
4250
4129
|
getBbTurnId(threadId: string, providerTurnId: string): string | undefined;
|
|
4251
|
-
/** Provider turn id behind a bb turn id (steer/interrupt reverse lookup). */
|
|
4252
4130
|
getProviderTurnId(threadId: string, bbTurnId: string): string | undefined;
|
|
4253
4131
|
getOpenTurnId(threadId: string): string | undefined;
|
|
4254
4132
|
}
|
|
4255
4133
|
declare function createDeltaAssembler(options: CreateDeltaAssemblerOptions): DeltaAssembler;
|
|
4256
4134
|
|
|
4257
|
-
/**
|
|
4258
|
-
* Test-side view of the runtime's delta assembly: bridge tests capture raw
|
|
4259
|
-
* JSON-RPC output, and bridges emit `thread/delta` notifications rather than
|
|
4260
|
-
* finished `ThreadEvent`s. These helpers run captured notifications through
|
|
4261
|
-
* the real delta assembler — the exact translation the bridge protocol
|
|
4262
|
-
* adapter performs — so assertions keep working against canonical
|
|
4263
|
-
* `ThreadEvent`s.
|
|
4264
|
-
*/
|
|
4265
|
-
|
|
4266
4135
|
interface CapturedBridgeNotification {
|
|
4267
4136
|
method?: string;
|
|
4268
4137
|
params?: unknown;
|
|
4269
4138
|
}
|
|
4270
4139
|
interface BridgeDeltaEventCollector {
|
|
4271
4140
|
assembler: DeltaAssembler;
|
|
4272
|
-
/** Canonical events for one captured notification (empty for non-deltas). */
|
|
4273
4141
|
assembleMessage(message: CapturedBridgeNotification): ThreadEvent[];
|
|
4274
4142
|
}
|
|
4275
4143
|
declare function createBridgeDeltaEventCollector(providerId?: string): BridgeDeltaEventCollector;
|
|
4276
|
-
/**
|
|
4277
|
-
* All canonical events an ordered capture of bridge notifications assembles
|
|
4278
|
-
* to. Builds a fresh assembler per call, so feed it the full capture (not an
|
|
4279
|
-
* incremental slice) for deterministic ids.
|
|
4280
|
-
*/
|
|
4281
4144
|
declare function assembleCapturedThreadEvents(messages: readonly CapturedBridgeNotification[], providerId?: string): ThreadEvent[];
|
|
4282
|
-
/**
|
|
4283
|
-
* Removed (SDK 0.4.16): the conformance kit assembles `thread/delta` itself.
|
|
4284
|
-
* A transport hands `runBridgeConformance` the raw captured messages
|
|
4285
|
-
* (`CapturedBridgeJsonRpcOutput.takeMessages`) and the run names its
|
|
4286
|
-
* `providerId`; this stub stays one release so a suite written against the
|
|
4287
|
-
* old transport shape fails with the replacement named, not a missing export.
|
|
4288
|
-
*/
|
|
4289
4145
|
declare function toConformanceMessages(): never;
|
|
4290
4146
|
|
|
4291
|
-
/**
|
|
4292
|
-
* Transport abstraction the conformance kit drives. Black-box at the message
|
|
4293
|
-
* level: lines in, JSON-RPC messages out. Two expected implementations — an
|
|
4294
|
-
* in-process bridge (`send` = the bridge's exported line handler,
|
|
4295
|
-
* `takeMessages` = the captured output's drain) and a spawned bridge binary
|
|
4296
|
-
* (stdin write + stdout readline). The kit never sees which: it assembles
|
|
4297
|
-
* the bridge's `thread/delta` notifications itself, through the runtime's
|
|
4298
|
-
* real delta assembler, so the transport hands over raw wire messages only.
|
|
4299
|
-
*/
|
|
4300
4147
|
interface BridgeConformanceTransport {
|
|
4301
|
-
/** Deliver one raw line to the bridge. */
|
|
4302
4148
|
send(line: string): void;
|
|
4303
|
-
/**
|
|
4304
|
-
* Every JSON-RPC message the bridge emitted since the last call, in order:
|
|
4305
|
-
* responses, notifications (`thread/delta` included) and bridge-initiated
|
|
4306
|
-
* requests, as parsed JSON.
|
|
4307
|
-
*/
|
|
4308
4149
|
takeMessages(): unknown[];
|
|
4309
4150
|
close?(): Promise<void> | void;
|
|
4310
4151
|
}
|
|
4311
|
-
/**
|
|
4312
|
-
* Retired. The kit once read its canonical events from a notification the
|
|
4313
|
-
* transport assembled under this method; it now assembles `thread/delta`
|
|
4314
|
-
* itself and reads nothing under this name. Kept because SDK 0.4.x published
|
|
4315
|
-
* it from `@get-bb/plugin-sdk/provider-bridge/testing`; removed at the next
|
|
4316
|
-
* major version.
|
|
4317
|
-
*/
|
|
4318
4152
|
declare const CONFORMANCE_ASSEMBLED_EVENT_METHOD = "conformance/assembledEvent";
|
|
4319
4153
|
type ConformanceStatus = "fail" | "pass" | "skipped";
|
|
4320
4154
|
interface ConformanceCheckResult {
|
|
4321
|
-
/** Stable rule id, e.g. "rpc/unknown-method". */
|
|
4322
4155
|
id: string;
|
|
4323
4156
|
title: string;
|
|
4324
4157
|
status: ConformanceStatus;
|
|
4325
|
-
/** Failure or skip explanation; empty on pass. */
|
|
4326
4158
|
detail: string;
|
|
4327
4159
|
}
|
|
4328
4160
|
interface ConformanceReport {
|
|
@@ -4331,119 +4163,35 @@ interface ConformanceReport {
|
|
|
4331
4163
|
}
|
|
4332
4164
|
|
|
4333
4165
|
interface ConformanceSessionFixture {
|
|
4334
|
-
/** Workspace directory for the session under test. */
|
|
4335
4166
|
cwd: string;
|
|
4336
|
-
/** Prompt expected to elicit at least one assistant-message item. */
|
|
4337
4167
|
promptInput: PromptInput[];
|
|
4338
|
-
/**
|
|
4339
|
-
* A prompt this provider accepts and completes locally, without producing
|
|
4340
|
-
* any of the activity that opens a bb turn — Claude Code's `/clear` is the
|
|
4341
|
-
* canonical example (#1431). Opting in enables
|
|
4342
|
-
* `turn/settles-without-activity`.
|
|
4343
|
-
*
|
|
4344
|
-
* The kit cannot elicit this shape generically: only the bridge knows what
|
|
4345
|
-
* its provider handles as zero work. A fixture that omits it produces no
|
|
4346
|
-
* result for that rule rather than a skip, so bridges that have not opted in
|
|
4347
|
-
* keep a fully green report.
|
|
4348
|
-
*/
|
|
4349
4168
|
zeroWorkPromptInput?: PromptInput[];
|
|
4350
|
-
/**
|
|
4351
|
-
* A prompt that opens a turn and never settles it on its own, so the kit
|
|
4352
|
-
* can interrupt it. Opting in enables `session/threads-independent` and
|
|
4353
|
-
* `stop/interrupt-settles-before-result` (the kit names the turn to the
|
|
4354
|
-
* bridge through its own assembler's reverse map). A fixture that omits it
|
|
4355
|
-
* produces no result for those rules.
|
|
4356
|
-
*/
|
|
4357
4169
|
interruptiblePromptInput?: PromptInput[];
|
|
4358
|
-
/** Execution options for the session; the kit defaults to full mode. */
|
|
4359
4170
|
options?: Record<string, unknown>;
|
|
4360
|
-
/**
|
|
4361
|
-
* The plugin's declared icons (`bb.branding.experimental_icons`): its
|
|
4362
|
-
* plugin id and the declared names. Opting in enables
|
|
4363
|
-
* `presentation/icon-namespaced-declared`, which fails when any item's
|
|
4364
|
-
* `presentation.icon.glyph` is a namespaced glyph (`"<pluginId>/<name>"`)
|
|
4365
|
-
* that names another plugin or an undeclared name — what the server
|
|
4366
|
-
* would refuse at ingest with `provider/unhandled`. A `server: "bb"` tool
|
|
4367
|
-
* row is not inspected: its presentation came from the plugin that
|
|
4368
|
-
* registered the tool, and the server checks it against that plugin. A
|
|
4369
|
-
* fixture that omits `icons` produces no result for the rule, like the
|
|
4370
|
-
* other opt-in rules, so a bridge whose plugin declares no icons keeps a
|
|
4371
|
-
* fully green report.
|
|
4372
|
-
*/
|
|
4373
4171
|
icons?: {
|
|
4374
4172
|
pluginId: string;
|
|
4375
4173
|
names: readonly string[];
|
|
4376
4174
|
};
|
|
4377
4175
|
}
|
|
4378
4176
|
|
|
4379
|
-
/**
|
|
4380
|
-
* Recorded-traffic conformance.
|
|
4381
|
-
*
|
|
4382
|
-
* The scripted scenarios in `scenarios.ts` drive a bridge with a fake
|
|
4383
|
-
* provider the kit authors wrote. This set drives it with what the provider
|
|
4384
|
-
* CLI really emitted: a committed recording (`recordings/<provider>/<cell>`),
|
|
4385
|
-
* replayed through the bridge by `testing/parity.ts`, checked with the same
|
|
4386
|
-
* grammar rules. A bridge passes when the replay reproduces a complete,
|
|
4387
|
-
* schema-valid, grammar-clean session for every recorded cell — so a
|
|
4388
|
-
* translation change that only the real dialect exercises fails conformance,
|
|
4389
|
-
* not just a golden.
|
|
4390
|
-
*
|
|
4391
|
-
* Pure over a replay's output, like `checkItemOpensBeforeDelta`: the caller
|
|
4392
|
-
* owns the bridge transport and the replay; this module owns the verdicts.
|
|
4393
|
-
*/
|
|
4394
|
-
|
|
4395
|
-
/** The cells every bridge is expected to reproduce (the live-QA matrix core). */
|
|
4396
4177
|
declare const RECORDED_CONFORMANCE_CELLS: readonly ["turn-tools", "steer", "stop-interrupt", "approval-allow", "approval-deny", "user-question", "resume", "fork"];
|
|
4397
4178
|
type RecordedConformanceCell = (typeof RECORDED_CONFORMANCE_CELLS)[number];
|
|
4398
4179
|
interface RecordedCellReplay {
|
|
4399
4180
|
provider: string;
|
|
4400
4181
|
cell: string;
|
|
4401
|
-
/** Events the replayed bridge output assembled to, in order. */
|
|
4402
4182
|
events: readonly ThreadEvent[];
|
|
4403
|
-
/**
|
|
4404
|
-
* Events the recording's own bridge output assembled to: the turn count the
|
|
4405
|
-
* replay must reach. A provider that legitimately refused a cell (an ACP
|
|
4406
|
-
* agent without `session/fork`) recorded no turns, and the replay must
|
|
4407
|
-
* reproduce that rather than invent one.
|
|
4408
|
-
*/
|
|
4409
4183
|
recordedEvents: readonly ThreadEvent[];
|
|
4410
|
-
/** Requests the harness had to answer for the bridge, or gates that timed out. */
|
|
4411
4184
|
stalls: readonly string[];
|
|
4412
4185
|
}
|
|
4413
|
-
/**
|
|
4414
|
-
* The verdicts for one replayed cell. Rule ids are `recorded/<cell>/<rule>`
|
|
4415
|
-
* so a report lists every cell and a regression names the one it broke.
|
|
4416
|
-
*/
|
|
4417
4186
|
declare function checkRecordedCellReplay(replay: RecordedCellReplay): ConformanceCheckResult[];
|
|
4418
4187
|
|
|
4419
4188
|
interface RunBridgeConformanceOptions {
|
|
4420
4189
|
transport: BridgeConformanceTransport;
|
|
4421
4190
|
session: ConformanceSessionFixture;
|
|
4422
|
-
/**
|
|
4423
|
-
* The provider id the bridge's plugin registers. The kit assembles the
|
|
4424
|
-
* bridge's `thread/delta` stream through the runtime's real delta
|
|
4425
|
-
* assembler, and the canonical events it builds carry this id, as the
|
|
4426
|
-
* runtime's would.
|
|
4427
|
-
*/
|
|
4428
4191
|
providerId: string;
|
|
4429
|
-
/** Per-wait timeout. Conformant bridges answer fast; keep this tight. */
|
|
4430
4192
|
timeoutMs?: number;
|
|
4431
4193
|
}
|
|
4432
|
-
/**
|
|
4433
|
-
* Drive one bridge through the conformance scenarios: JSON-RPC hygiene, the
|
|
4434
|
-
* initialize handshake, then a shared session lifecycle (start → turn →
|
|
4435
|
-
* grammar checks → release stop → resume with its identity → id-uniqueness
|
|
4436
|
-
* → fork with its identity when the handshake declares fork → the opt-in
|
|
4437
|
-
* rules), released at the end the way the runtime releases a thread it
|
|
4438
|
-
* detaches. One transport for the whole run, mirroring a real bridge
|
|
4439
|
-
* lifetime.
|
|
4440
|
-
*
|
|
4441
|
-
* Against a conformant bridge every result passes. Against a bridge that is
|
|
4442
|
-
* not yet protocol-pure, the failures ARE the migration work list — run it
|
|
4443
|
-
* before migrating and pin the report, then make it shrink.
|
|
4444
|
-
*/
|
|
4445
4194
|
declare function runBridgeConformance(options: RunBridgeConformanceOptions): Promise<ConformanceReport>;
|
|
4446
|
-
/** Compact single-line-per-rule rendering for test snapshots and logs. */
|
|
4447
4195
|
declare function formatConformanceReport(report: ConformanceReport): string;
|
|
4448
4196
|
|
|
4449
4197
|
type BridgeJsonRpcId = string | number;
|
|
@@ -4465,16 +4213,11 @@ interface BridgeJsonRpcOutputMessage {
|
|
|
4465
4213
|
}
|
|
4466
4214
|
interface CapturedBridgeJsonRpcOutput {
|
|
4467
4215
|
messages: BridgeJsonRpcOutputMessage[];
|
|
4468
|
-
/**
|
|
4469
|
-
* Every message since the last call: the conformance transport's drain
|
|
4470
|
-
* (`{ send: handleLine, takeMessages: output.takeMessages }`).
|
|
4471
|
-
*/
|
|
4472
4216
|
takeMessages(): BridgeJsonRpcOutputMessage[];
|
|
4473
4217
|
restore(): void;
|
|
4474
4218
|
}
|
|
4475
4219
|
interface BridgeJsonRpcTestHarness {
|
|
4476
4220
|
messages: BridgeJsonRpcOutputMessage[];
|
|
4477
|
-
/** Every message since the last call: the conformance transport's drain. */
|
|
4478
4221
|
takeMessages(): BridgeJsonRpcOutputMessage[];
|
|
4479
4222
|
flushWork(): Promise<void>;
|
|
4480
4223
|
hasResponse(id: BridgeJsonRpcId): boolean;
|
|
@@ -4482,64 +4225,22 @@ interface BridgeJsonRpcTestHarness {
|
|
|
4482
4225
|
sendRequest(id: BridgeJsonRpcId, method: string, params: BridgeJsonRpcObject): void;
|
|
4483
4226
|
waitForResponse(id: BridgeJsonRpcId): Promise<BridgeJsonRpcOutputMessage>;
|
|
4484
4227
|
}
|
|
4485
|
-
/**
|
|
4486
|
-
* Capture everything a bridge writes to stdout as parsed JSON-RPC messages.
|
|
4487
|
-
* Patches `process.stdout.write` directly (no test-framework spy), so the
|
|
4488
|
-
* kit runs under any runner; `restore()` puts the original writer back.
|
|
4489
|
-
*/
|
|
4490
4228
|
declare function captureBridgeJsonRpcOutput(): CapturedBridgeJsonRpcOutput;
|
|
4491
4229
|
declare function createBridgeJsonRpcTestHarness(handleLine: BridgeJsonRpcLineHandler): BridgeJsonRpcTestHarness;
|
|
4492
4230
|
|
|
4493
|
-
/**
|
|
4494
|
-
* Dual-path calibration support.
|
|
4495
|
-
*
|
|
4496
|
-
* A calibration replays one scripted provider session through both the legacy
|
|
4497
|
-
* adapter and the canonical bridge, then diffs the two ThreadEvent streams.
|
|
4498
|
-
* Anything the diff reports is either a deliberate, documented protocol
|
|
4499
|
-
* difference (the bridge synthesizes item/started, announces thread/identity,
|
|
4500
|
-
* …) or a regression — there is no third category, which is what makes these
|
|
4501
|
-
* suites a graduation gate.
|
|
4502
|
-
*
|
|
4503
|
-
* Ids legitimately differ between the paths: the legacy adapter numbers from
|
|
4504
|
-
* its process-lifetime translator ("turn-1", "claude-assistant-2"), while a
|
|
4505
|
-
* canonical session mints per-session entropy ("bt3f9a2b1c-1-…") so ids stay
|
|
4506
|
-
* unique across resumes (#1224). Normalization interns them by first-seen
|
|
4507
|
-
* order instead of matching either scheme, so a stream that *reused* an id
|
|
4508
|
-
* still diffs.
|
|
4509
|
-
*/
|
|
4510
4231
|
interface NormalizeCalibrationEventsOptions {
|
|
4511
|
-
/**
|
|
4512
|
-
* Ids the provider itself owns (tool call ids, checkpoints) are identical on
|
|
4513
|
-
* both paths and are left alone. Anything reaching the intern table is a
|
|
4514
|
-
* translator- or bridge-minted id.
|
|
4515
|
-
*/
|
|
4516
4232
|
internedIdFields?: readonly string[];
|
|
4517
4233
|
}
|
|
4518
|
-
/**
|
|
4519
|
-
* Normalize one path's stream. Each stream gets its own interner, so the token
|
|
4520
|
-
* a given id receives depends only on the order ids first appear — identical
|
|
4521
|
-
* across paths when the streams agree, different the moment they do not.
|
|
4522
|
-
*/
|
|
4523
4234
|
declare function normalizeCalibrationEvents(events: readonly ThreadEvent[], options?: NormalizeCalibrationEventsOptions): unknown[];
|
|
4524
|
-
/** Compact `type` (+ item type) rendering for asserting a known-divergence list. */
|
|
4525
4235
|
declare function describeCalibrationEvents(events: readonly unknown[]): string[];
|
|
4526
4236
|
|
|
4527
4237
|
declare const BRIDGE_RECORDING_DIRECTIONS: readonly ["runtime→bridge", "bridge→runtime", "provider→bridge", "bridge→provider"];
|
|
4528
4238
|
type BridgeRecordingDirection = (typeof BRIDGE_RECORDING_DIRECTIONS)[number];
|
|
4529
4239
|
interface BridgeRecordingEntry {
|
|
4530
|
-
/** Wall-clock milliseconds when the line crossed. */
|
|
4531
4240
|
ts: number;
|
|
4532
|
-
/**
|
|
4533
|
-
* The recorder's start time, identifying the bridge process that wrote the
|
|
4534
|
-
* entry. A thread can span several bridge processes (the runtime restarts a
|
|
4535
|
-
* bridge, or releases and later resumes the thread), each appending to the
|
|
4536
|
-
* same files with its own `seq`; `(run, seq)` orders entries exactly.
|
|
4537
|
-
*/
|
|
4538
4241
|
run: number;
|
|
4539
|
-
/** Process-wide monotonic counter across all four lanes. */
|
|
4540
4242
|
seq: number;
|
|
4541
4243
|
dir: BridgeRecordingDirection;
|
|
4542
|
-
/** The raw line, without its terminator. */
|
|
4543
4244
|
line: string;
|
|
4544
4245
|
}
|
|
4545
4246
|
|
|
@@ -4558,22 +4259,9 @@ interface BridgeRecordingManifest {
|
|
|
4558
4259
|
interface BridgeRecording {
|
|
4559
4260
|
dir: string;
|
|
4560
4261
|
manifest: BridgeRecordingManifest | null;
|
|
4561
|
-
/** Every lane merged back into wire order: by bridge process, then seq. */
|
|
4562
4262
|
entries: BridgeRecordingEntry[];
|
|
4563
4263
|
}
|
|
4564
|
-
/**
|
|
4565
|
-
* The file a bridge change re-records its side of the wire into
|
|
4566
|
-
* (`pnpm rerecord`): the `bridge→runtime` lane as THIS checkout's bridge
|
|
4567
|
-
* emits it for the recording's provider and runtime lanes. The recorded lane
|
|
4568
|
-
* itself is never rewritten — it is the recording, and a pre-migration
|
|
4569
|
-
* checkout paces its replay from it — so the current expectation lives
|
|
4570
|
-
* beside it. Absent until a bridge change first needs one.
|
|
4571
|
-
*/
|
|
4572
4264
|
declare const CURRENT_BRIDGE_LANE_FILE = "bridge\u2192runtime.current.ndjson";
|
|
4573
|
-
/**
|
|
4574
|
-
* The recording with its `bridge→runtime` lane replaced by the current
|
|
4575
|
-
* expectation when one exists: what the self-suite pins and compares.
|
|
4576
|
-
*/
|
|
4577
4265
|
declare function withCurrentBridgeLane(recording: BridgeRecording): BridgeRecording;
|
|
4578
4266
|
declare function readBridgeRecording(dir: string): BridgeRecording;
|
|
4579
4267
|
interface RecordedCell {
|
|
@@ -4581,13 +4269,8 @@ interface RecordedCell {
|
|
|
4581
4269
|
cell: string;
|
|
4582
4270
|
dir: string;
|
|
4583
4271
|
}
|
|
4584
|
-
/**
|
|
4585
|
-
* Every `<provider>/<cell>` directory under a recordings root that holds at
|
|
4586
|
-
* least one lane, sorted for stable iteration.
|
|
4587
|
-
*/
|
|
4588
4272
|
declare function listRecordedCells(root: string): RecordedCell[];
|
|
4589
4273
|
|
|
4590
|
-
/** One stateful assembler: `thread/delta` notifications in, events out. */
|
|
4591
4274
|
interface ParityAssembler {
|
|
4592
4275
|
assembleMessage(message: {
|
|
4593
4276
|
method?: string;
|
|
@@ -4595,140 +4278,55 @@ interface ParityAssembler {
|
|
|
4595
4278
|
}): ThreadEvent[];
|
|
4596
4279
|
}
|
|
4597
4280
|
type CreateParityAssembler = (providerId: string) => ParityAssembler;
|
|
4598
|
-
/** Project canonical events into timeline rows (the server's projection). */
|
|
4599
4281
|
type ParityRowProjector = (args: {
|
|
4600
4282
|
events: readonly ThreadEvent[];
|
|
4601
4283
|
providerId: string;
|
|
4602
4284
|
}) => unknown[];
|
|
4603
|
-
/** A bridge process, ready to spawn: the bootstrap, the module, its scope. */
|
|
4604
4285
|
interface ProviderBridgeLaunch {
|
|
4605
4286
|
command: string;
|
|
4606
4287
|
args: string[];
|
|
4607
4288
|
cwd: string;
|
|
4608
|
-
/** Added to the harness's own environment for the bridge process. */
|
|
4609
4289
|
env: Record<string, string>;
|
|
4610
4290
|
}
|
|
4611
4291
|
interface ResolveProviderBridgeLaunchOptions {
|
|
4612
|
-
/**
|
|
4613
|
-
* The bridge module: the file whose `experimental_providerBridge` export the
|
|
4614
|
-
* bootstrap runs. Absolute; a built artifact (`host.mjs`) or, with a
|
|
4615
|
-
* TypeScript loader among `nodeArgs`, the source file.
|
|
4616
|
-
*/
|
|
4617
4292
|
modulePath: string;
|
|
4618
|
-
/** The plugin the bridge belongs to (its data and temp directories). */
|
|
4619
4293
|
pluginId: string;
|
|
4620
|
-
/** Working directory of the bridge process; defaults to the caller's. */
|
|
4621
4294
|
cwd?: string;
|
|
4622
|
-
/**
|
|
4623
|
-
* The plugin data directory the bootstrap hands the bridge; defaults to a
|
|
4624
|
-
* fresh temp directory per launch.
|
|
4625
|
-
*/
|
|
4626
4295
|
dataDir?: string;
|
|
4627
|
-
/**
|
|
4628
|
-
* The provider-bridge bootstrap (`bridge-worker-entry`) that runs the
|
|
4629
|
-
* module; defaults to the kit's own — the source entry in a bb checkout,
|
|
4630
|
-
* the bundled one in the published SDK.
|
|
4631
|
-
*/
|
|
4632
4296
|
bootstrapPath?: string;
|
|
4633
|
-
/**
|
|
4634
|
-
* Node flags before the bootstrap. Defaults: in a bb checkout (source
|
|
4635
|
-
* bootstrap) `--conditions=source` plus the tsx loader; otherwise the tsx
|
|
4636
|
-
* loader for a TypeScript module and nothing for a built one.
|
|
4637
|
-
*/
|
|
4638
4297
|
nodeArgs?: string[];
|
|
4639
4298
|
}
|
|
4640
|
-
/**
|
|
4641
|
-
* The process that runs one bridge module through the bootstrap — exactly the
|
|
4642
|
-
* shape the runtime spawns, so a replayed bridge sees the argv, stdin framing
|
|
4643
|
-
* and signal handling it gets in production.
|
|
4644
|
-
*/
|
|
4645
4299
|
declare function resolveProviderBridgeLaunch(options: ResolveProviderBridgeLaunchOptions): ProviderBridgeLaunch;
|
|
4646
4300
|
type ReplayDialect = "claude-cli" | "json-rpc" | "pi-rpc";
|
|
4647
|
-
/**
|
|
4648
|
-
* How a provider's bridge is pointed at the replay child. Codex reads its
|
|
4649
|
-
* app-server command from env, Claude its CLI path from env, pi its RPC
|
|
4650
|
-
* command from env (`pi-rpc`: JSON lines plus the extension channel on fds
|
|
4651
|
-
* 3/4), and an ACP bridge its agent command from the launch spec inside
|
|
4652
|
-
* `thread/start`. A bridge with no provider child (the echo example) needs no
|
|
4653
|
-
* profile at all.
|
|
4654
|
-
*/
|
|
4655
4301
|
interface ReplayProviderProfile {
|
|
4656
|
-
/** The protocol the replay child speaks on its pipe. */
|
|
4657
4302
|
dialect: ReplayDialect;
|
|
4658
|
-
/** Environment the bridge reads the child's command from. */
|
|
4659
4303
|
env(args: {
|
|
4660
4304
|
replayCommand: string[];
|
|
4661
4305
|
wrapperPath: string;
|
|
4662
4306
|
stateDir: string;
|
|
4663
4307
|
}): Record<string, string>;
|
|
4664
|
-
/** Rewrite a recorded runtime request that carries the child's command. */
|
|
4665
4308
|
rewriteRuntimeLine?(line: string, args: {
|
|
4666
4309
|
replayCommand: string[];
|
|
4667
4310
|
}): string;
|
|
4668
|
-
/**
|
|
4669
|
-
* Provider state a bridge reads outside its provider pipe, seeded before
|
|
4670
|
-
* the replay starts (the Claude SDK forks by copying the source session's
|
|
4671
|
-
* transcript from disk).
|
|
4672
|
-
*/
|
|
4673
4311
|
prepareState?(args: {
|
|
4674
4312
|
recording: BridgeRecording;
|
|
4675
4313
|
stateDir: string;
|
|
4676
4314
|
workspaceDir: string;
|
|
4677
4315
|
}): void;
|
|
4678
4316
|
}
|
|
4679
|
-
/** A bridge that spawns no provider, or one whose child command is fixed. */
|
|
4680
4317
|
declare const DEFAULT_REPLAY_PROFILE: ReplayProviderProfile;
|
|
4681
4318
|
interface ReplayRecordingOptions {
|
|
4682
4319
|
recordingDir: string;
|
|
4683
|
-
/** The provider the recording belongs to; keys the assembler's ids. */
|
|
4684
4320
|
providerId: string;
|
|
4685
|
-
/** The bridge process to replay through (see `resolveProviderBridgeLaunch`). */
|
|
4686
4321
|
bridge: ProviderBridgeLaunch;
|
|
4687
|
-
/** How the bridge reaches the replay child; `DEFAULT_REPLAY_PROFILE` when omitted. */
|
|
4688
4322
|
profile?: ReplayProviderProfile;
|
|
4689
4323
|
createAssembler: CreateParityAssembler;
|
|
4690
|
-
/**
|
|
4691
|
-
* The assembler that plans the replay's gates from the recorded
|
|
4692
|
-
* `bridge→runtime` lane; defaults to `createAssembler`. A re-recording run
|
|
4693
|
-
* on a checkout whose grammar no longer accepts the whole recorded lane
|
|
4694
|
-
* plans with the recording-time checkout's assembler instead.
|
|
4695
|
-
*/
|
|
4696
4324
|
createPlanAssembler?: CreateParityAssembler;
|
|
4697
|
-
/**
|
|
4698
|
-
* Plan the replay's gates from the cell's current bridge lane
|
|
4699
|
-
* (`bridge→runtime.current.ndjson`, see `withCurrentBridgeLane`) when one
|
|
4700
|
-
* exists, instead of the recorded lane. The leg whose bridge wrote that
|
|
4701
|
-
* lane parses all of it; the recording-time leg parses the recorded lane.
|
|
4702
|
-
*/
|
|
4703
4325
|
planFromCurrentLane?: boolean;
|
|
4704
|
-
/** Per-wait timeout for a gate or a response. */
|
|
4705
4326
|
timeoutMs?: number;
|
|
4706
|
-
/**
|
|
4707
|
-
* The quiet period after which a request is sent even though the bridge
|
|
4708
|
-
* has emitted fewer lines than the recording had before it — a divergent
|
|
4709
|
-
* bridge pays this once per request instead of stalling. Only a plan from
|
|
4710
|
-
* the recorded lane can be short for that reason: a plan from the current
|
|
4711
|
-
* lane (`planFromCurrentLane`) was written by this very bridge, so a
|
|
4712
|
-
* shortfall there is latency, never divergence, and the request waits for
|
|
4713
|
-
* its events up to `timeoutMs` instead — a starved bridge (a loaded CI
|
|
4714
|
-
* runner) still has provider lines to read, and a request sent on quiet
|
|
4715
|
-
* alone lands before them, at a point the recording never had.
|
|
4716
|
-
*/
|
|
4717
4327
|
orderTimeoutMs?: number;
|
|
4718
|
-
/**
|
|
4719
|
-
* Quiet period after the last bridge output before the replay is closed.
|
|
4720
|
-
* An exact current-lane replay first waits for every planned event.
|
|
4721
|
-
*/
|
|
4722
4328
|
settleMs?: number;
|
|
4723
|
-
/**
|
|
4724
|
-
* Quiet period a request waits for once the gates are met. The replay child
|
|
4725
|
-
* plays every provider line before the request's cursor point a couple of
|
|
4726
|
-
* milliseconds apart, so a short silence means the bridge has emitted all
|
|
4727
|
-
* that the pre-request stream produces; without it a request the bridge
|
|
4728
|
-
* acknowledges at once (a steer) lands at a load-dependent point.
|
|
4729
|
-
*/
|
|
4730
4329
|
drainMs?: number;
|
|
4731
|
-
/** Mirror the bridge's stderr (and the replay child's logs) here. */
|
|
4732
4330
|
onStderr?: (text: string) => void;
|
|
4733
4331
|
}
|
|
4734
4332
|
interface ParityGrammarViolation {
|
|
@@ -4739,39 +4337,21 @@ interface ParityGrammarViolation {
|
|
|
4739
4337
|
interface ParityRun {
|
|
4740
4338
|
providerId: string;
|
|
4741
4339
|
recordingDir: string;
|
|
4742
|
-
/** Raw `bridge→runtime` lines, in order. */
|
|
4743
4340
|
lines: string[];
|
|
4744
|
-
/** When each line arrived, ms since the replay started (diagnostics). */
|
|
4745
4341
|
lineTimes: number[];
|
|
4746
|
-
/**
|
|
4747
|
-
* For each line, the recorded `runtime→bridge` entry written last before
|
|
4748
|
-
* it arrived (null before any was sent) — where the line sits in the
|
|
4749
|
-
* recording's wire order, for a lane re-recorded through this bridge.
|
|
4750
|
-
*/
|
|
4751
4342
|
lineAfter: Array<{
|
|
4752
4343
|
run: number;
|
|
4753
4344
|
seq: number;
|
|
4754
4345
|
ts: number;
|
|
4755
4346
|
} | null>;
|
|
4756
|
-
/** Assembled events, minus the ones the grammar dropped (as the runtime does). */
|
|
4757
4347
|
events: ThreadEvent[];
|
|
4758
4348
|
grammarViolations: ParityGrammarViolation[];
|
|
4759
|
-
/** Gates that timed out or requests that were never answered. */
|
|
4760
4349
|
stalls: string[];
|
|
4761
4350
|
stderr: string;
|
|
4762
4351
|
exitCode: number | null;
|
|
4763
4352
|
}
|
|
4764
|
-
/** The id of the harness's own `initialize` request; never part of a recording. */
|
|
4765
4353
|
declare const PARITY_INITIALIZE_ID = "parity-initialize";
|
|
4766
|
-
/**
|
|
4767
|
-
* Replay one recording through one bridge. Resolves when the bridge exits
|
|
4768
|
-
* after the last recorded runtime line has been sent and answered.
|
|
4769
|
-
*/
|
|
4770
4354
|
declare function replayRecording(options: ReplayRecordingOptions): Promise<ParityRun>;
|
|
4771
|
-
/**
|
|
4772
|
-
* The events the recorded `bridge→runtime` lane assembles to, without any
|
|
4773
|
-
* bridge in the loop: the recording's own view of what the bridge emitted.
|
|
4774
|
-
*/
|
|
4775
4355
|
declare function assembleRecordedEvents(recording: BridgeRecording, createAssembler: CreateParityAssembler, providerId: string): {
|
|
4776
4356
|
events: ThreadEvent[];
|
|
4777
4357
|
grammarViolations: ParityGrammarViolation[];
|
|
@@ -4781,7 +4361,6 @@ interface ParityAllowlistEntry {
|
|
|
4781
4361
|
provider: string | "*";
|
|
4782
4362
|
cell: string | "*";
|
|
4783
4363
|
layer: "events" | "rows";
|
|
4784
|
-
/** A JSON pointer over the normalized list, with `*` and `**` wildcards. */
|
|
4785
4364
|
path: string;
|
|
4786
4365
|
pr: string;
|
|
4787
4366
|
reason: string;
|
|
@@ -4795,16 +4374,13 @@ interface ParityComparison {
|
|
|
4795
4374
|
cell: string;
|
|
4796
4375
|
events: ParityLayerDiff;
|
|
4797
4376
|
rows: ParityLayerDiff;
|
|
4798
|
-
/** Grammar drops, compared as `rule:eventType` multisets. */
|
|
4799
4377
|
grammar: ParityLayerDiff;
|
|
4800
|
-
/** Allowlist entries that matched this cell but masked nothing. */
|
|
4801
4378
|
staleAllowlist: ParityAllowlistEntry[];
|
|
4802
4379
|
passed: boolean;
|
|
4803
4380
|
}
|
|
4804
4381
|
interface ParityInputs {
|
|
4805
4382
|
events: readonly ThreadEvent[];
|
|
4806
4383
|
rows: readonly unknown[];
|
|
4807
|
-
/** Events the grammar dropped; a regression when the lists differ. */
|
|
4808
4384
|
grammarViolations?: readonly ParityGrammarViolation[];
|
|
4809
4385
|
}
|
|
4810
4386
|
declare function compareParity(oldRun: ParityInputs, newRun: ParityInputs, allowlist: readonly ParityAllowlistEntry[], scope: {
|
|
@@ -4812,13 +4388,9 @@ declare function compareParity(oldRun: ParityInputs, newRun: ParityInputs, allow
|
|
|
4812
4388
|
cell: string;
|
|
4813
4389
|
}): ParityComparison;
|
|
4814
4390
|
interface ReplayRecordedCellsOptions {
|
|
4815
|
-
/** The `<provider>/<cell>` tree to read (see `listRecordedCells`). */
|
|
4816
4391
|
recordingsRoot: string;
|
|
4817
|
-
/** Which recorded providers this bridge serves (`acp` serves `acp-*`). */
|
|
4818
4392
|
servesProvider: (providerId: string) => boolean;
|
|
4819
|
-
/** Cell names to replay; defaults to every cell of those providers. */
|
|
4820
4393
|
cells?: readonly string[];
|
|
4821
|
-
/** The bridge process and replay profile for one cell's provider. */
|
|
4822
4394
|
bridge: (cell: RecordedCell) => {
|
|
4823
4395
|
launch: ProviderBridgeLaunch;
|
|
4824
4396
|
profile?: ReplayProviderProfile;
|
|
@@ -4830,22 +4402,11 @@ interface ReplayRecordedCellsOptions {
|
|
|
4830
4402
|
|
|
4831
4403
|
type RerecordCurrentBridgeLaneOptions = Omit<ReplayRecordingOptions, "planFromCurrentLane">;
|
|
4832
4404
|
interface RerecordCurrentBridgeLaneResult {
|
|
4833
|
-
/** The file written, or null when the replay stalled and nothing was. */
|
|
4834
4405
|
file: string | null;
|
|
4835
|
-
/** Lines in the new lane (the harness's own handshake excluded). */
|
|
4836
4406
|
lines: number;
|
|
4837
|
-
/** Events the replay assembled. */
|
|
4838
4407
|
events: number;
|
|
4839
|
-
/** A stalled replay leaves the current lane untouched. */
|
|
4840
4408
|
stalls: string[];
|
|
4841
4409
|
}
|
|
4842
|
-
/**
|
|
4843
|
-
* Replay one recording through a bridge and write what the bridge emitted
|
|
4844
|
-
* as the recording's current bridge lane. The replay plans its gates from
|
|
4845
|
-
* the recorded lane (or `createPlanAssembler`'s view of it), never from a
|
|
4846
|
-
* previous current lane: the new lane must reproduce the recorded session,
|
|
4847
|
-
* not the last re-recording of it.
|
|
4848
|
-
*/
|
|
4849
4410
|
declare function rerecordCurrentBridgeLane(options: RerecordCurrentBridgeLaneOptions): Promise<RerecordCurrentBridgeLaneResult>;
|
|
4850
4411
|
|
|
4851
4412
|
export { ASSEMBLER_GRAMMAR_VERSIONS, CONFORMANCE_ASSEMBLED_EVENT_METHOD, CURRENT_BRIDGE_LANE_FILE, DEFAULT_REPLAY_PROFILE, PARITY_INITIALIZE_ID, RECORDED_CONFORMANCE_CELLS, assembleCapturedThreadEvents as experimental_assembleCapturedThreadEvents, assembleRecordedEvents as experimental_assembleRecordedEvents, captureBridgeJsonRpcOutput as experimental_captureBridgeJsonRpcOutput, checkRecordedCellReplay as experimental_checkRecordedCellReplay, compareParity as experimental_compareParity, createBridgeDeltaEventCollector as experimental_createBridgeDeltaEventCollector, createBridgeJsonRpcTestHarness as experimental_createBridgeJsonRpcTestHarness, createDeltaAssembler as experimental_createDeltaAssembler, describeCalibrationEvents as experimental_describeCalibrationEvents, formatConformanceReport as experimental_formatConformanceReport, listRecordedCells as experimental_listRecordedCells, normalizeCalibrationEvents as experimental_normalizeCalibrationEvents, readBridgeRecording as experimental_readBridgeRecording, replayRecording as experimental_replayRecording, rerecordCurrentBridgeLane as experimental_rerecordCurrentBridgeLane, resolveProviderBridgeLaunch as experimental_resolveProviderBridgeLaunch, runBridgeConformance as experimental_runBridgeConformance, toConformanceMessages as experimental_toConformanceMessages, withCurrentBridgeLane as experimental_withCurrentBridgeLane };
|