@loucompanion/forge-bridge 0.1.1-dev.718bdb0018b9 → 0.1.1-dev.895607f4402a
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/dist/bridge/bridge.service.js +39 -8
- package/dist/session/internals.d.ts +1 -1
- package/dist/session/phase-completion.d.ts +27 -2
- package/dist/session/phase-completion.js +831 -25
- package/dist/session/provider-cli/provider-cli.service.js +339 -131
- package/dist/session/session.service.js +6 -1
- package/dist/session/session.types.d.ts +23 -0
- package/dist/session/session.types.js +29 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worktree/artifact-injector.d.ts +1 -0
- package/dist/worktree/artifact-injector.js +30 -1
- package/dist/worktree/worktree.service.js +5 -3
- package/dist/worktree/worktree.types.d.ts +2 -0
- package/package.json +8 -3
|
@@ -51,7 +51,7 @@ export class ForgeBridgeService {
|
|
|
51
51
|
attempt = 0;
|
|
52
52
|
await this.waitForClose(signal);
|
|
53
53
|
}
|
|
54
|
-
catch
|
|
54
|
+
catch {
|
|
55
55
|
if (this.stopped || signal?.aborted) {
|
|
56
56
|
break;
|
|
57
57
|
}
|
|
@@ -87,11 +87,20 @@ export class ForgeBridgeService {
|
|
|
87
87
|
const normalized = this.normalizeDispatch(dispatch);
|
|
88
88
|
const result = await this.sessions.runOnce(normalized, {
|
|
89
89
|
emit: async (event) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
try {
|
|
91
|
+
await this.invokeAck("DispatchEvent", {
|
|
92
|
+
leaseId,
|
|
93
|
+
fencingToken,
|
|
94
|
+
event: redactSecrets(event, redactionSecrets)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (isDispatchNoLongerPending(error)) {
|
|
99
|
+
controller.abort(error instanceof Error ? error.message : "Dispatch is no longer pending.");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
95
104
|
}
|
|
96
105
|
}, controller.signal);
|
|
97
106
|
await this.sendResult(leaseId, fencingToken, redactSecrets(result, redactionSecrets));
|
|
@@ -149,7 +158,15 @@ export class ForgeBridgeService {
|
|
|
149
158
|
fencingToken,
|
|
150
159
|
result
|
|
151
160
|
};
|
|
152
|
-
|
|
161
|
+
try {
|
|
162
|
+
await this.invokeAck("DispatchResult", payload);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (isDispatchNoLongerPending(error)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
153
170
|
}
|
|
154
171
|
startHeartbeat() {
|
|
155
172
|
this.stopHeartbeat();
|
|
@@ -196,7 +213,7 @@ export class ForgeBridgeService {
|
|
|
196
213
|
}
|
|
197
214
|
const ack = await connection.invoke(methodName, payload);
|
|
198
215
|
if (!ack.accepted) {
|
|
199
|
-
throw new
|
|
216
|
+
throw new BridgeCallbackRejectedError(ack.code ?? null, ack.message ?? ack.code ?? `${methodName} callback was rejected.`);
|
|
200
217
|
}
|
|
201
218
|
return ack;
|
|
202
219
|
}
|
|
@@ -214,6 +231,20 @@ export class ForgeBridgeService {
|
|
|
214
231
|
}
|
|
215
232
|
}
|
|
216
233
|
}
|
|
234
|
+
class BridgeCallbackRejectedError extends Error {
|
|
235
|
+
code;
|
|
236
|
+
constructor(code, message) {
|
|
237
|
+
super(message);
|
|
238
|
+
this.code = code;
|
|
239
|
+
this.name = "BridgeCallbackRejectedError";
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function isDispatchNoLongerPending(error) {
|
|
243
|
+
if (error instanceof BridgeCallbackRejectedError) {
|
|
244
|
+
return error.code === "bridge.dispatch_not_pending" || error.code === "bridge.stale_dispatch";
|
|
245
|
+
}
|
|
246
|
+
return error instanceof Error && error.message === "Dispatch is no longer pending.";
|
|
247
|
+
}
|
|
217
248
|
export class SignalRBridgeConnectionFactory {
|
|
218
249
|
create(config) {
|
|
219
250
|
return new SignalRBridgeConnection(config);
|
|
@@ -2,7 +2,7 @@ export { parseRunOnceDispatchPacket, failureResult } from "./session.types.js";
|
|
|
2
2
|
export { buildCompletionToolServerArgs, codexMcpConfigArgs, completionPhaseFromDispatch, expectedCompletionToolName, prepareCompletionToolRuntime, readCompletionArtifact, writeCompletionArtifact } from "./phase-completion.js";
|
|
3
3
|
export type { CompletionArtifactReference, CompletionPhase, CompletionToolRuntime } from "./phase-completion.js";
|
|
4
4
|
export type { SessionEventSink, SessionService } from "./session.base.js";
|
|
5
|
-
export type { ApiKeySecretGrant, DispatchCycleRun, DispatchExecution, DispatchLease, DispatchSession, DispatchRepo, DispatchServerLocalConfig, DispatchWorkItem, RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchArtifact, RunnerDispatchEvent, RunnerDispatchSpec, RunnerEventLine } from "./session.types.js";
|
|
5
|
+
export type { ApiKeySecretGrant, DispatchCycleRun, DispatchExecution, DispatchLease, DispatchPullRequestContext, DispatchSession, DispatchRepo, DispatchServerLocalConfig, DispatchWorkItem, RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchArtifact, RunnerDispatchEvent, RunnerDispatchSpec, RunnerEventLine } from "./session.types.js";
|
|
6
6
|
export { DeterministicProviderCliService, ProcessBackedProviderCliService, RoutingProviderCliService, buildProviderCliCommand } from "./provider-cli/provider-cli.service.js";
|
|
7
7
|
export type { ProviderCliService } from "./provider-cli/provider-cli.base.js";
|
|
8
8
|
export type { ProviderCliCommand, ProviderProcessRunner, ProviderProcessRunRequest, ProviderProcessRunResult } from "./provider-cli/provider-cli.service.js";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { RunOnceDispatchPacket, RunnerDispatchArtifact } from "./session.types.js";
|
|
2
2
|
import type { WorktreeHandle } from "../worktree/worktree.types.js";
|
|
3
|
-
export type
|
|
3
|
+
export type DevelopCompletionPhase = "implementation" | "self_review" | "validation";
|
|
4
|
+
export type DebugCompletionPhase = "debug_repro" | "debug_root_cause" | "debug_fix" | "debug_regression";
|
|
5
|
+
export type CompletionPhase = DevelopCompletionPhase | "qa" | DebugCompletionPhase;
|
|
6
|
+
export type QaCompletionGate = "qa_plan" | "qa_regression" | "qa_api" | "qa_manual_web" | "qa_bug_repro" | "qa_findings" | "qa_verdict";
|
|
4
7
|
export interface CompletionToolRuntime {
|
|
5
8
|
readonly serverName: string;
|
|
6
9
|
readonly command: string;
|
|
@@ -17,10 +20,14 @@ export interface CompletionToolRuntimeOptions {
|
|
|
17
20
|
export interface CompletionToolServerConfig {
|
|
18
21
|
readonly worktreePath: string;
|
|
19
22
|
readonly workItemId: string;
|
|
23
|
+
readonly ownerType?: string;
|
|
24
|
+
readonly ownerId?: string;
|
|
20
25
|
readonly phase: CompletionPhase;
|
|
21
26
|
readonly producedBy?: string;
|
|
22
27
|
readonly redactionSecrets?: readonly string[];
|
|
23
28
|
readonly developCycle?: boolean;
|
|
29
|
+
readonly qaCycle?: boolean;
|
|
30
|
+
readonly debugCycle?: boolean;
|
|
24
31
|
}
|
|
25
32
|
export interface CompletionToolCallResult {
|
|
26
33
|
readonly content: readonly {
|
|
@@ -30,17 +37,20 @@ export interface CompletionToolCallResult {
|
|
|
30
37
|
readonly structuredContent: CompletionArtifactReference & {
|
|
31
38
|
readonly gate: {
|
|
32
39
|
readonly phase: CompletionPhase;
|
|
40
|
+
readonly qaGate?: QaCompletionGate;
|
|
33
41
|
readonly status: string;
|
|
34
42
|
readonly allowed: boolean;
|
|
35
43
|
readonly reason: string;
|
|
36
44
|
};
|
|
37
|
-
readonly nextPhase: CompletionPhase | "dev_test_ready" | "sign_off_ready";
|
|
45
|
+
readonly nextPhase: CompletionPhase | "dev_test_ready" | "qa_ready" | "sign_off_ready";
|
|
38
46
|
readonly nextInstruction: string;
|
|
39
47
|
};
|
|
40
48
|
}
|
|
41
49
|
export interface CompletionArtifactReference {
|
|
42
50
|
readonly phase: CompletionPhase;
|
|
43
51
|
readonly workItemId: string;
|
|
52
|
+
readonly ownerType?: string;
|
|
53
|
+
readonly ownerId?: string;
|
|
44
54
|
readonly repoPath: string;
|
|
45
55
|
readonly path: string;
|
|
46
56
|
readonly reportPath: string;
|
|
@@ -48,11 +58,19 @@ export interface CompletionArtifactReference {
|
|
|
48
58
|
readonly status: string;
|
|
49
59
|
readonly producedBy: string;
|
|
50
60
|
}
|
|
61
|
+
export declare const debugCompletionPhaseOrder: readonly DebugCompletionPhase[];
|
|
62
|
+
export declare const qaCompletionGateOrder: readonly QaCompletionGate[];
|
|
51
63
|
export declare function completionPhaseFromDispatch(dispatch: RunOnceDispatchPacket): CompletionPhase;
|
|
52
64
|
export declare function normalizeCompletionPhase(value: string | null | undefined): CompletionPhase;
|
|
53
65
|
export declare function usesDevelopCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
|
|
66
|
+
export declare function usesQaCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
|
|
67
|
+
export declare function usesDebugCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
|
|
54
68
|
export declare function completionToolNamesForPhase(phase: CompletionPhase): readonly string[];
|
|
69
|
+
export declare function completionToolNamesForQaGate(gate: QaCompletionGate): readonly string[];
|
|
70
|
+
export declare function completionToolNamesForDebugGate(gate: DebugCompletionPhase): readonly string[];
|
|
55
71
|
export declare function expectedCompletionToolName(phase: CompletionPhase): string;
|
|
72
|
+
export declare function expectedQaCompletionToolName(gate: QaCompletionGate): string;
|
|
73
|
+
export declare function expectedDebugCompletionToolName(gate: DebugCompletionPhase): string;
|
|
56
74
|
export declare function artifactRootFor(worktreePath: string, workItemId: string): string;
|
|
57
75
|
export declare function completionArtifactJsonPath(worktreePath: string, workItemId: string, phase: CompletionPhase): string;
|
|
58
76
|
export declare function completionArtifactReportPath(worktreePath: string, workItemId: string, phase: CompletionPhase): string;
|
|
@@ -62,16 +80,23 @@ export declare function codexMcpConfigArgs(runtime: CompletionToolRuntime): read
|
|
|
62
80
|
export declare function cursorMcpServerConfig(runtime: CompletionToolRuntime): unknown;
|
|
63
81
|
export declare function completionPromptForPhase(phase: CompletionPhase): string;
|
|
64
82
|
export declare function completionPromptForDevelopCycle(phase: CompletionPhase): string;
|
|
83
|
+
export declare function completionPromptForQaCycle(currentGate?: QaCompletionGate): string;
|
|
84
|
+
export declare function completionPromptForDebugCycle(currentGate?: DebugCompletionPhase): string;
|
|
65
85
|
export declare function completionToolNamesForServer(config: CompletionToolServerConfig): readonly string[];
|
|
66
86
|
export declare class CompletionToolServerSession {
|
|
67
87
|
private readonly config;
|
|
68
88
|
private currentPhase;
|
|
89
|
+
private currentQaGate;
|
|
69
90
|
private completed;
|
|
70
91
|
constructor(config: CompletionToolServerConfig);
|
|
71
92
|
get instructions(): string;
|
|
72
93
|
toolDefinitions(): readonly unknown[];
|
|
73
94
|
callTool(toolName: string, input: unknown): Promise<CompletionToolCallResult>;
|
|
95
|
+
private callDebugGateTool;
|
|
96
|
+
private callQaGateTool;
|
|
74
97
|
private advanceAfterPass;
|
|
98
|
+
private advanceAfterQaGate;
|
|
99
|
+
private advanceAfterDebugGate;
|
|
75
100
|
}
|
|
76
101
|
export declare function writeCompletionArtifact(config: CompletionToolServerConfig, toolName: string, input: unknown): Promise<CompletionArtifactReference>;
|
|
77
102
|
export declare function readCompletionArtifact(worktreePath: string, workItemId: string, phase: CompletionPhase): Promise<RunnerDispatchArtifact | null>;
|