@loucompanion/forge-bridge 0.1.3-dev.fbe15023cdfe → 0.1.4-dev.1ff37038366e
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/README.md +88 -2
- package/dist/bridge/bridge-chat.types.d.ts +111 -0
- package/dist/bridge/bridge-chat.types.js +401 -0
- package/dist/bridge/bridge.base.d.ts +4 -1
- package/dist/bridge/bridge.service.d.ts +72 -3
- package/dist/bridge/bridge.service.js +1563 -152
- package/dist/bridge/bridge.types.d.ts +46 -1
- package/dist/bridge/dispatch-result-outbox.d.ts +25 -0
- package/dist/bridge/dispatch-result-outbox.js +62 -0
- package/dist/bridge/dispatch-result-worker.d.ts +2 -0
- package/dist/bridge/dispatch-result-worker.js +122 -0
- package/dist/bridge/internals.d.ts +2 -0
- package/dist/bridge/internals.js +1 -0
- package/dist/bridge/readiness-result-outbox.d.ts +21 -0
- package/dist/bridge/readiness-result-outbox.js +54 -0
- package/dist/bridge/readiness-result-worker.d.ts +2 -0
- package/dist/bridge/readiness-result-worker.js +121 -0
- package/dist/bridge/runner-host-capabilities.d.ts +15 -0
- package/dist/bridge/runner-host-capabilities.js +93 -0
- package/dist/cleanup/cleanup.service.d.ts +1 -0
- package/dist/cleanup/cleanup.service.js +70 -9
- package/dist/cli/cli.help.js +2 -2
- package/dist/cli/cli.service.d.ts +14 -6
- package/dist/cli/cli.service.js +75 -16
- package/dist/cli/local-config.d.ts +1 -0
- package/dist/cli/local-config.js +4 -0
- package/dist/runtime/aspnet-runtime-prebuild.d.ts +36 -0
- package/dist/runtime/aspnet-runtime-prebuild.js +341 -0
- package/dist/runtime/attempt-database-broker.d.ts +89 -0
- package/dist/runtime/attempt-database-broker.js +390 -0
- package/dist/runtime/attempt-node-runtime-launcher.d.ts +2 -1
- package/dist/runtime/attempt-node-runtime-launcher.js +57 -18
- package/dist/runtime/attempt-path-operation.d.ts +21 -0
- package/dist/runtime/attempt-path-operation.js +94 -0
- package/dist/runtime/attempt-private-directory.d.ts +6 -0
- package/dist/runtime/attempt-private-directory.js +54 -0
- package/dist/runtime/attempt-process-supervisor.d.ts +11 -0
- package/dist/runtime/attempt-process-supervisor.js +67 -20
- package/dist/runtime/canonical-source-file.d.ts +3 -0
- package/dist/runtime/canonical-source-file.js +54 -0
- package/dist/runtime/docker-engine-probe.d.ts +90 -0
- package/dist/runtime/docker-engine-probe.js +333 -0
- package/dist/runtime/generated-output-reset.d.ts +10 -0
- package/dist/runtime/generated-output-reset.js +62 -8
- package/dist/runtime/host-database-capability-boundary.d.ts +16 -0
- package/dist/runtime/host-database-capability-boundary.js +62 -0
- package/dist/runtime/host-diagnostics.d.ts +11 -0
- package/dist/runtime/host-diagnostics.js +191 -0
- package/dist/runtime/host-execution-root.d.ts +4 -0
- package/dist/runtime/host-execution-root.js +39 -0
- package/dist/runtime/host-listener-inspector.d.ts +8 -1
- package/dist/runtime/host-listener-inspector.js +121 -60
- package/dist/runtime/host-runtime-contract.d.ts +12 -1
- package/dist/runtime/host-runtime-contract.js +168 -55
- package/dist/runtime/host-runtime-lease.d.ts +92 -8
- package/dist/runtime/host-runtime-lease.js +1141 -114
- package/dist/runtime/host-runtime-promotion.d.ts +12 -3
- package/dist/runtime/host-runtime-promotion.js +59 -12
- package/dist/runtime/memory-capacity.d.ts +70 -0
- package/dist/runtime/memory-capacity.js +123 -0
- package/dist/runtime/native-test-postgres-fallback.d.ts +25 -0
- package/dist/runtime/native-test-postgres-fallback.js +91 -0
- package/dist/runtime/node-host-runtime-adapter.d.ts +3 -0
- package/dist/runtime/node-host-runtime-adapter.js +28 -11
- package/dist/runtime/pinned-directory-process.d.ts +9 -0
- package/dist/runtime/pinned-directory-process.js +61 -0
- package/dist/runtime/pinned-source-directory.d.ts +17 -0
- package/dist/runtime/pinned-source-directory.js +94 -0
- package/dist/runtime/playwright-host-runtime-adapter.d.ts +1 -0
- package/dist/runtime/playwright-host-runtime-adapter.js +53 -5
- package/dist/runtime/prepared-runtime-identity.d.ts +6 -0
- package/dist/runtime/prepared-runtime-identity.js +218 -0
- package/dist/runtime/prepared-runtime-readiness.d.ts +30 -0
- package/dist/runtime/prepared-runtime-readiness.js +285 -0
- package/dist/runtime/runtime-isolation-lease.js +4 -1
- package/dist/runtime/workspace-resource-estimator.d.ts +17 -0
- package/dist/runtime/workspace-resource-estimator.js +174 -0
- package/dist/sandbox/preflight.d.ts +31 -1
- package/dist/sandbox/preflight.js +237 -51
- package/dist/sandbox/repository-lock.d.ts +2 -1
- package/dist/sandbox/repository-lock.js +17 -8
- package/dist/sandbox/runtime.d.ts +6 -1
- package/dist/sandbox/runtime.js +132 -103
- package/dist/sandbox/sandbox.types.d.ts +7 -0
- package/dist/sandbox/workspace.service.js +2 -0
- package/dist/session/managed-attempt-tools.d.ts +17 -1
- package/dist/session/managed-attempt-tools.js +485 -31
- package/dist/session/managed-build-coordinator.d.ts +5 -0
- package/dist/session/managed-build-coordinator.js +105 -0
- package/dist/session/managed-build-receipt.d.ts +21 -0
- package/dist/session/managed-build-receipt.js +337 -0
- package/dist/session/managed-verification-timeouts.d.ts +8 -0
- package/dist/session/managed-verification-timeouts.js +17 -0
- package/dist/session/phase-completion.artifacts.d.ts +17 -0
- package/dist/session/phase-completion.artifacts.js +224 -22
- package/dist/session/phase-completion.d.ts +11 -1
- package/dist/session/phase-completion.helpers.d.ts +5 -0
- package/dist/session/phase-completion.helpers.js +30 -7
- package/dist/session/phase-completion.js +14 -3
- package/dist/session/phase-completion.prompts.js +17 -18
- package/dist/session/phase-completion.runtime.d.ts +3 -1
- package/dist/session/phase-completion.runtime.js +126 -17
- package/dist/session/phase-completion.schemas.js +49 -2
- package/dist/session/phase-completion.validation.d.ts +1 -0
- package/dist/session/phase-completion.validation.js +111 -21
- package/dist/session/pre-publication-validation.d.ts +75 -0
- package/dist/session/pre-publication-validation.js +661 -0
- package/dist/session/provider-cli/bridge-cli.conformance-fixtures.d.ts +72 -0
- package/dist/session/provider-cli/bridge-cli.conformance-fixtures.js +462 -0
- package/dist/session/provider-cli/ci-repair-readiness.d.ts +8 -0
- package/dist/session/provider-cli/ci-repair-readiness.js +23 -3
- package/dist/session/provider-cli/provider-cli.artifacts.d.ts +4 -2
- package/dist/session/provider-cli/provider-cli.artifacts.js +47 -13
- package/dist/session/provider-cli/provider-cli.deterministic.js +34 -2
- package/dist/session/provider-cli/provider-cli.process.d.ts +51 -0
- package/dist/session/provider-cli/provider-cli.process.js +422 -22
- package/dist/session/provider-cli/provider-cli.prompts.d.ts +5 -0
- package/dist/session/provider-cli/provider-cli.prompts.js +136 -16
- package/dist/session/provider-cli/provider-cli.repair-epoch.d.ts +6 -0
- package/dist/session/provider-cli/provider-cli.repair-epoch.js +11 -0
- package/dist/session/provider-cli/provider-cli.runtime.d.ts +8 -1
- package/dist/session/provider-cli/provider-cli.runtime.js +43 -3
- package/dist/session/provider-cli/provider-cli.service.d.ts +30 -5
- package/dist/session/provider-cli/provider-cli.service.js +771 -68
- package/dist/session/provider-cli/provider-cli.types.d.ts +2 -0
- package/dist/session/provider-cli/provider-output-state.d.ts +10 -0
- package/dist/session/provider-cli/provider-output-state.js +361 -17
- package/dist/session/provider-cli/provider-usage.d.ts +7 -0
- package/dist/session/provider-cli/provider-usage.js +28 -5
- package/dist/session/session-redaction.js +434 -9
- package/dist/session/session.service.js +145 -23
- package/dist/session/session.types.d.ts +147 -2
- package/dist/session/session.types.js +587 -7
- package/dist/session/unreferenced-exports.d.ts +12 -0
- package/dist/session/unreferenced-exports.js +59 -0
- package/dist/shared/format/format-bytes.d.ts +1 -0
- package/dist/shared/format/format-bytes.js +9 -0
- package/dist/shared/git/git.js +2 -1
- package/dist/shared/path/path.d.ts +1 -0
- package/dist/shared/path/path.js +18 -0
- package/dist/shared/process/dotnet-toolchain.d.ts +17 -0
- package/dist/shared/process/dotnet-toolchain.js +307 -0
- package/dist/shared/process/host-process-supervisor.d.ts +2 -0
- package/dist/shared/process/host-process-supervisor.js +57 -9
- package/dist/shared/process/process.d.ts +2 -0
- package/dist/shared/process/process.js +12 -7
- package/dist/shared/provider-capabilities.d.ts +3 -0
- package/dist/shared/provider-capabilities.js +85 -0
- package/dist/shared/redaction/redaction.d.ts +1 -0
- package/dist/shared/redaction/redaction.js +39 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worktree/dependency-warmer.d.ts +41 -9
- package/dist/worktree/dependency-warmer.js +497 -22
- package/dist/worktree/index.d.ts +1 -1
- package/dist/worktree/story-qa-reference-hydrator.d.ts +4 -0
- package/dist/worktree/story-qa-reference-hydrator.js +253 -0
- package/dist/worktree/worktree.service.d.ts +7 -0
- package/dist/worktree/worktree.service.js +253 -21
- package/dist/worktree/worktree.types.d.ts +7 -1
- package/package.json +7 -5
- package/runtime/windows-job-supervisor.ps1 +380 -14
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type BridgeChatCapability, type BridgeChatRequestedCapability, type ChatTurnCallbackEnvelope, type ChatTurnCallbackKind, type ChatTurnDispatchPacket, type ChatTurnMessage } from "../../bridge/bridge-chat.types.js";
|
|
2
|
+
export declare const requiredBridgeCliScenarioKeys: readonly ["happy-path", "cancellation", "failure", "malformed-tool-call", "redaction"];
|
|
3
|
+
export type BridgeCliConformanceScenarioKey = typeof requiredBridgeCliScenarioKeys[number];
|
|
4
|
+
export type BridgeCliConformanceProviderKind = "codex" | "cursor";
|
|
5
|
+
export type BridgeCliConformanceRuntimeKind = "managed-host";
|
|
6
|
+
export interface BridgeCliConformanceCapabilityFixture {
|
|
7
|
+
readonly fixtureKey: string;
|
|
8
|
+
readonly runtimeState: string;
|
|
9
|
+
readonly supportedCapabilities: readonly BridgeChatRequestedCapability[];
|
|
10
|
+
readonly metadata: Readonly<Record<string, string>>;
|
|
11
|
+
readonly capability: BridgeChatCapability;
|
|
12
|
+
}
|
|
13
|
+
export interface BridgeCliConformanceInputTurn {
|
|
14
|
+
readonly turnKey: string;
|
|
15
|
+
readonly messages: readonly ChatTurnMessage[];
|
|
16
|
+
readonly toolCalls: readonly BridgeCliConformanceInputToolCall[];
|
|
17
|
+
readonly requestedCapabilities: readonly BridgeChatRequestedCapability[];
|
|
18
|
+
readonly providerThreadId: string | null;
|
|
19
|
+
readonly dispatchPacket: ChatTurnDispatchPacket;
|
|
20
|
+
}
|
|
21
|
+
export interface BridgeCliConformanceInputToolCall {
|
|
22
|
+
readonly toolName: string;
|
|
23
|
+
readonly argumentsJson: string;
|
|
24
|
+
readonly isMalformed?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface BridgeCliConformanceExpectedEvent {
|
|
27
|
+
readonly sequence: number;
|
|
28
|
+
readonly adapterEventId: string | null;
|
|
29
|
+
readonly eventType: ChatTurnCallbackKind;
|
|
30
|
+
readonly payloadKey?: string | null;
|
|
31
|
+
}
|
|
32
|
+
export interface BridgeCliConformanceExpectedTerminalState {
|
|
33
|
+
readonly state: "completed" | "cancelled" | "failed" | "rejected";
|
|
34
|
+
readonly failureCode?: string | null;
|
|
35
|
+
readonly failureKind?: string | null;
|
|
36
|
+
}
|
|
37
|
+
export interface BridgeCliConformanceExpectedSnapshotState {
|
|
38
|
+
readonly runtimeState: string;
|
|
39
|
+
readonly providerThreadId: string | null;
|
|
40
|
+
readonly metadata: Readonly<Record<string, string>>;
|
|
41
|
+
}
|
|
42
|
+
export interface BridgeCliConformanceProviderStreamFixture {
|
|
43
|
+
readonly stdoutLines: readonly string[];
|
|
44
|
+
readonly expectedEventTypes: readonly string[];
|
|
45
|
+
readonly expectedFinalMessage: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface BridgeCliChatAdapterConformanceCase {
|
|
48
|
+
readonly adapterKind: "bridge-cli";
|
|
49
|
+
readonly runtimeKind: BridgeCliConformanceRuntimeKind;
|
|
50
|
+
readonly providerKind: BridgeCliConformanceProviderKind;
|
|
51
|
+
readonly capabilityFixture: BridgeCliConformanceCapabilityFixture;
|
|
52
|
+
readonly scenarioKey: BridgeCliConformanceScenarioKey;
|
|
53
|
+
readonly inputTurn: BridgeCliConformanceInputTurn;
|
|
54
|
+
readonly expectedEvents: readonly BridgeCliConformanceExpectedEvent[];
|
|
55
|
+
readonly expectedTerminalState: BridgeCliConformanceExpectedTerminalState;
|
|
56
|
+
readonly expectedSnapshotState: BridgeCliConformanceExpectedSnapshotState;
|
|
57
|
+
readonly prohibitedLogPatterns: readonly string[];
|
|
58
|
+
readonly skipReason: string | null;
|
|
59
|
+
readonly callbackEnvelope: ChatTurnCallbackEnvelope;
|
|
60
|
+
readonly providerStream: BridgeCliConformanceProviderStreamFixture;
|
|
61
|
+
readonly redactionSecrets: readonly string[];
|
|
62
|
+
}
|
|
63
|
+
export interface BridgeCliEnvelopeRejectionCase {
|
|
64
|
+
readonly caseKey: string;
|
|
65
|
+
readonly sourceScenarioKey: BridgeCliConformanceScenarioKey;
|
|
66
|
+
readonly dispatchPacket: Readonly<Record<string, unknown>>;
|
|
67
|
+
readonly capability: BridgeChatCapability;
|
|
68
|
+
readonly expectedMessage: string;
|
|
69
|
+
}
|
|
70
|
+
export declare const bridgeCliConformanceCases: readonly BridgeCliChatAdapterConformanceCase[];
|
|
71
|
+
export declare const bridgeCliEnvelopeRejectionCases: readonly BridgeCliEnvelopeRejectionCase[];
|
|
72
|
+
export declare const malformedProviderStreamFixtures: Readonly<Record<BridgeCliConformanceProviderKind, readonly string[]>>;
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { bridgeChatProtocolVersion, unavailableBridgeChatCapability, } from "../../bridge/bridge-chat.types.js";
|
|
2
|
+
export const requiredBridgeCliScenarioKeys = [
|
|
3
|
+
"happy-path",
|
|
4
|
+
"cancellation",
|
|
5
|
+
"failure",
|
|
6
|
+
"malformed-tool-call",
|
|
7
|
+
"redaction",
|
|
8
|
+
];
|
|
9
|
+
const ids = {
|
|
10
|
+
callbackId: "77777777-7777-4777-8777-777777777777",
|
|
11
|
+
chatRunId: "11111111-1111-4111-8111-111111111111",
|
|
12
|
+
conversationId: "22222222-2222-4222-8222-222222222222",
|
|
13
|
+
turnId: "33333333-3333-4333-8333-333333333333",
|
|
14
|
+
leaseId: "44444444-4444-4444-8444-444444444444",
|
|
15
|
+
fencingToken: "55555555-5555-4555-8555-555555555555",
|
|
16
|
+
runnerInstanceId: "66666666-6666-4666-8666-666666666666",
|
|
17
|
+
runnerId: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
18
|
+
attachmentId: "88888888-8888-4888-8888-888888888888",
|
|
19
|
+
grantId: "99999999-9999-4999-8999-999999999999",
|
|
20
|
+
};
|
|
21
|
+
const deterministicExpiresAt = "2099-01-01T00:00:00.000Z";
|
|
22
|
+
const redactionSecrets = [
|
|
23
|
+
"raw-provider-secret",
|
|
24
|
+
"raw-tool-token",
|
|
25
|
+
"opaque-temp-file-token",
|
|
26
|
+
"opaque-grant-nonce",
|
|
27
|
+
];
|
|
28
|
+
const prohibitedLogPatterns = [
|
|
29
|
+
"raw-provider-secret",
|
|
30
|
+
"raw-tool-token",
|
|
31
|
+
"opaque-temp-file-token",
|
|
32
|
+
"opaque-grant-nonce",
|
|
33
|
+
"sk-[A-Za-z0-9_-]+",
|
|
34
|
+
"Authorization:\\s*Bearer\\s+(?!\\[REDACTED\\])\\S+",
|
|
35
|
+
];
|
|
36
|
+
const providerDefinitions = [
|
|
37
|
+
{
|
|
38
|
+
providerKind: "codex",
|
|
39
|
+
model: "gpt-5-codex",
|
|
40
|
+
runtimeState: "codex-cli-authenticated",
|
|
41
|
+
providerThreadPrefix: "codex-thread",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
providerKind: "cursor",
|
|
45
|
+
model: "cursor-fast",
|
|
46
|
+
runtimeState: "cursor-agent-authenticated",
|
|
47
|
+
providerThreadPrefix: "cursor-session",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const scenarioDefinitions = [
|
|
51
|
+
{
|
|
52
|
+
scenarioKey: "happy-path",
|
|
53
|
+
requestedCapabilities: [
|
|
54
|
+
"text",
|
|
55
|
+
"cancel",
|
|
56
|
+
"resume",
|
|
57
|
+
"thread_continuity",
|
|
58
|
+
"attachment_handoffs",
|
|
59
|
+
"action_broker_grants",
|
|
60
|
+
],
|
|
61
|
+
terminalEventType: "output_completed",
|
|
62
|
+
terminalState: { state: "completed" },
|
|
63
|
+
finalMessage: "Deterministic Bridge CLI turn completed.",
|
|
64
|
+
includeBoundedEnvelopes: true,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
scenarioKey: "cancellation",
|
|
68
|
+
requestedCapabilities: ["text", "cancel", "thread_continuity"],
|
|
69
|
+
terminalEventType: "cancelled",
|
|
70
|
+
terminalState: {
|
|
71
|
+
state: "cancelled",
|
|
72
|
+
failureCode: "chat_turn_cancelled",
|
|
73
|
+
failureKind: "cancelled",
|
|
74
|
+
},
|
|
75
|
+
finalMessage: null,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
scenarioKey: "failure",
|
|
79
|
+
requestedCapabilities: ["text", "thread_continuity"],
|
|
80
|
+
terminalEventType: "failed",
|
|
81
|
+
terminalState: {
|
|
82
|
+
state: "failed",
|
|
83
|
+
failureCode: "provider_failed",
|
|
84
|
+
failureKind: "provider",
|
|
85
|
+
},
|
|
86
|
+
finalMessage: null,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
scenarioKey: "malformed-tool-call",
|
|
90
|
+
requestedCapabilities: ["text", "thread_continuity"],
|
|
91
|
+
terminalEventType: "failed",
|
|
92
|
+
terminalState: {
|
|
93
|
+
state: "rejected",
|
|
94
|
+
failureCode: "bridge_cli.malformed_tool_call",
|
|
95
|
+
failureKind: "malformed_tool_call",
|
|
96
|
+
},
|
|
97
|
+
finalMessage: null,
|
|
98
|
+
toolCalls: [{
|
|
99
|
+
toolName: "write_file",
|
|
100
|
+
argumentsJson: "{\"path\":",
|
|
101
|
+
isMalformed: true,
|
|
102
|
+
}],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
scenarioKey: "redaction",
|
|
106
|
+
requestedCapabilities: [
|
|
107
|
+
"text",
|
|
108
|
+
"thread_continuity",
|
|
109
|
+
"attachment_handoffs",
|
|
110
|
+
"action_broker_grants",
|
|
111
|
+
],
|
|
112
|
+
terminalEventType: "output_completed",
|
|
113
|
+
terminalState: { state: "completed" },
|
|
114
|
+
finalMessage: "Redacted Bridge CLI turn completed.",
|
|
115
|
+
includeBoundedEnvelopes: true,
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
export const bridgeCliConformanceCases = providerDefinitions.flatMap((provider) => scenarioDefinitions.map((scenario) => buildCase(provider, scenario)));
|
|
119
|
+
const sourceCase = bridgeCliConformanceCases.find((testCase) => testCase.providerKind === "codex" && testCase.scenarioKey === "happy-path");
|
|
120
|
+
if (!sourceCase) {
|
|
121
|
+
throw new Error("Bridge CLI conformance happy-path fixture was not initialized.");
|
|
122
|
+
}
|
|
123
|
+
const sourcePacket = sourceCase.inputTurn.dispatchPacket;
|
|
124
|
+
const sourceCapability = sourceCase.capabilityFixture.capability;
|
|
125
|
+
export const bridgeCliEnvelopeRejectionCases = [
|
|
126
|
+
{
|
|
127
|
+
caseKey: "attachment_handoff_unsupported_runner",
|
|
128
|
+
sourceScenarioKey: "happy-path",
|
|
129
|
+
capability: capabilityFor("codex", "gpt-5-codex", { supportsAttachments: false }),
|
|
130
|
+
dispatchPacket: {
|
|
131
|
+
...packetRecord(sourcePacket),
|
|
132
|
+
requestedCapabilities: ["text", "attachment_handoffs"],
|
|
133
|
+
attachmentHandoffs: [attachmentHandoff()],
|
|
134
|
+
actionBrokerGrants: [],
|
|
135
|
+
},
|
|
136
|
+
expectedMessage: "requestedCapabilities attachment_handoffs for this runner",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
caseKey: "attachment_handoff_unfenced_turn",
|
|
140
|
+
sourceScenarioKey: "happy-path",
|
|
141
|
+
capability: sourceCapability,
|
|
142
|
+
dispatchPacket: {
|
|
143
|
+
...packetRecord(sourcePacket),
|
|
144
|
+
requestedCapabilities: ["text", "attachment_handoffs"],
|
|
145
|
+
attachmentHandoffs: [{
|
|
146
|
+
...attachmentHandoff(),
|
|
147
|
+
turnId: "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
|
|
148
|
+
}],
|
|
149
|
+
actionBrokerGrants: [],
|
|
150
|
+
},
|
|
151
|
+
expectedMessage: "attachmentHandoffs[0].turnId must match turnId",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
caseKey: "attachment_handoff_malformed_direct_path",
|
|
155
|
+
sourceScenarioKey: "happy-path",
|
|
156
|
+
capability: sourceCapability,
|
|
157
|
+
dispatchPacket: {
|
|
158
|
+
...packetRecord(sourcePacket),
|
|
159
|
+
requestedCapabilities: ["text", "attachment_handoffs"],
|
|
160
|
+
attachmentHandoffs: [{
|
|
161
|
+
...attachmentHandoff(),
|
|
162
|
+
rawPath: "C:\\Users\\developer\\secret.txt",
|
|
163
|
+
}],
|
|
164
|
+
actionBrokerGrants: [],
|
|
165
|
+
},
|
|
166
|
+
expectedMessage: "attachmentHandoffs[0].rawPath is not supported",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
caseKey: "action_grant_widened_without_request",
|
|
170
|
+
sourceScenarioKey: "happy-path",
|
|
171
|
+
capability: sourceCapability,
|
|
172
|
+
dispatchPacket: {
|
|
173
|
+
...packetRecord(sourcePacket),
|
|
174
|
+
requestedCapabilities: ["text"],
|
|
175
|
+
attachmentHandoffs: [],
|
|
176
|
+
actionBrokerGrants: [actionBrokerGrant()],
|
|
177
|
+
},
|
|
178
|
+
expectedMessage: "actionBrokerGrants require requestedCapabilities to include action_broker_grants",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
caseKey: "action_grant_direct_execution_input",
|
|
182
|
+
sourceScenarioKey: "happy-path",
|
|
183
|
+
capability: sourceCapability,
|
|
184
|
+
dispatchPacket: {
|
|
185
|
+
...packetRecord(sourcePacket),
|
|
186
|
+
requestedCapabilities: ["text", "action_broker_grants"],
|
|
187
|
+
attachmentHandoffs: [],
|
|
188
|
+
actionBrokerGrants: [{
|
|
189
|
+
...actionBrokerGrant(),
|
|
190
|
+
executeCommand: "Remove-Item -Recurse C:\\repo",
|
|
191
|
+
}],
|
|
192
|
+
},
|
|
193
|
+
expectedMessage: "actionBrokerGrants[0].executeCommand is not supported",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
caseKey: "action_grant_unfenced_lease",
|
|
197
|
+
sourceScenarioKey: "happy-path",
|
|
198
|
+
capability: sourceCapability,
|
|
199
|
+
dispatchPacket: {
|
|
200
|
+
...packetRecord(sourcePacket),
|
|
201
|
+
requestedCapabilities: ["text", "action_broker_grants"],
|
|
202
|
+
attachmentHandoffs: [],
|
|
203
|
+
actionBrokerGrants: [{
|
|
204
|
+
...actionBrokerGrant(),
|
|
205
|
+
leaseId: "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
|
|
206
|
+
}],
|
|
207
|
+
},
|
|
208
|
+
expectedMessage: "actionBrokerGrants[0] must match the active dispatch fence",
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
export const malformedProviderStreamFixtures = {
|
|
212
|
+
codex: [
|
|
213
|
+
"not-json",
|
|
214
|
+
JSON.stringify({ type: "item.started", item: { type: "mcp_tool_call", server: "forge", status: "in_progress" } }),
|
|
215
|
+
JSON.stringify({ type: "item.completed", item: { type: "mcp_tool_call", server: "forge", status: "completed" } }),
|
|
216
|
+
],
|
|
217
|
+
cursor: [
|
|
218
|
+
"not-json",
|
|
219
|
+
JSON.stringify({ type: "tool_call", subtype: "started", tool_call: { writeToolCall: { args: { path: "" } } } }),
|
|
220
|
+
JSON.stringify({ type: "tool_call", subtype: "completed", tool_call: { writeToolCall: { result: { success: {} } } } }),
|
|
221
|
+
],
|
|
222
|
+
};
|
|
223
|
+
function buildCase(provider, scenario) {
|
|
224
|
+
const providerThreadId = `${provider.providerThreadPrefix}-${scenario.scenarioKey}`;
|
|
225
|
+
const capability = capabilityFor(provider.providerKind, provider.model);
|
|
226
|
+
const attachmentHandoffs = scenario.includeBoundedEnvelopes ? [attachmentHandoff()] : [];
|
|
227
|
+
const actionBrokerGrants = scenario.includeBoundedEnvelopes ? [actionBrokerGrant()] : [];
|
|
228
|
+
const messages = messagesFor(scenario.scenarioKey);
|
|
229
|
+
const dispatchPacket = {
|
|
230
|
+
chatRunId: ids.chatRunId,
|
|
231
|
+
conversationId: ids.conversationId,
|
|
232
|
+
turnId: ids.turnId,
|
|
233
|
+
leaseId: ids.leaseId,
|
|
234
|
+
fencingToken: ids.fencingToken,
|
|
235
|
+
runnerInstanceId: ids.runnerInstanceId,
|
|
236
|
+
providerKind: provider.providerKind,
|
|
237
|
+
model: provider.model,
|
|
238
|
+
messages,
|
|
239
|
+
contextRefs: [{
|
|
240
|
+
kind: "work_item",
|
|
241
|
+
refId: `bridge-cli-${scenario.scenarioKey}`,
|
|
242
|
+
title: "Bridge CLI deterministic conformance",
|
|
243
|
+
summary: "Fixture mapped to ChatAdapterConformanceCase fields.",
|
|
244
|
+
metadata: {
|
|
245
|
+
adapterKind: "bridge-cli",
|
|
246
|
+
runtimeKind: "managed-host",
|
|
247
|
+
providerKind: provider.providerKind,
|
|
248
|
+
scenarioKey: scenario.scenarioKey,
|
|
249
|
+
},
|
|
250
|
+
}],
|
|
251
|
+
idempotencyKey: `bridge-cli-${provider.providerKind}-${scenario.scenarioKey}`,
|
|
252
|
+
providerThreadId,
|
|
253
|
+
protocolVersion: bridgeChatProtocolVersion,
|
|
254
|
+
requestedCapabilities: scenario.requestedCapabilities,
|
|
255
|
+
attachmentHandoffs,
|
|
256
|
+
actionBrokerGrants,
|
|
257
|
+
};
|
|
258
|
+
return {
|
|
259
|
+
adapterKind: "bridge-cli",
|
|
260
|
+
runtimeKind: "managed-host",
|
|
261
|
+
providerKind: provider.providerKind,
|
|
262
|
+
capabilityFixture: {
|
|
263
|
+
fixtureKey: `${provider.providerKind}-managed-host-${scenario.scenarioKey}`,
|
|
264
|
+
runtimeState: provider.runtimeState,
|
|
265
|
+
supportedCapabilities: [
|
|
266
|
+
"text",
|
|
267
|
+
"cancel",
|
|
268
|
+
"resume",
|
|
269
|
+
"thread_continuity",
|
|
270
|
+
"attachment_handoffs",
|
|
271
|
+
"action_broker_grants",
|
|
272
|
+
],
|
|
273
|
+
metadata: {
|
|
274
|
+
model: provider.model,
|
|
275
|
+
protocolVersion: bridgeChatProtocolVersion,
|
|
276
|
+
},
|
|
277
|
+
capability,
|
|
278
|
+
},
|
|
279
|
+
scenarioKey: scenario.scenarioKey,
|
|
280
|
+
inputTurn: {
|
|
281
|
+
turnKey: `${provider.providerKind}-${scenario.scenarioKey}`,
|
|
282
|
+
messages,
|
|
283
|
+
toolCalls: scenario.toolCalls ?? [],
|
|
284
|
+
requestedCapabilities: scenario.requestedCapabilities,
|
|
285
|
+
providerThreadId,
|
|
286
|
+
dispatchPacket,
|
|
287
|
+
},
|
|
288
|
+
expectedEvents: expectedEventsFor(scenario.terminalEventType),
|
|
289
|
+
expectedTerminalState: scenario.terminalState,
|
|
290
|
+
expectedSnapshotState: {
|
|
291
|
+
runtimeState: scenario.terminalState.state,
|
|
292
|
+
providerThreadId,
|
|
293
|
+
metadata: {
|
|
294
|
+
providerKind: provider.providerKind,
|
|
295
|
+
scenarioKey: scenario.scenarioKey,
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
prohibitedLogPatterns,
|
|
299
|
+
skipReason: null,
|
|
300
|
+
callbackEnvelope: callbackEnvelopeFor(dispatchPacket, scenario.terminalEventType, scenario.finalMessage),
|
|
301
|
+
providerStream: providerStreamFor(provider.providerKind, providerThreadId, scenario),
|
|
302
|
+
redactionSecrets,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function capabilityFor(providerKind, model, overrides = {}) {
|
|
306
|
+
return {
|
|
307
|
+
...unavailableBridgeChatCapability(),
|
|
308
|
+
availability: "available",
|
|
309
|
+
supportedProviders: [providerKind],
|
|
310
|
+
supportedModels: [model],
|
|
311
|
+
supportsTextStreaming: true,
|
|
312
|
+
supportsCancel: true,
|
|
313
|
+
supportsResume: true,
|
|
314
|
+
supportsProviderThreadContinuity: true,
|
|
315
|
+
supportsAttachments: true,
|
|
316
|
+
supportsActionBrokerGrants: true,
|
|
317
|
+
maxMessageBytes: 128 * 1024,
|
|
318
|
+
maxContextRefs: 8,
|
|
319
|
+
...overrides,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function messagesFor(scenarioKey) {
|
|
323
|
+
if (scenarioKey === "redaction") {
|
|
324
|
+
return [{
|
|
325
|
+
role: "user",
|
|
326
|
+
content: "Check redaction boundaries without exposing raw-provider-secret.",
|
|
327
|
+
metadata: { scenarioKey },
|
|
328
|
+
}];
|
|
329
|
+
}
|
|
330
|
+
return [{
|
|
331
|
+
role: "user",
|
|
332
|
+
content: `Run deterministic ${scenarioKey} conformance.`,
|
|
333
|
+
metadata: { scenarioKey },
|
|
334
|
+
}];
|
|
335
|
+
}
|
|
336
|
+
function expectedEventsFor(terminalEventType) {
|
|
337
|
+
const events = [{
|
|
338
|
+
sequence: 1,
|
|
339
|
+
adapterEventId: "bridge-cli-turn-started",
|
|
340
|
+
eventType: "turn_started",
|
|
341
|
+
payloadKey: "turn_started",
|
|
342
|
+
}];
|
|
343
|
+
if (terminalEventType === "output_completed") {
|
|
344
|
+
events.push({
|
|
345
|
+
sequence: 2,
|
|
346
|
+
adapterEventId: "bridge-cli-output-delta",
|
|
347
|
+
eventType: "output_delta",
|
|
348
|
+
payloadKey: "provider_message",
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
events.push({
|
|
352
|
+
sequence: events.length + 1,
|
|
353
|
+
adapterEventId: `bridge-cli-${terminalEventType}`,
|
|
354
|
+
eventType: terminalEventType,
|
|
355
|
+
payloadKey: terminalEventType,
|
|
356
|
+
});
|
|
357
|
+
return events;
|
|
358
|
+
}
|
|
359
|
+
function callbackEnvelopeFor(packet, eventType, finalMessage) {
|
|
360
|
+
return {
|
|
361
|
+
callbackId: ids.callbackId,
|
|
362
|
+
chatRunId: packet.chatRunId,
|
|
363
|
+
conversationId: packet.conversationId,
|
|
364
|
+
turnId: packet.turnId,
|
|
365
|
+
leaseId: packet.leaseId,
|
|
366
|
+
fencingToken: packet.fencingToken,
|
|
367
|
+
runnerId: ids.runnerId,
|
|
368
|
+
runnerInstanceId: packet.runnerInstanceId,
|
|
369
|
+
sequence: eventType === "output_completed" ? 3 : 2,
|
|
370
|
+
eventType,
|
|
371
|
+
redactionStatus: "redacted",
|
|
372
|
+
providerThreadId: packet.providerThreadId,
|
|
373
|
+
payload: {
|
|
374
|
+
code: eventType,
|
|
375
|
+
text: finalMessage ?? "",
|
|
376
|
+
provider: packet.providerKind,
|
|
377
|
+
model: packet.model,
|
|
378
|
+
},
|
|
379
|
+
occurredAt: "2026-09-26T12:00:00.000Z",
|
|
380
|
+
protocolVersion: bridgeChatProtocolVersion,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function providerStreamFor(providerKind, providerThreadId, scenario) {
|
|
384
|
+
if (providerKind === "cursor") {
|
|
385
|
+
const stdoutLines = [
|
|
386
|
+
JSON.stringify({ type: "system", subtype: "init", session_id: providerThreadId }),
|
|
387
|
+
...(scenario.finalMessage
|
|
388
|
+
? [JSON.stringify({
|
|
389
|
+
type: "assistant",
|
|
390
|
+
message: { role: "assistant", content: [{ type: "text", text: scenario.finalMessage }] },
|
|
391
|
+
})]
|
|
392
|
+
: []),
|
|
393
|
+
JSON.stringify({ type: "result", subtype: "success", is_error: false, result: scenario.finalMessage ?? "" }),
|
|
394
|
+
];
|
|
395
|
+
return {
|
|
396
|
+
stdoutLines,
|
|
397
|
+
expectedEventTypes: scenario.finalMessage
|
|
398
|
+
? ["provider_thread_started", "provider_message"]
|
|
399
|
+
: ["provider_thread_started"],
|
|
400
|
+
expectedFinalMessage: scenario.finalMessage,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
const stdoutLines = [
|
|
404
|
+
JSON.stringify({ type: "thread.started", thread_id: providerThreadId }),
|
|
405
|
+
...(scenario.finalMessage
|
|
406
|
+
? [JSON.stringify({ type: "item.completed", item: { type: "agent_message", text: scenario.finalMessage } })]
|
|
407
|
+
: []),
|
|
408
|
+
JSON.stringify({ type: "turn.completed" }),
|
|
409
|
+
];
|
|
410
|
+
return {
|
|
411
|
+
stdoutLines,
|
|
412
|
+
expectedEventTypes: scenario.finalMessage
|
|
413
|
+
? ["provider_thread_started", "provider_message", "provider_turn_completed"]
|
|
414
|
+
: ["provider_thread_started", "provider_turn_completed"],
|
|
415
|
+
expectedFinalMessage: scenario.finalMessage,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function attachmentHandoff() {
|
|
419
|
+
return {
|
|
420
|
+
turnId: ids.turnId,
|
|
421
|
+
attachmentId: ids.attachmentId,
|
|
422
|
+
tempFileToken: "opaque-temp-file-token",
|
|
423
|
+
mimeType: "text/plain",
|
|
424
|
+
sizeBytes: 123,
|
|
425
|
+
sha256: "a".repeat(64),
|
|
426
|
+
fileNameDisplay: "notes.txt",
|
|
427
|
+
expiresAt: deterministicExpiresAt,
|
|
428
|
+
status: "available",
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function actionBrokerGrant() {
|
|
432
|
+
return {
|
|
433
|
+
grantId: ids.grantId,
|
|
434
|
+
turnId: ids.turnId,
|
|
435
|
+
leaseId: ids.leaseId,
|
|
436
|
+
fencingToken: ids.fencingToken,
|
|
437
|
+
allowedScopes: ["action_broker_grants", "text"],
|
|
438
|
+
nonce: "opaque-grant-nonce",
|
|
439
|
+
expiresAt: deterministicExpiresAt,
|
|
440
|
+
redactionStatus: "not_applicable",
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function packetRecord(packet) {
|
|
444
|
+
return {
|
|
445
|
+
chatRunId: packet.chatRunId,
|
|
446
|
+
conversationId: packet.conversationId,
|
|
447
|
+
turnId: packet.turnId,
|
|
448
|
+
leaseId: packet.leaseId,
|
|
449
|
+
fencingToken: packet.fencingToken,
|
|
450
|
+
runnerInstanceId: packet.runnerInstanceId,
|
|
451
|
+
providerKind: packet.providerKind,
|
|
452
|
+
model: packet.model,
|
|
453
|
+
messages: packet.messages,
|
|
454
|
+
contextRefs: packet.contextRefs,
|
|
455
|
+
idempotencyKey: packet.idempotencyKey,
|
|
456
|
+
providerThreadId: packet.providerThreadId,
|
|
457
|
+
protocolVersion: packet.protocolVersion,
|
|
458
|
+
requestedCapabilities: packet.requestedCapabilities,
|
|
459
|
+
attachmentHandoffs: packet.attachmentHandoffs,
|
|
460
|
+
actionBrokerGrants: packet.actionBrokerGrants,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { RunOnceDispatchPacket } from "../session.types.js";
|
|
2
2
|
export declare const ciRepairProviderOnlySpecs: readonly ["**/bridge-dispatch.spec.ts", "**/develop-agent-run.spec.ts", "**/runner-availability.spec.ts"];
|
|
3
|
+
export declare const ciRepairLocalPreflightCommands: readonly CiRepairLocalPreflightCommand[];
|
|
4
|
+
export interface CiRepairLocalPreflightCommand {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
readonly command: readonly string[];
|
|
8
|
+
readonly coverage: string;
|
|
9
|
+
}
|
|
3
10
|
export interface CiRepairReadinessResult {
|
|
4
11
|
readonly path: string;
|
|
5
12
|
readonly environment: Readonly<Record<string, string>>;
|
|
6
13
|
readonly manifest: Readonly<Record<string, unknown>>;
|
|
7
14
|
}
|
|
8
15
|
export declare function writeCiRepairReadinessManifest(dispatch: RunOnceDispatchPacket, worktreePath: string, specPath: string, runtimeEnvironment: Readonly<Record<string, string>> | undefined): Promise<CiRepairReadinessResult>;
|
|
16
|
+
export declare function assertCiRepairPreflightContract(providerOnlySpecs: readonly string[], localPreflightCommands: readonly CiRepairLocalPreflightCommand[]): void;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
3
4
|
export const ciRepairProviderOnlySpecs = [
|
|
4
5
|
"**/bridge-dispatch.spec.ts",
|
|
5
6
|
"**/develop-agent-run.spec.ts",
|
|
6
7
|
"**/runner-availability.spec.ts",
|
|
7
8
|
];
|
|
9
|
+
export const ciRepairLocalPreflightCommands = [];
|
|
8
10
|
export async function writeCiRepairReadinessManifest(dispatch, worktreePath, specPath, runtimeEnvironment) {
|
|
11
|
+
assertCiRepairPreflightContract(ciRepairProviderOnlySpecs, ciRepairLocalPreflightCommands);
|
|
9
12
|
const metadataRoot = path.dirname(specPath);
|
|
10
13
|
const manifestPath = path.join(metadataRoot, "ci-repair.readiness.json");
|
|
11
14
|
const workflowPath = path.join(worktreePath, ".github", "workflows", "ci.yml");
|
|
12
15
|
const browserReady = runtimeEnvironment?.FORGE_PLAYWRIGHT_BROWSER_READY === "true";
|
|
16
|
+
const providerOnlySpecsJson = JSON.stringify(ciRepairProviderOnlySpecs);
|
|
13
17
|
const apiUrl = runtimeEnvironment?.FORGE_E2E_API_URL ?? runtimeEnvironment?.FORGE_API_URL ?? null;
|
|
14
18
|
const webUrl = runtimeEnvironment?.FORGE_E2E_WEB_URL
|
|
15
19
|
?? runtimeEnvironment?.FORGE_WEB_URL
|
|
@@ -21,7 +25,7 @@ export async function writeCiRepairReadinessManifest(dispatch, worktreePath, spe
|
|
|
21
25
|
...(webUrl ? { FORGE_E2E_WEB_URL: webUrl } : {}),
|
|
22
26
|
FORGE_CI_REPAIR_READINESS_PATH: manifestPath,
|
|
23
27
|
FORGE_CI_REPAIR_HANDOFF_PATH: path.join(metadataRoot, "artifacts", "ci-repair.handoff.json"),
|
|
24
|
-
FORGE_CI_REPAIR_PROVIDER_ONLY_SPECS:
|
|
28
|
+
FORGE_CI_REPAIR_PROVIDER_ONLY_SPECS: providerOnlySpecsJson,
|
|
25
29
|
};
|
|
26
30
|
const manifest = {
|
|
27
31
|
schema_version: 1,
|
|
@@ -64,19 +68,32 @@ export async function writeCiRepairReadinessManifest(dispatch, worktreePath, spe
|
|
|
64
68
|
playwright_browser_install_command: browserReady
|
|
65
69
|
? null
|
|
66
70
|
: runtimeEnvironment?.FORGE_PLAYWRIGHT_BROWSER_INSTALL_COMMAND ?? "npx playwright install chromium",
|
|
71
|
+
attempt_database_schema: runtimeEnvironment?.FORGE_ATTEMPT_DATABASE_SCHEMA ?? null,
|
|
72
|
+
attempt_database_readiness_path: runtimeEnvironment?.FORGE_ATTEMPT_DATABASE_READINESS_PATH ?? null,
|
|
67
73
|
},
|
|
68
74
|
local_equivalence: {
|
|
69
75
|
default: "supported",
|
|
70
76
|
nested_bridge: "provider_only",
|
|
71
77
|
provider_only_specs: ciRepairProviderOnlySpecs,
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
provider_only_specs_fingerprint: `sha256:${createHash("sha256").update(providerOnlySpecsJson).digest("hex")}`,
|
|
79
|
+
local_preflight_commands: ciRepairLocalPreflightCommands,
|
|
80
|
+
reason: "A managed Forge attempt disables its hosted reconciler and cannot exercise specs that require the live Bridge/runner control plane. Those specs remain authoritative in provider CI; attempt-local unit, contract, API, and browser coverage remains supported.",
|
|
81
|
+
policy: "Run every listed local_preflight_command. Treat every provider_only_specs pattern as unavailable in the managed attempt, do not override its exclusion or weaken provider CI, and record the provider check that supplies that proof in workflow_validation.",
|
|
74
82
|
},
|
|
75
83
|
};
|
|
76
84
|
await fs.mkdir(metadataRoot, { recursive: true });
|
|
77
85
|
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
78
86
|
return { path: manifestPath, environment, manifest };
|
|
79
87
|
}
|
|
88
|
+
export function assertCiRepairPreflightContract(providerOnlySpecs, localPreflightCommands) {
|
|
89
|
+
const providerOnlyFileNames = new Set(providerOnlySpecs.map(fileName));
|
|
90
|
+
for (const preflight of localPreflightCommands) {
|
|
91
|
+
const conflictingArgument = preflight.command.find(argument => providerOnlyFileNames.has(fileName(argument)));
|
|
92
|
+
if (conflictingArgument) {
|
|
93
|
+
throw new Error(`ci_repair_readiness_invalid: local preflight '${preflight.id}' references provider-only spec '${conflictingArgument}'.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
80
97
|
async function isFile(candidate) {
|
|
81
98
|
try {
|
|
82
99
|
return (await fs.stat(candidate)).isFile();
|
|
@@ -88,3 +105,6 @@ async function isFile(candidate) {
|
|
|
88
105
|
function relativePath(worktreePath, candidate) {
|
|
89
106
|
return path.relative(worktreePath, candidate).replaceAll(path.sep, "/");
|
|
90
107
|
}
|
|
108
|
+
function fileName(candidate) {
|
|
109
|
+
return path.posix.basename(candidate.replaceAll("\\", "/"));
|
|
110
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GitClient } from "../../shared/git/git.js";
|
|
2
2
|
import { type CompletionPhase, type CompletionToolRuntime, type DebugCompletionPhase, type QaCompletionGate } from "../phase-completion.js";
|
|
3
|
-
import type { RunOnceDispatchPacket, RunnerDispatchArtifact } from "../session.types.js";
|
|
3
|
+
import type { RunOnceDispatchPacket, RunnerDispatchArtifact, RunnerDispatchSidecar } from "../session.types.js";
|
|
4
4
|
import type { ProviderCliRunContext } from "./provider-cli.types.js";
|
|
5
5
|
export declare function emitDraftGateArtifacts(emit: ProviderCliRunContext["emit"], worktreePath: string, workItemId: string): Promise<void>;
|
|
6
6
|
export declare function emitDecomposeGateArtifacts(emit: ProviderCliRunContext["emit"], worktreePath: string, workItemId: string): Promise<void>;
|
|
@@ -9,10 +9,11 @@ export declare function summarizeStderr(stderr: string): string;
|
|
|
9
9
|
export declare function waitForCompletionArtifact(worktreePath: string, workItemId: string, phase: "draft" | "decompose", signal?: AbortSignal): Promise<RunnerDispatchArtifact>;
|
|
10
10
|
export declare function delay(ms: number, signal?: AbortSignal): Promise<void>;
|
|
11
11
|
export declare function cleanupCompletionTools(completionTools: CompletionToolRuntime, emit: ProviderCliRunContext["emit"]): Promise<void>;
|
|
12
|
-
export declare function commitWorktreeChanges(git: GitClient, worktreePath: string, workItemId: string): Promise<{
|
|
12
|
+
export declare function commitWorktreeChanges(git: GitClient, worktreePath: string, workItemId: string, alreadyStagedChangedFiles?: readonly string[]): Promise<{
|
|
13
13
|
readonly commitSha: string;
|
|
14
14
|
readonly changedFiles: readonly string[];
|
|
15
15
|
}>;
|
|
16
|
+
export declare function stagePublishableWorktreeChanges(git: GitClient, worktreePath: string): Promise<readonly string[]>;
|
|
16
17
|
export declare function phaseCompleteEventType(phase: CompletionPhase): string;
|
|
17
18
|
export declare function isDebugCompletionPhaseForProvider(phase: CompletionPhase): phase is DebugCompletionPhase;
|
|
18
19
|
export declare function emitQaArtifactRecorded(emit: ProviderCliRunContext["emit"], worktreePath: string, artifact: RunnerDispatchArtifact): Promise<void>;
|
|
@@ -20,6 +21,7 @@ export declare function readQaCompletionArtifactBundle(worktreePath: string, wor
|
|
|
20
21
|
export declare function hasCompleteQaArtifactBundle(worktreePath: string, workItemId: string, ownerType?: string | null, ownerId?: string | null): Promise<boolean>;
|
|
21
22
|
export declare function enforceQaBrowserLaunchTargetGate(dispatch: RunOnceDispatchPacket, artifact: RunnerDispatchArtifact): Promise<void>;
|
|
22
23
|
export declare function validateQaBundleSidecarReferences(worktreePath: string, workItemId: string, ownerType?: string | null, ownerId?: string | null): Promise<void>;
|
|
24
|
+
export declare function readQaBundleSidecars(worktreePath: string, workItemId: string, ownerType?: string | null, ownerId?: string | null): Promise<RunnerDispatchSidecar[]>;
|
|
23
25
|
export declare function emitQaStructuredEvents(emit: ProviderCliRunContext["emit"], artifact: RunnerDispatchArtifact): Promise<void>;
|
|
24
26
|
interface QaGateArtifactSnapshot {
|
|
25
27
|
readonly gate: QaCompletionGate;
|