@nowcrew/daemon 0.6.18 → 0.6.20

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.
Files changed (37) hide show
  1. package/dist/atomic-no-replace-rename.js +91 -0
  2. package/dist/control-plane-url.js +4 -2
  3. package/dist/directory-projection-publication.js +105 -0
  4. package/dist/directory-projection.js +20 -4
  5. package/dist/execution-journal.js +40 -4
  6. package/dist/execution-posix-stop-proof.js +82 -0
  7. package/dist/execution-runner.js +68 -8
  8. package/dist/local-executor.js +73 -52
  9. package/dist/machine-info.js +8 -5
  10. package/dist/project-skills/capability.js +109 -0
  11. package/dist/project-skills/controller-convergence.js +57 -0
  12. package/dist/project-skills/controller.js +80 -24
  13. package/dist/project-skills/initialized-reconciler.js +4 -4
  14. package/dist/project-skills/projection-state-domain.js +19 -2
  15. package/dist/project-skills/projection-state-store.js +3 -2
  16. package/dist/project-skills/projection-state-transaction.js +5 -1
  17. package/dist/project-skills/projection-state.js +1 -1
  18. package/dist/project-skills/reconciler.js +275 -102
  19. package/dist/project-skills/runtime-launch.js +102 -0
  20. package/dist/project-skills/runtime-root-bootstrap.js +47 -0
  21. package/dist/project-skills/runtime-root-domain.js +268 -0
  22. package/dist/project-skills/runtime-root-gc.js +293 -0
  23. package/dist/project-skills/runtime-root-lease-artifact.js +46 -0
  24. package/dist/project-skills/runtime-root-leases.js +487 -0
  25. package/dist/project-skills/runtime-root-source-identity.js +60 -0
  26. package/dist/project-skills/runtime-root-startup.js +49 -0
  27. package/dist/project-skills/runtime-root-state-artifact-domain.js +143 -0
  28. package/dist/project-skills/runtime-root-state-index.js +356 -0
  29. package/dist/project-skills/runtime-root-store.js +722 -0
  30. package/dist/project-skills/serve-capability.js +28 -0
  31. package/dist/project-skills/serve-startup.js +22 -0
  32. package/dist/project-skills/types.js +1 -0
  33. package/dist/provider-env.js +3 -0
  34. package/dist/runtimes/codex-home.js +50 -0
  35. package/dist/serve.js +58 -73
  36. package/dist/supervised-runtime.js +1 -5
  37. package/package.json +2 -2
@@ -0,0 +1,28 @@
1
+ import { WebSocket } from "ws";
2
+ import { daemonCapabilityBindings, } from "../machine-info.js";
3
+ import { prepareProjectSkillConnectionCapabilities, } from "./capability.js";
4
+ export function createProjectSkillConnectionCapabilityProvider(input) {
5
+ return async () => daemonCapabilityBindings(input.platform, await prepareProjectSkillConnectionCapabilities(input));
6
+ }
7
+ export function createProjectSkillMachineHelloPublisher(input) {
8
+ let latest = null;
9
+ let latestSocket = null;
10
+ const republish = () => {
11
+ if (latest === null || latestSocket?.readyState !== WebSocket.OPEN)
12
+ return;
13
+ const hello = input.effective(latest, input.status());
14
+ try {
15
+ latestSocket.send(JSON.stringify(hello));
16
+ input.onSent(hello);
17
+ }
18
+ catch { /* 非 OPEN,忽略 */ }
19
+ };
20
+ return Object.freeze({
21
+ publish: (hello, socket) => {
22
+ latest = hello;
23
+ latestSocket = socket;
24
+ republish();
25
+ },
26
+ republish,
27
+ });
28
+ }
@@ -0,0 +1,22 @@
1
+ import { createExecutionJournal } from "../execution-journal.js";
2
+ import { reconcileExecutionJournal } from "../execution-recovery.js";
3
+ import { dslog, flushSlog } from "../slog.js";
4
+ export async function initializeProjectSkillProtectedExecutionJournal(input) {
5
+ return input.startup.initializeAfterLeaseProtection(input.config.agentsRoot, async (snapshot) => {
6
+ input.protectedExecutionIds.clear();
7
+ for (const executionId of snapshot)
8
+ input.protectedExecutionIds.add(executionId);
9
+ const journal = input.injectedJournal ?? createExecutionJournal(input.config.agentsRoot, {
10
+ protectedExecutionIds: () => input.protectedExecutionIds,
11
+ });
12
+ await reconcileExecutionJournal(journal, {
13
+ agentsRoot: input.config.agentsRoot,
14
+ serverUrl: input.config.serverUrl,
15
+ ...(input.profileName === undefined ? {} : { profileName: input.profileName }),
16
+ log: dslog,
17
+ flush: flushSlog,
18
+ writeStderr: (line) => process.stderr.write(line),
19
+ });
20
+ return journal;
21
+ });
22
+ }
@@ -1,4 +1,5 @@
1
1
  export const PROJECT_SKILLS_CAPABILITY = "project_skills_v1";
