Files
fusion/packages/engine/src/project-runtime.ts
gsxdsm a9d2064f66 FN-5703: forward task:deleted events through in-process runtime
Ensure engine-side task deletes propagate through all runtime transports so GitHub tracking cleanup runs consistently.

- extend IPC protocol and child-process runtime/worker plumbing to carry `task:deleted` events
- forward `task:deleted` from in-process runtime through project runtime and project manager dispatch
- add regression coverage for in-process runtime forwarding and GitHub tracking delete handling

Files changed:
 .../src/__tests__/github-tracking-delete.test.ts   | 29 ++++++++++++++++++
 .../src/__tests__/in-process-runtime.test.ts       | 34 +++++++++++++++++++++-
 packages/engine/src/ipc/ipc-protocol.ts            | 14 ++++++++-
 packages/engine/src/project-manager.ts             |  7 +++++
 packages/engine/src/project-runtime.ts             |  4 ++-
 .../engine/src/runtimes/child-process-runtime.ts   |  6 ++++
 .../engine/src/runtimes/child-process-worker.ts    | 14 +++++++--
 packages/engine/src/runtimes/in-process-runtime.ts | 10 ++++++-
 8 files changed, 111 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-5703

Fusion-Task-Lineage: 1406838b-5abf-4b86-8161-c2dd59f88a9b
2026-05-29 20:05:14 -07:00

158 lines
5.3 KiB
TypeScript

import type { EventEmitter } from "node:events";
import type { TaskStore, Task, IsolationMode, ProjectSettings, GithubIssueAction } from "@fusion/core";
import type { Scheduler } from "./scheduler.js";
/**
* Runtime status for a ProjectRuntime instance.
* Represents the lifecycle states of a project runtime.
*/
export type RuntimeStatus =
| "active" // Runtime is running and processing tasks
| "paused" // Runtime is temporarily suspended
| "errored" // Runtime encountered a fatal error
| "stopped" // Runtime is stopped (graceful shutdown complete)
| "starting" // Runtime is in the process of starting
| "stopping"; // Runtime is in the process of stopping
/**
* Metrics for a ProjectRuntime instance.
* Used for monitoring and health tracking.
*/
export interface RuntimeMetrics {
/** Number of tasks currently in-progress */
inFlightTasks: number;
/** Number of active agents currently running */
activeAgents: number;
/** ISO-8601 timestamp of the last activity */
lastActivityAt: string;
/** Memory usage in bytes (optional, may not be available in all modes) */
memoryBytes?: number;
}
/**
* Configuration for creating a ProjectRuntime instance.
*/
export interface ProjectRuntimeConfig {
/** Unique project ID (e.g., "proj_abc123") */
projectId: string;
/** Absolute path to the project working directory */
workingDirectory: string;
/** Execution isolation mode */
isolationMode: IsolationMode;
/** Maximum concurrent agents for this project */
maxConcurrent: number;
/** Maximum worktrees for this project */
maxWorktrees: number;
/** Optional project settings override */
settings?: ProjectSettings;
/** Shared global semaphore from ProjectManager. When provided, the runtime
* uses this semaphore for concurrency control instead of creating its own.
* This ensures cross-project concurrency limits are enforced. */
globalSemaphore?: import("./concurrency.js").AgentSemaphore;
/**
* An already-initialized TaskStore to use instead of creating a new one.
* When provided, the runtime will skip TaskStore construction and init().
* Useful when the caller (e.g. dashboard.ts) owns and watches the store.
*/
externalTaskStore?: TaskStore;
}
/**
* Events emitted by a ProjectRuntime instance.
*/
export interface ProjectRuntimeEvents {
/** Emitted when a task is created in the project */
"task:created": [task: Task];
/** Emitted when a task is moved between columns */
"task:moved": [data: { task: Task; from: string; to: string }];
/** Emitted when a task is updated */
"task:updated": [task: Task];
/** Emitted when a task is deleted */
"task:deleted": [task: Task, meta?: { githubIssueAction?: GithubIssueAction }];
/** Emitted when a cross-node assignment event is observed */
"task:assigned": [data: { taskId: string; agentId: string; assignedAt: string; source?: string }];
/** Emitted when an error occurs in the runtime */
"error": [error: Error];
/** Emitted when the runtime health status changes */
"health-changed": [data: { status: RuntimeStatus; previous: RuntimeStatus }];
}
/**
* ProjectRuntime interface — core abstraction for multi-project support.
*
* Each project instance runs as a ProjectRuntime, either in-process (default)
* or in an isolated child process (opt-in). The ProjectManager orchestrates
* all runtimes and enforces global concurrency limits from CentralCore.
*
* @example
* ```typescript
* const runtime = new InProcessRuntime(config, centralCore);
* await runtime.start();
*
* // Access project TaskStore
* const taskStore = runtime.getTaskStore();
*
* // Listen for events
* runtime.on("task:created", (task) => {
* console.log(`Task ${task.id} created`);
* });
*
* // Shutdown gracefully
* await runtime.stop();
* ```
*/
export interface ProjectRuntime extends EventEmitter<ProjectRuntimeEvents> {
/**
* Start the runtime and initialize all subsystems.
* This includes initializing the TaskStore, Scheduler, Executor, and WorktreePool.
*/
start(): Promise<void>;
/**
* Stop the runtime with graceful shutdown.
* Waits for active tasks to complete (with timeout), stops the scheduler,
* and cleans up resources.
*/
stop(): Promise<void>;
/**
* Get the current runtime status.
* @returns The current status of the runtime
*/
getStatus(): RuntimeStatus;
/**
* Get the project's TaskStore instance.
* @returns The TaskStore for this project
* @throws Error if called on a ChildProcessRuntime (not accessible in child mode)
*/
getTaskStore(): TaskStore;
/**
* Get the project's Scheduler instance.
* @returns The Scheduler for this project
* @throws Error if called on a ChildProcessRuntime (not accessible in child mode)
*/
getScheduler(): Scheduler;
/**
* Get current runtime metrics.
* @returns Metrics including in-flight tasks, active agents, and memory usage
*/
getMetrics(): RuntimeMetrics;
}
/**
* Global metrics aggregated across all project runtimes.
*/
export interface GlobalMetrics {
/** Total number of in-flight tasks across all runtimes */
totalInFlightTasks: number;
/** Total number of active agents across all runtimes */
totalActiveAgents: number;
/** Number of runtimes by status */
runtimeCountByStatus: Record<RuntimeStatus, number>;
/** Total number of registered runtimes */
totalRuntimes: number;
}