@primitive.ai/prim 0.1.0-alpha.94 → 0.1.0-alpha.97
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 +7 -4
- package/dist/{chunk-UKUAAAXE.js → chunk-27ADT6FQ.js} +2 -2
- package/dist/{chunk-TYAHC25F.js → chunk-2MBV7ZMV.js} +1 -1
- package/dist/{chunk-OTHKG76J.js → chunk-35FMRWJH.js} +1 -1
- package/dist/{chunk-O7YAW7G6.js → chunk-3I4GEWXQ.js} +9 -11
- package/dist/{chunk-DXJQR4QI.js → chunk-4GHANPWQ.js} +2 -2
- package/dist/{chunk-WUXFLE7X.js → chunk-7KABYYWG.js} +64 -66
- package/dist/{chunk-LFFLHSQO.js → chunk-AJYZB5PF.js} +63 -6
- package/dist/{chunk-H4UNYFUC.js → chunk-DHOQGHKQ.js} +184 -1
- package/dist/{chunk-2GP5UFV7.js → chunk-DWRSEC34.js} +5 -3
- package/dist/{chunk-ZU563PQI.js → chunk-FBPZ4YUD.js} +2 -2
- package/dist/{chunk-G2VMA2QO.js → chunk-LY6NJ7KL.js} +6 -4
- package/dist/{chunk-ZB4F75SZ.js → chunk-MXVCP33E.js} +5 -1
- package/dist/{chunk-ICM2XCXS.js → chunk-OW4GJBLW.js} +2 -2
- package/dist/{chunk-K7D2EYBS.js → chunk-QNPTWTBG.js} +2 -2
- package/dist/{chunk-IMK4JKTA.js → chunk-RK4ZS3HG.js} +2 -2
- package/dist/{chunk-OH3EZXYX.js → chunk-UO2U6IKF.js} +1 -1
- package/dist/{chunk-FXF4JWK2.js → chunk-XEDJ5N3M.js} +17 -2
- package/dist/{chunk-AXQQMX2U.js → chunk-Y5W4TZM7.js} +2 -2
- package/dist/{chunk-DSWT6BCC.js → chunk-ZYK3TBEW.js} +2542 -2250
- package/dist/daemon/server.js +2547 -2119
- package/dist/hook-runtime/daemon/server.js +2547 -2119
- package/dist/hook-runtime/hooks/post-commit.js +2547 -2119
- package/dist/hook-runtime/hooks/post-rewrite.js +2547 -2119
- package/dist/hook-runtime/hooks/post-tool-use.js +2874 -2373
- package/dist/hook-runtime/hooks/pre-tool-use.js +3766 -3325
- package/dist/hook-runtime/hooks/prim-hook.js +2973 -2440
- package/dist/hook-runtime/hooks/session-end.js +179 -129
- package/dist/hook-runtime/hooks/session-start.js +2651 -2221
- package/dist/hook-runtime/index.js +2596 -2126
- package/dist/hooks/post-commit.js +11 -11
- package/dist/hooks/post-rewrite.js +10 -10
- package/dist/hooks/post-tool-use.js +20 -20
- package/dist/hooks/pre-commit.js +4 -4
- package/dist/hooks/pre-tool-use.js +29 -17
- package/dist/hooks/prim-hook.js +22 -18
- package/dist/hooks/session-end.js +11 -5
- package/dist/hooks/session-start.js +26 -22
- package/dist/index.js +79 -60
- package/package.json +1 -1
|
@@ -385,6 +385,157 @@ function daemonRequest(method, params = {}, opts = {}) {
|
|
|
385
385
|
});
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
+
// src/lib/activation.ts
|
|
389
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
390
|
+
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
391
|
+
import { homedir as homedir2 } from "os";
|
|
392
|
+
import { join as join4 } from "path";
|
|
393
|
+
|
|
394
|
+
// src/lib/git.ts
|
|
395
|
+
import { execFileSync } from "child_process";
|
|
396
|
+
import { createHash as createHash3 } from "crypto";
|
|
397
|
+
import { lstatSync, realpathSync } from "fs";
|
|
398
|
+
import { basename, dirname, isAbsolute as isAbsolute2, relative, resolve, sep } from "path";
|
|
399
|
+
var GIT_TIMEOUT_MS = 1e3;
|
|
400
|
+
var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
|
|
401
|
+
var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
|
|
402
|
+
function gitToplevel(cwd) {
|
|
403
|
+
try {
|
|
404
|
+
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
405
|
+
cwd,
|
|
406
|
+
encoding: "utf-8",
|
|
407
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
408
|
+
timeout: GIT_TIMEOUT_MS
|
|
409
|
+
}).trim();
|
|
410
|
+
} catch {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function gitValue(cwd, args) {
|
|
415
|
+
try {
|
|
416
|
+
const value = execFileSync("git", args, {
|
|
417
|
+
cwd,
|
|
418
|
+
encoding: "utf-8",
|
|
419
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
420
|
+
timeout: GIT_TIMEOUT_MS
|
|
421
|
+
}).trim();
|
|
422
|
+
return value || void 0;
|
|
423
|
+
} catch {
|
|
424
|
+
return void 0;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function githubRepositoryFullName(cwd) {
|
|
428
|
+
const remote = gitValue(cwd, ["config", "--get", "remote.origin.url"]);
|
|
429
|
+
if (!remote || [...remote].some((char) => char < " " || char === "\x7F")) return null;
|
|
430
|
+
const match = /^(?:git@github\.com:([^?#]+)|(?:https|ssh):\/\/(?:[^/@]+@)?github\.com(?::\d+)?\/([^?#]+))$/i.exec(
|
|
431
|
+
remote
|
|
432
|
+
);
|
|
433
|
+
const path = match?.[1] ?? match?.[2];
|
|
434
|
+
if (!path) return null;
|
|
435
|
+
const parts = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "").split("/");
|
|
436
|
+
if (parts.length !== 2 || !GITHUB_OWNER_PATTERN.test(parts[0] ?? "") || !GITHUB_REPOSITORY_PATTERN.test(parts[1] ?? "")) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
return `${parts[0]}/${parts[1]}`;
|
|
440
|
+
}
|
|
441
|
+
function normalizeOriginRemote(remote) {
|
|
442
|
+
const value = remote.trim();
|
|
443
|
+
if (!value) return void 0;
|
|
444
|
+
const scp = !value.includes("://") ? /^(?:[^@/\s]+@)?(?<host>[^:/\s]+):(?<path>.+)$/.exec(value)?.groups : void 0;
|
|
445
|
+
if (scp?.host && scp.path) {
|
|
446
|
+
const path = scp.path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
447
|
+
return path ? `${scp.host.toLowerCase()}/${path}` : void 0;
|
|
448
|
+
}
|
|
449
|
+
try {
|
|
450
|
+
const url = new URL(value);
|
|
451
|
+
url.username = "";
|
|
452
|
+
url.password = "";
|
|
453
|
+
url.search = "";
|
|
454
|
+
url.hash = "";
|
|
455
|
+
const path = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
456
|
+
if (url.host && path) return `${url.host.toLowerCase()}/${path}`;
|
|
457
|
+
return void 0;
|
|
458
|
+
} catch {
|
|
459
|
+
return void 0;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function opaqueRepoKey(source, value) {
|
|
463
|
+
return `repo_v1_${createHash3("sha256").update(`${source}\0${value}`).digest("hex")}`;
|
|
464
|
+
}
|
|
465
|
+
function resolveRepositoryContext(cwd = process.cwd()) {
|
|
466
|
+
const top = gitToplevel(cwd);
|
|
467
|
+
if (!top) return null;
|
|
468
|
+
let repoRoot;
|
|
469
|
+
try {
|
|
470
|
+
repoRoot = realpathSync.native(top);
|
|
471
|
+
} catch {
|
|
472
|
+
repoRoot = resolve(top);
|
|
473
|
+
}
|
|
474
|
+
const origin = gitValue(repoRoot, ["config", "--get", "remote.origin.url"]);
|
|
475
|
+
const repoFullName = githubRepositoryFullName(repoRoot) ?? void 0;
|
|
476
|
+
const normalizedOrigin = origin ? normalizeOriginRemote(origin) : void 0;
|
|
477
|
+
if (normalizedOrigin) {
|
|
478
|
+
return {
|
|
479
|
+
repoRoot,
|
|
480
|
+
repoKey: opaqueRepoKey("origin", normalizedOrigin),
|
|
481
|
+
identitySource: "origin",
|
|
482
|
+
repoFullName
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const roots = gitValue(repoRoot, ["rev-list", "--max-parents=0", "HEAD"])?.split(/\s+/).filter(Boolean).sort();
|
|
486
|
+
if (roots && roots.length > 0) {
|
|
487
|
+
return {
|
|
488
|
+
repoRoot,
|
|
489
|
+
repoKey: opaqueRepoKey("root_commit", roots.join("\n")),
|
|
490
|
+
identitySource: "root_commit",
|
|
491
|
+
repoFullName
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
return { repoRoot, repoFullName };
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// src/lib/activation.ts
|
|
498
|
+
var PRIM_ACTIVE_KEY = "prim.active";
|
|
499
|
+
var GIT_TIMEOUT_MS2 = 1e3;
|
|
500
|
+
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
|
|
501
|
+
var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
|
|
502
|
+
function repoActiveFlag(cwd) {
|
|
503
|
+
try {
|
|
504
|
+
const value = execFileSync2("git", ["config", "--get", PRIM_ACTIVE_KEY], {
|
|
505
|
+
cwd,
|
|
506
|
+
encoding: "utf-8",
|
|
507
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
508
|
+
timeout: GIT_TIMEOUT_MS2
|
|
509
|
+
}).trim();
|
|
510
|
+
if (value === "true") return "true";
|
|
511
|
+
if (value === "false") return "false";
|
|
512
|
+
return void 0;
|
|
513
|
+
} catch {
|
|
514
|
+
return void 0;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function hasProjectPrimInstall(cwd) {
|
|
518
|
+
const root = gitToplevel(cwd);
|
|
519
|
+
if (root === null || root === homedir2()) return false;
|
|
520
|
+
for (const rel of PROJECT_INSTALL_FILES) {
|
|
521
|
+
const path = join4(root, rel);
|
|
522
|
+
if (existsSync(path)) {
|
|
523
|
+
try {
|
|
524
|
+
const content = readFileSync2(path, "utf-8");
|
|
525
|
+
if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
|
|
526
|
+
} catch {
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
function isRepoActiveForCapture(cwd) {
|
|
533
|
+
const flag = repoActiveFlag(cwd);
|
|
534
|
+
if (flag === "true") return true;
|
|
535
|
+
if (flag === "false") return false;
|
|
536
|
+
return hasProjectPrimInstall(cwd);
|
|
537
|
+
}
|
|
538
|
+
|
|
388
539
|
// src/hooks/agent.ts
|
|
389
540
|
function parseAgent(argv) {
|
|
390
541
|
const i = argv.indexOf("--agent");
|
|
@@ -396,9 +547,9 @@ function parseAgent(argv) {
|
|
|
396
547
|
}
|
|
397
548
|
|
|
398
549
|
// src/commands/cursor-install.ts
|
|
399
|
-
import { existsSync as
|
|
400
|
-
import { homedir as
|
|
401
|
-
import { isAbsolute as isAbsolute5, join as
|
|
550
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
551
|
+
import { homedir as homedir4 } from "os";
|
|
552
|
+
import { isAbsolute as isAbsolute5, join as join9 } from "path";
|
|
402
553
|
|
|
403
554
|
// src/lib/atomic-file.ts
|
|
404
555
|
import { randomUUID } from "crypto";
|
|
@@ -413,11 +564,11 @@ import {
|
|
|
413
564
|
rmSync,
|
|
414
565
|
writeFileSync
|
|
415
566
|
} from "fs";
|
|
416
|
-
import { dirname } from "path";
|
|
567
|
+
import { dirname as dirname2 } from "path";
|
|
417
568
|
|
|
418
569
|
// src/lib/bin-path.ts
|
|
419
|
-
import { existsSync, readFileSync as
|
|
420
|
-
import { dirname as
|
|
570
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
|
|
571
|
+
import { dirname as dirname3, isAbsolute as isAbsolute3, join as join5 } from "path";
|
|
421
572
|
import { fileURLToPath } from "url";
|
|
422
573
|
var PKG_NAME = "@primitive.ai/prim";
|
|
423
574
|
var STABLE_HOOK_LAUNCHER_NAME = "prim-hook-launcher-v1";
|
|
@@ -454,31 +605,31 @@ function detachedHookShimCommand(bin, args = "") {
|
|
|
454
605
|
}
|
|
455
606
|
|
|
456
607
|
// src/lib/hook-runtime.ts
|
|
457
|
-
import { createHash as
|
|
608
|
+
import { createHash as createHash4, randomBytes as randomBytes2 } from "crypto";
|
|
458
609
|
import {
|
|
459
610
|
constants as constants2,
|
|
460
611
|
accessSync,
|
|
461
612
|
chmodSync,
|
|
462
613
|
copyFileSync,
|
|
463
|
-
existsSync as
|
|
464
|
-
lstatSync,
|
|
614
|
+
existsSync as existsSync4,
|
|
615
|
+
lstatSync as lstatSync2,
|
|
465
616
|
mkdirSync as mkdirSync3,
|
|
466
617
|
mkdtempSync,
|
|
467
|
-
readFileSync as
|
|
618
|
+
readFileSync as readFileSync5,
|
|
468
619
|
readdirSync,
|
|
469
|
-
realpathSync,
|
|
620
|
+
realpathSync as realpathSync2,
|
|
470
621
|
renameSync as renameSync2,
|
|
471
622
|
rmSync as rmSync3,
|
|
472
623
|
statSync as statSync2,
|
|
473
624
|
utimesSync,
|
|
474
625
|
writeFileSync as writeFileSync3
|
|
475
626
|
} from "fs";
|
|
476
|
-
import { delimiter, dirname as
|
|
627
|
+
import { delimiter, dirname as dirname5, isAbsolute as isAbsolute4, join as join7, resolve as resolve2 } from "path";
|
|
477
628
|
|
|
478
629
|
// src/lib/file-lock.ts
|
|
479
630
|
import { randomBytes } from "crypto";
|
|
480
|
-
import { existsSync as
|
|
481
|
-
import { dirname as
|
|
631
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync as rmSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
632
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
482
633
|
var syncSleeper = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
483
634
|
|
|
484
635
|
// src/lib/git-hook-contract.ts
|
|
@@ -572,114 +723,9 @@ exec "$prim_node" "$prim_entry" "$@"
|
|
|
572
723
|
`;
|
|
573
724
|
|
|
574
725
|
// src/commands/claude-install.ts
|
|
575
|
-
import { existsSync as
|
|
576
|
-
import { homedir as
|
|
577
|
-
import { join as
|
|
578
|
-
|
|
579
|
-
// src/lib/git.ts
|
|
580
|
-
import { execFileSync } from "child_process";
|
|
581
|
-
import { createHash as createHash4 } from "crypto";
|
|
582
|
-
import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "fs";
|
|
583
|
-
import { basename, dirname as dirname5, isAbsolute as isAbsolute4, relative, resolve as resolve2, sep } from "path";
|
|
584
|
-
var GIT_TIMEOUT_MS = 1e3;
|
|
585
|
-
var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
|
|
586
|
-
var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
|
|
587
|
-
function gitToplevel(cwd) {
|
|
588
|
-
try {
|
|
589
|
-
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
590
|
-
cwd,
|
|
591
|
-
encoding: "utf-8",
|
|
592
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
593
|
-
timeout: GIT_TIMEOUT_MS
|
|
594
|
-
}).trim();
|
|
595
|
-
} catch {
|
|
596
|
-
return null;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
function gitValue(cwd, args) {
|
|
600
|
-
try {
|
|
601
|
-
const value = execFileSync("git", args, {
|
|
602
|
-
cwd,
|
|
603
|
-
encoding: "utf-8",
|
|
604
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
605
|
-
timeout: GIT_TIMEOUT_MS
|
|
606
|
-
}).trim();
|
|
607
|
-
return value || void 0;
|
|
608
|
-
} catch {
|
|
609
|
-
return void 0;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
function githubRepositoryFullName(cwd) {
|
|
613
|
-
const remote = gitValue(cwd, ["config", "--get", "remote.origin.url"]);
|
|
614
|
-
if (!remote || [...remote].some((char) => char < " " || char === "\x7F")) return null;
|
|
615
|
-
const match = /^(?:git@github\.com:([^?#]+)|(?:https|ssh):\/\/(?:[^/@]+@)?github\.com(?::\d+)?\/([^?#]+))$/i.exec(
|
|
616
|
-
remote
|
|
617
|
-
);
|
|
618
|
-
const path = match?.[1] ?? match?.[2];
|
|
619
|
-
if (!path) return null;
|
|
620
|
-
const parts = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "").split("/");
|
|
621
|
-
if (parts.length !== 2 || !GITHUB_OWNER_PATTERN.test(parts[0] ?? "") || !GITHUB_REPOSITORY_PATTERN.test(parts[1] ?? "")) {
|
|
622
|
-
return null;
|
|
623
|
-
}
|
|
624
|
-
return `${parts[0]}/${parts[1]}`;
|
|
625
|
-
}
|
|
626
|
-
function normalizeOriginRemote(remote) {
|
|
627
|
-
const value = remote.trim();
|
|
628
|
-
if (!value) return void 0;
|
|
629
|
-
const scp = !value.includes("://") ? /^(?:[^@/\s]+@)?(?<host>[^:/\s]+):(?<path>.+)$/.exec(value)?.groups : void 0;
|
|
630
|
-
if (scp?.host && scp.path) {
|
|
631
|
-
const path = scp.path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
632
|
-
return path ? `${scp.host.toLowerCase()}/${path}` : void 0;
|
|
633
|
-
}
|
|
634
|
-
try {
|
|
635
|
-
const url = new URL(value);
|
|
636
|
-
url.username = "";
|
|
637
|
-
url.password = "";
|
|
638
|
-
url.search = "";
|
|
639
|
-
url.hash = "";
|
|
640
|
-
const path = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
641
|
-
if (url.host && path) return `${url.host.toLowerCase()}/${path}`;
|
|
642
|
-
return void 0;
|
|
643
|
-
} catch {
|
|
644
|
-
return void 0;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
function opaqueRepoKey(source, value) {
|
|
648
|
-
return `repo_v1_${createHash4("sha256").update(`${source}\0${value}`).digest("hex")}`;
|
|
649
|
-
}
|
|
650
|
-
function resolveRepositoryContext(cwd = process.cwd()) {
|
|
651
|
-
const top = gitToplevel(cwd);
|
|
652
|
-
if (!top) return null;
|
|
653
|
-
let repoRoot;
|
|
654
|
-
try {
|
|
655
|
-
repoRoot = realpathSync2.native(top);
|
|
656
|
-
} catch {
|
|
657
|
-
repoRoot = resolve2(top);
|
|
658
|
-
}
|
|
659
|
-
const origin = gitValue(repoRoot, ["config", "--get", "remote.origin.url"]);
|
|
660
|
-
const repoFullName = githubRepositoryFullName(repoRoot) ?? void 0;
|
|
661
|
-
const normalizedOrigin = origin ? normalizeOriginRemote(origin) : void 0;
|
|
662
|
-
if (normalizedOrigin) {
|
|
663
|
-
return {
|
|
664
|
-
repoRoot,
|
|
665
|
-
repoKey: opaqueRepoKey("origin", normalizedOrigin),
|
|
666
|
-
identitySource: "origin",
|
|
667
|
-
repoFullName
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
const roots = gitValue(repoRoot, ["rev-list", "--max-parents=0", "HEAD"])?.split(/\s+/).filter(Boolean).sort();
|
|
671
|
-
if (roots && roots.length > 0) {
|
|
672
|
-
return {
|
|
673
|
-
repoRoot,
|
|
674
|
-
repoKey: opaqueRepoKey("root_commit", roots.join("\n")),
|
|
675
|
-
identitySource: "root_commit",
|
|
676
|
-
repoFullName
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
return { repoRoot, repoFullName };
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
// src/commands/claude-install.ts
|
|
726
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
|
|
727
|
+
import { homedir as homedir3 } from "os";
|
|
728
|
+
import { join as join8 } from "path";
|
|
683
729
|
var CAPTURE_BIN = "prim-hook";
|
|
684
730
|
var GATE_BIN = "prim-pre-tool-use";
|
|
685
731
|
var POST_TOOL_USE_BIN = "prim-post-tool-use";
|
|
@@ -688,7 +734,7 @@ var SESSION_END_BIN = "prim-session-end";
|
|
|
688
734
|
var STATUSLINE_BIN = "prim-statusline";
|
|
689
735
|
var STATUSLINE_ARGS = "";
|
|
690
736
|
var STATUSLINE_COMMAND = stableHookCommand(STATUSLINE_BIN, STATUSLINE_ARGS);
|
|
691
|
-
var USER_SCOPE_PATH =
|
|
737
|
+
var USER_SCOPE_PATH = join8(homedir3(), ".claude", "settings.json");
|
|
692
738
|
function projectRoot() {
|
|
693
739
|
return gitToplevel() ?? process.cwd();
|
|
694
740
|
}
|
|
@@ -763,24 +809,24 @@ var REGISTRATIONS2 = [
|
|
|
763
809
|
{ event: "sessionStart", bin: SESSION_START_BIN2 },
|
|
764
810
|
{ event: "sessionEnd", bin: SESSION_END_BIN2 }
|
|
765
811
|
];
|
|
766
|
-
function cursorConfigDirectory(env = process.env, home =
|
|
812
|
+
function cursorConfigDirectory(env = process.env, home = homedir4(), platform = process.platform) {
|
|
767
813
|
const explicit = env.CURSOR_CONFIG_DIR?.trim();
|
|
768
814
|
if (explicit && isAbsolute5(explicit)) return explicit;
|
|
769
815
|
const xdg = env.XDG_CONFIG_HOME?.trim();
|
|
770
|
-
if (platform !== "darwin" && xdg && isAbsolute5(xdg)) return
|
|
771
|
-
return
|
|
816
|
+
if (platform !== "darwin" && xdg && isAbsolute5(xdg)) return join9(xdg, "cursor");
|
|
817
|
+
return join9(home, ".cursor");
|
|
772
818
|
}
|
|
773
819
|
function cursorHooksPath(scope, root = projectRoot()) {
|
|
774
|
-
return scope === "user" ?
|
|
820
|
+
return scope === "user" ? join9(cursorConfigDirectory(), "hooks.json") : join9(root, ".cursor", "hooks.json");
|
|
775
821
|
}
|
|
776
822
|
function plainObject(value) {
|
|
777
823
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
778
824
|
}
|
|
779
825
|
function readCursorHooks(path) {
|
|
780
|
-
if (!
|
|
826
|
+
if (!existsSync6(path)) return {};
|
|
781
827
|
let parsed;
|
|
782
828
|
try {
|
|
783
|
-
parsed = JSON.parse(
|
|
829
|
+
parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
784
830
|
} catch {
|
|
785
831
|
throw new Error(`invalid Cursor hooks JSON at ${path}`);
|
|
786
832
|
}
|
|
@@ -1114,6 +1160,10 @@ async function main() {
|
|
|
1114
1160
|
emit();
|
|
1115
1161
|
return;
|
|
1116
1162
|
}
|
|
1163
|
+
if (!isRepoActiveForCapture(envelope.cwd ?? process.cwd())) {
|
|
1164
|
+
emit();
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1117
1167
|
await daemonRequest(
|
|
1118
1168
|
"session_end",
|
|
1119
1169
|
{ sessionId: envelope.session_id },
|