2
+ export const PROJECT_SKILL_PROJECTION_V2_CAPABILITY = "project_skill_projection_v2";
2
3
  export const MAX_PROJECT_ID_LENGTH = 64;
3
4
  export const MAX_PROJECT_SKILL_NAME_LENGTH = 128;
4
5
  export const MAX_PROJECT_SKILL_DESCRIPTION_LENGTH = 1_000;
@@ -49,6 +49,9 @@ export function applyProviderEnv(base, runtime, cfg, homeDir) {
49
49
  env[DEEPSEEK_CODEX_KEY_ENV] = cfg.providerApiKey;
50
50
  return env;
51
51
  }
52
+ if (runtime === "codex") {
53
+ return { ...base, CODEX_HOME: join(homeDir, ".codex") };
54
+ }
52
55
  if (runtime !== "claude" || cfg.provider !== "custom")
53
56
  return base;
54
57
  const env = { ...base };
@@ -0,0 +1,50 @@
1
+ import { chmod, lstat, mkdir, symlink } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ const PRIVATE_CODEX_HOME = ".codex";
4
+ const SHARED_CODEX_ENTRIES = [
5
+ { name: "auth.json", type: "file" },
6
+ { name: "sessions", type: "dir" },
7
+ { name: "session_index.jsonl", type: "file" },
8
+ ];
9
+ export function defaultCodexHome(homeDir) {
10
+ return resolve(homeDir, PRIVATE_CODEX_HOME);
11
+ }
12
+ async function linkIfMissing(source, target, type) {
13
+ try {
14
+ await lstat(target);
15
+ return;
16
+ }
17
+ catch (error) {
18
+ if (error.code !== "ENOENT")
19
+ throw error;
20
+ }
21
+ try {
22
+ await lstat(source);
23
+ }
24
+ catch (error) {
25
+ if (error.code === "ENOENT")
26
+ return;
27
+ throw error;
28
+ }
29
+ try {
30
+ await symlink(source, target, type);
31
+ }
32
+ catch (error) {
33
+ if (error.code !== "EEXIST")
34
+ throw error;
35
+ }
36
+ }
37
+ /**
38
+ * Isolate Codex's high-volume runtime state per Agent while preserving the
39
+ * machine login and native resume files used by existing sessions.
40
+ */
41
+ export async function materializeDefaultCodexHome(agentHome, sourceHome) {
42
+ const codexHome = defaultCodexHome(agentHome);
43
+ await mkdir(codexHome, { recursive: true, mode: 0o700 });
44
+ await chmod(codexHome, 0o700);
45
+ const source = sourceHome === undefined ? null : resolve(sourceHome);
46
+ if (source === null || source === codexHome)
47
+ return codexHome;
48
+ await Promise.all(SHARED_CODEX_ENTRIES.map(({ name, type }) => linkIfMissing(join(source, name), join(codexHome, name), type)));
49
+ return codexHome;
50
+ }
package/dist/serve.js CHANGED
@@ -8,7 +8,7 @@ import { randomUUID } from "node:crypto";
8
8
  import { initSlog, dslog, setSlogDefaults, drainSpool, flushSlog } from "./slog.js";
