devlyn-cli 4.2.1 → 4.2.2
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/devlyn.js +17 -7
- package/package.json +1 -1
package/bin/devlyn.js
CHANGED
|
@@ -425,7 +425,10 @@ function readInstallManifest(root) {
|
|
|
425
425
|
if (!stat) return {};
|
|
426
426
|
if (!stat.isFile()) throw new Error(`not a regular install marker: ${markerPath}`);
|
|
427
427
|
const marker = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
|
|
428
|
-
|
|
428
|
+
if (marker?.package !== PKG.name || marker.schemaVersion !== 1) {
|
|
429
|
+
throw new Error('not a devlyn-cli install marker');
|
|
430
|
+
}
|
|
431
|
+
return marker.skills || {};
|
|
429
432
|
}
|
|
430
433
|
|
|
431
434
|
// Enumerate every directory this install may replace, migrate or remove, before
|
|
@@ -474,7 +477,13 @@ function preflightSkills(roots, optionalNames = [], commandDir = null) {
|
|
|
474
477
|
if (stat && !stat.isDirectory()) throw new Error(`not a real directory: ${dir}`);
|
|
475
478
|
}
|
|
476
479
|
const tracked = trackedPaths(root);
|
|
477
|
-
|
|
480
|
+
let manifest;
|
|
481
|
+
try {
|
|
482
|
+
manifest = readInstallManifest(root);
|
|
483
|
+
} catch (error) {
|
|
484
|
+
conflicts.push(`${path.join(root, DEVLYN_INSTALL_MARKER)}: ${error.message}`);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
478
487
|
for (const name of plannedSkills(root, optionalNames)) {
|
|
479
488
|
const dest = path.join(root, name);
|
|
480
489
|
const isTracked = tracked.some((file) => file.toLowerCase() === dest.toLowerCase()
|
|
@@ -542,12 +551,13 @@ function writeInstallMarker(skillsDir, names, previous) {
|
|
|
542
551
|
version: PKG.version,
|
|
543
552
|
skills: { ...previous, ...Object.fromEntries(names.map((name) => [name, fingerprint(path.join(skillsDir, name))])) },
|
|
544
553
|
};
|
|
554
|
+
const fd = fs.openSync(tempPath, 'wx', 0o600);
|
|
545
555
|
try {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
556
|
+
try {
|
|
557
|
+
fs.writeFileSync(fd, JSON.stringify(marker, null, 2) + '\n', 'utf8');
|
|
558
|
+
} finally {
|
|
559
|
+
fs.closeSync(fd);
|
|
560
|
+
}
|
|
551
561
|
fs.renameSync(tempPath, markerPath);
|
|
552
562
|
} finally {
|
|
553
563
|
fs.rmSync(tempPath, { force: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "Loop & harness engineering for AI coding agents (Claude Code, Codex, and any AGENTS.md-driven agent) — core engineering principles for CLAUDE.md/AGENTS.md and a loop designer that splits one intent into tasks agents drain hands-free",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|