@loucompanion/forge-bridge 0.1.1-dev.8dcbc6245e51 → 0.1.1-dev.9219f8477b8a

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.
Files changed (37) hide show
  1. package/dist/bridge/bridge.service.d.ts +1 -0
  2. package/dist/bridge/bridge.service.js +219 -25
  3. package/dist/bridge/bridge.types.d.ts +19 -2
  4. package/dist/cli/cli.service.d.ts +27 -2
  5. package/dist/cli/cli.service.js +630 -25
  6. package/dist/cli/local-config.d.ts +4 -0
  7. package/dist/cli/local-config.js +42 -4
  8. package/dist/config.js +1 -1
  9. package/dist/session/index.d.ts +2 -0
  10. package/dist/session/index.js +1 -0
  11. package/dist/session/internals.d.ts +5 -3
  12. package/dist/session/internals.js +2 -1
  13. package/dist/session/phase-completion.d.ts +126 -0
  14. package/dist/session/phase-completion.js +3233 -0
  15. package/dist/session/provider-cli/index.d.ts +2 -2
  16. package/dist/session/provider-cli/index.js +1 -1
  17. package/dist/session/provider-cli/provider-cli.base.d.ts +5 -3
  18. package/dist/session/provider-cli/provider-cli.service.d.ts +64 -4
  19. package/dist/session/provider-cli/provider-cli.service.js +2787 -51
  20. package/dist/session/provider-cli/provider-cli.types.d.ts +7 -0
  21. package/dist/session/provider-cli/provider-usage.d.ts +25 -0
  22. package/dist/session/provider-cli/provider-usage.js +64 -0
  23. package/dist/session/qa-sidecar-validation.d.ts +3 -0
  24. package/dist/session/qa-sidecar-validation.js +44 -0
  25. package/dist/session/session.service.js +62 -11
  26. package/dist/session/session.types.d.ts +132 -0
  27. package/dist/session/session.types.js +261 -2
  28. package/dist/shared/cursor-agent/cursor-agent.launch.d.ts +9 -0
  29. package/dist/shared/cursor-agent/cursor-agent.launch.js +66 -0
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/dist/worktree/artifact-injector.d.ts +2 -1
  33. package/dist/worktree/artifact-injector.js +125 -9
  34. package/dist/worktree/worktree.service.d.ts +3 -0
  35. package/dist/worktree/worktree.service.js +239 -8
  36. package/dist/worktree/worktree.types.d.ts +8 -1
  37. package/package.json +8 -3
@@ -13,6 +13,10 @@ export interface BridgeLocalConfig {
13
13
  readonly repoMappings?: readonly LocalRepoMapping[];
14
14
  readonly sandboxProfiles?: readonly string[];
15
15
  readonly supportsApiSecretGrant?: boolean;
16
+ readonly supportsManagedWorktrees?: boolean;
17
+ readonly supportsManagedForgeArtifacts?: boolean;
18
+ readonly supportsRunnerAuthoredPhaseArtifacts?: boolean;
19
+ readonly supportsDraftRunOnce?: boolean;
16
20
  }
17
21
  export interface LocalRepoMapping extends BridgeRepoMapping {
18
22
  readonly label: string;
@@ -49,8 +49,12 @@ export function applyLocalConfigDefaults(config, local) {
49
49
  providerStatuses: normalizeProviderStatuses(local.providerStatuses) ?? providerStatusesFor(cliProviders),
50
50
  projectLabels: local.projectLabels ?? config.projectLabels,
51
51
  repoMappings: local.repoMappings ?? config.repoMappings,
52
- sandboxProfiles: local.sandboxProfiles ?? config.sandboxProfiles,
53
- supportsApiSecretGrant: local.supportsApiSecretGrant ?? config.supportsApiSecretGrant
52
+ sandboxProfiles: normalizeSandboxProfiles(local.sandboxProfiles ?? config.sandboxProfiles, cliProviders) ?? config.sandboxProfiles,
53
+ supportsApiSecretGrant: local.supportsApiSecretGrant ?? config.supportsApiSecretGrant,
54
+ supportsManagedWorktrees: local.supportsManagedWorktrees ?? config.supportsManagedWorktrees,
55
+ supportsManagedForgeArtifacts: local.supportsManagedForgeArtifacts ?? config.supportsManagedForgeArtifacts,
56
+ supportsRunnerAuthoredPhaseArtifacts: local.supportsRunnerAuthoredPhaseArtifacts ?? config.supportsRunnerAuthoredPhaseArtifacts,
57
+ supportsDraftRunOnce: local.supportsDraftRunOnce ?? config.supportsDraftRunOnce
54
58
  };
55
59
  }
56
60
  export async function addRepoMapping(label, repoPath) {
@@ -105,7 +109,11 @@ function normalizeLocalConfig(config) {
105
109
  projectLabels: cleanList(config.projectLabels),
106
110
  repoMappings: normalizeRepoMappings(config.repoMappings),
107
111
  sandboxProfiles: cleanList(config.sandboxProfiles),
108
- supportsApiSecretGrant: config.supportsApiSecretGrant
112
+ supportsApiSecretGrant: config.supportsApiSecretGrant,
113
+ supportsManagedWorktrees: config.supportsManagedWorktrees,
114
+ supportsManagedForgeArtifacts: config.supportsManagedForgeArtifacts,
115
+ supportsRunnerAuthoredPhaseArtifacts: config.supportsRunnerAuthoredPhaseArtifacts,
116
+ supportsDraftRunOnce: config.supportsDraftRunOnce
109
117
  };
110
118
  }
111
119
  function emptyConfig() {
@@ -143,6 +151,19 @@ function splitCsv(value) {
143
151
  .map((entry) => entry.trim())
144
152
  .filter((entry) => entry.length > 0);
145
153
  }
154
+ function normalizeSandboxProfiles(profiles, cliProviders) {
155
+ const normalized = cleanList(profiles);
156
+ if (process.platform === "win32"
157
+ && cliProviders.some((provider) => provider.toLowerCase() === "codex")
158
+ && normalized?.some((profile) => profile.toLowerCase() === "provider-workspace-write")
159
+ && !normalized.some((profile) => profile.toLowerCase() === "danger-full-access")) {
160
+ return [
161
+ ...normalized.filter((profile) => profile.toLowerCase() !== "provider-workspace-write"),
162
+ "danger-full-access"
163
+ ];
164
+ }
165
+ return normalized;
166
+ }
146
167
  function normalizeRepoMappings(values) {
147
168
  return (values ?? [])
148
169
  .filter((mapping) => !!mapping.label?.trim() && !!mapping.localPath?.trim())
@@ -153,7 +174,8 @@ function normalizeRepoMappings(values) {
153
174
  repoId: cleanString(mapping.repoId),
154
175
  name: cleanString(mapping.name) ?? label,
155
176
  remoteUrl: cleanString(mapping.remoteUrl),
156
- localPath: path.resolve(mapping.localPath)
177
+ localPath: path.resolve(mapping.localPath),
178
+ qaAppLaunchTarget: normalizeQaAppLaunchTarget(mapping.qaAppLaunchTarget)
157
179
  };
158
180
  })
159
181
  .sort((left, right) => left.label.localeCompare(right.label));
@@ -165,6 +187,22 @@ function normalizeLabel(value) {
165
187
  }
166
188
  return label;
167
189
  }
