@prismer/runtime 1.9.24 → 2.0.0

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/dist/index.d.ts CHANGED
@@ -28,6 +28,11 @@ interface AdapterDef {
28
28
  workspaceSchema: z.ZodSchema;
29
29
  /** Long-running: ensure the underlying service is reachable. May spawn or just connect. */
30
30
  ensureService?(profile: AgentProfile): Promise<AdapterService>;
31
+ /**
32
+ * Optional preflight called when the daemon syncs a profile. This should
33
+ * prepare local profile files/config without starting a long-running service.
34
+ */
35
+ prepareProfile?(profile: AgentProfile): Promise<void>;
31
36
  /** Interactive: one-shot dispatch (spawn-per-task). */
32
37
  dispatch?(profile: AgentProfile, task: TaskInput): Promise<TaskResult>;
33
38
  /** Validate config before persisting `AgentProfile.config`. */
@@ -148,6 +153,11 @@ declare class AdapterRegistry {
148
153
  * Match rules (deterministic, sorted by name):
149
154
  * - exact: adapter declared the tag verbatim
150
155
  * - wildcard: adapter declared `code.*` → matches `code.write`
156
+ *
157
+ * @internal — v2.0: no caller in tree uses capability-based selection;
158
+ * dispatch routes by `profile.adapterName` directly. Kept for tests +
159
+ * future use (e.g. mobile capability negotiation), but not part of the
160
+ * stable adapter contract surface.
151
161
  */
152
162
  findByCapability(capability: string): AdapterDef[];
153
163
  }
@@ -210,6 +220,84 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
210
220
  nativeMirrorTimeoutMs: z.ZodDefault<z.ZodNumber>;
211
221
  /** Task authority level: executor (default) or orchestrator. */
212
222
  taskAuthority: z.ZodDefault<z.ZodOptional<z.ZodEnum<["executor", "orchestrator"]>>>;
223
+ /** Human approval escalation policy. Enforcement is currently prompt/cloud-side. */
224
+ approvalPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["strict", "auto-low-risk", "autonomous"]>>>;
225
+ /** Agent-level MCP tool allowlist. Empty/null means all tools. Supports exact names and trailing * wildcards. */
226
+ mcpAllowlist: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
227
+ /** Agent-level operating principles injected through /v1/runs instructions. */
228
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
229
+ source: z.ZodString;
230
+ text: z.ZodString;
231
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
232
+ source: z.ZodString;
233
+ text: z.ZodString;
234
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
235
+ source: z.ZodString;
236
+ text: z.ZodString;
237
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
238
+ /** Override the skills root read for dispatch-time SKILL.md injection. */
239
+ skillsDir: z.ZodOptional<z.ZodString>;
240
+ /**
241
+ * Role-template snapshot carried in AgentProfile.config by cloud ACP.
242
+ * Expected fields used here:
243
+ * - roleTemplate.mcpServers[].toolsAllowlist
244
+ * - roleTemplate.operatingPrinciples
245
+ */
246
+ roleTemplate: z.ZodOptional<z.ZodObject<{
247
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
248
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
249
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
250
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
251
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
252
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
253
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
254
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
255
+ source: z.ZodString;
256
+ text: z.ZodString;
257
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
258
+ source: z.ZodString;
259
+ text: z.ZodString;
260
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
261
+ source: z.ZodString;
262
+ text: z.ZodString;
263
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
264
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
265
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
266
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
267
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
268
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
269
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
270
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
271
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
272
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
273
+ source: z.ZodString;
274
+ text: z.ZodString;
275
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
276
+ source: z.ZodString;
277
+ text: z.ZodString;
278
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
279
+ source: z.ZodString;
280
+ text: z.ZodString;
281
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
282
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
283
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
284
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
285
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
286
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
287
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
288
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
289
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
290
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
291
+ source: z.ZodString;
292
+ text: z.ZodString;
293
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
294
+ source: z.ZodString;
295
+ text: z.ZodString;
296
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
297
+ source: z.ZodString;
298
+ text: z.ZodString;
299
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
300
+ }, z.ZodTypeAny, "passthrough">>>;
213
301
  }, "strip", z.ZodTypeAny, {
214
302
  port: number;
215
303
  apiKey: string;
@@ -224,10 +312,36 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
224
312
  mirrorNativeGoals: boolean;
225
313
  nativeMirrorTimeoutMs: number;
226
314
  taskAuthority: "executor" | "orchestrator";
315
+ approvalPolicy: "strict" | "auto-low-risk" | "autonomous";
227
316
  hermesProfileName?: string | undefined;
228
317
  prismerMcpServerPath?: string | undefined;
229
318
  prismerProviderBaseUrl?: string | undefined;
230
319
  hermesSourceDir?: string | undefined;
320
+ mcpAllowlist?: string[] | null | undefined;
321
+ operatingPrinciples?: string | Record<string, string> | z.objectOutputType<{
322
+ source: z.ZodString;
323
+ text: z.ZodString;
324
+ }, z.ZodTypeAny, "passthrough">[] | undefined;
325
+ skillsDir?: string | undefined;
326
+ roleTemplate?: z.objectOutputType<{
327
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
328
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
329
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
330
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
331
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
332
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
333
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
334
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
335
+ source: z.ZodString;
336
+ text: z.ZodString;
337
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
338
+ source: z.ZodString;
339
+ text: z.ZodString;
340
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
341
+ source: z.ZodString;
342
+ text: z.ZodString;
343
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
344
+ }, z.ZodTypeAny, "passthrough"> | undefined;
231
345
  }, {
232
346
  apiKey: string;
233
347
  hermesProfileName?: string | undefined;
@@ -246,10 +360,114 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
246
360
  hermesSourceDir?: string | undefined;
247
361
  nativeMirrorTimeoutMs?: number | undefined;
248
362
  taskAuthority?: "executor" | "orchestrator" | undefined;
363
+ approvalPolicy?: "strict" | "auto-low-risk" | "autonomous" | undefined;
364
+ mcpAllowlist?: string[] | null | undefined;
365
+ operatingPrinciples?: string | Record<string, string> | z.objectInputType<{
366
+ source: z.ZodString;
367
+ text: z.ZodString;
368
+ }, z.ZodTypeAny, "passthrough">[] | undefined;
369
+ skillsDir?: string | undefined;
370
+ roleTemplate?: z.objectInputType<{
371
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
372
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
373
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
374
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
375
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
376
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
377
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
378
+ operatingPrinciples: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>, z.ZodArray<z.ZodObject<{
379
+ source: z.ZodString;
380
+ text: z.ZodString;
381
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
382
+ source: z.ZodString;
383
+ text: z.ZodString;
384
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
385
+ source: z.ZodString;
386
+ text: z.ZodString;
387
+ }, z.ZodTypeAny, "passthrough">>, "many">]>>;
388
+ }, z.ZodTypeAny, "passthrough"> | undefined;
249
389
  }>;