9
9
  import { mergeRunAgentResults, reportScheduledStartFailure, runAgent } from "./runner.js";
10
10
  import { buildOriginDecisionRetryPrompt, buildScheduledPrompt } from "./prompt.js";
11
- import { collectMachineHello, cliVersion, daemonCapabilityBindings, daemonVersion, detectExecutionRuntimesWithSignal, } from "./machine-info.js";
11
+ import { collectMachineHello, cliVersion, daemonCapabilities, daemonVersion, detectExecutionRuntimesWithSignal, } from "./machine-info.js";
12
12
  import { conservativeExecutionRuntimes, createRuntimeProbeCoordinator, } from "./runtime-probe.js";
13
13
  import { listWorkspace, readWorkspaceFile } from "./workspace-fs.js";
14
14
  import { listSkills } from "./skills.js";
@@ -18,14 +18,12 @@ import { normalizeScheduledContext } from "./scheduled-report.js";
18
18
  import { formatDaemonLogLine } from "./log-format.js";
19
19
  import { reportAgentRunComplete } from "./scheduled-run-report.js";
20
20
  import { runWithOriginDecisionGuard } from "./origin-decision.js";
21
- import { createExecutionJournal } from "./execution-journal.js";
22
21
  import { createExecutionTelemetryJournal } from "./execution-telemetry-journal.js";
23
22
  import { ExecutionRejectedSchema, ExecutionSnapshotSchema, LegacyAgentStartSchema, ServerToDaemonExecutionFrameSchema, } from "./execution-protocol.js";
24
23
  import { hashExecutionSpec, projectWorkspaceCapabilityRejection, runExecution, } from "./execution-runner.js";
25
24
  import { awaitWithCancellation, createRuntimeCancellation, RuntimeCancelledError, } from "./runtime-cancellation.js";
26
25
  import { createShutdownDeadline, readTestShutdownConfiguration } from "./shutdown-deadline.js";
27
26
  import { closeWebSocketWithinDeadline } from "./websocket-shutdown.js";
28
- import { reconcileExecutionJournal } from "./execution-recovery.js";
29
27
  import { createSharedSlotManager } from "./shared-execution-slots.js";
30
28
  import { createCompletionRetransmitter } from "./completion-retransmitter.js";
31
29
  import { createAgentMemoryBridge } from "./agent-memory/bridge.js";
@@ -39,6 +37,10 @@ import { createProjectRegistry } from "./project-skills/registry.js";
39
37
  import { createProjectSkillsController, } from "./project-skills/controller.js";
40
38
  import { PROJECT_SKILLS_CAPABILITY } from "./project-skills/types.js";
41
39
  import { createAgentProjectionCoordinator } from "./project-skills/agent-projection-coordinator.js";
40
+ import { createProjectSkillRuntimeRootStartup, } from "./project-skills/runtime-root-startup.js";
41
+ import { createProjectSkillControllerReadiness, withProjectSkillCapabilityStatus } from "./project-skills/capability.js";
42
+ import { initializeProjectSkillProtectedExecutionJournal } from "./project-skills/serve-startup.js";
43
+ import { createProjectSkillConnectionCapabilityProvider, createProjectSkillMachineHelloPublisher } from "./project-skills/serve-capability.js";
42
44
  import { createAgentAbilityRuntime } from "./agent-ability/runtime.js";
43
45
  import { createProjectSkillsReconciler, } from "./project-skills/reconciler.js";
44
46
  import { initializedProjectSkillsReconciler } from "./project-skills/initialized-reconciler.js";