190
+ function normalizeQaAppLaunchTarget(value) {
191
+ if (!value)
192
+ return undefined;
193
+ const routes = cleanList(value.routes);
194
+ const normalized = {
195
+ url: cleanString(value.url),
196
+ command: cleanString(value.command),
197
+ working_directory: cleanString(value.working_directory),
198
+ ready_url: cleanString(value.ready_url),
199
+ routes,
200
+ notes: cleanString(value.notes)
201
+ };
202
+ return normalized.url || normalized.command || normalized.ready_url || routes?.length
203
+ ? normalized
204
+ : undefined;
205
+ }
168
206
  function cleanString(value) {
169
207
  const clean = value?.trim();
170
208
  return clean ? clean : undefined;
package/dist/config.js CHANGED
@@ -2,7 +2,7 @@ import os from "node:os";
2
2
  import path from "node:path";
3
3
  export function defaultForgeBridgeConfig() {
4
4
  return {
5
- defaultRepoRoot: path.join(os.tmpdir(), "forge-phase5-repos"),
5
+ defaultRepoRoot: path.join(os.tmpdir(), "forge-repos"),
6
6
  cleanupWorktrees: true
7
7
  };
8
8
  }
@@ -1,2 +1,4 @@
1
1
  export { BridgeSessionService } from "./session.service.js";
2
+ export { buildCompletionToolServerArgs, codexMcpConfigArgs, completionPhaseFromDispatch, expectedCompletionToolName, prepareCompletionToolRuntime, readCompletionArtifact, writeCompletionArtifact } from "./phase-completion.js";
3
+ export type { CompletionArtifactReference, CompletionPhase, CompletionToolRuntime } from "./phase-completion.js";
2
4
  export type { SessionService } from "./session.base.js";
@@ -1 +1,2 @@
1
1
  export { BridgeSessionService } from "./session.service.js";
2
+ export { buildCompletionToolServerArgs, codexMcpConfigArgs, completionPhaseFromDispatch, expectedCompletionToolName, prepareCompletionToolRuntime, readCompletionArtifact, writeCompletionArtifact } from "./phase-completion.js";
@@ -1,7 +1,9 @@
1
1
  export { parseRunOnceDispatchPacket, failureResult } from "./session.types.js";
2
+ export { buildCompletionToolServerArgs, codexMcpConfigArgs, completionPhaseFromDispatch, expectedCompletionToolName, prepareCompletionToolRuntime, readCompletionArtifact, writeCompletionArtifact } from "./phase-completion.js";
3
+ export type { CompletionArtifactReference, CompletionPhase, CompletionToolRuntime } from "./phase-completion.js";
2
4
  export type { SessionEventSink, SessionService } from "./session.base.js";
3
- export type { ApiKeySecretGrant, DispatchCycleRun, DispatchExecution, DispatchLease, DispatchSession, DispatchRepo, DispatchServerLocalConfig, DispatchWorkItem, RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchArtifact, RunnerDispatchEvent, RunnerDispatchSpec, RunnerEventLine } from "./session.types.js";
4
- export { DeterministicProviderCliService, buildProviderCliCommand } from "./provider-cli/provider-cli.service.js";
5
+ export type { ApiKeySecretGrant, DispatchCycleRun, DispatchExecution, DispatchLease, DispatchPullRequestContext, DispatchSession, DispatchRepo, DispatchServerLocalConfig, DispatchWorkItem, RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchArtifact, RunnerDispatchEvent, RunnerDispatchSpec, RunnerEventLine } from "./session.types.js";
6
+ export { DeterministicProviderCliService, ProcessBackedProviderCliService, RoutingProviderCliService, buildProviderCliCommand } from "./provider-cli/provider-cli.service.js";
5
7
  export type { ProviderCliService } from "./provider-cli/provider-cli.base.js";
6
- export type { ProviderCliCommand } from "./provider-cli/provider-cli.service.js";
8
+ export type { ProviderCliCommand, ProviderProcessRunner, ProviderProcessRunRequest, ProviderProcessRunResult } from "./provider-cli/provider-cli.service.js";
7
9
  export type { ProviderCliRunContext, ProviderCliRunResult } from "./provider-cli/provider-cli.types.js";
@@ -1,2 +1,3 @@
1
1
  export { parseRunOnceDispatchPacket, failureResult } from "./session.types.js";
2
- export { DeterministicProviderCliService, buildProviderCliCommand } from "./provider-cli/provider-cli.service.js";
2
+ export { buildCompletionToolServerArgs, codexMcpConfigArgs, completionPhaseFromDispatch, expectedCompletionToolName, prepareCompletionToolRuntime, readCompletionArtifact, writeCompletionArtifact } from "./phase-completion.js";
3
+ export { DeterministicProviderCliService, ProcessBackedProviderCliService, RoutingProviderCliService, buildProviderCliCommand } from "./provider-cli/provider-cli.service.js";
@@ -0,0 +1,126 @@
1
+ import type { RunOnceDispatchPacket, RunnerDispatchArtifact } from "./session.types.js";
2
+ import type { WorktreeHandle } from "../worktree/worktree.types.js";
3
+ export type DevelopCompletionPhase = "implementation" | "self_review" | "validation";
4
+ export type DebugCompletionPhase = "debug_repro" | "debug_root_cause" | "debug_fix" | "debug_regression";
5
+ export type ArchitectCompletionPhase = "architect";
6
+ export type DraftCompletionPhase = "draft";
7
+ export type CompletionPhase = DevelopCompletionPhase | "qa" | DebugCompletionPhase | ArchitectCompletionPhase | DraftCompletionPhase;
8
+ export type QaCompletionGate = "qa_plan" | "qa_regression" | "qa_api" | "qa_manual_web" | "qa_bug_repro" | "qa_findings" | "qa_verdict";
9
+ export type DraftCompletionGate = "draft_intent" | "draft_repo_context" | "draft_graph_context" | "draft_product_scope" | "draft_work_order_plan" | "draft_critic" | "draft_proposal";
10
+ export interface CompletionToolRuntime {
11
+ readonly serverName: string;
12
+ readonly command: string;
13
+ readonly args: readonly string[];
14
+ readonly env: Readonly<Record<string, string>>;
15
+ readonly cursorMcpConfigPath?: string | null;
16
+ cleanup(): Promise<void>;
17
+ }
18
+ export interface CompletionToolRuntimeOptions {
19
+ readonly dispatch: RunOnceDispatchPacket;
20
+ readonly worktree: WorktreeHandle;
21
+ readonly phase?: CompletionPhase;
22
+ }
23
+ export interface CompletionToolServerConfig {
24
+ readonly worktreePath: string;
25
+ readonly workItemId: string;
26
+ readonly ownerType?: string;
27
+ readonly ownerId?: string;
28
+ readonly phase: CompletionPhase;
29
+ readonly producedBy?: string;
30
+ readonly redactionSecrets?: readonly string[];
31
+ readonly developCycle?: boolean;
32
+ readonly qaCycle?: boolean;
33
+ readonly debugCycle?: boolean;
34
+ readonly architectCycle?: boolean;
35
+ readonly draftCycle?: boolean;
36
+ }
37
+ export interface CompletionToolCallResult {
38
+ readonly content: readonly {
39
+ readonly type: "text";
40
+ readonly text: string;
41
+ }[];
42
+ readonly structuredContent: CompletionArtifactReference & {
43
+ readonly gate: {
44
+ readonly phase: CompletionPhase;
45
+ readonly qaGate?: QaCompletionGate;
46
+ readonly draftGate?: DraftCompletionGate;
47
+ readonly status: string;
48
+ readonly allowed: boolean;
49
+ readonly reason: string;
50
+ };
51
+ readonly nextPhase: CompletionPhase | "dev_test_ready" | "qa_ready" | "sign_off_ready";
52
+ readonly nextInstruction: string;
53
+ };
54
+ }
55
+ export interface CompletionArtifactReference {
56
+ readonly phase: CompletionPhase;
57
+ readonly workItemId: string;
58
+ readonly ownerType?: string;
59
+ readonly ownerId?: string;
60
+ readonly repoPath: string;
61
+ readonly path: string;
62
+ readonly reportPath: string;
63
+ readonly contentHash: string;
64
+ readonly status: string;
65
+ readonly producedBy: string;
66
+ }
67
+ export declare const debugCompletionPhaseOrder: readonly DebugCompletionPhase[];
68
+ export declare const qaCompletionGateOrder: readonly QaCompletionGate[];
69
+ export declare const draftCompletionGateOrder: readonly DraftCompletionGate[];
70
+ export declare function completionPhaseFromDispatch(dispatch: RunOnceDispatchPacket): CompletionPhase;
71
+ export declare function normalizeCompletionPhase(value: string | null | undefined): CompletionPhase;
72
+ export declare function usesDevelopCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
73
+ export declare function usesQaCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
74
+ export declare function usesDebugCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
75
+ export declare function usesArchitectCycleCompletion(dispatch: RunOnceDispatchPacket): boolean;
76
+ export declare function completionToolNamesForPhase(phase: CompletionPhase): readonly string[];
77
+ export declare function completionToolNamesForQaGate(gate: QaCompletionGate): readonly string[];
78
+ export declare function completionToolNamesForDebugGate(gate: DebugCompletionPhase): readonly string[];
79
+ export declare function completionToolNamesForDraftGate(gate: DraftCompletionGate): readonly string[];
80
+ export declare function expectedCompletionToolName(phase: CompletionPhase): string;
81
+ export declare function expectedQaCompletionToolName(gate: QaCompletionGate): string;
82
+ export declare function expectedDebugCompletionToolName(gate: DebugCompletionPhase): string;
83
+ export declare function expectedDraftCompletionToolName(gate: DraftCompletionGate): string;
84
+ export declare function artifactRootFor(worktreePath: string, workItemId: string): string;
85
+ export declare function artifactRootForOwner(worktreePath: string, ownerType: string, ownerId: string): string;
86
+ export declare function completionArtifactJsonPath(worktreePath: string, workItemId: string, phase: CompletionPhase, ownerType?: string | null, ownerId?: string | null): string;
87
+ export declare function completionArtifactReportPath(worktreePath: string, workItemId: string, phase: CompletionPhase, ownerType?: string | null, ownerId?: string | null): string;
88
+ export declare function prepareCompletionToolRuntime(options: CompletionToolRuntimeOptions): Promise<CompletionToolRuntime>;
89
+ export declare function buildCompletionToolServerArgs(config: CompletionToolServerConfig): readonly string[];
90
+ export declare function codexMcpConfigArgs(runtime: CompletionToolRuntime): readonly string[];
91
+ export declare function cursorMcpServerConfig(runtime: CompletionToolRuntime): unknown;
92
+ export declare function completionPromptForPhase(phase: CompletionPhase): string;
93
+ export declare function completionPromptForDevelopCycle(phase: CompletionPhase): string;
94
+ export declare function completionPromptForQaCycle(currentGate?: QaCompletionGate): string;
95
+ export declare function completionPromptForDraftCycle(currentGate?: DraftCompletionGate): string;
96
+ export declare function completionPromptForDebugCycle(currentGate?: DebugCompletionPhase): string;
97
+ export declare function completionToolNamesForServer(config: CompletionToolServerConfig): readonly string[];
98
+ export declare class CompletionToolServerSession {
99
+ private readonly config;
100
+ private currentPhase;
101
+ private currentQaGate;
102
+ private currentDraftGate;
103
+ private completed;
104
+ constructor(config: CompletionToolServerConfig);
105
+ get instructions(): string;
106
+ toolDefinitions(): readonly unknown[];
107
+ callTool(toolName: string, input: unknown): Promise<CompletionToolCallResult>;
108
+ private callDraftGateTool;
109
+ private callDebugGateTool;
110
+ private callQaGateTool;
111
+ private advanceAfterPass;
112
+ private advanceAfterDraftGate;
113
+ private advanceAfterQaGate;
114
+ private advanceAfterDebugGate;
115
+ }
116
+ export declare function writeCompletionArtifact(config: CompletionToolServerConfig, toolName: string, input: unknown): Promise<CompletionArtifactReference>;
117
+ export declare function readCompletionArtifact(worktreePath: string, workItemId: string, phase: CompletionPhase, ownerType?: string | null, ownerId?: string | null): Promise<RunnerDispatchArtifact | null>;
118
+ export declare function runCompletionMcpServer(config: CompletionToolServerConfig): Promise<void>;
119
+ export declare function parseCompletionMcpArgs(argv: readonly string[]): {
120
+ readonly ok: true;
121
+ readonly config: CompletionToolServerConfig;
122
+ } | {
123
+ readonly ok: false;
124
+ readonly error: string;
125
+ };
126
+ export declare function completionRedactionEnv(secrets: readonly string[]): Readonly<Record<string, string>>;