@femtomc/mu-server 26.2.90 → 26.2.91

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.
@@ -7,6 +7,7 @@ const STATIC_ADAPTER_MODULES = [
7
7
  pipeline: opts.pipeline,
8
8
  outbox: opts.outbox,
9
9
  signingSecret: opts.secret,
10
+ botToken: opts.config.adapters.slack.bot_token,
10
11
  }),
11
12
  },
12
13
  {
@@ -68,6 +69,7 @@ export function createStaticAdaptersFromDetected(opts) {
68
69
  pipeline: opts.pipeline,
69
70
  outbox: opts.outbox,
70
71
  secret: detected.secret,
72
+ config: opts.config,
71
73
  }));
72
74
  }
73
75
  return adapters;
@@ -17,7 +17,6 @@ export function buildMessagingOperatorRuntime(opts) {
17
17
  return new MessagingOperatorRuntime({
18
18
  backend,
19
19
  broker: new ApprovedCommandBroker({
20
- runTriggersEnabled: opts.config.operator.run_triggers_enabled,
21
20
  contextResolver: new CommandContextResolver({ allowedRepoRoots: [opts.repoRoot] }),
22
21
  }),
23
22
  enabled: true,
@@ -1,5 +1,4 @@
1
1
  import type { Channel, CommandPipelineResult, ReloadableGenerationIdentity } from "@femtomc/mu-control-plane";
2
- import type { ControlPlaneRunInterruptResult, ControlPlaneRunSnapshot, ControlPlaneRunTrace } from "./run_supervisor.js";
3
2
  import type { MuConfig } from "./config.js";
4
3
  /**
5
4
  * Boundary contracts for server/control-plane composition.
@@ -9,11 +8,6 @@ import type { MuConfig } from "./config.js";
9
8
  * - Interface adapters in `control_plane.ts` implement these seams.
10
9
  */
11
10
  export type ControlPlaneConfig = MuConfig["control_plane"];
12
- /**
13
- * Durable orchestration queue contract (default-on path).
14
- */
15
- export type { InterRootQueuePolicy, OrchestrationQueueState } from "./orchestration_queue.js";
16
- export { DEFAULT_INTER_ROOT_QUEUE_POLICY, normalizeInterRootQueuePolicy, ORCHESTRATION_QUEUE_ALLOWED_TRANSITIONS, ORCHESTRATION_QUEUE_INVARIANTS, } from "./orchestration_queue.js";
17
11
  export type ActiveAdapter = {
18
12
  name: Channel;
19
13
  route: string;
@@ -129,35 +123,6 @@ export type ControlPlaneHandle = {
129
123
  config: ControlPlaneConfig;
130
124
  reason: string;
131
125
  }): Promise<TelegramGenerationReloadResult>;
132
- listRuns?(opts?: {
133
- status?: string;
134
- limit?: number;
135
- }): Promise<ControlPlaneRunSnapshot[]>;
136
- getRun?(idOrRoot: string): Promise<ControlPlaneRunSnapshot | null>;
137
- /**
138
- * Run lifecycle boundary: accepts start intent into the default queue/reconcile path.
139
- * Queue coordinators may dispatch immediately after enqueue, but must preserve queue invariants.
140
- */
141
- startRun?(opts: {
142
- prompt: string;
143
- maxSteps?: number;
144
- }): Promise<ControlPlaneRunSnapshot>;
145
- /**
146
- * Run lifecycle boundary: accepts resume intent into the default queue/reconcile path.
147
- * No flag-based alternate path is allowed.
148
- */
149
- resumeRun?(opts: {
150
- rootIssueId: string;
151
- maxSteps?: number;
152
- }): Promise<ControlPlaneRunSnapshot>;
153
- interruptRun?(opts: {
154
- jobId?: string | null;
155
- rootIssueId?: string | null;
156
- }): Promise<ControlPlaneRunInterruptResult>;
157
- traceRun?(opts: {
158
- idOrRoot: string;
159
- limit?: number;
160
- }): Promise<ControlPlaneRunTrace | null>;
161
126
  submitTerminalCommand?(opts: {
162
127
  commandText: string;
163
128
  repoRoot: string;
@@ -1 +1 @@
1
- export { DEFAULT_INTER_ROOT_QUEUE_POLICY, normalizeInterRootQueuePolicy, ORCHESTRATION_QUEUE_ALLOWED_TRANSITIONS, ORCHESTRATION_QUEUE_INVARIANTS, } from "./orchestration_queue.js";
1
+ export {};
@@ -111,6 +111,7 @@ export class TelegramAdapterGenerationManager {
111
111
  pipeline: this.#pipeline,
112
112
  outbox: this.#outbox,
113
113
  webhookSecret: config.webhookSecret,
114
+ botToken: config.botToken,
114
115
  botUsername: config.botUsername,
115
116
  deferredIngress: true,
116
117
  onOutboxEnqueued: this.#onOutboxEnqueued ?? undefined,
@@ -1,5 +1,5 @@
1
1
  import type { Channel, IdentityBinding, OutboundEnvelope } from "@femtomc/mu-control-plane";
2
- export type WakeFanoutSkipReasonCode = "channel_delivery_unsupported" | "telegram_bot_token_missing";
2
+ export type WakeFanoutSkipReasonCode = "channel_delivery_unsupported" | "slack_bot_token_missing" | "telegram_bot_token_missing";
3
3
  export type WakeFanoutContext = {
4
4
  wakeId: string;
5
5
  dedupeKey: string;
@@ -23,6 +23,7 @@ export declare function wakeFanoutDedupeKey(opts: {
23
23
  export declare function resolveWakeFanoutCapability(opts: {
24
24
  binding: IdentityBinding;
25
25
  isChannelDeliverySupported: (channel: Channel) => boolean;
26
+ slackBotToken: string | null;
26
27
  telegramBotToken: string | null;
27
28
  }): {
28
29
  ok: true;
@@ -31,6 +31,9 @@ export function resolveWakeFanoutCapability(opts) {
31
31
  if (!opts.isChannelDeliverySupported(binding.channel)) {
32
32
  return { ok: false, reasonCode: "channel_delivery_unsupported" };
33
33
  }
34
+ if (binding.channel === "slack" && (!opts.slackBotToken || opts.slackBotToken.trim().length === 0)) {
35
+ return { ok: false, reasonCode: "slack_bot_token_missing" };
36
+ }
34
37
  if (binding.channel === "telegram" && (!opts.telegramBotToken || opts.telegramBotToken.trim().length === 0)) {
35
38
  return { ok: false, reasonCode: "telegram_bot_token_missing" };
36
39
  }
@@ -72,7 +75,6 @@ export function buildWakeOutboundEnvelope(opts) {
72
75
  operator_turn_id: null,
73
76
  cli_invocation_id: null,
74
77
  cli_command_kind: null,
75
- run_root_id: null,
76
78
  },
77
79
  metadata: {
78
80
  wake_delivery: true,
package/dist/index.d.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  export type { MuConfig, MuConfigPatch, MuConfigPresence } from "./config.js";
2
2
  export { applyMuConfigPatch, DEFAULT_MU_CONFIG, getMuConfigPath, muConfigPresence, normalizeMuConfig, readMuConfigFile, redactMuConfigSecrets, writeMuConfigFile, } from "./config.js";
3
- export type { ActiveAdapter, ControlPlaneConfig, ControlPlaneHandle, ControlPlaneSessionLifecycle, ControlPlaneSessionMutationAction, ControlPlaneSessionMutationResult, InterRootQueuePolicy, NotifyOperatorsOpts, NotifyOperatorsResult, OrchestrationQueueState, WakeDeliveryEvent, WakeNotifyContext, WakeNotifyDecision, } from "./control_plane_contract.js";
4
- export { DEFAULT_INTER_ROOT_QUEUE_POLICY, normalizeInterRootQueuePolicy, ORCHESTRATION_QUEUE_ALLOWED_TRANSITIONS, ORCHESTRATION_QUEUE_INVARIANTS, } from "./control_plane_contract.js";
5
- export type { DurableRunQueueClaimOpts, DurableRunQueueEnqueueOpts, DurableRunQueueOpts, DurableRunQueueSnapshot, DurableRunQueueState, DurableRunQueueTransitionOpts, RunQueueReconcilePlan, } from "./run_queue.js";
6
- export { DurableRunQueue, queueStatesForRunStatusFilter, reconcileRunQueue, RUN_QUEUE_RECONCILE_INVARIANTS, runQueuePath, runSnapshotFromQueueSnapshot, runStatusFromQueueState, } from "./run_queue.js";
3
+ export type { ActiveAdapter, ControlPlaneConfig, ControlPlaneHandle, ControlPlaneSessionLifecycle, ControlPlaneSessionMutationAction, ControlPlaneSessionMutationResult, NotifyOperatorsOpts, NotifyOperatorsResult, WakeDeliveryEvent, WakeNotifyContext, WakeNotifyDecision, } from "./control_plane_contract.js";
7
4
  export { bootstrapControlPlane, detectAdapters } from "./control_plane.js";
8
5
  export type { CronProgramDispatchResult, CronProgramLifecycleAction, CronProgramLifecycleEvent, CronProgramOperationResult, CronProgramRegistryOpts, CronProgramSnapshot, CronProgramStatusSnapshot, CronProgramTickEvent, } from "./cron_programs.js";
9
6
  export { CronProgramRegistry } from "./cron_programs.js";
package/dist/index.js CHANGED
@@ -1,6 +1,4 @@
1
1
  export { applyMuConfigPatch, DEFAULT_MU_CONFIG, getMuConfigPath, muConfigPresence, normalizeMuConfig, readMuConfigFile, redactMuConfigSecrets, writeMuConfigFile, } from "./config.js";
2
- export { DEFAULT_INTER_ROOT_QUEUE_POLICY, normalizeInterRootQueuePolicy, ORCHESTRATION_QUEUE_ALLOWED_TRANSITIONS, ORCHESTRATION_QUEUE_INVARIANTS, } from "./control_plane_contract.js";
3
- export { DurableRunQueue, queueStatesForRunStatusFilter, reconcileRunQueue, RUN_QUEUE_RECONCILE_INVARIANTS, runQueuePath, runSnapshotFromQueueSnapshot, runStatusFromQueueState, } from "./run_queue.js";
4
2
  export { bootstrapControlPlane, detectAdapters } from "./control_plane.js";
5
3
  export { CronProgramRegistry } from "./cron_programs.js";
6
4
  export { computeNextScheduleRunAtMs, normalizeCronSchedule } from "./cron_schedule.js";
package/dist/server.js CHANGED
@@ -6,7 +6,7 @@ import { createReloadManager, } from "./control_plane_reload.js";
6
6
  import { ActivityHeartbeatScheduler } from "./heartbeat_scheduler.js";
7
7
  import { createProcessSessionLifecycle } from "./session_lifecycle.js";
8
8
  import { MemoryIndexMaintainer } from "./memory_index_maintainer.js";
9
- import { createServerProgramOrchestration } from "./server_program_orchestration.js";
9
+ import { createServerProgramCoordination } from "./server_program_coordination.js";
10
10
  import { createServerRequestHandler } from "./server_routing.js";
11
11
  import { toNonNegativeInt } from "./server_types.js";
12
12
  const DEFAULT_OPERATOR_WAKE_COALESCE_MS = 2_000;
@@ -404,45 +404,6 @@ function createServer(options = {}) {
404
404
  const handle = reloadManager.getControlPlaneCurrent();
405
405
  handle?.setWakeDeliveryObserver?.(observer ?? null);
406
406
  },
407
- async listRuns(opts) {
408
- const handle = reloadManager.getControlPlaneCurrent();
409
- if (!handle?.listRuns)
410
- return [];
411
- return await handle.listRuns(opts);
412
- },
413
- async getRun(idOrRoot) {
414
- const handle = reloadManager.getControlPlaneCurrent();
415
- if (!handle?.getRun)
416
- return null;
417
- return await handle.getRun(idOrRoot);
418
- },
419
- async startRun(opts) {
420
- const handle = reloadManager.getControlPlaneCurrent();
421
- if (!handle?.startRun) {
422
- throw new Error("run_supervisor_unavailable");
423
- }
424
- return await handle.startRun(opts);
425
- },
426
- async resumeRun(opts) {
427
- const handle = reloadManager.getControlPlaneCurrent();
428
- if (!handle?.resumeRun) {
429
- throw new Error("run_supervisor_unavailable");
430
- }
431
- return await handle.resumeRun(opts);
432
- },
433
- async interruptRun(opts) {
434
- const handle = reloadManager.getControlPlaneCurrent();
435
- if (!handle?.interruptRun) {
436
- return { ok: false, reason: "not_found", run: null };
437
- }
438
- return await handle.interruptRun(opts);
439
- },
440
- async traceRun(opts) {
441
- const handle = reloadManager.getControlPlaneCurrent();
442
- if (!handle?.traceRun)
443
- return null;
444
- return await handle.traceRun(opts);
445
- },
446
407
  async submitTerminalCommand(opts) {
447
408
  const handle = reloadManager.getControlPlaneCurrent();
448
409
  if (!handle?.submitTerminalCommand) {
@@ -458,7 +419,7 @@ function createServer(options = {}) {
458
419
  await handle?.stop();
459
420
  },
460
421
  };
461
- const { heartbeatPrograms, cronPrograms } = createServerProgramOrchestration({
422
+ const { heartbeatPrograms, cronPrograms } = createServerProgramCoordination({
462
423
  repoRoot,
463
424
  heartbeatScheduler,
464
425
  eventLog: context.eventLog,
@@ -11,7 +11,7 @@ type OperatorWakeEmitter = (opts: {
11
11
  status: "dispatched" | "coalesced" | "failed";
12
12
  reason: string;
13
13
  }>;
14
- export declare function createServerProgramOrchestration(opts: {
14
+ export declare function createServerProgramCoordination(opts: {
15
15
  repoRoot: string;
16
16
  heartbeatScheduler: ActivityHeartbeatScheduler;
17
17
  eventLog: EventLog;
@@ -6,7 +6,7 @@ function describeError(err) {
6
6
  }
7
7
  return String(err);
8
8
  }
9
- export function createServerProgramOrchestration(opts) {
9
+ export function createServerProgramCoordination(opts) {
10
10
  const heartbeatPrograms = new HeartbeatProgramRegistry({
11
11
  repoRoot: opts.repoRoot,
12
12
  heartbeatScheduler: opts.heartbeatScheduler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-server",
3
- "version": "26.2.90",
3
+ "version": "26.2.91",
4
4
  "description": "HTTP API server for mu control-plane transport/session plus run/activity scheduling coordination.",
5
5
  "keywords": [
6
6
  "mu",
@@ -30,8 +30,8 @@
30
30
  "start": "bun run dist/cli.js"
31
31
  },
32
32
  "dependencies": {
33
- "@femtomc/mu-agent": "26.2.90",
34
- "@femtomc/mu-control-plane": "26.2.90",
35
- "@femtomc/mu-core": "26.2.90"
33
+ "@femtomc/mu-agent": "26.2.91",
34
+ "@femtomc/mu-control-plane": "26.2.91",
35
+ "@femtomc/mu-core": "26.2.91"
36
36
  }
37
37
  }
@@ -1,2 +0,0 @@
1
- import type { ServerRoutingDependencies } from "../server_routing.js";
2
- export declare function runRoutes(request: Request, url: URL, deps: ServerRoutingDependencies, headers: Headers): Promise<Response>;
package/dist/api/runs.js DELETED
@@ -1,124 +0,0 @@
1
- export async function runRoutes(request, url, deps, headers) {
2
- const path = url.pathname;
3
- if (path === "/api/control-plane/runs") {
4
- if (request.method !== "GET") {
5
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
6
- }
7
- const status = url.searchParams.get("status")?.trim() || undefined;
8
- const limitRaw = url.searchParams.get("limit");
9
- const limit = limitRaw && /^\d+$/.test(limitRaw) ? Math.max(1, Math.min(500, Number.parseInt(limitRaw, 10))) : undefined;
10
- const runs = await deps.controlPlaneProxy.listRuns?.({ status, limit });
11
- return Response.json({ count: runs?.length ?? 0, runs: runs ?? [] }, { headers });
12
- }
13
- if (path === "/api/control-plane/runs/start") {
14
- if (request.method !== "POST") {
15
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
16
- }
17
- let body;
18
- try {
19
- body = (await request.json());
20
- }
21
- catch {
22
- return Response.json({ error: "invalid json body" }, { status: 400, headers });
23
- }
24
- const prompt = typeof body.prompt === "string" ? body.prompt.trim() : "";
25
- if (prompt.length === 0) {
26
- return Response.json({ error: "prompt is required" }, { status: 400, headers });
27
- }
28
- const maxSteps = typeof body.max_steps === "number" && Number.isFinite(body.max_steps)
29
- ? Math.max(1, Math.trunc(body.max_steps))
30
- : undefined;
31
- try {
32
- const run = await deps.controlPlaneProxy.startRun?.({ prompt, maxSteps });
33
- if (!run) {
34
- return Response.json({ error: "run supervisor unavailable" }, { status: 503, headers });
35
- }
36
- return Response.json({ ok: true, run }, { status: 201, headers });
37
- }
38
- catch (err) {
39
- return Response.json({ error: deps.describeError(err) }, { status: 500, headers });
40
- }
41
- }
42
- if (path === "/api/control-plane/runs/resume") {
43
- if (request.method !== "POST") {
44
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
45
- }
46
- let body;
47
- try {
48
- body = (await request.json());
49
- }
50
- catch {
51
- return Response.json({ error: "invalid json body" }, { status: 400, headers });
52
- }
53
- const rootIssueId = typeof body.root_issue_id === "string" ? body.root_issue_id.trim() : "";
54
- if (rootIssueId.length === 0) {
55
- return Response.json({ error: "root_issue_id is required" }, { status: 400, headers });
56
- }
57
- const maxSteps = typeof body.max_steps === "number" && Number.isFinite(body.max_steps)
58
- ? Math.max(1, Math.trunc(body.max_steps))
59
- : undefined;
60
- try {
61
- const run = await deps.controlPlaneProxy.resumeRun?.({ rootIssueId, maxSteps });
62
- if (!run) {
63
- return Response.json({ error: "run supervisor unavailable" }, { status: 503, headers });
64
- }
65
- return Response.json({ ok: true, run }, { status: 201, headers });
66
- }
67
- catch (err) {
68
- return Response.json({ error: deps.describeError(err) }, { status: 500, headers });
69
- }
70
- }
71
- if (path === "/api/control-plane/runs/interrupt") {
72
- if (request.method !== "POST") {
73
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
74
- }
75
- let body;
76
- try {
77
- body = (await request.json());
78
- }
79
- catch {
80
- return Response.json({ error: "invalid json body" }, { status: 400, headers });
81
- }
82
- const rootIssueId = typeof body.root_issue_id === "string" ? body.root_issue_id.trim() : null;
83
- const jobId = typeof body.job_id === "string" ? body.job_id.trim() : null;
84
- const result = await deps.controlPlaneProxy.interruptRun?.({
85
- rootIssueId,
86
- jobId,
87
- });
88
- if (!result) {
89
- return Response.json({ error: "run supervisor unavailable" }, { status: 503, headers });
90
- }
91
- return Response.json(result, { status: result.ok ? 200 : 404, headers });
92
- }
93
- if (path.startsWith("/api/control-plane/runs/")) {
94
- const rest = path.slice("/api/control-plane/runs/".length);
95
- const [rawId, maybeSub] = rest.split("/");
96
- const idOrRoot = decodeURIComponent(rawId ?? "").trim();
97
- if (idOrRoot.length === 0) {
98
- return Response.json({ error: "missing run id" }, { status: 400, headers });
99
- }
100
- if (maybeSub === "trace") {
101
- if (request.method !== "GET") {
102
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
103
- }
104
- const limitRaw = url.searchParams.get("limit");
105
- const limit = limitRaw && /^\d+$/.test(limitRaw)
106
- ? Math.max(1, Math.min(2_000, Number.parseInt(limitRaw, 10)))
107
- : undefined;
108
- const trace = await deps.controlPlaneProxy.traceRun?.({ idOrRoot, limit });
109
- if (!trace) {
110
- return Response.json({ error: "run trace not found" }, { status: 404, headers });
111
- }
112
- return Response.json(trace, { headers });
113
- }
114
- if (request.method !== "GET") {
115
- return Response.json({ error: "Method Not Allowed" }, { status: 405, headers });
116
- }
117
- const run = await deps.controlPlaneProxy.getRun?.(idOrRoot);
118
- if (!run) {
119
- return Response.json({ error: "run not found" }, { status: 404, headers });
120
- }
121
- return Response.json(run, { headers });
122
- }
123
- return Response.json({ error: "Not Found" }, { status: 404, headers });
124
- }
@@ -1,7 +0,0 @@
1
- import { type ControlPlaneOutbox, type OutboxRecord } from "@femtomc/mu-control-plane";
2
- import type { ControlPlaneRunEvent } from "./run_supervisor.js";
3
- export declare function enqueueRunEventOutbox(opts: {
4
- outbox: ControlPlaneOutbox;
5
- event: ControlPlaneRunEvent;
6
- nowMs: number;
7
- }): Promise<OutboxRecord | null>;
@@ -1,52 +0,0 @@
1
- import { correlationFromCommandRecord, } from "@femtomc/mu-control-plane";
2
- function sha256Hex(input) {
3
- const hasher = new Bun.CryptoHasher("sha256");
4
- hasher.update(input);
5
- return hasher.digest("hex");
6
- }
7
- function outboxKindForRunEvent(kind) {
8
- switch (kind) {
9
- case "run_completed":
10
- return "result";
11
- case "run_failed":
12
- return "error";
13
- default:
14
- return "lifecycle";
15
- }
16
- }
17
- export async function enqueueRunEventOutbox(opts) {
18
- const command = opts.event.command;
19
- if (!command) {
20
- return null;
21
- }
22
- const baseCorrelation = correlationFromCommandRecord(command);
23
- const correlation = {
24
- ...baseCorrelation,
25
- run_root_id: opts.event.run.root_issue_id ?? baseCorrelation.run_root_id,
26
- };
27
- const envelope = {
28
- v: 1,
29
- ts_ms: opts.nowMs,
30
- channel: command.channel,
31
- channel_tenant_id: command.channel_tenant_id,
32
- channel_conversation_id: command.channel_conversation_id,
33
- request_id: command.request_id,
34
- response_id: `resp-${sha256Hex(`run-event:${opts.event.run.job_id}:${opts.event.seq}:${opts.nowMs}`).slice(0, 20)}`,
35
- kind: outboxKindForRunEvent(opts.event.kind),
36
- body: opts.event.message,
37
- correlation,
38
- metadata: {
39
- async_run: true,
40
- run_event_kind: opts.event.kind,
41
- run_event_seq: opts.event.seq,
42
- run: opts.event.run,
43
- },
44
- };
45
- const decision = await opts.outbox.enqueue({
46
- dedupeKey: `run-event:${opts.event.run.job_id}:${opts.event.seq}`,
47
- envelope,
48
- nowMs: opts.nowMs,
49
- maxAttempts: 6,
50
- });
51
- return decision.record;
52
- }
@@ -1,42 +0,0 @@
1
- import type { CommandRecord } from "@femtomc/mu-control-plane";
2
- import type { InterRootQueuePolicy } from "./control_plane_contract.js";
3
- import { DurableRunQueue } from "./run_queue.js";
4
- import type { ControlPlaneRunEvent, ControlPlaneRunInterruptResult, ControlPlaneRunSnapshot, ControlPlaneRunSupervisor } from "./run_supervisor.js";
5
- export type QueueLaunchOpts = {
6
- mode: "run_start" | "run_resume";
7
- prompt?: string;
8
- rootIssueId?: string | null;
9
- maxSteps?: number;
10
- source: "command" | "api";
11
- command?: CommandRecord | null;
12
- dedupeKey: string;
13
- };
14
- export type ControlPlaneRunQueueCoordinatorOpts = {
15
- runQueue: DurableRunQueue;
16
- interRootQueuePolicy: InterRootQueuePolicy;
17
- getRunSupervisor: () => ControlPlaneRunSupervisor | null;
18
- defaultRunMaxSteps?: number;
19
- };
20
- /**
21
- * Queue/reconcile adapter for control-plane run lifecycle operations.
22
- *
23
- * Keeps inter-root queue execution concerns out of `control_plane.ts` while preserving
24
- * queue-first semantics:
25
- * - enqueue intents durably
26
- * - reconcile/claim/launch deterministically
27
- * - mirror runtime events back into durable queue state
28
- */
29
- export declare class ControlPlaneRunQueueCoordinator {
30
- #private;
31
- constructor(opts: ControlPlaneRunQueueCoordinatorOpts);
32
- runtimeSnapshotsByJobId(): Map<string, ControlPlaneRunSnapshot>;
33
- scheduleReconcile(reason: string): Promise<void>;
34
- launchQueuedRun(launchOpts: QueueLaunchOpts): Promise<ControlPlaneRunSnapshot>;
35
- launchQueuedRunFromCommand(record: CommandRecord): Promise<ControlPlaneRunSnapshot>;
36
- interruptQueuedRun(opts: {
37
- jobId?: string | null;
38
- rootIssueId?: string | null;
39
- }): Promise<ControlPlaneRunInterruptResult>;
40
- onRunEvent(event: ControlPlaneRunEvent): Promise<void>;
41
- stop(): void;
42
- }