@nowcrew/daemon 0.6.53 → 0.6.54

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.
@@ -249,6 +249,23 @@ const verifyCache = async (agentsRoot, ability) => {
249
249
  };
250
250
  const layerRelativePath = (path, layer) => path.startsWith(`${layer}/`) ? path.slice(layer.length + 1) : path;
251
251
  const readManagedCatalog = async (trainingRoot) => JSON.parse(await readFile(join(trainingRoot, "ACTIVE_RELEASE.json"), "utf8"));
252
+ const projectedSkillExists = async (trainingRoot, name) => {
253
+ const root = join(trainingRoot, "skills", safeAbilityName(name));
254
+ if (!await isRealDirectory(root))
255
+ return false;
256
+ const direct = await lstat(join(root, "SKILL.md")).catch(() => null);
257
+ if (direct?.isFile() && !direct.isSymbolicLink())
258
+ return true;
259
+ for (const entry of await readdir(root, { withFileTypes: true })) {
260
+ if (!entry.isDirectory())
261
+ continue;
262
+ const skill = await lstat(join(root, entry.name, "SKILL.md")).catch(() => null);
263
+ if (skill?.isFile() && !skill.isSymbolicLink())
264
+ return true;
265
+ }
266
+ return false;
267
+ };
268
+ const projectedSkillsComplete = async (trainingRoot, skills) => (await Promise.all(skills.map((skill) => projectedSkillExists(trainingRoot, skill.name)))).every(Boolean);
252
269
  const trainingSwitchJournalPath = (agentRoot) => join(agentRoot, ".training-switch.json");
253
270
  const trainingRollbackRoot = (agentRoot) => join(agentRoot, ".training-rollback");
254
271
  const trainingDiscardRoot = (agentRoot) => join(agentRoot, ".training-discard");
@@ -422,6 +439,7 @@ const activeTrainingRoot = async (agentsRoot, handle, ability) => {
422
439
  && catalog.releaseId === ability.releaseId
423
440
  && catalog.rootCommit === ability.rootCommit
424
441
  && catalog.artifactDigest === ability.artifactDigest
442
+ && await projectedSkillsComplete(trainingRoot, ability.skills)
425
443
  ? trainingRoot
426
444
  : null;
427
445
  };
@@ -463,7 +481,8 @@ const materializeWorkspaceTraining = async (agentsRoot, handle, ability) => {
463
481
  }
464
482
  if (previousCatalog.releaseId === ability.releaseId
465
483
  && previousCatalog.artifactDigest === ability.artifactDigest
466
- && previousCatalog.projectionDigest === projectionDigest)
484
+ && previousCatalog.projectionDigest === projectionDigest
485
+ && await projectedSkillsComplete(trainingRoot, ability.skills))
467
486
  return trainingRoot;
468
487
  }
469
488
  await mkdir(agentRoot, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nowcrew/daemon",
3
- "version": "0.6.53",
3
+ "version": "0.6.54",
4
4
  "type": "module",
5
5
  "description": "crew daemon — 运行在用户机器:拉起/管理 agent 进程,注入 crew CLI,归一化 runtime 事件",
6
6
  "license": "Apache-2.0",