Desktop IPC saves used to fire only automation and the reviewer wake, while HTTP API saves fired automation, thread integration, checkpoint engine, deliverable-review approval, and the reviewer wake. Two divergent paths produced two different lifecycle states for the same document, and a future fix to either branch would miss the other. Introduce `document-lifecycle.ts` as the single owner of document creation side effects: save, derive task binding from the originating run, fan out to automation/thread/checkpoint, wake the reviewer, then raise a deliverable-review approval when the document qualifies. The HTTP route and the IPC handler both call the pipeline — the API server's `onDocumentCreated` callback is replaced with a `createDocument` hook that delegates to the pipeline. Wire `checkpointEngine` through `bootstrap-application` → `main-runtime` → `main-runtime-support` so the IPC handler bag carries both thread integration and the checkpoint engine required by the pipeline. The document-run-provenance integration test harness is updated to pass a `createDocument` implementation backed by the same pipeline the production path uses.
66 lines
3.1 KiB
TypeScript
66 lines
3.1 KiB
TypeScript
import type { IpcMainInvokeEvent } from "electron";
|
|
import { z } from "zod";
|
|
import type { DesktopResult } from "@shared/contracts";
|
|
import type { bootstrapOnboardingSchema } from "@shared/contracts";
|
|
import type { DesktopEvent, SectionId } from "@shared/types";
|
|
import type { AppDatabase } from "./database";
|
|
import type { createSkillService } from "./skill-service";
|
|
import type { createBudgetEnforcementService } from "./budget-enforcement-service";
|
|
import type { CheckpointEngineLike } from "./document-lifecycle";
|
|
import type { ThreadIntegrationService } from "./thread-integration";
|
|
|
|
interface BrowserActionControl {
|
|
clearSocialAccountData: (socialAccountId: string, screenshotPaths?: string[]) => Promise<void>;
|
|
cancelAction: (actionId: string) => boolean;
|
|
launchLoginBrowser: (socialAccountId: string, platform: string, loginUrl?: string) => Promise<{
|
|
success: boolean;
|
|
cancelled: boolean;
|
|
summary: string;
|
|
screenshotPath: string | null;
|
|
error: string | null;
|
|
}>;
|
|
extractProfileFromSession: (socialAccountId: string, platform: string) => Promise<{
|
|
accountName: string;
|
|
displayName: string;
|
|
}>;
|
|
}
|
|
|
|
export interface RegisterDomainHandlersDependencies {
|
|
registerHandle: (
|
|
channel: string,
|
|
handler: (event: IpcMainInvokeEvent, ...args: unknown[]) => Promise<DesktopResult<unknown>> | DesktopResult<unknown>,
|
|
) => void;
|
|
db: AppDatabase;
|
|
logger: {
|
|
warn: (...args: unknown[]) => void;
|
|
error: (...args: unknown[]) => void;
|
|
};
|
|
ensureCompanyExists: (companyId: string) => DesktopResult<never> | null;
|
|
findInvalidReference: (
|
|
companyId: string,
|
|
refs: Array<{ id: string | null | undefined; table: string; label: string }>,
|
|
) => { id: string | null | undefined; table: string; label: string } | null;
|
|
publishDomainChanged: () => void;
|
|
emitEvent: (event: DesktopEvent) => void;
|
|
notify: (options: { title: string; body: string; urgency: "critical" | "informational"; navigation?: { section: SectionId; entityId?: string }; batchKey?: string }) => void;
|
|
wakeAgentIfPossible: (agentId: string | null | undefined, companyId: string, trigger: string) => string | null;
|
|
dispatchAutomation: (trigger: string, ctx: { companyId: string; [key: string]: unknown }) => void;
|
|
runWorkflowPipeline: (workflowId: string, companyId: string) => Promise<void>;
|
|
bootstrapOnboarding: (input: z.infer<typeof bootstrapOnboardingSchema>) => unknown;
|
|
getBrowserActions: () => BrowserActionControl | null;
|
|
randomFallbackCompanyId: () => string;
|
|
skillService: ReturnType<typeof createSkillService> | null;
|
|
budgetService: ReturnType<typeof createBudgetEnforcementService> | null;
|
|
/** Called when a human sends a message to resolve thread wait states. */
|
|
onHumanMessage?: (companyId: string, toAgentId?: string | null, threadId?: string | null, waitStateId?: string | null) => void;
|
|
/**
|
|
* Shared document-creation lifecycle collaborators. Routed through the
|
|
* dependency bag so both the IPC save path and the HTTP save path call
|
|
* the same `createDocumentWithLifecycle` fan-out.
|
|
*/
|
|
threadIntegration: ThreadIntegrationService;
|
|
checkpointEngine: CheckpointEngineLike;
|
|
}
|
|
|
|
export { ok, fail } from "./ipc-core-common";
|