250
390
  type HermesProfileConfig = z.infer<typeof HermesProfileConfigSchema>;
251
391
  declare const hermesAdapter: AdapterDef;
252
392
 
393
+ declare const OpenClawProfileConfigSchema: z.ZodObject<{
394
+ /** OpenClaw chat-completions HTTP port. */
395
+ port: z.ZodDefault<z.ZodNumber>;
396
+ /** Bearer token expected by the gateway (from gateway.auth.bearerTokens). */
397
+ apiKey: z.ZodString;
398
+ /**
399
+ * Model field passed to OpenClaw's /v1/chat/completions. OpenClaw
400
+ * intercepts this differently from a vanilla OpenAI server: the value
401
+ * MUST be `openclaw` (or `openclaw/<agentId>`) — it picks which
402
+ * OpenClaw agent answers, NOT the underlying LLM. The LLM is selected
403
+ * by `agents.defaults.model.primary` in openclaw.json (e.g.
404
+ * `prismer/us-kimi-k2.5`, set by the bootstrap).
405
+ */
406
+ model: z.ZodDefault<z.ZodString>;
407
+ mcpAllowlist: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
408
+ approvalPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["strict", "auto-low-risk", "autonomous"]>>>;
409
+ roleTemplate: z.ZodOptional<z.ZodObject<{
410
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
411
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
412
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
413
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
414
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
415
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
416
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
417
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
418
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
419
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
420
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
421
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
422
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
423
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
424
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
425
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
426
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
427
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
428
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
429
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
430
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
431
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
432
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
433
+ }, z.ZodTypeAny, "passthrough">>>;
434
+ skillsDir: z.ZodOptional<z.ZodString>;
435
+ }, "strip", z.ZodTypeAny, {
436
+ port: number;
437
+ apiKey: string;
438
+ model: string;
439
+ approvalPolicy: "strict" | "auto-low-risk" | "autonomous";
440
+ mcpAllowlist?: string[] | null | undefined;
441
+ skillsDir?: string | undefined;
442
+ roleTemplate?: z.objectOutputType<{
443
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
444
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
445
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
446
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
447
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
448
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
449
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
450
+ }, z.ZodTypeAny, "passthrough"> | undefined;
451
+ }, {
452
+ apiKey: string;
453
+ port?: number | undefined;
454
+ model?: string | undefined;
455
+ approvalPolicy?: "strict" | "auto-low-risk" | "autonomous" | undefined;
456
+ mcpAllowlist?: string[] | null | undefined;
457
+ skillsDir?: string | undefined;
458
+ roleTemplate?: z.objectInputType<{
459
+ mcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
460
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
461
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
462
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
463
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
464
+ toolsAllowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
465
+ }, z.ZodTypeAny, "passthrough">>, "many">>;
466
+ }, z.ZodTypeAny, "passthrough"> | undefined;
467
+ }>;
468
+ type OpenClawProfileConfig = z.infer<typeof OpenClawProfileConfigSchema>;
469
+ declare const openclawAdapter: AdapterDef;
470
+
253
471
  interface WsClientOptions {
254
472
  /** Cloud WS URL, e.g. `wss://cloud.prismer.dev/ws` or `ws://127.0.0.1:3000/ws`. */
255
473
  url: string;
@@ -552,6 +770,10 @@ declare class CloudClient {
552
770
  private readonly opts;
553
771
  private readonly fetchImpl;
554
772
  constructor(opts: CloudClientOptions);
773
+ /** Configured cloud base URL (no trailing slash). */
774
+ get baseUrl(): string;
775
+ /** Bearer API key used to authorize requests. Treat as a secret. */
776
+ get apiKey(): string;
555
777
  /** Low-level request. Caller decides on retry; sync-worker handles backoff. */
556
778
  request<T = unknown>(method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', path: string, init?: {
557
779
  body?: unknown;
@@ -887,6 +1109,9 @@ interface HostAckedPayload {
887
1109
  [key: string]: number;
888
1110
  };
889
1111
  profilesToSync: string[];
1112
+ /** Profile IDs the daemon declared but that no longer exist on the cloud
1113
+ * (soft-deleted). The daemon should remove these from its local store. */
1114
+ profilesToDelete: string[];
890
1115
  }
891
1116
  interface AgentStatusChangedPayload {
892
1117
  agentImUserId: string;
@@ -1020,6 +1245,14 @@ interface WorkspaceFileChangedPayload {
1020
1245
  contentHash?: string;
1021
1246
  version: number;
1022
1247
  }
1248
+ interface AssetChangedPayload {
1249
+ workspaceId: string;
1250
+ assetId: string;
1251
+ operation: 'create' | 'update' | 'delete';
1252
+ contentHash?: string;
1253
+ assetIndexSeq?: number;
1254
+ revision?: number;
1255
+ }
1023
1256
 
1024
1257
  interface OutboxWatcherOptions {
1025
1258
  /**
@@ -1212,6 +1445,7 @@ declare class AssetMetadataIndex {
1212
1445
  */
1213
1446
  pullDelta(opts?: {
1214
1447
  signal?: AbortSignal;
1448
+ force?: boolean;
1215
1449
  }): Promise<{
1216
1450
  applied: number;
1217
1451
  cursor: number;
@@ -1223,6 +1457,8 @@ declare class AssetMetadataIndex {
1223
1457
  search(query: string, limit?: number): AssetMetadataRow[];
1224
1458
  /** Exact match on filename column. Returns undefined if not indexed. */
1225
1459
  resolveByFilename(filename: string): AssetMetadataRow | undefined;
1460
+ resolveByAssetId(assetId: string): AssetMetadataRow | undefined;
1461
+ resolveByContentHash(contentHash: string): AssetMetadataRow | undefined;
1226
1462
  /** Batch exact match — returns Map for O(1) access. */
1227
1463
  resolveByFilenames(filenames: string[]): Map<string, AssetMetadataRow>;
1228
1464
  }
@@ -1268,6 +1504,101 @@ declare function handleDispatch(payload: TaskDispatchRequestPayload, requestId:
1268
1504
  */
1269
1505
  declare function composePrompt(currentPrompt: string, context: TaskDispatchContextEntry[], maxChars: number, assetBlocks?: string[]): string;
1270
1506
 
1507
+ type NormalizedContent = {
1508
+ type: 'text';
1509
+ text: string;
1510
+ } | {
1511
+ type: 'image';
1512
+ url: string;
1513
+ caption?: string;
1514
+ } | {
1515
+ type: 'file';
1516
+ url: string;
1517
+ fileName: string;
1518
+ mime: string;
1519
+ } | {
1520
+ type: 'voice';
1521
+ url: string;
1522
+ durationMs: number;
1523
+ } | {
1524
+ type: 'video';
1525
+ url: string;
1526
+ caption?: string;
1527
+ };
1528
+ interface AgentDispatchRequest {
1529
+ channelAccountId: string;
1530
+ externalUserId: string;
1531
+ conversationId: string;
1532
+ mentionedAgentImUserId: string;
1533
+ messageText: string;
1534
+ messageId: string;
1535
+ attachments?: NormalizedContent[];
1536
+ replyToken: string;
1537
+ replyDeadlineMs: number;
1538
+ }
1539
+ interface AgentDispatchResponse {
1540
+ ok: boolean;
1541
+ /** ISO8601 timestamp. Required when ok=true. */
1542
+ acceptedAt?: string;
1543
+ error?: {
1544
+ code: string;
1545
+ message: string;
1546
+ };
1547
+ }
1548
+ type AgentDispatchReplyStatus = 'ok' | 'agent_offline' | 'timeout' | 'agent_error';
1549
+ interface AgentDispatchReplyAttachment {
1550
+ kind: 'file' | 'image';
1551
+ assetId: string;
1552
+ }
1553
+ interface AgentDispatchReplyPayload {
1554
+ replyToken: string;
1555
+ conversationId: string;
1556
+ replyToMessageId: string;
1557
+ agentImUserId: string;
1558
+ status: AgentDispatchReplyStatus;
1559
+ /** Required when status='ok'. */
1560
+ replyText?: string;
1561
+ attachments?: AgentDispatchReplyAttachment[];
1562
+ completedAt: string;
1563
+ /** Required when status!='ok'. */
1564
+ error?: {
1565
+ code: string;
1566
+ message: string;
1567
+ };
1568
+ }
1569
+
1570
+ interface MessageDispatchAgent {
1571
+ agentImUserId: string;
1572
+ dispatch(input: MessageDispatchTaskInput): Promise<TaskResult>;
1573
+ }
1574
+ interface MessageDispatchTaskInput {
1575
+ taskId: string;
1576
+ prompt: string;
1577
+ metadata: {
1578
+ source: 'external-channel';
1579
+ channelAccountId: string;
1580
+ externalUserId: string;
1581
+ conversationId: string;
1582
+ messageId: string;
1583
+ attachments?: AgentDispatchRequest['attachments'];
1584
+ };
1585
+ timeoutMs: number;
1586
+ signal: AbortSignal;
1587
+ }
1588
+ interface MessageDispatchDeps {
1589
+ findAgent(agentImUserId: string): Promise<MessageDispatchAgent | null> | MessageDispatchAgent | null;
1590
+ postReply(payload: AgentDispatchReplyPayload): Promise<void> | void;
1591
+ now?: () => Date;
1592
+ setTimeout?: typeof setTimeout;
1593
+ clearTimeout?: typeof clearTimeout;
1594
+ onError?: (err: unknown, request: AgentDispatchRequest) => void;
1595
+ }
1596
+ interface MessageDispatchHandle {
1597
+ response: AgentDispatchResponse;
1598
+ done: Promise<AgentDispatchReplyPayload>;
1599
+ }
1600
+ declare function handleAgentMessageDispatch(request: AgentDispatchRequest, deps: MessageDispatchDeps): MessageDispatchHandle;
1601
+
1271
1602
  declare class ServicePool {
1272
1603
  private readonly services;
1273
1604
  /**
@@ -1295,6 +1626,24 @@ interface LocalServerOptions {
1295
1626
  * sink; tests may pass a stub.
1296
1627
  */
1297
1628
  onDispatch?: (payload: DispatchPayload, runId: string) => void;
1629
+ /**
1630
+ * Optional dependencies for POST /dispatch (Release 200 §2.6 external
1631
+ * message → agent dispatch). When provided, LocalServer invokes
1632
+ * `handleAgentMessageDispatch()` internally and returns its synchronous
1633
+ * AgentDispatchResponse before async reply posting completes.
1634
+ */
1635
+ messageDispatchDeps?: MessageDispatchDeps;
1636
+ /**
1637
+ * Shared HMAC secret for Cloud → daemon POST /dispatch. Production daemons
1638
+ * must receive this via DISPATCH_DAEMON_SECRET or this option.
1639
+ */
1640
+ messageDispatchSecret?: string;
1641
+ /**
1642
+ * Optional direct handler for POST /dispatch. Prefer messageDispatchDeps
1643
+ * for the standard daemon path; this hook exists for tests and alternate
1644
+ * embedders that already wrap `handleAgentMessageDispatch()`.
1645
+ */
1646
+ messageDispatchHandler?: (payload: AgentDispatchRequest) => MessageDispatchHandle;
1298
1647
  /**
1299
1648
  * Install or update one hosted agent/profile in the daemon's local mirror.
1300
1649
  * The runner persists it, reloads hostedAgents, and redeclares to cloud.
@@ -1387,6 +1736,12 @@ interface InstallAgentResult {
1387
1736
  }
1388
1737
  interface LocalServerState {
1389
1738
  daemonId: string;
1739
+ /**
1740
+ * Daemon binary version (Release 200 §5.4). Reported in /healthz so cloud
1741
+ * can validate image pin and graceful-degrade against pre-2.0.0 daemons.
1742
+ * Sourced from the runtime package.json (see runner.ts).
1743
+ */
1744
+ daemonVersion: string;
1390
1745
  cloudBaseUrl?: string;
1391
1746
  workspaceId?: string | null;
1392
1747
  pid: number;
@@ -1400,12 +1755,46 @@ interface LocalServerState {
1400
1755
  runningTaskIds: string[];
1401
1756
  observability?: {
1402
1757
  adapters?: Record<string, unknown>;
1758
+ assetSync?: Record<string, unknown>;
1403
1759
  lastTaskError?: {
1404
1760
  taskId: string;
1405
1761
  message: string;
1406
1762
  at: string;
1407
1763
  };
1408
1764
  };
1765
+ /**
1766
+ * Adapter-level readiness snapshot (Release 200 §5.4). One entry per
1767
+ * registered adapter. Cloud uses this to compute Ready-AND with the
1768
+ * cluster-level signals (pod Running, /healthz reachable).
1769
+ */
1770
+ adapters?: Array<{
1771
+ name: string;
1772
+ ready: boolean;
1773
+ version?: string;
1774
+ }>;
1775
+ /**
1776
+ * Resource snapshot (Release 200 §5.4 + 08 §175). v200 baseline returns
1777
+ * placeholder zeros — true CPU/Mem sampling lives in S5 reconciler or a
1778
+ * follow-up daemon iteration. Cloud should not depend on these values for
1779
+ * health gating yet; they are informational.
1780
+ * TODO(v210): wire real cgroup / process.resourceUsage() sampling.
1781
+ */
1782
+ resources?: {
1783
+ cpu: {
1784
+ usagePct: number;
1785
+ };
1786
+ mem: {
1787
+ usedBytes: number;
1788
+ limitBytes: number;
1789
+ };
1790
+ };
1791
+ /**
1792
+ * Final per-daemon Ready signal (Release 200 §5.4). True iff every
1793
+ * registered adapter reports ready=true. Cloud uses this with
1794
+ * `status==='ok'` to gate dispatch (graceful degrade: pre-2.0.0 daemons
1795
+ * that omit this field are treated as ready when status==='ok').
1796
+ */
1797
+ readyForDispatch?: boolean;
1409
1798
  }
1410
1799
  declare class LocalServer {
1411
1800
  private opts;
@@ -1438,9 +1827,19 @@ declare class LocalServer {
1438
1827
  *
1439
1828
  * Body: { workspaceId, bytes (base64), filename, mime?, path?, description?, sourceAgentImUserId? }
1440
1829
  * Response 200: { assetId, contentHash, prismerUri }
1441
- * 400 on validation failure; 502 on cloud upstream failure; 501 if no sink wired.
1830
+ * 400 on body validation failure; 422 on agent-output policy rejection;
1831
+ * 502 on cloud upstream failure; 501 if no sink wired.
1442
1832
  */
1443
1833
  private handleAssetWrite;
1834
+ /**
1835
+ * POST /dispatch — external channel message → hosted agent dispatch.
1836
+ *
1837
+ * Cloud calls this with AgentDispatchRequest (Release 200 §2.6). The daemon
1838
+ * returns AgentDispatchResponse immediately, while the handler's `done`
1839
+ * promise completes later by posting AgentDispatchReplyPayload back to cloud.
1840
+ */
1841
+ private handleMessageDispatch;
1842
+ private resolveMessageDispatchHandler;
1444
1843
  /**
1445
1844
  * POST /v1/runs — dispatch ack-only (Cloud 3 S3 Phase 1).
1446
1845
  *
@@ -1487,6 +1886,15 @@ declare class Runner extends EventEmitter {
1487
1886
  private outboxWatcher?;
1488
1887
  private memoryWiring?;
1489
1888
  private assetMetadataIndexes;
1889
+ private workspaceMirrors;
1890
+ private assetOriginOutbox?;
1891
+ private dropFolderAdapter?;
1892
+ private dropFolderUploadRunner?;
1893
+ private dropFolderTimer?;
1894
+ private dropFolderWorkspaceId;
1895
+ private dropFolderWorkspaceDir;
1896
+ private dropFolderTickInFlight;
1897
+ private readonly dropFolderStable;
1490
1898
  private state;
1491
1899
  private startedAt;
1492
1900
  private workspaceId;
@@ -1507,12 +1915,52 @@ declare class Runner extends EventEmitter {
1507
1915
  */
1508
1916
  private runShellCommand;
1509
1917
  snapshotState(): LocalServerState;
1918
+ /**
1919
+ * Per-adapter readiness snapshot for /healthz (Release 200 §5.4).
1920
+ *
1921
+ * We synthesize this from the AdapterRegistry rather than asking each
1922
+ * adapter to expose a per-call health probe — calling adapter.health()
1923
+ * on every /healthz hit would spawn subprocess probes and slow the
1924
+ * cloud-side handshake. Registered adapters are considered ready;
1925
+ * future iteration can flip individual entries to ready=false based on
1926
+ * cached ensureService / dispatch failures.
1927
+ */
1928
+ private snapshotAdapterReadiness;
1929
+ /**
1930
+ * Release 200 T11 — cgroup v2 resource sampling for /healthz.resources.
1931
+ *
1932
+ * Reads `memory.current` / `memory.max` (best-effort, single-shot) and
1933
+ * derives `cpu.usagePct` by diffing `cpu.stat::usage_usec` against a
1934
+ * baseline cached in module state. The very first call after process
1935
+ * start always reports 0% CPU (no baseline yet); subsequent calls
1936
+ * reflect wall-clock usage between probes.
1937
+ *
1938
+ * Graceful degrade: when `/sys/fs/cgroup/` is absent (mac dev host,
1939
+ * Kubernetes-pre-cgroup-v2 distros), all fields are returned as zero
1940
+ * — callers must treat sampler output as advisory, not authoritative.
1941
+ */
1942
+ private cpuBaseline;
1943
+ private sampleCgroupResources;
1944
+ /**
1945
+ * Resolve daemon binary version from runtime package.json. Cached after
1946
+ * first resolution; falls back to constructor override → '0.0.0'.
1947
+ *
1948
+ * The path probe walks `../package.json` first (which matches the layout
1949
+ * produced by `tsup` — dist/runner.js sits one level inside the package)
1950
+ * and then `../../package.json` (source-tree layout, where this file
1951
+ * lives in src/daemon/runner.ts). Either path resolves to the same
1952
+ * runtime package.json depending on whether the runner is executing
1953
+ * from a build or directly under tsx in tests.
1954
+ */
1955
+ private cachedDaemonVersion;
1956
+ private resolveDaemonVersion;
1510
1957
  /**
1511
1958
  * Re-read the local `agents` table (populated by `prismer agent register`)
1512
1959
  * and re-populate `hostedAgents` map. Profiles per agent come from local
1513
1960
  * `agent_profiles` table (filled by host.acked sync).
1514
1961
  */
1515
1962
  loadAgentsFromDb(): void;
1963
+ private prepareLocalProfiles;
1516
1964
  /**
1517
1965
  * Register an in-process AgentProfile snapshot (called by agent CLI / sync layer).
1518
1966
  * Used to populate the `agents` list in agent.host.declare.
@@ -1535,6 +1983,8 @@ declare class Runner extends EventEmitter {
1535
1983
  private onHostAcked;
1536
1984
  private onTaskDispatch;
1537
1985
  private onTaskCancel;
1986
+ private findMessageDispatchAgent;
1987
+ private postMessageDispatchReply;
1538
1988
  private onAgentChanged;
1539
1989
  private onAgentProfileChanged;
1540
1990
  private syncProfileFromCloud;
@@ -1543,12 +1993,31 @@ declare class Runner extends EventEmitter {
1543
1993
  private onAssetChanged;
1544
1994
  private onWorkspaceFileChanged;
1545
1995
  private snapshotAdapterObservability;
1996
+ private snapshotAssetSyncObservability;
1546
1997
  /**
1547
1998
  * Ensure an AssetMetadataIndex exists for the given workspace and pull
1548
1999
  * delta from cloud. Idempotent — creates the index on first call, reuses
1549
2000
  * it on subsequent calls. Same cursor-catch-up semantics as WorkspaceMirror.
1550
2001
  */
1551
2002
  private syncAssetMetadata;
2003
+ /**
2004
+ * Ensure a WorkspaceMirror exists for the workspace and pull path→asset
2005
+ * bindings from cloud. Cold-start daemons previously only had this table
2006
+ * populated by WS push or per-path URI fallback, so local asset state looked
2007
+ * empty even though cloud files existed.
2008
+ */
2009
+ private syncWorkspaceFiles;
2010
+ private syncAssetState;
2011
+ /**
2012
+ * Desktop asset ingress: watch a user-visible local asset folder
2013
+ * and upload new files as IMAssets, preserving nested relative dirs in
2014
+ * IMAsset.folderPath. The lower-level adapter/outbox/uploader already
2015
+ * existed; this method wires them into the real daemon lifecycle.
2016
+ */
2017
+ private ensureDropFolderRuntime;
2018
+ private stopDropFolderRuntime;
2019
+ private runDropFolderTick;
2020
+ private isDropFolderObservationStable;
1552
2021
  /**
1553
2022
  * SyncWorker FlushFn — pushes local writes to cloud.
1554
2023
  *
@@ -1646,29 +2115,29 @@ declare const CCConfigSchema: z.ZodObject<{
1646
2115
  cwd: string;
1647
2116
  maxTurns: number;
1648
2117
  route: "default" | "prismer" | "omniroute";
1649
- systemPrompt?: string | undefined;
1650
- allowedTools?: string[] | undefined;
1651
- envVars?: Record<string, string> | undefined;
1652
2118
  mcpServers?: {
1653
2119
  name: string;
1654
2120
  command: string;
1655
2121
  env?: Record<string, string> | undefined;
1656
2122
  args?: string[] | undefined;
1657
2123
  }[] | undefined;
2124
+ systemPrompt?: string | undefined;
2125
+ allowedTools?: string[] | undefined;
2126
+ envVars?: Record<string, string> | undefined;
1658
2127
  baseURL?: string | undefined;
1659
2128
  apiKeyRef?: string | undefined;
1660
2129
  }, {
1661
2130
  cwd: string;
1662
2131
  model?: string | undefined;
1663
- systemPrompt?: string | undefined;
1664
- allowedTools?: string[] | undefined;
1665
- envVars?: Record<string, string> | undefined;
1666
2132
  mcpServers?: {
1667
2133
  name: string;
1668
2134
  command: string;
1669
2135
  env?: Record<string, string> | undefined;
1670
2136
  args?: string[] | undefined;
1671
2137
  }[] | undefined;
2138
+ systemPrompt?: string | undefined;
2139
+ allowedTools?: string[] | undefined;
2140
+ envVars?: Record<string, string> | undefined;
1672
2141
  maxTurns?: number | undefined;
1673
2142
  baseURL?: string | undefined;
1674
2143
  apiKeyRef?: string | undefined;
@@ -1729,4 +2198,4 @@ declare const codexAdapter: AdapterDef;
1729
2198
  declare function buildProgram(): Command;
1730
2199
  declare function runCli(argv?: string[]): Promise<void>;
1731
2200
 
1732
- export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, getRoleTemplate, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
2201
+ export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };