@volter/supercode-orchestrator 0.4.4

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/index.d.ts ADDED
@@ -0,0 +1,508 @@
1
+ // Types for the orchestrator IR — docs/ORCHESTRATOR-IR.md §2 is normative.
2
+ //
3
+ // ONT-6: every record shape is the Rust ontology's
4
+ // (`crates/interchange/src/orchestration/`, `crates/interchange/src/ontology/`), reached
5
+ // through `./ontology.d.ts` — written by
6
+ // `node sdk/orchestrator/scripts/generate-types.mjs` from `supercode ontology schema`.
7
+ // Declare no record here; add the field in Rust and regenerate.
8
+
9
+ import type {
10
+ Access,
11
+ AccessPolicy,
12
+ ArtifactFidelity,
13
+ Attachment,
14
+ Binding,
15
+ ChannelConfig,
16
+ EndReason,
17
+ EnvValue,
18
+ Fidelity,
19
+ Fire,
20
+ FireStatus,
21
+ Handoff,
22
+ HarnessId,
23
+ Job,
24
+ JobOrigin,
25
+ Obligation,
26
+ ObligationSource,
27
+ ObligationState,
28
+ OutboundContent,
29
+ PermissionDefault,
30
+ PermissionPolicy,
31
+ PermissionUnattended,
32
+ PersonaRef,
33
+ Posted,
34
+ Profile,
35
+ ProfileResidue,
36
+ Recurrence,
37
+ Repeat,
38
+ Residue,
39
+ Route,
40
+ RouteMatch,
41
+ Schedule,
42
+ SecretRef,
43
+ SurfaceKey,
44
+ Target,
45
+ Trigger,
46
+ WebhookSubscription,
47
+ Worker,
48
+ WorkerSpec,
49
+ Orchestration,
50
+ } from './ontology.js';
51
+
52
+ export type {
53
+ Access,
54
+ AccessPolicy,
55
+ ArtifactFidelity,
56
+ Attachment,
57
+ Binding,
58
+ ChannelConfig,
59
+ EndReason,
60
+ EnvValue,
61
+ Fidelity,
62
+ Fire,
63
+ FireStatus,
64
+ Handoff,
65
+ HarnessId,
66
+ Job,
67
+ JobOrigin,
68
+ Obligation,
69
+ ObligationSource,
70
+ ObligationState,
71
+ OutboundContent,
72
+ PermissionDefault,
73
+ PermissionPolicy,
74
+ PermissionUnattended,
75
+ PersonaRef,
76
+ Posted,
77
+ Profile,
78
+ ProfileResidue,
79
+ Recurrence,
80
+ Repeat,
81
+ Residue,
82
+ Route,
83
+ RouteMatch,
84
+ Schedule,
85
+ SecretRef,
86
+ SurfaceKey,
87
+ Target,
88
+ Trigger,
89
+ WebhookSubscription,
90
+ Worker,
91
+ WorkerSpec,
92
+ Orchestration,
93
+ };
94
+
95
+ export type Path = string;
96
+ export type RelPath = string;
97
+ export type Instant = string; // RFC 3339
98
+ export type ProfileName = string;
99
+ export type Platform = string;
100
+ export type UserId = string;
101
+ export type JobId = string;
102
+ export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };
103
+
104
+ export type ChatType = 'dm' | 'group' | 'channel' | 'thread';
105
+
106
+ export interface RuntimeState {
107
+ leases: Record<string, { runtime_id: string; connection: string | null; since: Instant }>;
108
+ queues: Record<string, { text: string; at: Instant; context_from?: string[] | null; skills?: string[]; job_id?: string }[]>;
109
+ turns: Record<string, { started_at: Instant; buffer: string }>;
110
+ starting: Record<string, unknown>;
111
+ /** The last worker event per lease (§4.3's inactivity limit). */
112
+ activity: Record<string, Instant>;
113
+ adapters: Record<Platform, { state: 'up' | 'down' | 'paused'; breaker: { failures: number; until?: Instant } }>;
114
+ pending_requests: Record<string, { profile: ProfileName; keyString: string; runtime_id: string | null; asked_at: Instant; options: RequestOption[] }>;
115
+ clock: Instant | null;
116
+ hostedJobs?: boolean;
117
+ hostedFires?: Record<string, boolean>;
118
+ }
119
+
120
+ export interface RequestOption { optionId?: string; name: string; kind?: string; response?: JsonValue }
121
+
122
+ // ---------------------------------------------------------------- events (§3)
123
+
124
+ export type WorkerEvent =
125
+ | { kind: 'started'; runtime_id: string; session_id?: string; connection?: string | null; harness?: HarnessId; reattach_of?: string }
126
+ | { kind: 'text'; delta: string }
127
+ /** Any other runtime event (a tool call, reasoning, a turn start): the worker is alive. */
128
+ | { kind: 'activity' }
129
+ | { kind: 'final'; text: string | null; outcome?: 'completed' | 'error'; message?: string | null }
130
+ | { kind: 'request'; id: string; subject: string; options: RequestOption[] }
131
+ | { kind: 'ended'; reason: string }
132
+ | { kind: 'error'; message: string };
133
+
134
+ export type OrchestratorEvent =
135
+ | {
136
+ type: 'inbound'; profile: ProfileName; key: SurfaceKey; sender: UserId; sender_name: string | null;
137
+ text: string; attachments: Attachment[]; at: Instant; adapter: Platform; guild_id: string | null;
138
+ /** The platform's id for this message: the threading, reaction and edit target (ORC-1 F4). */
139
+ message_id: string | null;
140
+ /** Our own echo (§4.1 step 0 drops it), a bot sender (`null` = the SDK's "unknown"), and whether we were @-mentioned. */
141
+ is_me: boolean; is_bot: boolean | null; mention: boolean;
142
+ }
143
+ | { type: 'tick'; at: Instant; inactivity_s?: number | null; max_parallel?: number | null }
144
+ | { type: 'hosted_result'; profile: ProfileName; fire_id: string; at: Instant; receipt?: HostedReceipt; error?: string }
145
+ | { type: 'worker'; profile: ProfileName; keyString: string; runtime_id: string | null; ev: WorkerEvent; at: Instant }
146
+ | { type: 'adapter'; platform: Platform; state: 'up' | 'down'; error: string | null; at: Instant }
147
+ | { type: 'operator'; verb: string; profile: ProfileName; args: Record<string, unknown>; at: Instant }
148
+ | { type: 'webhook'; name: string; payload: JsonValue; verified: boolean; at: Instant; event: string | null; delivery_id: string | null }
149
+ | { type: 'restart'; at: Instant }
150
+ | { type: 'stopping'; at: Instant };
151
+
152
+ // ---------------------------------------------------------------- effects (§5)
153
+
154
+ export type Effect =
155
+ | { type: 'execute_job'; profile: ProfileName; job_id: string; fire_id: string }
156
+ | { type: 'runtime_start'; profile: ProfileName; keyString: string; worker: WorkerSpec; prompt: string | null }
157
+ | { type: 'runtime_close'; profile: ProfileName; keyString: string; lease: RuntimeState['leases'][string] }
158
+ | { type: 'send_input'; profile: ProfileName; keyString: string; text: string; context_from?: string[] | null; skills?: string[]; job_id?: string }
159
+ | { type: 'respond'; profile: ProfileName; keyString: string; request_id: string; response: JsonValue }
160
+ | { type: 'deliver'; profile: ProfileName; obligation_id: string }
161
+ | { type: 'write_local'; profile: ProfileName; path: RelPath; text: string }
162
+ | { type: 'save' }
163
+ | { type: 'log'; level: 'info' | 'warn' | 'error'; message: string };
164
+
165
+ /** The reducer: mutates `state`, returns effects, performs no I/O. */
166
+ export function step(state: OrchestratorState, event: OrchestratorEvent): Effect[];
167
+ /** Hermes's session reset, as `sessionReset` reads it from the home's `session_reset:`. */
168
+ export interface SessionReset { mode: 'none' | 'daily' | 'idle' | 'both'; at_hour: number; idle_minutes: number }
169
+ export function sessionReset(profile: Profile): SessionReset;
170
+ /** A platform's home channel (`platforms.<p>.home_channel`) as a chat key; with no platform, the first one; or null. */
171
+ export function homeChannel(profile: Profile, platform?: string | null): SurfaceKey | null;
172
+ export function expired(binding: Binding, reset: SessionReset, now: Instant): EndReason | null;
173
+ export function leaseId(profile: ProfileName, keyString: string): string;
174
+
175
+ export namespace events {
176
+ function inbound(fields: Omit<Extract<OrchestratorEvent, { type: 'inbound' }>, 'type' | 'attachments' | 'adapter' | 'guild_id' | 'sender_name' | 'message_id' | 'is_me' | 'is_bot' | 'mention'> & { attachments?: Attachment[]; adapter?: Platform; guild_id?: string | null; sender_name?: string | null; message_id?: string | null; is_me?: boolean; is_bot?: boolean | null; mention?: boolean }): Extract<OrchestratorEvent, { type: 'inbound' }>;
177
+ function tick(at: Instant, inactivity_s?: number | null, max_parallel?: number | null): Extract<OrchestratorEvent, { type: 'tick' }>;
178
+ function worker(fields: Omit<Extract<OrchestratorEvent, { type: 'worker' }>, 'type'>): Extract<OrchestratorEvent, { type: 'worker' }>;
179
+ function adapterStatus(fields: Omit<Extract<OrchestratorEvent, { type: 'adapter' }>, 'type' | 'error'> & { error?: string | null }): Extract<OrchestratorEvent, { type: 'adapter' }>;
180
+ function operator(fields: { verb: string; profile?: ProfileName; args?: Record<string, unknown>; at: Instant }): Extract<OrchestratorEvent, { type: 'operator' }>;
181
+ function restart(at: Instant): Extract<OrchestratorEvent, { type: 'restart' }>;
182
+ function stopping(at: Instant): Extract<OrchestratorEvent, { type: 'stopping' }>;
183
+ function webhook(fields: { name: string; payload?: JsonValue; verified?: boolean; at: Instant; event?: string | null; delivery_id?: string | null }): Extract<OrchestratorEvent, { type: 'webhook' }>;
184
+ }
185
+
186
+ export function parseCommand(text: string): { name: string; args: string } | null;
187
+ export function frame(profile: ProfileName, key: SurfaceKey, sender: UserId, senderName: string | null, at: Instant, text: string): string;
188
+ export const COMMANDS: Set<string>;
189
+ export const REPLY: Record<string, string | ((arg: string) => string)>;
190
+
191
+ export function activationEnv(o: { root: Path; profile: Profile; surfaceKey?: string | null; vault?: Vault }): Record<string, string>;
192
+ export function activationCwd(profile: Profile, workdir?: RelPath | null): Path;
193
+ /** Links the profile's `AGENTS.md` into the worker's config home where the harness reads a persona from any cwd (Codex; Claude Code with its `@AGENTS.md` bridge); answers that home, or null. */
194
+ export function materializePersona(profile: Profile): Path | null;
195
+ export const HOME_ENV: Readonly<Record<HarnessId, string>>;
196
+ /** Links each skill the profile has into the worker's config home `skills/` (Codex, Claude Code); answers that folder, or null. */
197
+ export function materializeSkills(profile: Profile): Path | null;
198
+ export const HOME_SKILLS: Readonly<Record<HarnessId, string>>;
199
+ export const HOME_PERSONA: Readonly<Record<HarnessId, Readonly<Record<string, 'link' | 'bridge'>>>>;
200
+ export const ORCH_ENV: Readonly<{ root: string; profile: string; surface: string }>;
201
+
202
+ // ---------------------------------------------------------------- the loop and adapters (§7)
203
+
204
+ export interface ChannelAdapter {
205
+ platform: Platform;
206
+ connect(emit: (msg: Omit<Extract<OrchestratorEvent, { type: 'inbound' }>, 'type' | 'at' | 'attachments' | 'adapter' | 'guild_id' | 'message_id' | 'is_me' | 'is_bot' | 'mention'> & { at?: Instant; attachments?: Attachment[]; guild_id?: string | null; message_id?: string | null; is_me?: boolean; is_bot?: boolean | null; mention?: boolean }) => unknown): Promise<{ state: 'up' | 'down'; error?: string } | void>;
207
+ /** A returned `message_id` is recorded on the obligation as `posted` (§2.6). */
208
+ send(target: SurfaceKey, content: { text: string; at?: Instant } & Partial<OutboundContent>): Promise<{ ok?: boolean; message_id?: string } | unknown>;
209
+ close?(): Promise<void>;
210
+ }
211
+
212
+ export class LoopbackAdapter implements ChannelAdapter {
213
+ constructor(o?: { platform?: Platform; profile?: ProfileName; failSends?: number });
214
+ platform: Platform;
215
+ profile: ProfileName;
216
+ outbox: { target: SurfaceKey; text: string; at: Instant | null }[];
217
+ failSends: number;
218
+ connect(emit: Parameters<ChannelAdapter['connect']>[0]): Promise<{ state: 'up' }>;
219
+ inject(m: { kind?: ChatType; chat_id?: string; thread_id?: string; sender?: UserId; sender_name?: string | null; text: string; at?: Instant; guild_id?: string | null }): unknown;
220
+ send(target: SurfaceKey, content: { text: string; at?: Instant }): Promise<{ ok: true }>;
221
+ close(): Promise<void>;
222
+ }
223
+
224
+ /**
225
+ * ORC-9: a sidecar over `chat@4.39.0` (`vercel/chat`), one instance per
226
+ * (platform, account). The platform packages (`@chat-adapter/*`) are imported
227
+ * lazily at `connect`; a missing one is `{ state: 'down' }`, not a throw.
228
+ */
229
+ export class ChatSdkAdapter implements ChannelAdapter {
230
+ constructor(o: {
231
+ platform: Platform; profile?: ProfileName; channel?: ChannelConfig | null; vault?: Vault;
232
+ sdkAdapter?: unknown; chat?: unknown; state?: unknown; log?: (level: string, message: string) => void;
233
+ });
234
+ platform: Platform;
235
+ profile: ProfileName;
236
+ /** thread_id -> the live SDK `Thread` this sidecar last answered on. */
237
+ readonly threads: Map<string, unknown>;
238
+ readonly chat: unknown;
239
+ connect(emit: Parameters<ChannelAdapter['connect']>[0]): Promise<{ state: 'up' | 'down'; error?: string }>;
240
+ /** The one door from the SDK into the loop: `(thread, message)` -> an `inbound`. */
241
+ handle(thread: unknown, message: unknown): unknown;
242
+ send(target: SurfaceKey, content: { text: string; at?: Instant; reply_to?: string }): Promise<{ ok: true; message_id?: string }>;
243
+ close(): Promise<void>;
244
+ }
245
+
246
+ export const CHAT_SDK_VERSION: string;
247
+ export const CHAT_SDK_PACKAGE: string;
248
+ export const CHAT_SDK_STATE_PACKAGE: string;
249
+ /** §2.3's four-value `kind` from the Chat SDK's `isDM` / `channelVisibility` split. */
250
+ export function chatType(thread: { isDM?: boolean; channelVisibility?: string }): ChatType;
251
+ export function toAttachment(a: Record<string, unknown>): Attachment;
252
+ export function toInbound(o: { profile: ProfileName; thread: unknown; message: unknown }): Parameters<Parameters<ChannelAdapter['connect']>[0]>[0];
253
+
254
+ /**
255
+ * ORC-9: Hermes's `api_server` client API, served by this loop on its own
256
+ * listener at `platforms.api_server.extra.host|port`. Every route it makes the
257
+ * loop act on enters as an `inbound` (§3).
258
+ */
259
+ export class ApiServerAdapter implements ChannelAdapter {
260
+ constructor(o: {
261
+ platform?: Platform; profile?: ProfileName; channel?: ChannelConfig | null; vault?: Vault;
262
+ state: OrchestratorState; clock?: () => Instant; log?: (level: string, message: string) => void;
263
+ });
264
+ platform: Platform;
265
+ profile: ProfileName;
266
+ /** The bound port; `extra.port: 0` lets the OS choose and tests read it here. */
267
+ readonly port: number | null;
268
+ readonly sessions: Map<string, unknown>;
269
+ readonly runs: Map<string, { run_id: string; status: string; output: string | null }>;
270
+ connect(emit: Parameters<ChannelAdapter['connect']>[0]): Promise<{ state: 'up' }>;
271
+ send(target: SurfaceKey, content: { text: string; at?: Instant }): Promise<{ ok: true; message_id: string }>;
272
+ close(): Promise<void>;
273
+ }
274
+
275
+ export const API_SERVER_HOST: string;
276
+ export const API_SERVER_PORT: number;
277
+
278
+ export class Orchestrator {
279
+ constructor(o: {
280
+ state: OrchestratorState;
281
+ vault?: Vault;
282
+ client: unknown; // SupercodeHarnessClient from @volter/supercode-harness-sdk
283
+ adapters?: Record<Platform, ChannelAdapter>;
284
+ clock?: () => Instant;
285
+ executeJob?: ((task: HostedTask) => Promise<HostedReceipt>) | null;
286
+ launchFor?: (profile: Profile, worker: WorkerSpec, env: Record<string, string>) => { program: string; arguments: string[]; env: Record<string, string> } | undefined;
287
+ log?: (level: string, message: string) => void;
288
+ });
289
+ readonly state: OrchestratorState;
290
+ readonly vault: Vault;
291
+ readonly queue: Promise<unknown>;
292
+ readonly effectLog: Effect[];
293
+ readonly webhookPort: number | null;
294
+ start(): Promise<void>;
295
+ stop(): Promise<void>;
296
+ tick(at?: Instant): Promise<Effect[]>;
297
+ drainHosted(): Promise<void>;
298
+ dispatch(event: OrchestratorEvent): Promise<Effect[]>;
299
+ enqueue(event: OrchestratorEvent): void;
300
+ /** §7: effects produced by an MCP tool call, run on the loop's own queue. */
301
+ /** §7: the model-facing MCP door's loop side, open between start and stop. */
302
+ readonly bridge: { path: Path; close(): Promise<void> } | null;
303
+ }
304
+
305
+ export function normalizeWorkerEvent(ev: unknown): WorkerEvent | null;
306
+
307
+ // ---------------------------------------------------------------- cron and webhooks (ORC-5, §4.3/§4.4)
308
+
309
+ export interface CronFields { minute: Set<number>; hour: Set<number>; dom: Set<number>; month: Set<number>; dow: Set<number>; domRestricted: boolean; dowRestricted: boolean }
310
+
311
+ /** The next run strictly after `after`, or null when the schedule is spent. */
312
+ export function nextRunAt(schedule: Schedule, after: Instant): Instant | null;
313
+ export function parseCron(expr: string): CronFields;
314
+ /** Why a schedule cannot be evaluated (bad instant, interval, expression or zone), or null. */
315
+ export function scheduleError(schedule: Schedule): string | null;
316
+ export function dueJobs(profile: Profile, now: Instant): Job[];
317
+ export function claimFire(profile: Profile, job: Job, now: Instant): Fire | null;
318
+ export function finishFire(profile: Profile, fire: Fire, job: Job | null, status: FireStatus, now: Instant, error?: string | null, effects?: Effect[] | null): Fire;
319
+ /** Re-arm after a run; a schedule that cannot be evaluated disables the job and returns why. */
320
+ export function advanceSchedule(job: Job, now: Instant): string | null;
321
+ export function resolveTarget(job: Job | null, profile: Profile, target?: Target | null): SurfaceKey | { kind: 'local' };
322
+ export function cronTick(state: OrchestratorState, ev: Extract<OrchestratorEvent, { type: 'tick' }>, effects: Effect[]): void;
323
+ export function fireFinal(state: OrchestratorState, profile: Profile, binding: Binding, text: string, now: Instant, effects: Effect[]): boolean;
324
+ export function fireFailed(state: OrchestratorState, profile: Profile, binding: Binding, message: string, now: Instant, effects: Effect[]): boolean;
325
+ export function fireSessionName(jobId: JobId, at: Instant): string;
326
+ export function fireSessionId(fire: Fire): string | null;
327
+ export function compactStamp(at: Instant): string;
328
+ export const BACKOFF_MINUTES: readonly number[];
329
+ export const BREAKER_FAILURES: number;
330
+ export const BREAKER_MINUTES: number;
331
+ export const MAX_ATTEMPTS: number;
332
+ export const TICK_MS: number;
333
+
334
+ export function handleWebhook(state: OrchestratorState, ev: Extract<OrchestratorEvent, { type: 'webhook' }>, effects: Effect[]): void;
335
+ export function renderTemplate(template: string, payload: unknown): string;
336
+ export function signBody(secret: string, body: string): Promise<string>;
337
+ export function verifySignature(secret: string | null, body: string, header: string | null): Promise<boolean>;
338
+ export function subscriptionSecret(sub: WebhookSubscription | null, vault?: Vault): string | null;
339
+ export function findSubscription(state: OrchestratorState, name: string): { profile: Profile; sub: WebhookSubscription } | null;
340
+ export function webhookKey(name: string): SurfaceKey;
341
+ export function startWebhookListener(o: { state: OrchestratorState; vault?: Vault; port?: number; host?: string; dispatch: (event: OrchestratorEvent) => unknown; clock: () => Instant; log?: (level: string, message: string) => void }): Promise<{ server: unknown; port: number; close(): Promise<void> }>;
342
+ /** `gateway.webhook_port` from config residue; 0 when unset. */
343
+ export function webhookPort(state: OrchestratorState): number;
344
+
345
+ // ---------------------------------------------------------------- §7: the model-facing MCP door
346
+
347
+ /** One published tool: `name`, `description`, and its JSON Schema. */
348
+ export interface OrchestratorTool { name: string; description: string; inputSchema: Record<string, unknown> }
349
+ export const TOOLS: readonly OrchestratorTool[];
350
+ export const TOOL_NAMES: readonly string[];
351
+ export const SERVER_NAME: string;
352
+ export const PROTOCOL_VERSION: string;
353
+ export const SOCKET_ENV: string;
354
+ export const SERVER_PATH: Path;
355
+
356
+ /** The door a harness publishes for an MCP server. */
357
+ export type McpDoor = 'flag' | 'toml' | 'json' | 'none' | 'acp';
358
+ export const MCP_DOORS: Readonly<Record<string, McpDoor>>;
359
+ export function doorFor(harness: string): McpDoor;
360
+
361
+ /** One stdio MCP server, in the uniform shape `harness.v1.runtimes.start` carries. */
362
+ export interface McpServerLaunch { name: string; command: string; arguments: string[]; env: Record<string, string> }
363
+
364
+ export function mountOrchestratorMcp(o: {
365
+ root: Path; profile: Profile; harness: string; surfaceKey?: string | null;
366
+ launch?: { program: string; arguments?: string[]; env?: Record<string, string> };
367
+ socketPath?: Path; serverPath?: Path; program?: string;
368
+ }): { door: McpDoor; ran: string; launch: unknown; mcp_servers: McpServerLaunch[] | null; path: Path | null };
369
+
370
+ export function socketPathFor(root: Path): Path;
371
+ export function startBridge(o: { orch: Orchestrator; socketPath: Path; log?: (level: string, message: string) => void }): Promise<{ path: Path; close(): Promise<void> }>;
372
+ export function runVerb(orch: Orchestrator, call: { verb: string; args?: Record<string, unknown>; profile: ProfileName; surface?: string | null }): Promise<{ result?: Record<string, unknown>; effects?: Effect[]; error?: string }>;
373
+ export function parseSchedule(spec: unknown, now: Instant): Schedule;
374
+ export function routedProfile(state: OrchestratorState, key: SurfaceKey): ProfileName | null;
375
+ export function keyFromString(text: string | null): SurfaceKey | null;
376
+
377
+ /** The binding a spawned MCP server reads out of its environment. */
378
+ export function bindingFromEnv(env?: Record<string, string | undefined>): { root: Path; profile: ProfileName; surface: string | null; socket: Path };
379
+ export function handleRequest(binding: { root: Path; profile: ProfileName; surface: string | null; socket: Path }, request: unknown): Promise<unknown>;
380
+ export function serveStdio(binding: { root: Path; profile: ProfileName; surface: string | null; socket: Path }, input?: unknown, output?: unknown): unknown;
381
+
382
+ export interface OrchestratorState {
383
+ root: Path;
384
+ profiles: Record<ProfileName, Profile>;
385
+ runtime: RuntimeState;
386
+ }
387
+
388
+ export type Vault = Map<string, string>;
389
+
390
+ export class LoadError extends Error { file: string; key: string | null }
391
+
392
+ /** What `orchestration.decompile` / `orchestration.export` did (the SDK's `OrchestrationDecompiled`). */
393
+ export interface OrchestrationDecompiled {
394
+ written: ArtifactFidelity[];
395
+ refused: { file: RelPath; reason: string }[];
396
+ notes?: string[];
397
+ rows_byte?: number;
398
+ rows_emitted?: number;
399
+ }
400
+ /** What `orchestration.import` did: the orchestration as written, the vault's key names, and what was carried by path. */
401
+ export interface OrchestrationImported {
402
+ orchestration: Omit<OrchestratorState, 'runtime'>;
403
+ vault_keys: string[];
404
+ root: Path;
405
+ carried: RelPath[];
406
+ }
407
+
408
+ /** Our folder, strict, through `harness.v1.orchestration.load`; the vault is read out of the home's own `.env`. */
409
+ export function load(root: Path): Promise<{ state: OrchestratorState; vault: Vault }>;
410
+ /** Our folder, canonical and byte-stable, through `harness.v1.orchestration.save`. Sends no secret. */
411
+ export function save(state: OrchestratorState, root?: Path): Promise<void>;
412
+ /** Another harness's home as a state value; `vault_keys` names the `.env` keys it would need. */
413
+ export function compile(from: 'hermes' | 'openclaw', home: Path): Promise<{ state: OrchestratorState; vault_keys: string[] }>;
414
+ /** Another harness's home becomes our folder, credentials along (`harness.v1.orchestration.import`). */
415
+ export function importFrom(from: 'hermes' | 'openclaw', home: Path, into: Path): Promise<OrchestrationImported>;
416
+ /** Our folder becomes another harness's home, credentials along (`harness.v1.orchestration.export`). */
417
+ export function exportTo(to: 'hermes' | 'openclaw', root: Path, dest: Path): Promise<OrchestrationDecompiled>;
418
+ /** An orchestration value as the loop's state: the persisted half plus an empty runtime half. */
419
+ export function stateOf(orchestration: Omit<OrchestratorState, 'runtime'>): OrchestratorState;
420
+ /** Hold the door open (a running loop does); balanced by `releaseWorld`, after which it closes itself when idle. */
421
+ export function retainWorld(): void;
422
+ export function releaseWorld(): void;
423
+ /** Close the shared door to `supercode harness serve` now; the next verb opens it again. */
424
+ export function closeWorld(): Promise<void>;
425
+ /** The binary the doors are opened with: `SUPERCODE_BIN`, else this checkout's build, else PATH. */
426
+ export function supercodeCommand(): string;
427
+
428
+ export function renderSurfaceKey(profile: ProfileName, key: SurfaceKey): string;
429
+ export function parseSurfaceKey(text: string): { profile: ProfileName; key: SurfaceKey } | null;
430
+ export function surfaceKeyString(key: SurfaceKey): string;
431
+ /** `context_from` as Hermes stores it: a list of job ids (or `self`), or null. */
432
+ export function decodeContextFrom(file: string, key: string, value: unknown): string[] | null;
433
+ export function parseTarget(file: string, key: string, word: string | null, extra?: { chat_id?: string; thread_id?: string }): Target | null;
434
+ export function renderTarget(t: Target | null): string | null;
435
+ export function resolveRoute(routes: Route[], key: SurfaceKey, guildId?: string): ProfileName | null;
436
+ export function routeSpecificity(r: Route): number;
437
+ export function emptyState(root: Path): OrchestratorState;
438
+ export function emptyProfile(name: ProfileName, dir: Path): Profile;
439
+ export function emptyRuntime(): RuntimeState;
440
+ export function canonicalJson(value: unknown): string;
441
+ export function persistedView(state: OrchestratorState): Omit<OrchestratorState, 'runtime'>;
442
+ export function parseDotenv(text: string): Map<string, string>;
443
+
444
+ export const CHAT_TYPES: Set<ChatType>;
445
+ export const END_REASONS: Set<EndReason>;
446
+ export const FIRE_STATUSES: Set<FireStatus>;
447
+ export const OBLIGATION_STATES: Set<ObligationState>;
448
+
449
+ /** Host receipts confirm dispatch, not the eventual model answer. */
450
+ export interface HostedTask { profile: string; job: Job; fire: Fire }
451
+ export interface HostedReceipt { accepted: true; output: string; profile?: string; fire_id?: string; delivery?: { platform: string; chat_id: string; id: string } }
452
+ export function callOperator(options: { root: string; profile?: string; op: string; args?: Record<string, unknown>; timeoutMs?: number }): Promise<unknown>;
453
+ export function httpJobExecutor(options: { url: string; tokenFile: string; root: string; timeoutMs?: number }): (task: HostedTask) => Promise<HostedReceipt>;
454
+ /** Stop only a hosted daemon owned by this root; wait for native shutdown. */
455
+ export function stopHostedDaemon(options: { root: string; executorUrl?: string; timeoutMs?: number }): Promise<{ stopped: boolean; wasRunning: boolean }>;
456
+
457
+ // ---------------------------------------------------------------- the agent-setup applier (apply/, plan §7)
458
+
459
+ /** One agent-setup package: declared records for one home (docs/plans/content-spec-status.md §6). */
460
+ export interface SetupPackage {
461
+ schema_version: 1;
462
+ parameters?: Record<string, { default?: string | number | boolean }>;
463
+ inference?: {
464
+ models?: Record<string, { provider?: string; model: string; endpoint?: string; base_url?: string; credential?: string; placeholder_key?: string; api_mode?: string }>;
465
+ default?: string; unattended?: string; delegation?: string; fallbacks?: string[];
466
+ };
467
+ jobs?: Record<string, Record<string, unknown>>;
468
+ extensions?: { hermes?: { config?: Record<string, unknown> } };
469
+ moved?: Array<{ from: string; to: string }>;
470
+ removed?: Array<{ key: string; then: 'forget' | 'pause' | 'delete' }>;
471
+ }
472
+ export interface SetupRow { key: string; action: string; id?: string; detail?: string }
473
+ export interface SetupPlan { homeId: string; planOnly: boolean; rows: SetupRow[]; hash: string }
474
+ export interface SetupDoor { target: 'hermes' | 'orchestrator' }
475
+ export function planSetup(o: { door: SetupDoor; homeId: string; spec: SetupPackage; root?: string; params?: Record<string, string> }): Promise<SetupPlan>;
476
+ export function applySetup(o: { door: SetupDoor; homeId: string; spec: SetupPackage; root?: string; params?: Record<string, string>; planHash?: string | null; reviewedPlan?: boolean }): Promise<SetupPlan & { applied: SetupRow[] }>;
477
+ export function adoptSetup(o: { door: SetupDoor; homeId: string; keys: string[]; root?: string }): Promise<SetupRow[]>;
478
+ export function resolveSetup(o: { door: SetupDoor; homeId: string; keys: string[]; root?: string }): Promise<SetupRow[]>;
479
+ export function provisionHome(o: { homeId: string; root?: string }): unknown;
480
+ export function validateSetup(spec: SetupPackage): SetupPackage;
481
+ export function resolveParameters(spec: SetupPackage, values?: Record<string, string>): SetupPackage;
482
+ export function hermesConfig(spec: SetupPackage): Record<string, unknown>;
483
+ export const SETUP_SCHEMA_VERSION: 1;
484
+ export function hermesDoor(o: { home: string; python?: string | null; source?: string | null; runner?: unknown; prefix?: string[] }): SetupDoor;
485
+ export function orchestratorDoor(o: { root: string; profile?: string; load: unknown; socket?: string | null }): Promise<SetupDoor>;
486
+ export function locateHermes(o?: { python?: string | null; source?: string | null }): { python: string; source: string };
487
+ export function localRunner(o: { python: string; source: string; prefix?: string[] }): unknown;
488
+ export function containerRunner(o: { container: string; user?: string; python?: string; source?: string; docker?: string }): unknown;
489
+
490
+ /** The daemon's lease, `<home>/orchestrator.lock`. */
491
+ export interface OrchestratorLease {
492
+ pid: number;
493
+ started_at: string;
494
+ root: string;
495
+ /** The machine that wrote it, and that machine's boot (Linux's boot id). */
496
+ host?: string | null;
497
+ boot?: string | null;
498
+ executor_url?: string | null;
499
+ }
500
+ export const LOCK_FILE: 'orchestrator.lock';
501
+ /** This machine's name and, on Linux, its boot id. */
502
+ export function thisHost(): { host: string | null; boot: string | null };
503
+ export function pidIsLive(pid: number): boolean;
504
+ /** Whether a lease is this machine's, since this boot: only then may its pid be signalled. */
505
+ export function leaseIsHere(lease: Pick<OrchestratorLease, 'host' | 'boot'> | null | undefined): boolean;
506
+ /** Whether the daemon a lease names is alive now: here, and its pid live. */
507
+ export function leaseIsLive(lease: OrchestratorLease | null | undefined): boolean;
508
+ export function readLease(root: string): OrchestratorLease | null;
package/index.mjs ADDED
@@ -0,0 +1,38 @@
1
+ export {
2
+ LoadError, sessionReset, homeChannel, CHAT_TYPES, END_REASONS, FIRE_STATUSES, OBLIGATION_STATES,
3
+ renderSurfaceKey, parseSurfaceKey, surfaceKeyString, parseTarget, renderTarget, resolveRoute, routeSpecificity,
4
+ emptyState, emptyProfile, emptyRuntime, canonicalJson, persistedView, decodeContextFrom,
5
+ } from './ir.mjs';
6
+ export { load, save, compile, importFrom, exportTo, closeWorld, retainWorld, releaseWorld, stateOf, parseDotenv, supercodeCommand } from './orchestration.mjs';
7
+ export { step, expired, leaseId, accessPolicy, dmBehavior } from './reducer.mjs';
8
+ export * as events from './events.mjs';
9
+ export { parseCommand, frame, COMMANDS, REPLY } from './commands.mjs';
10
+ export { activationEnv, activationCwd, materializePersona, materializeSkills, HOME_ENV, HOME_PERSONA, HOME_SKILLS, ORCH_ENV } from './activation.mjs';
11
+ export { Orchestrator, normalizeWorkerEvent, webhookPort, TICK_MS } from './loop.mjs';
12
+ export {
13
+ cronTick, dueJobs, nextRunAt, parseCron, scheduleError, claimFire, finishFire, advanceSchedule, resolveTarget,
14
+ fireFinal, fireFailed, fireSessionName, fireSessionId, compactStamp,
15
+ BACKOFF_MINUTES, BREAKER_FAILURES, BREAKER_MINUTES, MAX_ATTEMPTS,
16
+ } from './cron.mjs';
17
+ export {
18
+ handleWebhook, renderTemplate, verifySignature, signBody, subscriptionSecret,
19
+ findSubscription, webhookKey, startWebhookListener,
20
+ } from './webhook.mjs';
21
+ export { LoopbackAdapter } from './adapters/loopback.mjs';
22
+ export { ChatSdkAdapter, toInbound, toAttachment, chatType, CHAT_SDK_VERSION, CHAT_SDK_PACKAGE, CHAT_SDK_STATE_PACKAGE } from './adapters/chat-sdk.mjs';
23
+ export { ApiServerAdapter, DEFAULT_HOST as API_SERVER_HOST, DEFAULT_PORT as API_SERVER_PORT } from './adapters/api-server.mjs';
24
+ export { Rh2Adapter } from './adapters/rh2.mjs';
25
+ export { TOOLS, TOOL_NAMES, SERVER_NAME, PROTOCOL_VERSION } from './mcp/tools.mjs';
26
+ export { mountOrchestratorMcp, doorFor, MCP_DOORS, SERVER_PATH } from './mcp/mount.mjs';
27
+ export { startBridge } from './mcp/bridge.mjs';
28
+ export { socketPathFor, bindingFromEnv, handleRequest, serveStdio, SOCKET_ENV } from './mcp/server.mjs';
29
+ export { runVerb, parseSchedule, routedProfile, keyFromString } from './mcp/verbs.mjs';
30
+ export { applyOperator, buildJob, performRemoveProfileDir, OPERATOR_OPS, TRASH_DIR } from './operator.mjs';
31
+
32
+ export { callOperator, httpJobExecutor, stopHostedDaemon } from './hosted.mjs';
33
+ export { plan as planSetup, apply as applySetup, adopt as adoptSetup, resolve as resolveSetup, provision as provisionHome, validate as validateSetup, resolveParameters, hermesConfig, SCHEMA_VERSION as SETUP_SCHEMA_VERSION } from './apply/index.mjs';
34
+ export { hermesDoor, orchestratorDoor, locateHermes, localRunner, containerRunner } from './apply/doors.mjs';
35
+ export { LOCK_FILE, thisHost, pidIsLive, leaseIsHere, leaseIsLive, readLease } from './lease.mjs';
36
+ export { adoptHome, adoptPersona, adoptSkills, managedSkills, skillSources, profileDirs, AGENTS_SKILLS } from './hermes-home.mjs';
37
+ export { hermesAccess, recordIncident, hermesToolEnv, hermesInstall } from './hermes-cli.mjs';
38
+ export { holdGatewayLock, gatewayLockHeld, acquireTokenLock, releaseTokenLock, looksLikeGateway, TOKEN_SCOPES } from './hermes-locks.mjs';