@get-bb/plugin-sdk 0.4.22 → 0.4.27
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-app.d.ts +6 -7
- 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 +0 -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 +31 -284
- package/dist/ai-services.js +5 -1
- package/dist/internal/host-policy.js +95 -108
- package/dist/provider-bridge-acp.js +113 -623
- package/dist/provider-bridge-testing.js +175 -580
- package/dist/provider-bridge-worker-entry.mjs +15 -9
- package/dist/provider-bridge.js +62 -557
- 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">;
|
|
@@ -3394,12 +3315,6 @@ declare const promptInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3394
3315
|
}, z.core.$strip>], "type">;
|
|
3395
3316
|
type PromptInput = z.infer<typeof promptInputSchema>;
|
|
3396
3317
|
|
|
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
3318
|
declare const bridgeGrammarVersionsSchema: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
3404
3319
|
type BridgeGrammarVersions = z.infer<typeof bridgeGrammarVersionsSchema>;
|
|
3405
3320
|
|
|
@@ -4185,15 +4100,6 @@ declare const threadDeltaSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
4185
4100
|
}, z.core.$strip>], "kind">;
|
|
4186
4101
|
type ThreadDelta = z.infer<typeof threadDeltaSchema>;
|
|
4187
4102
|
|
|
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
4103
|
declare const ASSEMBLER_GRAMMAR_VERSIONS: BridgeGrammarVersions;
|
|
4198
4104
|
interface DiffCumulativeTextArgs {
|
|
4199
4105
|
nextText: string;
|
|
@@ -4205,35 +4111,10 @@ interface DiffCumulativeTextResult {
|
|
|
4205
4111
|
reset: boolean;
|
|
4206
4112
|
}
|
|
4207
4113
|
interface CreateDeltaAssemblerOptions {
|
|
4208
|
-
/** Provider id stamped onto provider/unhandled events. */
|
|
4209
4114
|
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
4115
|
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
4116
|
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
4117
|
textDeltaFlushMs?: number;
|
|
4236
|
-
/** Clock override for tests. */
|
|
4237
4118
|
now?: () => number;
|
|
4238
4119
|
}
|
|
4239
4120
|
interface AssembleDeltasArgs {
|
|
@@ -4242,87 +4123,37 @@ interface AssembleDeltasArgs {
|
|
|
4242
4123
|
}
|
|
4243
4124
|
interface DeltaAssembler {
|
|
4244
4125
|
assemble(args: AssembleDeltasArgs): ThreadEvent[];
|
|
4245
|
-
/** bb item id minted for a provider item id (command-plane lookup). */
|
|
4246
4126
|
getBbItemId(threadId: string, providerItemId: string): string | undefined;
|
|
4247
|
-
/** Provider item id behind a bb item id (reverse command-plane lookup). */
|
|
4248
4127
|
getProviderItemId(threadId: string, bbItemId: string): string | undefined;
|
|
4249
|
-
/** bb turn id minted for a vouched provider turn id. */
|
|
4250
4128
|
getBbTurnId(threadId: string, providerTurnId: string): string | undefined;
|
|
4251
|
-
/** Provider turn id behind a bb turn id (steer/interrupt reverse lookup). */
|
|
4252
4129
|
getProviderTurnId(threadId: string, bbTurnId: string): string | undefined;
|
|
4253
4130
|
getOpenTurnId(threadId: string): string | undefined;
|
|
4254
4131
|
}
|
|
4255
4132
|
declare function createDeltaAssembler(options: CreateDeltaAssemblerOptions): DeltaAssembler;
|
|
4256
4133
|
|
|
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
4134
|
interface CapturedBridgeNotification {
|
|
4267
4135
|
method?: string;
|
|
4268
4136
|
params?: unknown;
|
|
4269
4137
|
}
|
|
4270
4138
|
interface BridgeDeltaEventCollector {
|
|
4271
4139
|
assembler: DeltaAssembler;
|
|
4272
|
-
/** Canonical events for one captured notification (empty for non-deltas). */
|
|
4273
4140
|
assembleMessage(message: CapturedBridgeNotification): ThreadEvent[];
|
|
4274
4141
|
}
|
|
4275
4142
|
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
4143
|
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
4144
|
declare function toConformanceMessages(): never;
|
|
4290
4145
|
|
|
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
4146
|
interface BridgeConformanceTransport {
|
|
4301
|
-
/** Deliver one raw line to the bridge. */
|
|
4302
4147
|
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
4148
|
takeMessages(): unknown[];
|
|
4309
4149
|
close?(): Promise<void> | void;
|
|
4310
4150
|
}
|
|
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
4151
|
declare const CONFORMANCE_ASSEMBLED_EVENT_METHOD = "conformance/assembledEvent";
|
|
4319
4152
|
type ConformanceStatus = "fail" | "pass" | "skipped";
|
|
4320
4153
|
interface ConformanceCheckResult {
|
|
4321
|
-
/** Stable rule id, e.g. "rpc/unknown-method". */
|
|
4322
4154
|
id: string;
|
|
4323
4155
|
title: string;
|
|
4324
4156
|
status: ConformanceStatus;
|
|
4325
|
-
/** Failure or skip explanation; empty on pass. */
|
|
4326
4157
|
detail: string;
|
|
4327
4158
|
}
|
|
4328
4159
|
interface ConformanceReport {
|
|
@@ -4331,119 +4162,35 @@ interface ConformanceReport {
|
|
|
4331
4162
|
}
|
|
4332
4163
|
|
|
4333
4164
|
interface ConformanceSessionFixture {
|
|
4334
|
-
/** Workspace directory for the session under test. */
|
|
4335
4165
|
cwd: string;
|
|
4336
|
-
/** Prompt expected to elicit at least one assistant-message item. */
|
|
4337
4166
|
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
4167
|
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
4168
|
interruptiblePromptInput?: PromptInput[];
|
|
4358
|
-
/** Execution options for the session; the kit defaults to full mode. */
|
|
4359
4169
|
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
4170
|
icons?: {
|
|
4374
4171
|
pluginId: string;
|
|
4375
4172
|
names: readonly string[];
|
|
4376
4173
|
};
|
|
4377
4174
|
}
|
|
4378
4175
|
|
|
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
4176
|
declare const RECORDED_CONFORMANCE_CELLS: readonly ["turn-tools", "steer", "stop-interrupt", "approval-allow", "approval-deny", "user-question", "resume", "fork"];
|
|
4397
4177
|
type RecordedConformanceCell = (typeof RECORDED_CONFORMANCE_CELLS)[number];
|
|
4398
4178
|
interface RecordedCellReplay {
|
|
4399
4179
|
provider: string;
|
|
4400
4180
|
cell: string;
|
|
4401
|
-
/** Events the replayed bridge output assembled to, in order. */
|
|
4402
4181
|
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
4182
|
recordedEvents: readonly ThreadEvent[];
|
|
4410
|
-
/** Requests the harness had to answer for the bridge, or gates that timed out. */
|
|
4411
4183
|
stalls: readonly string[];
|
|
4412
4184
|
}
|
|
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
4185
|
declare function checkRecordedCellReplay(replay: RecordedCellReplay): ConformanceCheckResult[];
|
|
4418
4186
|
|
|
4419
4187
|
interface RunBridgeConformanceOptions {
|
|
4420
4188
|
transport: BridgeConformanceTransport;
|
|
4421
4189
|
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
4190
|
providerId: string;
|
|
4429
|
-
/** Per-wait timeout. Conformant bridges answer fast; keep this tight. */
|
|
4430
4191
|
timeoutMs?: number;
|
|
4431
4192
|
}
|
|
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
4193
|
declare function runBridgeConformance(options: RunBridgeConformanceOptions): Promise<ConformanceReport>;
|
|
4446
|
-
/** Compact single-line-per-rule rendering for test snapshots and logs. */
|
|
4447
4194
|
declare function formatConformanceReport(report: ConformanceReport): string;
|
|
4448
4195
|
|
|
4449
4196
|
type BridgeJsonRpcId = string | number;
|
|
@@ -4465,16 +4212,11 @@ interface BridgeJsonRpcOutputMessage {
|
|
|
4465
4212
|
}
|
|
4466
4213
|
interface CapturedBridgeJsonRpcOutput {
|
|
4467
4214
|
messages: BridgeJsonRpcOutputMessage[];
|
|
4468
|
-
/**
|
|
4469
|
-
* Every message since the last call: the conformance transport's drain
|
|
4470
|
-
* (`{ send: handleLine, takeMessages: output.takeMessages }`).
|
|
4471
|
-
*/
|
|
4472
4215
|
takeMessages(): BridgeJsonRpcOutputMessage[];
|
|
4473
4216
|
restore(): void;
|
|
4474
4217
|
}
|
|
4475
4218
|
interface BridgeJsonRpcTestHarness {
|
|
4476
4219
|
messages: BridgeJsonRpcOutputMessage[];
|
|
4477
|
-
/** Every message since the last call: the conformance transport's drain. */
|
|
4478
4220
|
takeMessages(): BridgeJsonRpcOutputMessage[];
|
|
4479
4221
|
flushWork(): Promise<void>;
|
|
4480
4222
|
hasResponse(id: BridgeJsonRpcId): boolean;
|
|
@@ -4482,64 +4224,22 @@ interface BridgeJsonRpcTestHarness {
|
|
|
4482
4224
|
sendRequest(id: BridgeJsonRpcId, method: string, params: BridgeJsonRpcObject): void;
|
|
4483
4225
|
waitForResponse(id: BridgeJsonRpcId): Promise<BridgeJsonRpcOutputMessage>;
|
|
4484
4226
|
}
|
|
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
4227
|
declare function captureBridgeJsonRpcOutput(): CapturedBridgeJsonRpcOutput;
|
|
4491
4228
|
declare function createBridgeJsonRpcTestHarness(handleLine: BridgeJsonRpcLineHandler): BridgeJsonRpcTestHarness;
|
|
4492
4229
|
|
|
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
4230
|
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
4231
|
internedIdFields?: readonly string[];
|
|
4517
4232
|
}
|
|
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
4233
|
declare function normalizeCalibrationEvents(events: readonly ThreadEvent[], options?: NormalizeCalibrationEventsOptions): unknown[];
|
|
4524
|
-
/** Compact `type` (+ item type) rendering for asserting a known-divergence list. */
|
|
4525
4234
|
declare function describeCalibrationEvents(events: readonly unknown[]): string[];
|
|
4526
4235
|
|
|
4527
4236
|
declare const BRIDGE_RECORDING_DIRECTIONS: readonly ["runtime→bridge", "bridge→runtime", "provider→bridge", "bridge→provider"];
|
|
4528
4237
|
type BridgeRecordingDirection = (typeof BRIDGE_RECORDING_DIRECTIONS)[number];
|
|
4529
4238
|
interface BridgeRecordingEntry {
|
|
4530
|
-
/** Wall-clock milliseconds when the line crossed. */
|
|
4531
4239
|
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
4240
|
run: number;
|
|
4539
|
-
/** Process-wide monotonic counter across all four lanes. */
|
|
4540
4241
|
seq: number;
|
|
4541
4242
|
dir: BridgeRecordingDirection;
|
|
4542
|
-
/** The raw line, without its terminator. */
|
|
4543
4243
|
line: string;
|
|
4544
4244
|
}
|
|
4545
4245
|
|
|
@@ -4558,22 +4258,9 @@ interface BridgeRecordingManifest {
|
|
|
4558
4258
|
interface BridgeRecording {
|
|
4559
4259
|
dir: string;
|
|
4560
4260
|
manifest: BridgeRecordingManifest | null;
|
|
4561
|
-
/** Every lane merged back into wire order: by bridge process, then seq. */
|
|
4562
4261
|
entries: BridgeRecordingEntry[];
|
|
4563
4262
|
}
|
|
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
4263
|
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
4264
|
declare function withCurrentBridgeLane(recording: BridgeRecording): BridgeRecording;
|
|
4578
4265
|
declare function readBridgeRecording(dir: string): BridgeRecording;
|
|
4579
4266
|
interface RecordedCell {
|
|
@@ -4581,13 +4268,8 @@ interface RecordedCell {
|
|
|
4581
4268
|
cell: string;
|
|
4582
4269
|
dir: string;
|
|
4583
4270
|
}
|
|
4584
|
-
/**
|
|
4585
|
-
* Every `<provider>/<cell>` directory under a recordings root that holds at
|
|
4586
|
-
* least one lane, sorted for stable iteration.
|
|
4587
|
-
*/
|
|
4588
4271
|
declare function listRecordedCells(root: string): RecordedCell[];
|
|
4589
4272
|
|
|
4590
|
-
/** One stateful assembler: `thread/delta` notifications in, events out. */
|
|
4591
4273
|
interface ParityAssembler {
|
|
4592
4274
|
assembleMessage(message: {
|
|
4593
4275
|
method?: string;
|
|
@@ -4595,140 +4277,55 @@ interface ParityAssembler {
|
|
|
4595
4277
|
}): ThreadEvent[];
|
|
4596
4278
|
}
|
|
4597
4279
|
type CreateParityAssembler = (providerId: string) => ParityAssembler;
|
|
4598
|
-
/** Project canonical events into timeline rows (the server's projection). */
|
|
4599
4280
|
type ParityRowProjector = (args: {
|
|
4600
4281
|
events: readonly ThreadEvent[];
|
|
4601
4282
|
providerId: string;
|
|
4602
4283
|
}) => unknown[];
|
|
4603
|
-
/** A bridge process, ready to spawn: the bootstrap, the module, its scope. */
|
|
4604
4284
|
interface ProviderBridgeLaunch {
|
|
4605
4285
|
command: string;
|
|
4606
4286
|
args: string[];
|
|
4607
4287
|
cwd: string;
|
|
4608
|
-
/** Added to the harness's own environment for the bridge process. */
|
|
4609
4288
|
env: Record<string, string>;
|
|
4610
4289
|
}
|
|
4611
4290
|
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
4291
|
modulePath: string;
|
|
4618
|
-
/** The plugin the bridge belongs to (its data and temp directories). */
|
|
4619
4292
|
pluginId: string;
|
|
4620
|
-
/** Working directory of the bridge process; defaults to the caller's. */
|
|
4621
4293
|
cwd?: string;
|
|
4622
|
-
/**
|
|
4623
|
-
* The plugin data directory the bootstrap hands the bridge; defaults to a
|
|
4624
|
-
* fresh temp directory per launch.
|
|
4625
|
-
*/
|
|
4626
4294
|
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
4295
|
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
4296
|
nodeArgs?: string[];
|
|
4639
4297
|
}
|
|
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
4298
|
declare function resolveProviderBridgeLaunch(options: ResolveProviderBridgeLaunchOptions): ProviderBridgeLaunch;
|
|
4646
4299
|
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
4300
|
interface ReplayProviderProfile {
|
|
4656
|
-
/** The protocol the replay child speaks on its pipe. */
|
|
4657
4301
|
dialect: ReplayDialect;
|
|
4658
|
-
/** Environment the bridge reads the child's command from. */
|
|
4659
4302
|
env(args: {
|
|
4660
4303
|
replayCommand: string[];
|
|
4661
4304
|
wrapperPath: string;
|
|
4662
4305
|
stateDir: string;
|
|
4663
4306
|
}): Record<string, string>;
|
|
4664
|
-
/** Rewrite a recorded runtime request that carries the child's command. */
|
|
4665
4307
|
rewriteRuntimeLine?(line: string, args: {
|
|
4666
4308
|
replayCommand: string[];
|
|
4667
4309
|
}): 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
4310
|
prepareState?(args: {
|
|
4674
4311
|
recording: BridgeRecording;
|
|
4675
4312
|
stateDir: string;
|
|
4676
4313
|
workspaceDir: string;
|
|
4677
4314
|
}): void;
|
|
4678
4315
|
}
|
|
4679
|
-
/** A bridge that spawns no provider, or one whose child command is fixed. */
|
|
4680
4316
|
declare const DEFAULT_REPLAY_PROFILE: ReplayProviderProfile;
|
|
4681
4317
|
interface ReplayRecordingOptions {
|
|
4682
4318
|
recordingDir: string;
|
|
4683
|
-
/** The provider the recording belongs to; keys the assembler's ids. */
|
|
4684
4319
|
providerId: string;
|
|
4685
|
-
/** The bridge process to replay through (see `resolveProviderBridgeLaunch`). */
|
|
4686
4320
|
bridge: ProviderBridgeLaunch;
|
|
4687
|
-
/** How the bridge reaches the replay child; `DEFAULT_REPLAY_PROFILE` when omitted. */
|
|
4688
4321
|
profile?: ReplayProviderProfile;
|
|
4689
4322
|
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
4323
|
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
4324
|
planFromCurrentLane?: boolean;
|
|
4704
|
-
/** Per-wait timeout for a gate or a response. */
|
|
4705
4325
|
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
4326
|
orderTimeoutMs?: number;
|
|
4718
|
-
/**
|
|
4719
|
-
* Quiet period after the last request before a non-exact replay is closed.
|
|
4720
|
-
* An exact current-lane replay waits for every planned event instead.
|
|
4721
|
-
*/
|
|
4722
4327
|
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
4328
|
drainMs?: number;
|
|
4731
|
-
/** Mirror the bridge's stderr (and the replay child's logs) here. */
|
|
4732
4329
|
onStderr?: (text: string) => void;
|
|
4733
4330
|
}
|
|
4734
4331
|
interface ParityGrammarViolation {
|
|
@@ -4739,39 +4336,21 @@ interface ParityGrammarViolation {
|
|
|
4739
4336
|
interface ParityRun {
|
|
4740
4337
|
providerId: string;
|
|
4741
4338
|
recordingDir: string;
|
|
4742
|
-
/** Raw `bridge→runtime` lines, in order. */
|
|
4743
4339
|
lines: string[];
|
|
4744
|
-
/** When each line arrived, ms since the replay started (diagnostics). */
|
|
4745
4340
|
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
4341
|
lineAfter: Array<{
|
|
4752
4342
|
run: number;
|
|
4753
4343
|
seq: number;
|
|
4754
4344
|
ts: number;
|
|
4755
4345
|
} | null>;
|
|
4756
|
-
/** Assembled events, minus the ones the grammar dropped (as the runtime does). */
|
|
4757
4346
|
events: ThreadEvent[];
|
|
4758
4347
|
grammarViolations: ParityGrammarViolation[];
|
|
4759
|
-
/** Gates that timed out or requests that were never answered. */
|
|
4760
4348
|
stalls: string[];
|
|
4761
4349
|
stderr: string;
|
|
4762
4350
|
exitCode: number | null;
|
|
4763
4351
|
}
|
|
4764
|
-
/** The id of the harness's own `initialize` request; never part of a recording. */
|
|
4765
4352
|
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
4353
|
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
4354
|
declare function assembleRecordedEvents(recording: BridgeRecording, createAssembler: CreateParityAssembler, providerId: string): {
|
|
4776
4355
|
events: ThreadEvent[];
|
|
4777
4356
|
grammarViolations: ParityGrammarViolation[];
|
|
@@ -4781,7 +4360,6 @@ interface ParityAllowlistEntry {
|
|
|
4781
4360
|
provider: string | "*";
|
|
4782
4361
|
cell: string | "*";
|
|
4783
4362
|
layer: "events" | "rows";
|
|
4784
|
-
/** A JSON pointer over the normalized list, with `*` and `**` wildcards. */
|
|
4785
4363
|
path: string;
|
|
4786
4364
|
pr: string;
|
|
4787
4365
|
reason: string;
|
|
@@ -4795,16 +4373,13 @@ interface ParityComparison {
|
|
|
4795
4373
|
cell: string;
|
|
4796
4374
|
events: ParityLayerDiff;
|
|
4797
4375
|
rows: ParityLayerDiff;
|
|
4798
|
-
/** Grammar drops, compared as `rule:eventType` multisets. */
|
|
4799
4376
|
grammar: ParityLayerDiff;
|
|
4800
|
-
/** Allowlist entries that matched this cell but masked nothing. */
|
|
4801
4377
|
staleAllowlist: ParityAllowlistEntry[];
|
|
4802
4378
|
passed: boolean;
|
|
4803
4379
|
}
|
|
4804
4380
|
interface ParityInputs {
|
|
4805
4381
|
events: readonly ThreadEvent[];
|
|
4806
4382
|
rows: readonly unknown[];
|
|
4807
|
-
/** Events the grammar dropped; a regression when the lists differ. */
|
|
4808
4383
|
grammarViolations?: readonly ParityGrammarViolation[];
|
|
4809
4384
|
}
|
|
4810
4385
|
declare function compareParity(oldRun: ParityInputs, newRun: ParityInputs, allowlist: readonly ParityAllowlistEntry[], scope: {
|
|
@@ -4812,13 +4387,9 @@ declare function compareParity(oldRun: ParityInputs, newRun: ParityInputs, allow
|
|
|
4812
4387
|
cell: string;
|
|
4813
4388
|
}): ParityComparison;
|
|
4814
4389
|
interface ReplayRecordedCellsOptions {
|
|
4815
|
-
/** The `<provider>/<cell>` tree to read (see `listRecordedCells`). */
|
|
4816
4390
|
recordingsRoot: string;
|
|
4817
|
-
/** Which recorded providers this bridge serves (`acp` serves `acp-*`). */
|
|
4818
4391
|
servesProvider: (providerId: string) => boolean;
|
|
4819
|
-
/** Cell names to replay; defaults to every cell of those providers. */
|
|
4820
4392
|
cells?: readonly string[];
|
|
4821
|
-
/** The bridge process and replay profile for one cell's provider. */
|
|
4822
4393
|
bridge: (cell: RecordedCell) => {
|
|
4823
4394
|
launch: ProviderBridgeLaunch;
|
|
4824
4395
|
profile?: ReplayProviderProfile;
|
|
@@ -4830,22 +4401,11 @@ interface ReplayRecordedCellsOptions {
|
|
|
4830
4401
|
|
|
4831
4402
|
type RerecordCurrentBridgeLaneOptions = Omit<ReplayRecordingOptions, "planFromCurrentLane">;
|
|
4832
4403
|
interface RerecordCurrentBridgeLaneResult {
|
|
4833
|
-
/** The file written, or null when the replay stalled and nothing was. */
|
|
4834
4404
|
file: string | null;
|
|
4835
|
-
/** Lines in the new lane (the harness's own handshake excluded). */
|
|
4836
4405
|
lines: number;
|
|
4837
|
-
/** Events the replay assembled. */
|
|
4838
4406
|
events: number;
|
|
4839
|
-
/** A stalled replay leaves the current lane untouched. */
|
|
4840
4407
|
stalls: string[];
|
|
4841
4408
|
}
|
|
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
4409
|
declare function rerecordCurrentBridgeLane(options: RerecordCurrentBridgeLaneOptions): Promise<RerecordCurrentBridgeLaneResult>;
|
|
4850
4410
|
|
|
4851
4411
|
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 };
|