nearly-cli 0.1.2 → 0.1.3
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/package.json +1 -1
- package/scripts/attach.mjs +24 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nearly-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A pull request tells you what changed. Nearly tells you what nearly happened: the commands a human refused, the pushes policy blocked, the turns rolled back.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/scripts/attach.mjs
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// it, and if it cannot start, Claude Code falls back to its own prompts and
|
|
17
17
|
// nothing breaks.
|
|
18
18
|
|
|
19
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
19
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, realpathSync } from 'node:fs';
|
|
20
20
|
import { join, resolve, dirname, basename } from 'node:path';
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { execFileSync, spawnSync } from 'node:child_process';
|
|
@@ -40,15 +40,31 @@ function pkgVersion() {
|
|
|
40
40
|
catch { return 'latest'; }
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// Only trust a `nearly` on PATH if it really is this tool
|
|
43
|
+
// Only trust a `nearly` on PATH if it really is this tool and it will still be
|
|
44
|
+
// there tomorrow.
|
|
45
|
+
//
|
|
46
|
+
// npx puts its own temporary bin first on PATH for the life of the process, so
|
|
47
|
+
// during `npx nearly-cli` a naive lookup finds a `nearly` that ceases to exist
|
|
48
|
+
// the moment npx exits. Believing it meant writing hooks that call a command
|
|
49
|
+
// nobody has, which fail on every tool call, which means no gate at all.
|
|
44
50
|
function onPath() {
|
|
51
|
+
const args = process.platform === 'win32' ? ['nearly'] : ['-a', 'nearly'];
|
|
52
|
+
let found = [];
|
|
45
53
|
try {
|
|
46
|
-
|
|
47
|
-
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim().split('\n')
|
|
48
|
-
if (!p) return null;
|
|
49
|
-
const out = execFileSync(p, ['--which'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
50
|
-
return out ? p : null;
|
|
54
|
+
found = execFileSync(process.platform === 'win32' ? 'where' : 'which', args,
|
|
55
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim().split('\n').filter(Boolean);
|
|
51
56
|
} catch { return null; }
|
|
57
|
+
|
|
58
|
+
for (const p of found) {
|
|
59
|
+
let resolved = p;
|
|
60
|
+
try { resolved = realpathSync(p); } catch { /* keep the literal path */ }
|
|
61
|
+
if (/[\\/]_npx[\\/]/.test(p) || /[\\/]_npx[\\/]/.test(resolved)) continue; // vanishes when npx exits
|
|
62
|
+
try {
|
|
63
|
+
const out = execFileSync(p, ['--which'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
64
|
+
if (out) return p;
|
|
65
|
+
} catch { /* not our command; try the next one */ }
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
52
68
|
}
|
|
53
69
|
|
|
54
70
|
const fromPackage = /[\\/]node_modules[\\/]/.test(root) || /[\\/]_npx[\\/]/.test(root);
|
|
@@ -72,7 +88,7 @@ function installGlobally() {
|
|
|
72
88
|
}
|
|
73
89
|
let installed = onPath();
|
|
74
90
|
const hookCmd = (ev) => installed
|
|
75
|
-
? `nearly hook ${ev}`
|
|
91
|
+
? `nearly hook ${ev}` // verified above to survive this process
|
|
76
92
|
: fromPackage
|
|
77
93
|
? `npx -y nearly-cli@${pkgVersion()} hook ${ev}`
|
|
78
94
|
: `node ${JSON.stringify(HOOK)} ${ev}`;
|