@@ -65,7 +67,9 @@ export function serve(config, opts = {}) {
65
67
  const createWebSocket = opts.createWebSocket ?? ((url) => new WebSocket(url));
66
68
  let reconnectTimer = null;
67
69
  let stopPromise = null;
68
- const executionJournal = opts.execution?.journal ?? createExecutionJournal(config.agentsRoot);
70
+ let executionJournal;
71
+ const injectedExecutionJournal = opts.execution?.journal;
72
+ const protectedExecutionIds = new Set();
69
73
  const agentMemory = opts.execution?.dependencies?.agentMemory
70
74
  ?? (config.agentMemory === null ? undefined : createAgentMemoryBridge(config.agentMemory));
71
75
  const executionTelemetry = createExecutionTelemetryJournal(config.agentsRoot);
@@ -126,6 +130,7 @@ export function serve(config, opts = {}) {
126
130
  agentsRoot: config.agentsRoot,
127
131
  coordinator: projectionCoordinator,
128
132
  scannedProjects: () => projectSkillsController.scannedProjects(),
133
+ protectedExecutionIds,
129
134
  });
130
135
  projectSkillsController = opts.projectSkills?.controller ?? createProjectSkillsController({
131
136
  registry: createProjectRegistry(config.agentsRoot),
@@ -139,53 +144,34 @@ export function serve(config, opts = {}) {
139
144
  catch { /* 下一次 ready 或项目操作会重新发送完整快照 */ }
140
145
  },
141
146
  reconcile: (handle, bindings) => projectSkillsReconciler.reconcile(handle, bindings),
142
- ensureSnapshot: (handle, snapshot) => projectSkillsReconciler.ensureSnapshot(handle, snapshot),
147
+ ensureSnapshot: (handle, snapshot, options) => projectSkillsReconciler.ensureSnapshot(handle, snapshot, options),
143
148
  });
