@nurix/etna 0.20.33 → 0.20.34

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "ae4ad9c21fb9",
2
+ "fingerprint": "748e1019e5d8",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.20.4",
4
+ "version": "3.20.5",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -29,5 +29,5 @@
29
29
  "origin": "https://cdn.nustack.io",
30
30
  "track": "latest"
31
31
  },
32
- "digest": "919a36549601"
32
+ "digest": "00beb7af3c87"
33
33
  }
@@ -184,6 +184,14 @@ function prunableFiles(projectDir, owned) {
184
184
  return out.filter((rel) => rel !== '.claude/hooks');
185
185
  }
186
186
 
187
+ // Whether the owned skills and agents a mount record names are still on disk.
188
+ function ownedOnDisk(projectDir, owned) {
189
+ if (!owned) return true;
190
+ for (const name of owned.skills || []) if (!existsSync(join(projectDir, '.claude', 'skills', name))) return false;
191
+ for (const name of owned.agents || []) if (!existsSync(join(projectDir, '.claude', 'agents', name))) return false;
192
+ return true;
193
+ }
194
+
187
195
  function unionOwned(...maps) {
188
196
  const out = {};
189
197
  for (const map of maps) {
@@ -305,7 +313,7 @@ function mountSettings(marker) {
305
313
  };
306
314
  }
307
315
 
308
- // Mounts the pinned version unless the mount record already names it.
316
+ // Mounts the pinned version unless the mount record already names it and its owned files are on disk.
309
317
  async function mountHarness({ projectDir, cacheDir = cacheRoot(), fetchImpl = globalThis.fetch, timeoutMs = 5000, force = false }) {
310
318
  const marker = readJsonFile(join(projectDir, '.claude', 'harness.json'));
311
319
  if (!marker || !marker.harness || !marker.version) return { status: 'unmarked' };
@@ -313,7 +321,9 @@ async function mountHarness({ projectDir, cacheDir = cacheRoot(), fetchImpl = gl
313
321
  const slug = marker.harness;
314
322
  const version = marker.version;
315
323
  const prior = readJsonFile(join(projectDir, '.claude', 'state', 'mount.json'));
316
- if (!force && prior && prior.version === version) return { status: 'current', slug, version, digest: prior.digest };
324
+ if (!force && prior && prior.version === version && ownedOnDisk(projectDir, prior.owned)) {
325
+ return { status: 'current', slug, version, digest: prior.digest };
326
+ }
317
327
  let resolved;
318
328
  try {
319
329
  resolved = await resolveManifest({ origin, slug, version, cacheDir, fetchImpl, timeoutMs });
@@ -182,6 +182,14 @@ function prunableFiles(projectDir, owned) {
182
182
  return out.filter((rel) => rel !== '.claude/hooks');
183
183
  }
184
184
 
185
+ // Whether the owned skills and agents a mount record names are still on disk.
186
+ function ownedOnDisk(projectDir, owned) {
187
+ if (!owned) return true;
188
+ for (const name of owned.skills || []) if (!existsSync(join(projectDir, '.claude', 'skills', name))) return false;
189
+ for (const name of owned.agents || []) if (!existsSync(join(projectDir, '.claude', 'agents', name))) return false;
190
+ return true;
191
+ }
192
+
185
193
  function unionOwned(...maps) {
186
194
  const out = {};
187
195
  for (const map of maps) {
@@ -303,7 +311,7 @@ function mountSettings(marker) {
303
311
  };
304
312
  }
305
313
 
306
- // Mounts the pinned version unless the mount record already names it.
314
+ // Mounts the pinned version unless the mount record already names it and its owned files are on disk.
307
315
  async function mountHarness({ projectDir, cacheDir = cacheRoot(), fetchImpl = globalThis.fetch, timeoutMs = 5000, force = false }) {
308
316
  const marker = readJsonFile(join(projectDir, '.claude', 'harness.json'));
309
317
  if (!marker || !marker.harness || !marker.version) return { status: 'unmarked' };
@@ -311,7 +319,9 @@ async function mountHarness({ projectDir, cacheDir = cacheRoot(), fetchImpl = gl
311
319
  const slug = marker.harness;
312
320
  const version = marker.version;
313
321
  const prior = readJsonFile(join(projectDir, '.claude', 'state', 'mount.json'));
314
- if (!force && prior && prior.version === version) return { status: 'current', slug, version, digest: prior.digest };
322
+ if (!force && prior && prior.version === version && ownedOnDisk(projectDir, prior.owned)) {
323
+ return { status: 'current', slug, version, digest: prior.digest };
324
+ }
315
325
  let resolved;
316
326
  try {
317
327
  resolved = await resolveManifest({ origin, slug, version, cacheDir, fetchImpl, timeoutMs });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.20.33",
3
+ "version": "0.20.34",
4
4
  "description": "Bootstrap a project with a Nurix harness — writes the committed contract (CLAUDE.md, AGENTS.md, .claude/harness.json, settings.json, the mount hook) and mounts the harness itself, gitignored, from a bundled payload; sessions keep it current from the CDN.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,5 +46,5 @@
46
46
  "agent",
47
47
  "plugin"
48
48
  ],
49
- "etnaFingerprint": "ae4ad9c21fb9"
49
+ "etnaFingerprint": "748e1019e5d8"
50
50
  }