@misaka-net/misakanet-setup 0.7.1 → 0.8.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/README.md +29 -9
- package/bin/misakanet-setup.mjs +632 -146
- package/hook/checkpoint_reminder.mjs +47 -11
- package/package.json +1 -1
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
* Manual test:
|
|
21
21
|
* echo '{"session_id":"demo"}' | node checkpoint_reminder.mjs prompt
|
|
22
22
|
*/
|
|
23
|
-
import { writeFileSync, mkdirSync, renameSync, readFileSync } from 'node:fs';
|
|
23
|
+
import { writeFileSync, mkdirSync, renameSync, readFileSync, realpathSync } from 'node:fs';
|
|
24
24
|
import { createHash } from 'node:crypto';
|
|
25
25
|
import { homedir } from 'node:os';
|
|
26
26
|
import { join, dirname } from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
27
28
|
|
|
28
29
|
// NOTE: JavaScript does not concatenate adjacent string literals the way Python does.
|
|
29
30
|
// Writing these as three consecutive strings silently keeps only the first one, so the
|
|
@@ -418,14 +419,49 @@ async function failureMode(payload) {
|
|
|
418
419
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
419
420
|
}
|
|
420
421
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
422
|
+
/**
|
|
423
|
+
* Is this file the process's entry point?
|
|
424
|
+
*
|
|
425
|
+
* `import.meta.url` is the module's *resolved* URL: Node's ESM loader resolves symlinks, so a
|
|
426
|
+
* script started through a symlink gets the real path there while `process.argv[1]` still holds
|
|
427
|
+
* the symlinked one. Comparing the two strings directly then never matches, and the hook does
|
|
428
|
+
* nothing at all — silently, with exit 0, which is the shape of a tool that looks installed and
|
|
429
|
+
* is not.
|
|
430
|
+
*
|
|
431
|
+
* macOS is where that bites: `/var` is a symlink to `/private/var`, every temporary directory
|
|
432
|
+
* lives under it, and the packaged e2e installs the hook into such a directory. On 2026-10-26
|
|
433
|
+
* all three macOS legs went red with `exit=0 stdout=""` — the hook ran, and did nothing.
|
|
434
|
+
*
|
|
435
|
+
* So compare the real paths. The direct comparison is kept for a loader started with
|
|
436
|
+
* `--preserve-symlinks`, where the symlink survives in `import.meta.url` as well.
|
|
437
|
+
*/
|
|
438
|
+
function isEntryPoint() {
|
|
439
|
+
const invoked = process.argv[1];
|
|
440
|
+
if (!invoked) return false;
|
|
441
|
+
const here = fileURLToPath(import.meta.url);
|
|
442
|
+
if (here === invoked) return true;
|
|
443
|
+
try {
|
|
444
|
+
return realpathSync(invoked) === realpathSync(here);
|
|
445
|
+
} catch {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
430
448
|
}
|
|
431
|
-
|
|
449
|
+
|
|
450
|
+
// Run only when this file is the entry point (`node checkpoint_reminder.mjs …`). Importing it must
|
|
451
|
+
// not read stdin or exit the process: the inner `search()` is the gate that redacts the query on
|
|
452
|
+
// the way out, and #3719 wants a test that can drive it with *raw* text and see the payload.
|
|
453
|
+
if (isEntryPoint()) {
|
|
454
|
+
const mode = process.argv[2] || 'prompt';
|
|
455
|
+
try {
|
|
456
|
+
const payload = parsePayload(await readStdin());
|
|
457
|
+
if (!payload) debug('no usable payload - nothing to do');
|
|
458
|
+
else if (mode === 'prompt') promptMode(payload);
|
|
459
|
+
else if (mode === 'failure') await failureMode(payload);
|
|
460
|
+
else debug(`unknown mode ${mode}`);
|
|
461
|
+
} catch (err) {
|
|
462
|
+
debug(`hook error: ${err}`); // never break the user's session
|
|
463
|
+
}
|
|
464
|
+
process.exit(0);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export { search };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@misaka-net/misakanet-setup",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "MisakaNet failure lessons for your agents: writes an MCP endpoint into each agent config, rules blocks where the client takes one, and a Claude Code hook. At most one anonymous request leaves this machine at install; then only the agent's calls — unless MISAKANET_HOOK_FETCH=1 (off by default) the hook sends the failed call's error text or command.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"misakanet-setup": "bin/misakanet-setup.mjs"
|