144
- let projectSkillsStatus = "initializing";
145
- let projectSkillsInitialization = null;
146
- let latestMachineHello = null;
147
- let latestHelloSocket = null;
148
- const effectiveMachineHello = (hello) => ({
149
- ...hello,
150
- projectSkillsStatus,
151
- capabilities: projectSkillsStatus === "ready"
152
- ? hello.capabilities
153
- : hello.capabilities.filter((capability) => capability !== PROJECT_SKILLS_CAPABILITY),
149
+ const projectSkillRuntimeRootStartup = opts.projectSkills?.runtimeRootStartup
150
+ ?? createProjectSkillRuntimeRootStartup();
151
+ const projectSkillControllerReadiness = createProjectSkillControllerReadiness({
152
+ initialize: () => projectSkillsController.initialize(),
153
+ onUnavailable: (error) => dslog("project_skills.registry_failed", "本机项目注册表读取失败", {
154
+ level: "ERROR", error_code: error.code ?? "project_registry_corrupt",
155
+ }),
156
+ onSettled: () => machineHelloPublisher.republish(),
157
+ });
158
+ const machineHelloPublisher = createProjectSkillMachineHelloPublisher({
159
+ status: projectSkillControllerReadiness.status,
160
+ effective: withProjectSkillCapabilityStatus,
161
+ onSent: (hello) => log(`📤 已上报机器信息: ${hello.hostname} · ${hello.os} · installed=[${hello.runtimes.join(",")}] · executable=[${hello.executionRuntimes.join(",")}] · agents=[${hello.agentHandles.join(",")}]`),
162
+ });
163
+ const initializedProjectSkills = initializedProjectSkillsReconciler(projectSkillControllerReadiness.ensure, projectSkillsReconciler);
164
+ const prepareProjectSkillCapabilities = createProjectSkillConnectionCapabilityProvider({
165
+ platform: process.platform,
166
+ baseCapabilities: opts.machineInfo?.capabilities ?? daemonCapabilities(process.platform),
167
+ additionalCapabilities: () => managedDaemonCapabilities(updateEligibility),
168
+ probeRuntimeRootStorePrimitive: projectSkillRuntimeRootStartup.probeNativePublicationPrimitiveReadiness,
169
+ initializeController: projectSkillControllerReadiness.ensure,
170
+ recoverRuntimeRootsAndLeases: async () => projectSkillRuntimeRootStartup
171
+ .recover(config.agentsRoot, executionJournal, protectedExecutionIds)
172
+ .then(() => true, () => false),
173
+ applyReadiness: projectSkillControllerReadiness.applyPreflight,
154
174
  });
155
- const sendEffectiveMachineHello = () => {
156
- if (latestMachineHello === null || latestHelloSocket?.readyState !== WebSocket.OPEN)
157
- return;
158
- const hello = effectiveMachineHello(latestMachineHello);
159
- try {
160
- latestHelloSocket.send(JSON.stringify(hello));
161
- log(`📤 已上报机器信息: ${hello.hostname} · ${hello.os} · installed=[${hello.runtimes.join(",")}] · executable=[${hello.executionRuntimes.join(",")}] · agents=[${hello.agentHandles.join(",")}]`);
162
- }
163
- catch { /* 非 OPEN,忽略 */ }
164
- };
165
- const ensureProjectSkillsInitialized = () => {
166
- if (projectSkillsStatus === "ready")
167
- return Promise.resolve(true);
168
- if (projectSkillsInitialization !== null)
169
- return projectSkillsInitialization;
170
- projectSkillsStatus = "initializing";
171
- const attempt = projectSkillsController.initialize().then(() => {
172
- projectSkillsStatus = "ready";
173
- return true;
174
- }, (error) => {
175
- projectSkillsStatus = "unavailable";
176
- dslog("project_skills.registry_failed", "本机项目注册表读取失败", {
177
- level: "ERROR", error_code: error.code ?? "project_registry_corrupt",
178
- });
179
- return false;
180
- }).finally(() => {
181
- if (projectSkillsInitialization === attempt)
182
- projectSkillsInitialization = null;
183
- sendEffectiveMachineHello();
184
- });
185
- projectSkillsInitialization = attempt;
186
- return attempt;
187
- };
188
- const initializedProjectSkills = initializedProjectSkillsReconciler(ensureProjectSkillsInitialized, projectSkillsReconciler);
189
175
  const safeExecutionSend = (frame) => {
190
176
  try {
191
177
  if (ws?.readyState !== WebSocket.OPEN)
@@ -283,7 +269,6 @@ export function serve(config, opts = {}) {
283
269
  reservation.release();
284
270
  };
285
271
  let connectedAt = 0; // 本次 WS 连接建立时刻(断开日志算在线时长用)
286
- const capabilities = daemonCapabilityBindings(process.platform, opts.machineInfo?.capabilities);
287
272
  initSlog(config.serverUrl, config.machineToken, { daemonVersion: daemonVersion(), cliVersion: cliVersion(), ...(opts.profileName === undefined ? {} : { profileName: opts.profileName }), agentsRoot: config.agentsRoot });
288
273
  dslog("daemon.start", "daemon 常驻模式启动", { server_url: config.serverUrl, runtime: config.runtimeBin });
289
274
  // 并行调度:同一 agent 可并行处理多个【不同任务】(线程/频道),每任务隔离 cwd+work-log。
@@ -293,12 +278,17 @@ export function serve(config, opts = {}) {
293
278
  const activeExecutionTaskKeys = new Map();
294
279
  const legacyTaskTails = new Map();
295
280
  const log = (s) => process.stdout.write(formatDaemonLogLine(s) + "\n");
296
- function connect() {
281
+ async function connect() {
297
282
  if (stopped)
298
283
  return;
299
- const wsUrl = buildControlPlaneUrl(config.serverUrl, config.machineToken, process.platform, undefined, projectSkillsStatus === "ready", capabilities.controlPlaneUrl);
284
+ const capabilities = await prepareProjectSkillCapabilities();
285
+ if (stopped)
286
+ return;
287
+ const wsUrl = (opts.buildControlPlaneUrl ?? buildControlPlaneUrl)(config.serverUrl, config.machineToken, process.platform, undefined, projectSkillControllerReadiness.status() === "ready", capabilities.controlPlaneUrl);
300
288
  ws = createWebSocket(wsUrl);
289
+ let connectionEpochToken;
301
290
  ws.on("open", () => {
291
+ connectionEpochToken = projectSkillsController.beginConnectionEpoch();
302
292
  const openedSocket = ws;
303
293
  backoff = 1000;
304
294
  connectedAt = Date.now();
@@ -308,12 +298,11 @@ export function serve(config, opts = {}) {
308
298
  void drainSpool();
309
299
  // 上报本机信息 (hostname/os/daemon 版本/已装 runtimes)
310
300
  const { detectInstalled, detectExecutable = detectExecutionRuntimesWithSignal } = opts.machineInfo ?? {};
311
- const helloPromise = collectMachineHello(config.agentsRoot, config.executionLimits, process.platform, {
301
+ const helloPromise = (opts.machineInfo?.collect ?? collectMachineHello)(config.agentsRoot, config.executionLimits, process.platform, {
312
302
  ...(detectInstalled ? { detectInstalled } : {}),
313
303
  ...(opts.profileName === undefined ? {} : { profileName: opts.profileName }),
314
304
  // First hello must not wait for third-party handshakes; optional transports arrive in the refresh.
315
305
  detectExecutable: async (installed) => conservativeExecutionRuntimes(installed),
316
- additionalCapabilities: () => managedDaemonCapabilities(updateEligibility),
317
306
  capabilities: capabilities.machineHello,
318
307
  });
319
308
  runtimeFacts = helloPromise
@@ -324,9 +313,7 @@ export function serve(config, opts = {}) {
324
313
  if (ws === openedSocket && openedSocket.readyState === WebSocket.OPEN
325
314
  && detected.some((runtime) => !hello.executionRuntimes.includes(runtime))) {
326
315
  detectedExecutionRuntimes = detected;
327
- latestMachineHello = { ...hello, executionRuntimes: [...detected] };
328
- latestHelloSocket = openedSocket;
329
- sendEffectiveMachineHello();
316
+ machineHelloPublisher.publish({ ...hello, executionRuntimes: [...detected] }, openedSocket);
330
317
  }
331
318
  return detected;
332
319
  })
@@ -341,9 +328,7 @@ export function serve(config, opts = {}) {
341
328
  if (ws !== openedSocket || openedSocket.readyState !== WebSocket.OPEN)
342
329
  return;
343
330
  detectedExecutionRuntimes = hello.executionRuntimes;
344
- latestMachineHello = hello;
345
- latestHelloSocket = openedSocket;
346
- sendEffectiveMachineHello();
331
+ machineHelloPublisher.publish(hello, openedSocket);
347
332
  })
348
333
  .catch(() => { });
349
334
  opts.onOpen?.(ws);
@@ -678,7 +663,7 @@ export function serve(config, opts = {}) {
678
663
  ? r.serverCapabilities.filter((c) => typeof c === "string")
679
664
  : []);
680
665
  if (serverCapabilities.has(PROJECT_SKILLS_CAPABILITY)) {
681
- if (await ensureProjectSkillsInitialized())
666
+ if (await projectSkillControllerReadiness.ensure())
682
667
  await projectSkillsController.publishCurrent();
683
668
  }
684
669
  return;
@@ -700,11 +685,11 @@ export function serve(config, opts = {}) {
700
685
  if (typeof request.reqId !== "string")
701
686
  return;
702
687
  const result = serverCapabilities.has(PROJECT_SKILLS_CAPABILITY)
703
- ? await projectSkillsController.handle(msg)
688
+ ? await projectSkillsController.handle(msg, connectionEpochToken)
704
689
  : { ok: false, error: "capability_unavailable" };
705
690
  if (result.ok && (msg.type === "project:remove"
706
691
  || msg.type === "project:rescan")) {
707
- void ensureProjectSkillsInitialized();
692
+ void projectSkillControllerReadiness.ensure();
708
693
  }
709
694
  try {
710
695
  ws?.send(JSON.stringify({ type: "fs:result", reqId: request.reqId, ...result }));
@@ -1130,7 +1115,7 @@ export function serve(config, opts = {}) {
1130
1115
  void flushSlog();
1131
1116
  reconnectTimer = setTimeout(() => {
1132
1117
  reconnectTimer = null;
1133
- connect();
1118
+ void connect();
1134
1119
  }, backoff);
1135
1120
  backoff = Math.min(backoff * 2, maxBackoff);
1136
1121
  });
@@ -1140,16 +1125,14 @@ export function serve(config, opts = {}) {
1140
1125
  });
1141
1126
  }
1142
1127
  const ready = (async () => {
1143
- await reconcileExecutionJournal(executionJournal, {
1144
- agentsRoot: config.agentsRoot,
1145
- serverUrl: config.serverUrl,
1128
+ executionJournal = await initializeProjectSkillProtectedExecutionJournal({
1129
+ config,
1146
1130
  ...(opts.profileName === undefined ? {} : { profileName: opts.profileName }),
1147
- log: dslog,
1148
- flush: flushSlog,
1149
- writeStderr: (line) => process.stderr.write(line),
1131
+ startup: projectSkillRuntimeRootStartup,
1132
+ protectedExecutionIds,
1133
+ ...(injectedExecutionJournal === undefined ? {} : { injectedJournal: injectedExecutionJournal }),
1150
1134
  });
1151
- void ensureProjectSkillsInitialized();
1152
- connect();
1135
+ await connect();
1153
1136
  })();
1154
1137
  const stop = () => {
1155
1138
  if (stopPromise !== null)
@@ -1180,7 +1163,9 @@ export function serve(config, opts = {}) {
1180
1163
  run.controller.request();
1181
1164
  await deadline.waitFor(Promise.all(pending));
1182
1165
  await deadline.waitFor(hostCoordinator.drain());
1183
- await executionJournal.close({ signal: deadline.signal });
1166
+ if (executionJournal !== undefined) {
1167
+ await executionJournal.close({ signal: deadline.signal });
1168
+ }
1184
1169
  }
1185
1170
  finally {
1186
1171
  deadline.dispose();
@@ -1,5 +1,4 @@
1
1
  import { fileURLToPath } from "node:url";
2
- import { join } from "node:path";
3
2
  import { startDormantSupervisor, } from "./execution-supervisor.js";
4
3
  import { buildClaudeArgs } from "./runtimes/claude.js";
5
4
  import { DEEPSEEK_HARNESS_CONFIG_ENV, deepSeekHarnessConfigPath, } from "./runtimes/deepseek-harness.js";
@@ -13,10 +12,7 @@ export function supervisorLaunch(request) {
13
12
  ...(request.reasoning === undefined ? {} : { reasoning: request.reasoning }),
14
13
  };
15
14
  if (request.runtime === "claude") {
16
- const additionalDirectories = request.claudeAdditionalDirectories
17
- ?? (request.agentRoot === undefined
18
- ? undefined
19
- : [join(request.agentRoot, ".crew", "claude-skills"), request.agentRoot]);
15
+ const additionalDirectories = request.claudeAdditionalDirectories;
20
16
  return {
21
17
  command: request.bin,
22
18
  args: buildClaudeArgs({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nowcrew/daemon",
3
- "version": "0.6.18",
3
+ "version": "0.6.20",
4
4
  "type": "module",
5
5
  "description": "crew daemon — 运行在用户机器:拉起/管理 agent 进程,注入 crew CLI,归一化 runtime 事件",
6
6
  "license": "Apache-2.0",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@agentclientprotocol/sdk": "1.2.1",
28
- "@nowcrew/cli": "^0.4.14",
28
+ "@nowcrew/cli": "^0.4.13",
29
29
  "cross-spawn": "^7.0.6",
30
30
  "ws": "^8",
31
31
  "yaml": "^2.8.1",