@prismer/runtime 2.0.5 → 2.0.7

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.cts CHANGED
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
21
21
  platform: 'darwin' | 'linux' | 'win32';
22
22
  agents: HostedAgentDeclaration[];
23
23
  }
24
+ interface RejectedHostedAgent {
25
+ imUserId: string;
26
+ reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
27
+ ownerDaemonId?: string;
28
+ }
24
29
  interface HostAckedPayload {
25
30
  workspaceId: string;
26
31
  syncCursor: {
@@ -32,6 +37,8 @@ interface HostAckedPayload {
32
37
  /** Profile IDs the daemon declared but that no longer exist on the cloud
33
38
  * (soft-deleted). The daemon should remove these from its local store. */
34
39
  profilesToDelete: string[];
40
+ acceptedAgents?: string[];
41
+ rejectedAgents?: RejectedHostedAgent[];
35
42
  }
36
43
  interface AgentStatusChangedPayload {
37
44
  agentImUserId: string;
@@ -123,6 +130,15 @@ interface TaskDispatchRequestPayload {
123
130
  }>;
124
131
  /** Wave-8 W1: assets cloud wants daemon to fold into agent context. */
125
132
  assetRefs?: AssetRef[];
133
+ /**
134
+ * release201/09 Phase 2 — task project scope. NULL = workspace-level
135
+ * (`_unscoped` sentinel on disk). Daemon uses this together with
136
+ * `agentImUserId` / `profile.workspaceId` to compose the per-task
137
+ * scratch path: `workspaces/<wid>/projects/<pid|_unscoped>/tasks/<tid>/`.
138
+ * Also forwarded into the spawned agent process as `PRISMER_ACTIVE_PROJECT_ID`
139
+ * (when non-null) so built-in skill --project flag defaults work.
140
+ */
141
+ projectId?: string | null;
126
142
  }
127
143
  interface TaskDispatchProgressPayload {
128
144
  taskId: string;
@@ -148,6 +164,20 @@ interface AssetDispatchObservation {
148
164
  /** L5: end-to-end fetch duration in ms (DNS + connect + body read). */
149
165
  durationMs?: number;
150
166
  }
167
+ /**
168
+ * P1-2 (2026-05-25): per-file outbox rejection record. Surfaced when daemon's
169
+ * `outbox-watcher` rejects an artifact because its magic bytes don't match
170
+ * the file extension (e.g. agent wrote `report.pdf` with markdown content).
171
+ * Cloud persists these on `IMTask.metadata.outboxRejections` and prepends a
172
+ * warning section to the next dispatch prompt so the agent can self-correct.
173
+ */
174
+ interface OutboxRejectionRecord {
175
+ filename: string;
176
+ reason: string;
177
+ inferredMime: string;
178
+ detectedMime: string;
179
+ rejectedAt: string;
180
+ }
151
181
  interface TaskDispatchReplyPayload {
152
182
  taskId: string;
153
183
  ok: boolean;
@@ -163,6 +193,13 @@ interface TaskDispatchReplyPayload {
163
193
  };
164
194
  /** Wave-8 W1: per-asset handling report. */
165
195
  assetObservability?: AssetDispatchObservation[];
196
+ /**
197
+ * P1-2 (2026-05-25): files quarantined locally by outbox-watcher's
198
+ * magic-bytes check during this turn. Cloud writes them onto
199
+ * `IMTask.metadata.outboxRejections` so the next dispatch prompt can warn
200
+ * the agent.
201
+ */
202
+ outboxRejections?: OutboxRejectionRecord[];
166
203
  }
167
204
  interface TaskCancelPayload {
168
205
  taskId: string;
@@ -670,12 +707,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
670
707
  * native state key directly and records the exact bridge result on the task.
671
708
  */
672
709
  mirrorNativeGoals: z.ZodDefault<z.ZodBoolean>;
673
- /**
674
- * Optional checkout path for Hermes Agent source. Used only as a fallback
675
- * when the installed `hermes` binary is older than the native Kanban CLI
676
- * surface but the local source tree contains hermes_cli/kanban_db.py.
677
- */
678
- hermesSourceDir: z.ZodOptional<z.ZodString>;
679
710
  nativeMirrorTimeoutMs: z.ZodDefault<z.ZodNumber>;
680
711
  /** Task authority level: executor (default) or orchestrator. */
681
712
  taskAuthority: z.ZodDefault<z.ZodOptional<z.ZodEnum<["executor", "orchestrator"]>>>;
@@ -775,7 +806,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
775
806
  hermesProfileName?: string | undefined;
776
807
  prismerMcpServerPath?: string | undefined;
777
808
  prismerProviderBaseUrl?: string | undefined;
778
- hermesSourceDir?: string | undefined;
779
809
  mcpAllowlist?: string[] | null | undefined;
780
810
  operatingPrinciples?: string | Record<string, string> | z.objectOutputType<{
781
811
  source: z.ZodString;
@@ -816,7 +846,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
816
846
  prismerApiKeyEnv?: string | undefined;
817
847
  mirrorNativeKanban?: boolean | undefined;
818
848
  mirrorNativeGoals?: boolean | undefined;
819
- hermesSourceDir?: string | undefined;
820
849
  nativeMirrorTimeoutMs?: number | undefined;
821
850
  taskAuthority?: "executor" | "orchestrator" | undefined;
822
851
  approvalPolicy?: "strict" | "auto-low-risk" | "autonomous" | undefined;
@@ -987,7 +1016,7 @@ type LocalDb = Database.Database;
987
1016
  declare function openLocalDb(path: string): LocalDb;
988
1017
  declare function runMigrations(db: LocalDb): void;
989
1018
  declare function currentSchemaVersion(db: LocalDb): number;
990
- declare const TARGET_SCHEMA_VERSION = 4;
1019
+ declare const TARGET_SCHEMA_VERSION = 5;
991
1020
 
992
1021
  type SyncResourceType = 'workspace' | 'agent' | 'agent_profile';
993
1022
  type SyncOperation = 'create' | 'update' | 'delete';
@@ -1184,11 +1213,28 @@ interface ConfigPaths {
1184
1213
  cacheDir: string;
1185
1214
  logsDir: string;
1186
1215
  /**
1187
- * Per-task run scratch dirs. Each chat-mention dispatch creates
1188
- * `${runsDir}/${taskId}/_outbox/` for adapter-produced files; the
1189
- * OutboxWatcher uploads from there into IMAssets.
1216
+ * Legacy per-task run scratch dirs (pre-release201/09).
1217
+ *
1218
+ * Pre-09: `${runsDir}/${taskId}/_outbox|workdir/`.
1219
+ * 09 Phase 2: dispatch.ts now writes to
1220
+ * `${root}/workspaces/<wid>/projects/<pid|_unscoped>/tasks/<tid>/{result,workdir}`
1221
+ * via `resolveTaskWorkdir()`. `runsDir` is kept as a fallback for tests + a
1222
+ * once-off startup migration helper (`runs/<tid>/` → new path; symlink 兜底
1223
+ * 90 天兼容期, §9.3.1).
1190
1224
  */
1191
1225
  runsDir: string;
1226
+ /**
1227
+ * release201/09 Phase 2 root for workspace × project × task scoped scratch:
1228
+ * `${root}/workspaces/`. resolveTaskWorkdir() composes the per-task path
1229
+ * underneath. Cache GC + project archive scan this root.
1230
+ */
1231
+ workspacesDir: string;
1232
+ /**
1233
+ * release201/09 Phase 2 root for device × agent role layer:
1234
+ * `${root}/devices/`. v2.0.7 Phase 2 不主动创建,Phase 3 (agent transfer)
1235
+ * 才落盘 `profile.json` / `skills/<slug>/` 等内容,本 helper 只解析路径。
1236
+ */
1237
+ devicesDir: string;
1192
1238
  }
1193
1239
  /**
1194
1240
  * Resolve paths for the prismer home directory. Honors `PRISMER_HOME` env var;
@@ -1876,6 +1922,13 @@ interface DispatchDeps {
1876
1922
  outboxWatcher?: OutboxWatcher;
1877
1923
  /** Daemon paths — used to derive the per-task outbox dir. */
1878
1924
  paths?: ConfigPaths;
1925
+ /**
1926
+ * release201/09 §9.9 — Stable device identifier from `config.toml`. Surfaced
1927
+ * to the spawned agent process as `PRISMER_DAEMON_ID` env for metric-outbox
1928
+ * emission + transfer manifest authoring. Optional so existing tests can
1929
+ * omit it; production runner always provides.
1930
+ */
1931
+ daemonId?: string;
1879
1932
  /**
1880
1933
  * Multi-workspace asset metadata indexes for #filename resolution.
1881
1934
  * Keyed by workspaceId. If absent, #ref resolution is skipped entirely.
@@ -2078,6 +2131,40 @@ interface LocalServerOptions {
2078
2131
  * When set, /healthz reports `assetReady: true`.
2079
2132
  */
2080
2133
  attachAsset?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2134
+ /**
2135
+ * Optional first-pass handler for `/v1/hooks/*` routes (v2.1 §9.5
2136
+ * daemon-as-hook-intake). Returns true if the request was handled
2137
+ * (response written); false to let the normal route table fall through.
2138
+ * Wired by the daemon runner from `attachHookServer()` in
2139
+ * `daemon/memory/hook-server.ts` whenever both memory + run-session
2140
+ * registry are available. When set, /healthz reports `hooksReady: true`.
2141
+ */
2142
+ attachHooks?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2143
+ /**
2144
+ * Optional first-pass handler for `/v1/checkpoints/*` routes
2145
+ * (release201/09 §9.4a.7 task product self-check). Independent of
2146
+ * `attachHooks` — checkpoints fire on SDK status-transition only, while
2147
+ * hooks fire per LLM call. Wired by the runner from
2148
+ * `attachCheckpointServer()` in `daemon/checkpoint-server.ts`. When set,
2149
+ * /healthz reports `checkpointsReady: true`.
2150
+ */
2151
+ attachCheckpoints?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2152
+ /**
2153
+ * Optional snapshot getter for the eval-session capability
2154
+ * (release201/08 §7.2). When provided, /healthz reports `evalSessions`
2155
+ * with the current active count + per-run summaries. The runner wires
2156
+ * this from `EvalSessionRunner.getState()`.
2157
+ */
2158
+ getEvalSessions?: () => {
2159
+ active: number;
2160
+ queued: number;
2161
+ maxConcurrent: number;
2162
+ runs: Array<{
2163
+ runId: string;
2164
+ skillId: string;
2165
+ startedAt: string;
2166
+ }>;
2167
+ };
2081
2168
  }
2082
2169
  interface AssetWriteHandlerResult {
2083
2170
  status: 200 | 400 | 502;
@@ -2292,6 +2379,7 @@ declare class Runner extends EventEmitter {
2292
2379
  private localServer?;
2293
2380
  private outboxWatcher?;
2294
2381
  private memoryWiring?;
2382
+ private runSessionRegistry?;
2295
2383
  private assetMetadataIndexes;
2296
2384
  private workspaceMirrors;
2297
2385
  private assetOriginOutbox?;
@@ -2307,16 +2395,28 @@ declare class Runner extends EventEmitter {
2307
2395
  private workspaceId;
2308
2396
  private wsConnected;
2309
2397
  private readonly hostedAgents;
2398
+ private readonly rejectedHostedAgentIds;
2310
2399
  private readonly runningTasks;
2311
2400
  private lastTaskError?;
2312
2401
  private heartbeatTimer?;
2313
2402
  private taskReaperTimer?;
2314
2403
  private skillResyncTimer?;
2315
2404
  private skillSyncInFlight;
2405
+ private resumeInFlightTimer?;
2406
+ private resumeInFlightDone;
2316
2407
  private pendingReplyCache;
2317
2408
  private pendingReplyRecoveryDone;
2318
2409
  constructor(opts?: RunnerOptions);
2319
2410
  start(): Promise<void>;
2411
+ /**
2412
+ * v2.1 §9.5 — build a ProfileResolver backed by the daemon's local
2413
+ * `agent_profiles` mirror. Used by the hook server to translate
2414
+ * `?profile=<name>` query into agentImUserId + workspaceId + role slug
2415
+ * when the run-session registry doesn't yet have the run mapping
2416
+ * (e.g. for the very first pre_llm_call of a session, before the
2417
+ * adapter has had a chance to call register()).
2418
+ */
2419
+ private buildProfileResolver;
2320
2420
  /**
2321
2421
  * F16 (2026-05-20) — enumerate every non-deleted local agent_profile and
2322
2422
  * fan-out `syncInstalledSkillsForDispatch` via `syncAllAgentSkills`.
@@ -2326,6 +2426,33 @@ declare class Runner extends EventEmitter {
2326
2426
  private syncAllSkillsBackground;
2327
2427
  /** F16 — read all live agent_profiles from local DB → AgentProfile[]. */
2328
2428
  private loadAllProfiles;
2429
+ /**
2430
+ * P0-2 (2026-05-25) — daemon cold-start sweep.
2431
+ *
2432
+ * Pulls `IMTaskRun.status='running'` rows where the bound daemon (via
2433
+ * `IMAgentBinding.boundDaemonId`) is this daemon, then re-enqueues each
2434
+ * via the same `onTaskDispatch` handler the ws path uses. Replaces the
2435
+ * slow (~5min) cloud-side `sweepTimedOut()` fallback for pod restarts.
2436
+ *
2437
+ * Idempotent on the daemon side: `onTaskDispatch` dedupes by taskId
2438
+ * against `runningTasks`, so any task that happened to be redispatched
2439
+ * from cloud immediately after our reconnect (via redispatchPending on
2440
+ * the agent.host.declare path) won't double-trigger here.
2441
+ *
2442
+ * Caveat: if the agent was mid-LLM-call when the daemon crashed, the
2443
+ * resumed dispatch starts the call from scratch — token cost duplicated.
2444
+ * We accept that vs the alternative (5min of silence + cloud marks the
2445
+ * run `failed` without any retry).
2446
+ */
2447
+ private resumeInFlightTasks;
2448
+ /**
2449
+ * Rebuild a `task.dispatch.request` payload from an in-flight IMTaskRun
2450
+ * row + its parent IMTask. Mirrors what cloud-side
2451
+ * v19x-helpers.buildTaskDispatchRequest does, with one extra field:
2452
+ * `metadata.resumed = true` so downstream prompt injection can note
2453
+ * this is a recovery dispatch.
2454
+ */
2455
+ private reconstructDispatchPayload;
2329
2456
  stop(): Promise<void>;
2330
2457
  isRunning(): boolean;
2331
2458
  /**
@@ -2417,6 +2544,7 @@ declare class Runner extends EventEmitter {
2417
2544
  */
2418
2545
  private onWebhookDispatch;
2419
2546
  private onHostAcked;
2547
+ private applyHostAckOwnershipLock;
2420
2548
  private onTaskDispatch;
2421
2549
  private onTaskCancel;
2422
2550
  private findMessageDispatchAgent;
@@ -2543,13 +2671,13 @@ declare const CCConfigSchema: z.ZodObject<{
2543
2671
  args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2544
2672
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2545
2673
  }, "strip", z.ZodTypeAny, {
2546
- name: string;
2547
2674
  command: string;
2675
+ name: string;
2548
2676
  env?: Record<string, string> | undefined;
2549
2677
  args?: string[] | undefined;
2550
2678
  }, {
2551
- name: string;
2552
2679
  command: string;
2680
+ name: string;
2553
2681
  env?: Record<string, string> | undefined;
2554
2682
  args?: string[] | undefined;
2555
2683
  }>, "many">>;
@@ -2564,8 +2692,8 @@ declare const CCConfigSchema: z.ZodObject<{
2564
2692
  maxTurns: number;
2565
2693
  route: "default" | "prismer" | "omniroute";
2566
2694
  mcpServers?: {
2567
- name: string;
2568
2695
  command: string;
2696
+ name: string;
2569
2697
  env?: Record<string, string> | undefined;
2570
2698
  args?: string[] | undefined;
2571
2699
  }[] | undefined;
@@ -2578,8 +2706,8 @@ declare const CCConfigSchema: z.ZodObject<{
2578
2706
  cwd: string;
2579
2707
  model?: string | undefined;
2580
2708
  mcpServers?: {
2581
- name: string;
2582
2709
  command: string;
2710
+ name: string;
2583
2711
  env?: Record<string, string> | undefined;
2584
2712
  args?: string[] | undefined;
2585
2713
  }[] | undefined;
@@ -2646,4 +2774,4 @@ declare const codexAdapter: AdapterDef;
2646
2774
  declare function buildProgram(): Command;
2647
2775
  declare function runCli(argv?: string[]): Promise<void>;
2648
2776
 
2649
- 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 UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
2777
+ 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 RejectedHostedAgent, 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 UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
package/dist/index.d.ts CHANGED
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
21
21
  platform: 'darwin' | 'linux' | 'win32';
22
22
  agents: HostedAgentDeclaration[];
23
23
  }
24
+ interface RejectedHostedAgent {
25
+ imUserId: string;
26
+ reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
27
+ ownerDaemonId?: string;
28
+ }
24
29
  interface HostAckedPayload {
25
30
  workspaceId: string;
26
31
  syncCursor: {
@@ -32,6 +37,8 @@ interface HostAckedPayload {
32
37
  /** Profile IDs the daemon declared but that no longer exist on the cloud
33
38
  * (soft-deleted). The daemon should remove these from its local store. */
34
39
  profilesToDelete: string[];
40
+ acceptedAgents?: string[];
41
+ rejectedAgents?: RejectedHostedAgent[];
35
42
  }
36
43
  interface AgentStatusChangedPayload {
37
44
  agentImUserId: string;
@@ -123,6 +130,15 @@ interface TaskDispatchRequestPayload {
123
130
  }>;
124
131
  /** Wave-8 W1: assets cloud wants daemon to fold into agent context. */
125
132
  assetRefs?: AssetRef[];
133
+ /**
134
+ * release201/09 Phase 2 — task project scope. NULL = workspace-level
135
+ * (`_unscoped` sentinel on disk). Daemon uses this together with
136
+ * `agentImUserId` / `profile.workspaceId` to compose the per-task
137
+ * scratch path: `workspaces/<wid>/projects/<pid|_unscoped>/tasks/<tid>/`.
138
+ * Also forwarded into the spawned agent process as `PRISMER_ACTIVE_PROJECT_ID`
139
+ * (when non-null) so built-in skill --project flag defaults work.
140
+ */
141
+ projectId?: string | null;
126
142
  }
127
143
  interface TaskDispatchProgressPayload {
128
144
  taskId: string;
@@ -148,6 +164,20 @@ interface AssetDispatchObservation {
148
164
  /** L5: end-to-end fetch duration in ms (DNS + connect + body read). */
149
165
  durationMs?: number;
150
166
  }
167
+ /**
168
+ * P1-2 (2026-05-25): per-file outbox rejection record. Surfaced when daemon's
169
+ * `outbox-watcher` rejects an artifact because its magic bytes don't match
170
+ * the file extension (e.g. agent wrote `report.pdf` with markdown content).
171
+ * Cloud persists these on `IMTask.metadata.outboxRejections` and prepends a
172
+ * warning section to the next dispatch prompt so the agent can self-correct.
173
+ */
174
+ interface OutboxRejectionRecord {
175
+ filename: string;
176
+ reason: string;
177
+ inferredMime: string;
178
+ detectedMime: string;
179
+ rejectedAt: string;
180
+ }
151
181
  interface TaskDispatchReplyPayload {
152
182
  taskId: string;
153
183
  ok: boolean;
@@ -163,6 +193,13 @@ interface TaskDispatchReplyPayload {
163
193
  };
164
194
  /** Wave-8 W1: per-asset handling report. */
165
195
  assetObservability?: AssetDispatchObservation[];
196
+ /**
197
+ * P1-2 (2026-05-25): files quarantined locally by outbox-watcher's
198
+ * magic-bytes check during this turn. Cloud writes them onto
199
+ * `IMTask.metadata.outboxRejections` so the next dispatch prompt can warn
200
+ * the agent.
201
+ */
202
+ outboxRejections?: OutboxRejectionRecord[];
166
203
  }
167
204
  interface TaskCancelPayload {
168
205
  taskId: string;
@@ -670,12 +707,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
670
707
  * native state key directly and records the exact bridge result on the task.
671
708
  */
672
709
  mirrorNativeGoals: z.ZodDefault<z.ZodBoolean>;
673
- /**
674
- * Optional checkout path for Hermes Agent source. Used only as a fallback
675
- * when the installed `hermes` binary is older than the native Kanban CLI
676
- * surface but the local source tree contains hermes_cli/kanban_db.py.
677
- */
678
- hermesSourceDir: z.ZodOptional<z.ZodString>;
679
710
  nativeMirrorTimeoutMs: z.ZodDefault<z.ZodNumber>;
680
711
  /** Task authority level: executor (default) or orchestrator. */
681
712
  taskAuthority: z.ZodDefault<z.ZodOptional<z.ZodEnum<["executor", "orchestrator"]>>>;
@@ -775,7 +806,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
775
806
  hermesProfileName?: string | undefined;
776
807
  prismerMcpServerPath?: string | undefined;
777
808
  prismerProviderBaseUrl?: string | undefined;
778
- hermesSourceDir?: string | undefined;
779
809
  mcpAllowlist?: string[] | null | undefined;
780
810
  operatingPrinciples?: string | Record<string, string> | z.objectOutputType<{
781
811
  source: z.ZodString;
@@ -816,7 +846,6 @@ declare const HermesProfileConfigSchema: z.ZodObject<{
816
846
  prismerApiKeyEnv?: string | undefined;
817
847
  mirrorNativeKanban?: boolean | undefined;
818
848
  mirrorNativeGoals?: boolean | undefined;
819
- hermesSourceDir?: string | undefined;
820
849
  nativeMirrorTimeoutMs?: number | undefined;
821
850
  taskAuthority?: "executor" | "orchestrator" | undefined;
822
851
  approvalPolicy?: "strict" | "auto-low-risk" | "autonomous" | undefined;
@@ -987,7 +1016,7 @@ type LocalDb = Database.Database;
987
1016
  declare function openLocalDb(path: string): LocalDb;
988
1017
  declare function runMigrations(db: LocalDb): void;
989
1018
  declare function currentSchemaVersion(db: LocalDb): number;
990
- declare const TARGET_SCHEMA_VERSION = 4;
1019
+ declare const TARGET_SCHEMA_VERSION = 5;
991
1020
 
992
1021
  type SyncResourceType = 'workspace' | 'agent' | 'agent_profile';
993
1022
  type SyncOperation = 'create' | 'update' | 'delete';
@@ -1184,11 +1213,28 @@ interface ConfigPaths {
1184
1213
  cacheDir: string;
1185
1214
  logsDir: string;
1186
1215
  /**
1187
- * Per-task run scratch dirs. Each chat-mention dispatch creates
1188
- * `${runsDir}/${taskId}/_outbox/` for adapter-produced files; the
1189
- * OutboxWatcher uploads from there into IMAssets.
1216
+ * Legacy per-task run scratch dirs (pre-release201/09).
1217
+ *
1218
+ * Pre-09: `${runsDir}/${taskId}/_outbox|workdir/`.
1219
+ * 09 Phase 2: dispatch.ts now writes to
1220
+ * `${root}/workspaces/<wid>/projects/<pid|_unscoped>/tasks/<tid>/{result,workdir}`
1221
+ * via `resolveTaskWorkdir()`. `runsDir` is kept as a fallback for tests + a
1222
+ * once-off startup migration helper (`runs/<tid>/` → new path; symlink 兜底
1223
+ * 90 天兼容期, §9.3.1).
1190
1224
  */
1191
1225
  runsDir: string;
1226
+ /**
1227
+ * release201/09 Phase 2 root for workspace × project × task scoped scratch:
1228
+ * `${root}/workspaces/`. resolveTaskWorkdir() composes the per-task path
1229
+ * underneath. Cache GC + project archive scan this root.
1230
+ */
1231
+ workspacesDir: string;
1232
+ /**
1233
+ * release201/09 Phase 2 root for device × agent role layer:
1234
+ * `${root}/devices/`. v2.0.7 Phase 2 不主动创建,Phase 3 (agent transfer)
1235
+ * 才落盘 `profile.json` / `skills/<slug>/` 等内容,本 helper 只解析路径。
1236
+ */
1237
+ devicesDir: string;
1192
1238
  }
1193
1239
  /**
1194
1240
  * Resolve paths for the prismer home directory. Honors `PRISMER_HOME` env var;
@@ -1876,6 +1922,13 @@ interface DispatchDeps {
1876
1922
  outboxWatcher?: OutboxWatcher;
1877
1923
  /** Daemon paths — used to derive the per-task outbox dir. */
1878
1924
  paths?: ConfigPaths;
1925
+ /**
1926
+ * release201/09 §9.9 — Stable device identifier from `config.toml`. Surfaced
1927
+ * to the spawned agent process as `PRISMER_DAEMON_ID` env for metric-outbox
1928
+ * emission + transfer manifest authoring. Optional so existing tests can
1929
+ * omit it; production runner always provides.
1930
+ */
1931
+ daemonId?: string;
1879
1932
  /**
1880
1933
  * Multi-workspace asset metadata indexes for #filename resolution.
1881
1934
  * Keyed by workspaceId. If absent, #ref resolution is skipped entirely.
@@ -2078,6 +2131,40 @@ interface LocalServerOptions {
2078
2131
  * When set, /healthz reports `assetReady: true`.
2079
2132
  */
2080
2133
  attachAsset?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2134
+ /**
2135
+ * Optional first-pass handler for `/v1/hooks/*` routes (v2.1 §9.5
2136
+ * daemon-as-hook-intake). Returns true if the request was handled
2137
+ * (response written); false to let the normal route table fall through.
2138
+ * Wired by the daemon runner from `attachHookServer()` in
2139
+ * `daemon/memory/hook-server.ts` whenever both memory + run-session
2140
+ * registry are available. When set, /healthz reports `hooksReady: true`.
2141
+ */
2142
+ attachHooks?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2143
+ /**
2144
+ * Optional first-pass handler for `/v1/checkpoints/*` routes
2145
+ * (release201/09 §9.4a.7 task product self-check). Independent of
2146
+ * `attachHooks` — checkpoints fire on SDK status-transition only, while
2147
+ * hooks fire per LLM call. Wired by the runner from
2148
+ * `attachCheckpointServer()` in `daemon/checkpoint-server.ts`. When set,
2149
+ * /healthz reports `checkpointsReady: true`.
2150
+ */
2151
+ attachCheckpoints?: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
2152
+ /**
2153
+ * Optional snapshot getter for the eval-session capability
2154
+ * (release201/08 §7.2). When provided, /healthz reports `evalSessions`
2155
+ * with the current active count + per-run summaries. The runner wires
2156
+ * this from `EvalSessionRunner.getState()`.
2157
+ */
2158
+ getEvalSessions?: () => {
2159
+ active: number;
2160
+ queued: number;
2161
+ maxConcurrent: number;
2162
+ runs: Array<{
2163
+ runId: string;
2164
+ skillId: string;
2165
+ startedAt: string;
2166
+ }>;
2167
+ };
2081
2168
  }
2082
2169
  interface AssetWriteHandlerResult {
2083
2170
  status: 200 | 400 | 502;
@@ -2292,6 +2379,7 @@ declare class Runner extends EventEmitter {
2292
2379
  private localServer?;
2293
2380
  private outboxWatcher?;
2294
2381
  private memoryWiring?;
2382
+ private runSessionRegistry?;
2295
2383
  private assetMetadataIndexes;
2296
2384
  private workspaceMirrors;
2297
2385
  private assetOriginOutbox?;
@@ -2307,16 +2395,28 @@ declare class Runner extends EventEmitter {
2307
2395
  private workspaceId;
2308
2396
  private wsConnected;
2309
2397
  private readonly hostedAgents;
2398
+ private readonly rejectedHostedAgentIds;
2310
2399
  private readonly runningTasks;
2311
2400
  private lastTaskError?;
2312
2401
  private heartbeatTimer?;
2313
2402
  private taskReaperTimer?;
2314
2403
  private skillResyncTimer?;
2315
2404
  private skillSyncInFlight;
2405
+ private resumeInFlightTimer?;
2406
+ private resumeInFlightDone;
2316
2407
  private pendingReplyCache;
2317
2408
  private pendingReplyRecoveryDone;
2318
2409
  constructor(opts?: RunnerOptions);
2319
2410
  start(): Promise<void>;
2411
+ /**
2412
+ * v2.1 §9.5 — build a ProfileResolver backed by the daemon's local
2413
+ * `agent_profiles` mirror. Used by the hook server to translate
2414
+ * `?profile=<name>` query into agentImUserId + workspaceId + role slug
2415
+ * when the run-session registry doesn't yet have the run mapping
2416
+ * (e.g. for the very first pre_llm_call of a session, before the
2417
+ * adapter has had a chance to call register()).
2418
+ */
2419
+ private buildProfileResolver;
2320
2420
  /**
2321
2421
  * F16 (2026-05-20) — enumerate every non-deleted local agent_profile and
2322
2422
  * fan-out `syncInstalledSkillsForDispatch` via `syncAllAgentSkills`.
@@ -2326,6 +2426,33 @@ declare class Runner extends EventEmitter {
2326
2426
  private syncAllSkillsBackground;
2327
2427
  /** F16 — read all live agent_profiles from local DB → AgentProfile[]. */
2328
2428
  private loadAllProfiles;
2429
+ /**
2430
+ * P0-2 (2026-05-25) — daemon cold-start sweep.
2431
+ *
2432
+ * Pulls `IMTaskRun.status='running'` rows where the bound daemon (via
2433
+ * `IMAgentBinding.boundDaemonId`) is this daemon, then re-enqueues each
2434
+ * via the same `onTaskDispatch` handler the ws path uses. Replaces the
2435
+ * slow (~5min) cloud-side `sweepTimedOut()` fallback for pod restarts.
2436
+ *
2437
+ * Idempotent on the daemon side: `onTaskDispatch` dedupes by taskId
2438
+ * against `runningTasks`, so any task that happened to be redispatched
2439
+ * from cloud immediately after our reconnect (via redispatchPending on
2440
+ * the agent.host.declare path) won't double-trigger here.
2441
+ *
2442
+ * Caveat: if the agent was mid-LLM-call when the daemon crashed, the
2443
+ * resumed dispatch starts the call from scratch — token cost duplicated.
2444
+ * We accept that vs the alternative (5min of silence + cloud marks the
2445
+ * run `failed` without any retry).
2446
+ */
2447
+ private resumeInFlightTasks;
2448
+ /**
2449
+ * Rebuild a `task.dispatch.request` payload from an in-flight IMTaskRun
2450
+ * row + its parent IMTask. Mirrors what cloud-side
2451
+ * v19x-helpers.buildTaskDispatchRequest does, with one extra field:
2452
+ * `metadata.resumed = true` so downstream prompt injection can note
2453
+ * this is a recovery dispatch.
2454
+ */
2455
+ private reconstructDispatchPayload;
2329
2456
  stop(): Promise<void>;
2330
2457
  isRunning(): boolean;
2331
2458
  /**
@@ -2417,6 +2544,7 @@ declare class Runner extends EventEmitter {
2417
2544
  */
2418
2545
  private onWebhookDispatch;
2419
2546
  private onHostAcked;
2547
+ private applyHostAckOwnershipLock;
2420
2548
  private onTaskDispatch;
2421
2549
  private onTaskCancel;
2422
2550
  private findMessageDispatchAgent;
@@ -2543,13 +2671,13 @@ declare const CCConfigSchema: z.ZodObject<{
2543
2671
  args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2544
2672
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2545
2673
  }, "strip", z.ZodTypeAny, {
2546
- name: string;
2547
2674
  command: string;
2675
+ name: string;
2548
2676
  env?: Record<string, string> | undefined;
2549
2677
  args?: string[] | undefined;
2550
2678
  }, {
2551
- name: string;
2552
2679
  command: string;
2680
+ name: string;
2553
2681
  env?: Record<string, string> | undefined;
2554
2682
  args?: string[] | undefined;
2555
2683
  }>, "many">>;
@@ -2564,8 +2692,8 @@ declare const CCConfigSchema: z.ZodObject<{
2564
2692
  maxTurns: number;
2565
2693
  route: "default" | "prismer" | "omniroute";
2566
2694
  mcpServers?: {
2567
- name: string;
2568
2695
  command: string;
2696
+ name: string;
2569
2697
  env?: Record<string, string> | undefined;
2570
2698
  args?: string[] | undefined;
2571
2699
  }[] | undefined;
@@ -2578,8 +2706,8 @@ declare const CCConfigSchema: z.ZodObject<{
2578
2706
  cwd: string;
2579
2707
  model?: string | undefined;
2580
2708
  mcpServers?: {
2581
- name: string;
2582
2709
  command: string;
2710
+ name: string;
2583
2711
  env?: Record<string, string> | undefined;
2584
2712
  args?: string[] | undefined;
2585
2713
  }[] | undefined;
@@ -2646,4 +2774,4 @@ declare const codexAdapter: AdapterDef;
2646
2774
  declare function buildProgram(): Command;
2647
2775
  declare function runCli(argv?: string[]): Promise<void>;
2648
2776
 
2649
- 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 UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
2777
+ 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 RejectedHostedAgent, 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 UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };