@nurix/etna 0.18.25 → 0.19.1
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/bin/etna.js +31 -0
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/harness.json +1 -1
- package/data/harnesses/code/skills/brainstorm/README.md +1 -1
- package/data/harnesses/etna/harness.json +1 -1
- package/data/harnesses/etna/skills/brainstorm/README.md +1 -1
- package/package.json +1 -1
package/bin/etna.js
CHANGED
|
@@ -92,6 +92,17 @@ function backupIfExists(path) {
|
|
|
92
92
|
return backup;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
// Copy a directory to <path>.bak.<timestamp>, leaving the original in place. Returns the
|
|
96
|
+
// backup path, or null. Used for .claude/, which is refreshed in place (not overwritten
|
|
97
|
+
// wholesale), so the live tree must survive for the in-place update — snapshot, don't move.
|
|
98
|
+
function snapshotDirIfExists(path) {
|
|
99
|
+
if (!existsSync(path)) return null;
|
|
100
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
101
|
+
const backup = `${path}.bak.${ts}`;
|
|
102
|
+
cpSync(path, backup, { recursive: true });
|
|
103
|
+
return backup;
|
|
104
|
+
}
|
|
105
|
+
|
|
95
106
|
function readJson(path) {
|
|
96
107
|
if (!existsSync(path)) return {};
|
|
97
108
|
try {
|
|
@@ -349,6 +360,26 @@ async function installHarness(harnessName, harnesses) {
|
|
|
349
360
|
cpSync(bundledClaudeMd, claudeMdDest, { force: true });
|
|
350
361
|
installed.push('CLAUDE.md → ./');
|
|
351
362
|
|
|
363
|
+
// Same safety net for the .claude/ tree, mirroring the CLAUDE.md rule above. The tree is
|
|
364
|
+
// refreshed in place — owned files overwritten, orphaned owned components pruned — so a
|
|
365
|
+
// user's edits to owned files and any pruned component are the loss surface. A git repo
|
|
366
|
+
// recovers them from history, so we skip the backup; without git there's no net, so we
|
|
367
|
+
// snapshot the whole tree first and tell the user. (Snapshot, not move: the live tree has
|
|
368
|
+
// to stay for the in-place refresh below.)
|
|
369
|
+
const claudeDir = join(targetDir, '.claude');
|
|
370
|
+
if (existsSync(claudeDir)) {
|
|
371
|
+
if (projectHasGit) {
|
|
372
|
+
notices.push('Refreshed existing .claude/ in place (tracked by git — `git checkout .claude` to restore).');
|
|
373
|
+
} else {
|
|
374
|
+
const claudeDirBackup = snapshotDirIfExists(claudeDir);
|
|
375
|
+
if (claudeDirBackup) {
|
|
376
|
+
warnings.push(
|
|
377
|
+
`No .git here, so no version-control safety net — snapshotted existing .claude/ → ${claudeDirBackup}`,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
352
383
|
// What a prior install recorded as harness-owned — read before we overwrite the marker,
|
|
353
384
|
// so we can prune anything this bundle has since dropped.
|
|
354
385
|
const priorOwned = readInstalledOwned(targetDir);
|
package/data/harness-index.json
CHANGED
|
@@ -4,7 +4,7 @@ A Claude Code skill that is a **thinking partner for designing software** — no
|
|
|
4
4
|
|
|
5
5
|
Two principles: **the conversation is the work; the artifacts serve it.** And — because conversations are mortal (context compacts, sessions end) — **the session folder is the only memory**: everything the session produces is captured there, distilled, or it doesn't survive.
|
|
6
6
|
|
|
7
|
-
> Spec (single source of truth): `docs/features/brainstorm-skill
|
|
7
|
+
> Spec (single source of truth): `docs/features/brainstorm-skill/` in the etna repo. The etna copy of this skill (`skills/brainstorm/`) is canonical; the user-level path `~/.claude/skills/brainstorm/` is a symlink to it.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ A Claude Code skill that is a **thinking partner for designing software** — no
|
|
|
4
4
|
|
|
5
5
|
Two principles: **the conversation is the work; the artifacts serve it.** And — because conversations are mortal (context compacts, sessions end) — **the session folder is the only memory**: everything the session produces is captured there, distilled, or it doesn't survive.
|
|
6
6
|
|
|
7
|
-
> Spec (single source of truth): `docs/features/brainstorm-skill
|
|
7
|
+
> Spec (single source of truth): `docs/features/brainstorm-skill/` in the etna repo. The etna copy of this skill (`skills/brainstorm/`) is canonical; the user-level path `~/.claude/skills/brainstorm/` is a symlink to it.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nurix/etna",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|