@excitedjs/agent-runtime-claude-code 0.6.1-alpha.gffd8b4b7feab → 0.6.1-beta.204

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.
@@ -3,10 +3,13 @@ import type { AgentRuntimeSkillSource } from '@excitedjs/dreamux-types';
3
3
  * One source root as it exists on disk: the root's own name and absolute path,
4
4
  * plus the skill directories under it.
5
5
  *
6
- * The children are part of the adapter's identity because package upgrades
7
- * happen in place: `npm install --global` can rename the skills under a source
8
- * root whose own name and path never change, and a key that saw only the roots
9
- * would keep serving the previous names forever.
6
+ * The adapter root is keyed by the roots alone, so one set of roots always
7
+ * maps to one directory; the children are recorded in the manifest and
8
+ * compared on every start, because package upgrades happen in place:
9
+ * `npm install --global` can rename the skills under a source root whose own
10
+ * name and path never change, and a view validated by its roots alone would
11
+ * keep serving the previous names forever. A mismatch refreshes the same
12
+ * directory instead of opening a new one.
10
13
  */
11
14
  interface SkillAdapterSource {
12
15
  name: string;
@@ -21,6 +24,14 @@ export interface SkillAdapterManifest {
21
24
  key: string;
22
25
  sources: SkillAdapterSource[];
23
26
  }
27
+ /**
28
+ * Whether the directory at `root` is the current view: a plain directory whose
29
+ * manifest is exactly `expected`. Anything else that occupies the path — a
30
+ * view of an earlier inventory, a manifest of the previous format, a
31
+ * half-written tree — is stale and is reported as such so the caller replaces
32
+ * it. Only a path that is not a plain directory at all is refused, because
33
+ * replacing it would delete something this adapter never wrote.
34
+ */
24
35
  export declare function validateSkillAdapter(root: string, expected: SkillAdapterManifest): Promise<boolean>;
25
36
  /**
26
37
  * Read the adapter's identity from disk — the source roots and the skill
@@ -1 +1 @@
1
- {"version":3,"file":"skill-adapter.d.ts","sourceRoot":"","sources":["../src/skill-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE;;;;;;;;GAQG;AACH,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAiDlB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,SAAS,uBAAuB,EAAE,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
1
+ {"version":3,"file":"skill-adapter.d.ts","sourceRoot":"","sources":["../src/skill-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAgClB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,SAAS,uBAAuB,EAAE,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
@@ -1,6 +1,14 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { lstat, readFile, readdir } from 'node:fs/promises';
3
3
  import { isAbsolute, join, resolve } from 'node:path';
4
+ /**
5
+ * Whether the directory at `root` is the current view: a plain directory whose
6
+ * manifest is exactly `expected`. Anything else that occupies the path — a
7
+ * view of an earlier inventory, a manifest of the previous format, a
8
+ * half-written tree — is stale and is reported as such so the caller replaces
9
+ * it. Only a path that is not a plain directory at all is refused, because
10
+ * replacing it would delete something this adapter never wrote.
11
+ */
4
12
  export async function validateSkillAdapter(root, expected) {
5
13
  let rootInfo;
6
14
  try {
@@ -14,45 +22,26 @@ export async function validateSkillAdapter(root, expected) {
14
22
  if (!rootInfo.isDirectory() || rootInfo.isSymbolicLink()) {
15
23
  throw new Error(`invalid Claude skill adapter directory at ${root}`);
16
24
  }
17
- const skillsRoot = join(root, '.claude', 'skills');
18
- const manifest = join(root, '.dreamux-skill-adapter.json');
19
25
  let skillsInfo;
20
26
  try {
21
- skillsInfo = await lstat(skillsRoot);
27
+ skillsInfo = await lstat(join(root, '.claude', 'skills'));
22
28
  }
23
- catch (error) {
24
- throw new Error(`invalid Claude skill adapter directory at ${root}`, {
25
- cause: error,
26
- });
27
- }
28
- if (!skillsInfo.isDirectory() || skillsInfo.isSymbolicLink()) {
29
- throw new Error(`invalid Claude skill adapter directory at ${root}`);
30
- }
31
- let raw;
32
- try {
33
- raw = await readFile(manifest, 'utf8');
34
- }
35
- catch (error) {
36
- throw new Error(`invalid Claude skill adapter manifest at ${manifest}`, {
37
- cause: error,
38
- });
29
+ catch {
30
+ return false;
39
31
  }
32
+ if (!skillsInfo.isDirectory() || skillsInfo.isSymbolicLink())
33
+ return false;
40
34
  let value;
41
35
  try {
42
- value = JSON.parse(raw);
36
+ value = JSON.parse(await readFile(join(root, '.dreamux-skill-adapter.json'), 'utf8'));
43
37
  }
44
- catch (error) {
45
- throw new Error(`invalid Claude skill adapter manifest at ${manifest}`, {
46
- cause: error,
47
- });
48
- }
49
- if (value === null ||
50
- typeof value !== 'object' ||
51
- Array.isArray(value) ||
52
- JSON.stringify(value) !== JSON.stringify(expected)) {
53
- throw new Error(`invalid Claude skill adapter manifest at ${manifest}`);
38
+ catch {
39
+ return false;
54
40
  }
55
- return true;
41
+ return (value !== null &&
42
+ typeof value === 'object' &&
43
+ !Array.isArray(value) &&
44
+ JSON.stringify(value) === JSON.stringify(expected));
56
45
  }
57
46
  /**
58
47
  * Read the adapter's identity from disk — the source roots and the skill
@@ -65,15 +54,26 @@ export async function readSkillAdapterManifest(sources) {
65
54
  async function readSkillAdapterInventory(sources) {
66
55
  return Promise.all(uniqueSkillSources(sources).map(async (source) => {
67
56
  const path = resolve(source.path);
68
- return { name: source.name, path, skills: await skillDirsInRoot(path) };
57
+ return {
58
+ name: source.name,
59
+ path,
60
+ skills: await skillDirsInRoot(source.name, path),
61
+ };
69
62
  }));
70
63
  }
71
64
  function skillAdapterManifest(inventory) {
72
65
  return { version: 2, key: skillAdapterKey(inventory), sources: inventory };
73
66
  }
67
+ /**
68
+ * The key names the directory for one set of roots and nothing else, so the
69
+ * same roots always land in the same place and a refreshed view keeps the path
70
+ * a running child was given. It is the key the version-1 manifests used, so a
71
+ * root left by an earlier release is refreshed in place rather than orphaned.
72
+ */
74
73
  function skillAdapterKey(inventory) {
74
+ const roots = inventory.map(({ name, path }) => ({ name, path }));
75
75
  return createHash('sha256')
76
- .update(JSON.stringify(inventory))
76
+ .update(JSON.stringify(roots))
77
77
  .digest('hex')
78
78
  .slice(0, 24);
79
79
  }
@@ -92,9 +92,20 @@ function uniqueSkillSources(sources) {
92
92
  /**
93
93
  * The child skills of one root in code-point order: the key hashes this list,
94
94
  * so the order must not depend on the process locale.
95
+ *
96
+ * The roots are read on every start, so a custom root that was deleted or
97
+ * moved after the Team was created stops the start here; the error names the
98
+ * source so the operator knows which `skill_sources` entry to repair.
95
99
  */
96
- async function skillDirsInRoot(root) {
97
- const entries = await readdir(root, { withFileTypes: true });
100
+ async function skillDirsInRoot(name, root) {
101
+ let entries;
102
+ try {
103
+ entries = await readdir(root, { withFileTypes: true });
104
+ }
105
+ catch (error) {
106
+ throw new Error(`skill source ${JSON.stringify(name)} root ${root} cannot be read: ` +
107
+ (error instanceof Error ? error.message : String(error)), { cause: error });
108
+ }
98
109
  return entries
99
110
  .filter((entry) => entry.isDirectory())
100
111
  .map((entry) => ({ name: entry.name, path: join(root, entry.name) }))
@@ -1 +1 @@
1
- {"version":3,"file":"skill-adapter.js","sourceRoot":"","sources":["../src/skill-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-adapter.js","sourceRoot":"","sources":["../src/skill-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BtD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,QAA8B;IAE9B,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrE,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,UAAU,CAAC;IACf,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,UAAU,CAAC,cAAc,EAAE;QAAE,OAAO,KAAK,CAAC;IAC3E,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAChB,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,6BAA6B,CAAC,EAAE,MAAM,CAAC,CAClE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CACL,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACnD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAA2C;IAE3C,OAAO,oBAAoB,CAAC,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,OAA2C;IAE3C,OAAO,OAAO,CAAC,GAAG,CAChB,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI;YACJ,MAAM,EAAE,MAAM,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;SACjD,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAA+B;IAE/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,SAAwC;IAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;SAC7B,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,kBAAkB,CACzB,OAA2C;IAE3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CACpE,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SACzB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAY,EACZ,IAAY;IAEZ,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,gBAAgB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,IAAI,mBAAmB;YAClE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAC1D,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;IACD,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACpE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -1,14 +1,15 @@
1
1
  import type { AgentRuntimeSkillSource } from '@excitedjs/dreamux-types';
2
2
  /**
3
- * Atomically materialize the Claude-compatible view of role-gated skills and
4
- * return the adapter root the child must be given, or null when this runtime
5
- * has no skill sources.
3
+ * Materialize the Claude-compatible view of role-gated skills and return the
4
+ * adapter root the child must be given, or null when this runtime has no
5
+ * skill sources.
6
6
  *
7
- * The root is `<cacheDir>/claude-code/skills/<key>`, keyed by what is on disk:
8
- * the source roots and the skill directories under them. An in-place package
9
- * upgrade that renames skills under an unchanged root therefore lands on a new
10
- * key and materializes afresh; roots keyed by an earlier inventory are never
11
- * revalidated again.
7
+ * The root is `<cacheDir>/claude-code/skills/<key>`, one directory per set of
8
+ * source roots. Its manifest records the skill directories under each root as
9
+ * they were when the view was built; a start that reads a different inventory
10
+ * (an in-place package upgrade that renamed skills, a custom root that gained
11
+ * a skill) rebuilds the view beside the root and swaps it into the same path,
12
+ * so the path never changes and no earlier view is left behind.
12
13
  */
13
14
  export declare function materializeClaudeSkillAddDir(cacheDir: string, sources: readonly AgentRuntimeSkillSource[], testHooks?: {
14
15
  beforePublish?: () => void | Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"skill-materializer.d.ts","sourceRoot":"","sources":["../src/skill-materializer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAOxE;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,uBAAuB,EAAE,EAC3C,SAAS,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,GAC7D,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0CxB"}
1
+ {"version":3,"file":"skill-materializer.d.ts","sourceRoot":"","sources":["../src/skill-materializer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAQxE;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,uBAAuB,EAAE,EAC3C,SAAS,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,GAC7D,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqCxB"}
@@ -3,15 +3,16 @@ import { mkdir, rename, rm, symlink, writeFile, } from 'node:fs/promises';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { readSkillAdapterManifest, validateSkillAdapter, } from './skill-adapter.js';
5
5
  /**
6
- * Atomically materialize the Claude-compatible view of role-gated skills and
7
- * return the adapter root the child must be given, or null when this runtime
8
- * has no skill sources.
6
+ * Materialize the Claude-compatible view of role-gated skills and return the
7
+ * adapter root the child must be given, or null when this runtime has no
8
+ * skill sources.
9
9
  *
10
- * The root is `<cacheDir>/claude-code/skills/<key>`, keyed by what is on disk:
11
- * the source roots and the skill directories under them. An in-place package
12
- * upgrade that renames skills under an unchanged root therefore lands on a new
13
- * key and materializes afresh; roots keyed by an earlier inventory are never
14
- * revalidated again.
10
+ * The root is `<cacheDir>/claude-code/skills/<key>`, one directory per set of
11
+ * source roots. Its manifest records the skill directories under each root as
12
+ * they were when the view was built; a start that reads a different inventory
13
+ * (an in-place package upgrade that renamed skills, a custom root that gained
14
+ * a skill) rebuilds the view beside the root and swaps it into the same path,
15
+ * so the path never changes and no earlier view is left behind.
15
16
  */
16
17
  export async function materializeClaudeSkillAddDir(cacheDir, sources, testHooks = {}) {
17
18
  if (sources.length === 0)
@@ -41,18 +42,45 @@ export async function materializeClaudeSkillAddDir(cacheDir, sources, testHooks
41
42
  await writeFile(join(tmpRoot, '.dreamux-skill-adapter.json'), `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
42
43
  await mkdir(dirname(root), { recursive: true });
43
44
  await testHooks.beforePublish?.();
44
- await rename(tmpRoot, root);
45
+ await publish(tmpRoot, root, manifest);
45
46
  }
46
47
  catch (err) {
47
- const code = err.code;
48
- if (code === 'EEXIST' || code === 'ENOTEMPTY') {
49
- await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
50
- if (await validateSkillAdapter(root, manifest))
51
- return root;
52
- }
53
48
  await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
54
49
  throw err;
55
50
  }
56
51
  return root;
57
52
  }
53
+ /**
54
+ * Put the fresh view at `root`: whatever occupies the path (a stale view, a
55
+ * manifest of the previous format, a half-written tree) is moved aside first
56
+ * and removed once the swap is done. Two runtimes starting together may both
57
+ * reach here; each swap leaves a complete view at the path, and the one whose
58
+ * final rename finds the path already taken keeps the other's view when it
59
+ * validates.
60
+ */
61
+ async function publish(tmpRoot, root, manifest) {
62
+ const staleRoot = `${root}.${randomUUID()}.stale`;
63
+ try {
64
+ await rename(root, staleRoot);
65
+ }
66
+ catch (err) {
67
+ if (err.code !== 'ENOENT')
68
+ throw err;
69
+ }
70
+ try {
71
+ await rename(tmpRoot, root);
72
+ }
73
+ catch (err) {
74
+ const code = err.code;
75
+ if (code !== 'EEXIST' && code !== 'ENOTEMPTY')
76
+ throw err;
77
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
78
+ if (!(await validateSkillAdapter(root, manifest))) {
79
+ throw new Error(`invalid Claude skill adapter at ${root} after a concurrent publish`, { cause: err });
80
+ }
81
+ }
82
+ finally {
83
+ await rm(staleRoot, { recursive: true, force: true }).catch(() => undefined);
84
+ }
85
+ }
58
86
  //# sourceMappingURL=skill-materializer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-materializer.js","sourceRoot":"","sources":["../src/skill-materializer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-materializer.js","sourceRoot":"","sources":["../src/skill-materializer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@excitedjs/agent-runtime-claude-code",
3
- "version": "0.6.1-alpha.gffd8b4b7feab",
3
+ "version": "0.6.1-beta.204",
4
4
  "description": "Built-in Claude Code Agent Runtime provider for Dreamux (alias builtin:claude-code). Implements the @excitedjs/dreamux-types AgentRuntimeProvider contract against a resident `claude` stream-json child; depends on @excitedjs/dreamux-types only, never on @excitedjs/dreamux core (issue excitedjs/dreamux#209).",
5
5
  "license": "MIT",
6
6
  "repository": {