@primitive.ai/prim 0.1.0-alpha.93 → 0.1.0-alpha.94
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 +50 -8
- package/SKILL.md +5 -2
- package/dist/{chunk-X64HTHUF.js → chunk-AXQQMX2U.js} +200 -8
- package/dist/chunk-FXF4JWK2.js +162 -0
- package/dist/{chunk-C3VAA5CG.js → chunk-IMK4JKTA.js} +1 -1
- package/dist/{chunk-36TWVNBE.js → chunk-O7YAW7G6.js} +1 -1
- package/dist/{chunk-DCJN6LZH.js → chunk-WUXFLE7X.js} +684 -365
- package/dist/hook-runtime/hooks/post-commit.js +154 -38
- package/dist/hook-runtime/hooks/post-tool-use.js +55 -5
- package/dist/hook-runtime/hooks/pre-tool-use.js +55 -5
- package/dist/hook-runtime/hooks/prim-hook.js +55 -5
- package/dist/hook-runtime/hooks/session-end.js +53 -5
- package/dist/hook-runtime/hooks/session-start.js +843 -277
- package/dist/hook-runtime/index.js +2709 -1880
- package/dist/hooks/post-commit.js +4 -0
- package/dist/hooks/post-tool-use.js +3 -3
- package/dist/hooks/pre-tool-use.js +3 -3
- package/dist/hooks/prim-hook.js +3 -3
- package/dist/hooks/session-end.js +2 -2
- package/dist/hooks/session-start.js +28 -14
- package/dist/index.js +553 -339
- package/package.json +1 -1
|
@@ -52,9 +52,9 @@ var require_ucs2length = __commonJS({
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
// src/hooks/post-commit.ts
|
|
55
|
-
import { execFileSync as
|
|
56
|
-
import { lstatSync as lstatSync3, readFileSync as
|
|
57
|
-
import { basename as basename3, dirname as
|
|
55
|
+
import { execFileSync as execFileSync5, spawn } from "child_process";
|
|
56
|
+
import { lstatSync as lstatSync3, readFileSync as readFileSync11 } from "fs";
|
|
57
|
+
import { basename as basename3, dirname as dirname10, isAbsolute as isAbsolute4, join as join12 } from "path";
|
|
58
58
|
import { fileURLToPath } from "url";
|
|
59
59
|
|
|
60
60
|
// src/binding.ts
|
|
@@ -401,6 +401,69 @@ import {
|
|
|
401
401
|
writeFileSync
|
|
402
402
|
} from "fs";
|
|
403
403
|
import { dirname as dirname2 } from "path";
|
|
404
|
+
var DEFAULT_FILE_MODE = 438;
|
|
405
|
+
function syncDirectory(path) {
|
|
406
|
+
const fd = openSync(path, constants.O_RDONLY);
|
|
407
|
+
try {
|
|
408
|
+
fsyncSync(fd);
|
|
409
|
+
} finally {
|
|
410
|
+
closeSync(fd);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function syncCreatedParentChain(firstCreatedParent, parent) {
|
|
414
|
+
const createdDirectories = [];
|
|
415
|
+
let current = parent;
|
|
416
|
+
while (current !== firstCreatedParent) {
|
|
417
|
+
createdDirectories.push(current);
|
|
418
|
+
const next = dirname2(current);
|
|
419
|
+
if (next === current) {
|
|
420
|
+
throw new Error("recursive mkdir returned a path outside the target parent chain");
|
|
421
|
+
}
|
|
422
|
+
current = next;
|
|
423
|
+
}
|
|
424
|
+
createdDirectories.push(firstCreatedParent);
|
|
425
|
+
syncDirectory(dirname2(firstCreatedParent));
|
|
426
|
+
for (const directory of createdDirectories.reverse().slice(0, -1)) {
|
|
427
|
+
syncDirectory(directory);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function ensureDurableDirectory(path, mode) {
|
|
431
|
+
const firstCreatedParent = mkdirSync(path, { recursive: true, mode });
|
|
432
|
+
if (firstCreatedParent) {
|
|
433
|
+
syncCreatedParentChain(firstCreatedParent, path);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function atomicWriteFile(target, content, options = {}) {
|
|
437
|
+
const parent = dirname2(target);
|
|
438
|
+
if (options.ensureParent) {
|
|
439
|
+
ensureDurableDirectory(parent);
|
|
440
|
+
}
|
|
441
|
+
const temporaryPath = `${target}.${randomUUID()}.tmp`;
|
|
442
|
+
let temporaryCreated = false;
|
|
443
|
+
try {
|
|
444
|
+
const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
|
|
445
|
+
const fd = openSync(temporaryPath, flags, options.mode ?? DEFAULT_FILE_MODE);
|
|
446
|
+
temporaryCreated = true;
|
|
447
|
+
try {
|
|
448
|
+
if (options.mode !== void 0) fchmodSync(fd, options.mode);
|
|
449
|
+
writeFileSync(fd, content);
|
|
450
|
+
fsyncSync(fd);
|
|
451
|
+
} finally {
|
|
452
|
+
closeSync(fd);
|
|
453
|
+
}
|
|
454
|
+
options.validate?.(temporaryPath);
|
|
455
|
+
renameSync(temporaryPath, target);
|
|
456
|
+
syncDirectory(parent);
|
|
457
|
+
} catch (error) {
|
|
458
|
+
if (temporaryCreated) {
|
|
459
|
+
try {
|
|
460
|
+
rmSync(temporaryPath, { force: true });
|
|
461
|
+
} catch {
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
throw error;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
404
467
|
|
|
405
468
|
// src/lib/file-lock.ts
|
|
406
469
|
import { randomBytes } from "crypto";
|
|
@@ -18715,6 +18778,58 @@ function cachedCollectScopeAdmits(cwd, facts) {
|
|
|
18715
18778
|
);
|
|
18716
18779
|
}
|
|
18717
18780
|
|
|
18781
|
+
// src/lib/commit-heartbeat.ts
|
|
18782
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
18783
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, readdirSync as readdirSync3, unlinkSync } from "fs";
|
|
18784
|
+
import { dirname as dirname8, join as join9, resolve as resolve3 } from "path";
|
|
18785
|
+
var FIRED_DIR = "prim/post-commit-fired";
|
|
18786
|
+
var GIT_TIMEOUT_MS3 = 1e3;
|
|
18787
|
+
var MAX_STAMP_BYTES = 1024;
|
|
18788
|
+
var MAX_FIRED_STAMPS = 256;
|
|
18789
|
+
var PRUNE_SLACK = 64;
|
|
18790
|
+
var FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
|
|
18791
|
+
function gitPath(cwd, relative2) {
|
|
18792
|
+
const value = execFileSync3("git", ["rev-parse", "--git-path", relative2], {
|
|
18793
|
+
cwd,
|
|
18794
|
+
encoding: "utf8",
|
|
18795
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
18796
|
+
timeout: GIT_TIMEOUT_MS3
|
|
18797
|
+
}).replace(/\r?\n$/u, "");
|
|
18798
|
+
if (value === "" || /[\0\r\n]/u.test(value)) throw new Error("Git returned an unsafe path");
|
|
18799
|
+
return resolve3(cwd, value);
|
|
18800
|
+
}
|
|
18801
|
+
function ensurePrivateParent(path) {
|
|
18802
|
+
mkdirSync5(dirname8(dirname8(path)), { recursive: true, mode: 448 });
|
|
18803
|
+
mkdirSync5(dirname8(path), { recursive: true, mode: 448 });
|
|
18804
|
+
}
|
|
18805
|
+
function writeStamp(path, at) {
|
|
18806
|
+
ensurePrivateParent(path);
|
|
18807
|
+
atomicWriteFile(path, `${JSON.stringify({ at })}
|
|
18808
|
+
`, { mode: 384 });
|
|
18809
|
+
}
|
|
18810
|
+
function readStampAt(path) {
|
|
18811
|
+
try {
|
|
18812
|
+
const raw = readFileSync8(path, "utf8");
|
|
18813
|
+
if (raw.length > MAX_STAMP_BYTES) return void 0;
|
|
18814
|
+
const parsed = JSON.parse(raw);
|
|
18815
|
+
return typeof parsed.at === "number" && Number.isSafeInteger(parsed.at) && parsed.at > 0 ? parsed.at : void 0;
|
|
18816
|
+
} catch {
|
|
18817
|
+
return void 0;
|
|
18818
|
+
}
|
|
18819
|
+
}
|
|
18820
|
+
function recordPostCommitFired(cwd, sha, now = Date.now()) {
|
|
18821
|
+
if (!sha || !FULL_SHA_RE.test(sha)) return;
|
|
18822
|
+
try {
|
|
18823
|
+
const dir = gitPath(cwd, FIRED_DIR);
|
|
18824
|
+
writeStamp(join9(dir, sha), now);
|
|
18825
|
+
const names = readdirSync3(dir).filter((name) => FULL_SHA_RE.test(name));
|
|
18826
|
+
if (names.length <= MAX_FIRED_STAMPS + PRUNE_SLACK) return;
|
|
18827
|
+
const stale = names.map((name) => ({ name, at: readStampAt(join9(dir, name)) ?? 0 })).sort((left, right) => right.at - left.at || left.name.localeCompare(right.name)).slice(MAX_FIRED_STAMPS);
|
|
18828
|
+
for (const { name } of stale) unlinkSync(join9(dir, name));
|
|
18829
|
+
} catch {
|
|
18830
|
+
}
|
|
18831
|
+
}
|
|
18832
|
+
|
|
18718
18833
|
// src/lib/unattended.ts
|
|
18719
18834
|
var UNATTENDED_ENV = "PRIM_UNATTENDED";
|
|
18720
18835
|
function unattendedEnv(env = process.env) {
|
|
@@ -18722,7 +18837,7 @@ function unattendedEnv(env = process.env) {
|
|
|
18722
18837
|
}
|
|
18723
18838
|
|
|
18724
18839
|
// src/lib/workspace-id.ts
|
|
18725
|
-
import { execFileSync as
|
|
18840
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
18726
18841
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
18727
18842
|
import {
|
|
18728
18843
|
constants as constants2,
|
|
@@ -18732,15 +18847,15 @@ import {
|
|
|
18732
18847
|
fsyncSync as fsyncSync2,
|
|
18733
18848
|
linkSync,
|
|
18734
18849
|
lstatSync as lstatSync2,
|
|
18735
|
-
mkdirSync as
|
|
18850
|
+
mkdirSync as mkdirSync6,
|
|
18736
18851
|
openSync as openSync3,
|
|
18737
|
-
readFileSync as
|
|
18852
|
+
readFileSync as readFileSync9,
|
|
18738
18853
|
statSync as statSync2,
|
|
18739
|
-
unlinkSync,
|
|
18854
|
+
unlinkSync as unlinkSync2,
|
|
18740
18855
|
writeFileSync as writeFileSync3
|
|
18741
18856
|
} from "fs";
|
|
18742
|
-
import { dirname as
|
|
18743
|
-
var WORKSPACE_ID_RELATIVE_PATH =
|
|
18857
|
+
import { dirname as dirname9, isAbsolute as isAbsolute3, join as join10, resolve as resolve4 } from "path";
|
|
18858
|
+
var WORKSPACE_ID_RELATIVE_PATH = join10("prim", "workspace-id");
|
|
18744
18859
|
var MAX_ANCESTORS = 64;
|
|
18745
18860
|
var MAX_GIT_FILE_BYTES = 4096;
|
|
18746
18861
|
var MAX_ID_FILE_BYTES = 128;
|
|
@@ -18768,7 +18883,7 @@ function resolveWorkspaceIdPath(cwd) {
|
|
|
18768
18883
|
if (fromFilesystem) return { status: "resolved", path: fromFilesystem };
|
|
18769
18884
|
}
|
|
18770
18885
|
try {
|
|
18771
|
-
const output =
|
|
18886
|
+
const output = execFileSync4(
|
|
18772
18887
|
"git",
|
|
18773
18888
|
["rev-parse", "--is-inside-work-tree", "--git-path", WORKSPACE_ID_RELATIVE_PATH],
|
|
18774
18889
|
{
|
|
@@ -18780,13 +18895,13 @@ function resolveWorkspaceIdPath(cwd) {
|
|
|
18780
18895
|
windowsHide: true
|
|
18781
18896
|
}
|
|
18782
18897
|
);
|
|
18783
|
-
const [insideWorktree,
|
|
18784
|
-
if (insideWorktree !== "true" || !
|
|
18898
|
+
const [insideWorktree, gitPath2, ...extra] = output.trim().split(/\r?\n/);
|
|
18899
|
+
if (insideWorktree !== "true" || !gitPath2 || extra.length > 0 || gitPath2.includes("\0")) {
|
|
18785
18900
|
return { status: "not_git" };
|
|
18786
18901
|
}
|
|
18787
18902
|
return {
|
|
18788
18903
|
status: "resolved",
|
|
18789
|
-
path: isAbsolute3(
|
|
18904
|
+
path: isAbsolute3(gitPath2) ? resolve4(gitPath2) : resolve4(cwd, gitPath2)
|
|
18790
18905
|
};
|
|
18791
18906
|
} catch (error) {
|
|
18792
18907
|
const code = errorCode(error);
|
|
@@ -18797,21 +18912,21 @@ function resolveWorkspaceIdPath(cwd) {
|
|
|
18797
18912
|
}
|
|
18798
18913
|
}
|
|
18799
18914
|
function resolveFromFilesystem(cwd) {
|
|
18800
|
-
let current =
|
|
18915
|
+
let current = resolve4(cwd);
|
|
18801
18916
|
for (let depth = 0; depth < MAX_ANCESTORS; depth += 1) {
|
|
18802
|
-
const dotGit =
|
|
18917
|
+
const dotGit = join10(current, ".git");
|
|
18803
18918
|
try {
|
|
18804
18919
|
const stat = lstatSync2(dotGit);
|
|
18805
18920
|
if (stat.isDirectory() && isGitDirectory(dotGit)) {
|
|
18806
|
-
return
|
|
18921
|
+
return join10(dotGit, WORKSPACE_ID_RELATIVE_PATH);
|
|
18807
18922
|
}
|
|
18808
18923
|
if (stat.isFile() && stat.size <= MAX_GIT_FILE_BYTES) {
|
|
18809
|
-
const contents =
|
|
18924
|
+
const contents = readFileSync9(dotGit, "utf8");
|
|
18810
18925
|
const match = /^gitdir: (.+?)(?:\r?\n)?$/.exec(contents);
|
|
18811
18926
|
if (match?.[1]) {
|
|
18812
|
-
const gitDirectory = isAbsolute3(match[1]) ?
|
|
18927
|
+
const gitDirectory = isAbsolute3(match[1]) ? resolve4(match[1]) : resolve4(current, match[1]);
|
|
18813
18928
|
if (isGitDirectory(gitDirectory)) {
|
|
18814
|
-
return
|
|
18929
|
+
return join10(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
|
|
18815
18930
|
}
|
|
18816
18931
|
}
|
|
18817
18932
|
}
|
|
@@ -18822,7 +18937,7 @@ function resolveFromFilesystem(cwd) {
|
|
|
18822
18937
|
return null;
|
|
18823
18938
|
}
|
|
18824
18939
|
}
|
|
18825
|
-
const parent =
|
|
18940
|
+
const parent = dirname9(current);
|
|
18826
18941
|
if (parent === current) break;
|
|
18827
18942
|
current = parent;
|
|
18828
18943
|
}
|
|
@@ -18830,7 +18945,7 @@ function resolveFromFilesystem(cwd) {
|
|
|
18830
18945
|
}
|
|
18831
18946
|
function isGitDirectory(path) {
|
|
18832
18947
|
try {
|
|
18833
|
-
return statSync2(
|
|
18948
|
+
return statSync2(join10(path, "HEAD")).isFile();
|
|
18834
18949
|
} catch {
|
|
18835
18950
|
return false;
|
|
18836
18951
|
}
|
|
@@ -18849,7 +18964,7 @@ function inspectPath(path) {
|
|
|
18849
18964
|
return { status: "corrupt", path, reason: "invalid_content" };
|
|
18850
18965
|
}
|
|
18851
18966
|
try {
|
|
18852
|
-
const contents =
|
|
18967
|
+
const contents = readFileSync9(path, "utf8");
|
|
18853
18968
|
const workspaceId = contents.endsWith("\n") ? contents.slice(0, -1) : contents;
|
|
18854
18969
|
if ((contents === workspaceId || contents === `${workspaceId}
|
|
18855
18970
|
`) && isCanonicalWorkspaceId(workspaceId)) {
|
|
@@ -18866,13 +18981,13 @@ function inspectPath(path) {
|
|
|
18866
18981
|
}
|
|
18867
18982
|
}
|
|
18868
18983
|
function createWorkspaceId(path) {
|
|
18869
|
-
const parent =
|
|
18984
|
+
const parent = dirname9(path);
|
|
18870
18985
|
const workspaceId = randomUUID2();
|
|
18871
|
-
const temporaryPath =
|
|
18986
|
+
const temporaryPath = join10(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
|
|
18872
18987
|
let temporaryCreated = false;
|
|
18873
18988
|
let publishing = false;
|
|
18874
18989
|
try {
|
|
18875
|
-
|
|
18990
|
+
mkdirSync6(parent, { recursive: true, mode: 448 });
|
|
18876
18991
|
chmodSync3(parent, 448);
|
|
18877
18992
|
const fd = openSync3(
|
|
18878
18993
|
temporaryPath,
|
|
@@ -18902,7 +19017,7 @@ function createWorkspaceId(path) {
|
|
|
18902
19017
|
} finally {
|
|
18903
19018
|
if (temporaryCreated) {
|
|
18904
19019
|
try {
|
|
18905
|
-
|
|
19020
|
+
unlinkSync2(temporaryPath);
|
|
18906
19021
|
} catch {
|
|
18907
19022
|
}
|
|
18908
19023
|
}
|
|
@@ -18937,8 +19052,8 @@ var AGENT_ENVELOPE_VERSION = 3;
|
|
|
18937
19052
|
var ENVELOPE_VERSION = LEGACY_ENVELOPE_VERSION;
|
|
18938
19053
|
|
|
18939
19054
|
// src/hooks/redact.ts
|
|
18940
|
-
import { existsSync as existsSync7, readFileSync as
|
|
18941
|
-
import { join as
|
|
19055
|
+
import { existsSync as existsSync7, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
19056
|
+
import { join as join11 } from "path";
|
|
18942
19057
|
import { Worker } from "worker_threads";
|
|
18943
19058
|
var USER_HOME_RULES = [
|
|
18944
19059
|
{
|
|
@@ -19114,9 +19229,9 @@ function toCommitMove(commit, cliVersion, cwd, context = {}) {
|
|
|
19114
19229
|
}
|
|
19115
19230
|
|
|
19116
19231
|
// src/hooks/post-commit.ts
|
|
19117
|
-
var here =
|
|
19118
|
-
var
|
|
19119
|
-
var
|
|
19232
|
+
var here = dirname10(fileURLToPath(import.meta.url));
|
|
19233
|
+
var GIT_TIMEOUT_MS4 = 1e3;
|
|
19234
|
+
var FULL_SHA_RE2 = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
|
|
19120
19235
|
var OBSERVATION_MARKER_RE = /^prim-post-commit-observed\.[A-Za-z0-9]+$/u;
|
|
19121
19236
|
var MAX_OBSERVATION_MARKER_AGE_MS = 10 * 60 * 1e3;
|
|
19122
19237
|
var MAX_OBSERVATION_MARKER_FUTURE_SKEW_MS = 5e3;
|
|
@@ -19137,10 +19252,10 @@ function capturedAtFromLauncher(env = process.env, now = Date.now()) {
|
|
|
19137
19252
|
}
|
|
19138
19253
|
function gitText(args) {
|
|
19139
19254
|
try {
|
|
19140
|
-
return
|
|
19255
|
+
return execFileSync5("git", args, {
|
|
19141
19256
|
encoding: "utf-8",
|
|
19142
19257
|
stdio: ["ignore", "pipe", "ignore"],
|
|
19143
|
-
timeout:
|
|
19258
|
+
timeout: GIT_TIMEOUT_MS4
|
|
19144
19259
|
}).trim();
|
|
19145
19260
|
} catch {
|
|
19146
19261
|
return;
|
|
@@ -19148,10 +19263,10 @@ function gitText(args) {
|
|
|
19148
19263
|
}
|
|
19149
19264
|
function gitBytes(args) {
|
|
19150
19265
|
try {
|
|
19151
|
-
return
|
|
19266
|
+
return execFileSync5("git", args, {
|
|
19152
19267
|
encoding: "buffer",
|
|
19153
19268
|
stdio: ["ignore", "pipe", "ignore"],
|
|
19154
|
-
timeout:
|
|
19269
|
+
timeout: GIT_TIMEOUT_MS4
|
|
19155
19270
|
});
|
|
19156
19271
|
} catch {
|
|
19157
19272
|
return;
|
|
@@ -19182,7 +19297,7 @@ function parseNulPaths(value) {
|
|
|
19182
19297
|
function readCommit() {
|
|
19183
19298
|
const snapshotProvided = process.env.PRIM_COMMIT_SHA !== void 0;
|
|
19184
19299
|
const sha = snapshotProvided ? process.env.PRIM_COMMIT_SHA : gitText(["rev-parse", "HEAD"]);
|
|
19185
|
-
if (!sha || !
|
|
19300
|
+
if (!sha || !FULL_SHA_RE2.test(sha)) {
|
|
19186
19301
|
return null;
|
|
19187
19302
|
}
|
|
19188
19303
|
const rawBranch = process.env.PRIM_COMMIT_BRANCH !== void 0 ? process.env.PRIM_COMMIT_BRANCH : gitText(["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
@@ -19208,14 +19323,14 @@ function readCommit() {
|
|
|
19208
19323
|
}
|
|
19209
19324
|
function resolveCliVersion() {
|
|
19210
19325
|
try {
|
|
19211
|
-
const pkg = JSON.parse(
|
|
19326
|
+
const pkg = JSON.parse(readFileSync11(join12(here, "..", "..", "package.json"), "utf-8"));
|
|
19212
19327
|
return pkg.version ?? "unknown";
|
|
19213
19328
|
} catch {
|
|
19214
19329
|
return "unknown";
|
|
19215
19330
|
}
|
|
19216
19331
|
}
|
|
19217
19332
|
function spawnBackgroundFlush() {
|
|
19218
|
-
const entry =
|
|
19333
|
+
const entry = join12(here, "..", "index.js");
|
|
19219
19334
|
spawn(process.execPath, [entry, "moves", "flush"], {
|
|
19220
19335
|
detached: true,
|
|
19221
19336
|
stdio: "ignore",
|
|
@@ -19224,6 +19339,7 @@ function spawnBackgroundFlush() {
|
|
|
19224
19339
|
}
|
|
19225
19340
|
function runPostCommit() {
|
|
19226
19341
|
const cwd = gitText(["rev-parse", "--show-toplevel"]) ?? process.cwd();
|
|
19342
|
+
recordPostCommitFired(cwd, process.env.PRIM_COMMIT_SHA);
|
|
19227
19343
|
if (!isRepoActiveForCapture(cwd)) {
|
|
19228
19344
|
return;
|
|
19229
19345
|
}
|
|
@@ -19998,6 +19998,13 @@ function shellQuote(value) {
|
|
|
19998
19998
|
}
|
|
19999
19999
|
var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
|
|
20000
20000
|
var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
|
|
20001
|
+
var PRIM_CONFIG_SHELL_RESOLVER = [
|
|
20002
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
20003
|
+
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20004
|
+
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20005
|
+
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
20006
|
+
"fi; fi; "
|
|
20007
|
+
].join("");
|
|
20001
20008
|
function stableHookCommand(bin, args = "") {
|
|
20002
20009
|
if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
|
|
20003
20010
|
throw new Error("invalid stable hook command");
|
|
@@ -20007,11 +20014,7 @@ function stableHookCommand(bin, args = "") {
|
|
|
20007
20014
|
// it as inert data during the rolling window so an older uninstall or
|
|
20008
20015
|
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
20009
20016
|
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
20010
|
-
|
|
20011
|
-
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20012
|
-
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20013
|
-
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
20014
|
-
"fi; fi; ",
|
|
20017
|
+
PRIM_CONFIG_SHELL_RESOLVER,
|
|
20015
20018
|
`case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
|
|
20016
20019
|
'exec "$prim_launcher" "$@"'
|
|
20017
20020
|
].join("");
|
|
@@ -20661,6 +20664,53 @@ import {
|
|
|
20661
20664
|
writeFileSync as writeFileSync5
|
|
20662
20665
|
} from "fs";
|
|
20663
20666
|
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute5, join as join11, resolve as resolve4 } from "path";
|
|
20667
|
+
|
|
20668
|
+
// src/lib/git-hook-contract.ts
|
|
20669
|
+
var GIT_HOOK_ENTRYPOINT_CONTENT = `#!/bin/sh
|
|
20670
|
+
# prim git hook entrypoint v1 \u2014 managed by prim; do not edit.
|
|
20671
|
+
# Run by the "# >>> prim <hook> hook >>>" block in a Git hook file. Acts only
|
|
20672
|
+
# where prim is active (git config prim.active true) and never fails the hook.
|
|
20673
|
+
case "$0" in */*) prim_dir=\${0%/*} ;; *) exit 0 ;; esac
|
|
20674
|
+
prim_launcher="$prim_dir/${STABLE_HOOK_LAUNCHER_NAME}"
|
|
20675
|
+
[ -x "$prim_launcher" ] || exit 0
|
|
20676
|
+
[ "$(git config --get prim.active 2>/dev/null)" = "true" ] || exit 0
|
|
20677
|
+
prim_hook=\${1-}
|
|
20678
|
+
if [ "$#" -gt 0 ]; then shift; fi
|
|
20679
|
+
case "$prim_hook" in
|
|
20680
|
+
pre-commit)
|
|
20681
|
+
"$prim_launcher" prim-pre-commit "$@" || :
|
|
20682
|
+
;;
|
|
20683
|
+
post-commit)
|
|
20684
|
+
prim_sha=$(git rev-parse --verify HEAD 2>/dev/null) || exit 0
|
|
20685
|
+
case "$prim_sha" in *[!0-9a-f]* | "") exit 0 ;; esac
|
|
20686
|
+
case "\${#prim_sha}" in 40 | 64) ;; *) exit 0 ;; esac
|
|
20687
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20688
|
+
prim_observed=$(mktemp "\${TMPDIR:-/tmp}/prim-post-commit-observed.XXXXXXXX" 2>/dev/null) || prim_observed=
|
|
20689
|
+
(
|
|
20690
|
+
trap '' HUP
|
|
20691
|
+
trap 'if [ -n "$prim_observed" ]; then rm -f "$prim_observed"; fi' 0
|
|
20692
|
+
PRIM_COMMIT_SHA=$prim_sha PRIM_COMMIT_BRANCH=$prim_branch PRIM_COMMIT_OBSERVED_FILE=$prim_observed "$prim_launcher" prim-post-commit
|
|
20693
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20694
|
+
;;
|
|
20695
|
+
post-rewrite)
|
|
20696
|
+
case "\${1-}" in amend | rebase) prim_source=$1 ;; *) exit 0 ;; esac
|
|
20697
|
+
prim_pairs=$(mktemp "\${TMPDIR:-/tmp}/prim-post-rewrite-pairs.XXXXXXXX" 2>/dev/null) || exit 0
|
|
20698
|
+
if ! chmod 600 "$prim_pairs" 2>/dev/null || ! cat >"$prim_pairs"; then
|
|
20699
|
+
rm -f "$prim_pairs"
|
|
20700
|
+
exit 0
|
|
20701
|
+
fi
|
|
20702
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20703
|
+
(
|
|
20704
|
+
trap '' HUP
|
|
20705
|
+
trap 'rm -f "$prim_pairs"' 0
|
|
20706
|
+
PRIM_REWRITE_SOURCE=$prim_source PRIM_REWRITE_BRANCH=$prim_branch PRIM_REWRITE_PAIRS_FILE=$prim_pairs "$prim_launcher" prim-post-rewrite
|
|
20707
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20708
|
+
;;
|
|
20709
|
+
esac
|
|
20710
|
+
exit 0
|
|
20711
|
+
`;
|
|
20712
|
+
|
|
20713
|
+
// src/lib/hook-runtime.ts
|
|
20664
20714
|
var RELEASE_PREFIX = "release-";
|
|
20665
20715
|
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20666
20716
|
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|
|
@@ -370,6 +370,13 @@ function shellQuote(value) {
|
|
|
370
370
|
}
|
|
371
371
|
var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
|
|
372
372
|
var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
|
|
373
|
+
var PRIM_CONFIG_SHELL_RESOLVER = [
|
|
374
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
375
|
+
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
376
|
+
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
377
|
+
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
378
|
+
"fi; fi; "
|
|
379
|
+
].join("");
|
|
373
380
|
function stableHookCommand(bin, args = "") {
|
|
374
381
|
if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
|
|
375
382
|
throw new Error("invalid stable hook command");
|
|
@@ -379,11 +386,7 @@ function stableHookCommand(bin, args = "") {
|
|
|
379
386
|
// it as inert data during the rolling window so an older uninstall or
|
|
380
387
|
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
381
388
|
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
382
|
-
|
|
383
|
-
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
384
|
-
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
385
|
-
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
386
|
-
"fi; fi; ",
|
|
389
|
+
PRIM_CONFIG_SHELL_RESOLVER,
|
|
387
390
|
`case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
|
|
388
391
|
'exec "$prim_launcher" "$@"'
|
|
389
392
|
].join("");
|
|
@@ -20292,6 +20295,53 @@ import {
|
|
|
20292
20295
|
writeFileSync as writeFileSync4
|
|
20293
20296
|
} from "fs";
|
|
20294
20297
|
import { delimiter, dirname as dirname6, isAbsolute as isAbsolute4, join as join9, resolve as resolve3 } from "path";
|
|
20298
|
+
|
|
20299
|
+
// src/lib/git-hook-contract.ts
|
|
20300
|
+
var GIT_HOOK_ENTRYPOINT_CONTENT = `#!/bin/sh
|
|
20301
|
+
# prim git hook entrypoint v1 \u2014 managed by prim; do not edit.
|
|
20302
|
+
# Run by the "# >>> prim <hook> hook >>>" block in a Git hook file. Acts only
|
|
20303
|
+
# where prim is active (git config prim.active true) and never fails the hook.
|
|
20304
|
+
case "$0" in */*) prim_dir=\${0%/*} ;; *) exit 0 ;; esac
|
|
20305
|
+
prim_launcher="$prim_dir/${STABLE_HOOK_LAUNCHER_NAME}"
|
|
20306
|
+
[ -x "$prim_launcher" ] || exit 0
|
|
20307
|
+
[ "$(git config --get prim.active 2>/dev/null)" = "true" ] || exit 0
|
|
20308
|
+
prim_hook=\${1-}
|
|
20309
|
+
if [ "$#" -gt 0 ]; then shift; fi
|
|
20310
|
+
case "$prim_hook" in
|
|
20311
|
+
pre-commit)
|
|
20312
|
+
"$prim_launcher" prim-pre-commit "$@" || :
|
|
20313
|
+
;;
|
|
20314
|
+
post-commit)
|
|
20315
|
+
prim_sha=$(git rev-parse --verify HEAD 2>/dev/null) || exit 0
|
|
20316
|
+
case "$prim_sha" in *[!0-9a-f]* | "") exit 0 ;; esac
|
|
20317
|
+
case "\${#prim_sha}" in 40 | 64) ;; *) exit 0 ;; esac
|
|
20318
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20319
|
+
prim_observed=$(mktemp "\${TMPDIR:-/tmp}/prim-post-commit-observed.XXXXXXXX" 2>/dev/null) || prim_observed=
|
|
20320
|
+
(
|
|
20321
|
+
trap '' HUP
|
|
20322
|
+
trap 'if [ -n "$prim_observed" ]; then rm -f "$prim_observed"; fi' 0
|
|
20323
|
+
PRIM_COMMIT_SHA=$prim_sha PRIM_COMMIT_BRANCH=$prim_branch PRIM_COMMIT_OBSERVED_FILE=$prim_observed "$prim_launcher" prim-post-commit
|
|
20324
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20325
|
+
;;
|
|
20326
|
+
post-rewrite)
|
|
20327
|
+
case "\${1-}" in amend | rebase) prim_source=$1 ;; *) exit 0 ;; esac
|
|
20328
|
+
prim_pairs=$(mktemp "\${TMPDIR:-/tmp}/prim-post-rewrite-pairs.XXXXXXXX" 2>/dev/null) || exit 0
|
|
20329
|
+
if ! chmod 600 "$prim_pairs" 2>/dev/null || ! cat >"$prim_pairs"; then
|
|
20330
|
+
rm -f "$prim_pairs"
|
|
20331
|
+
exit 0
|
|
20332
|
+
fi
|
|
20333
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20334
|
+
(
|
|
20335
|
+
trap '' HUP
|
|
20336
|
+
trap 'rm -f "$prim_pairs"' 0
|
|
20337
|
+
PRIM_REWRITE_SOURCE=$prim_source PRIM_REWRITE_BRANCH=$prim_branch PRIM_REWRITE_PAIRS_FILE=$prim_pairs "$prim_launcher" prim-post-rewrite
|
|
20338
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20339
|
+
;;
|
|
20340
|
+
esac
|
|
20341
|
+
exit 0
|
|
20342
|
+
`;
|
|
20343
|
+
|
|
20344
|
+
// src/lib/hook-runtime.ts
|
|
20295
20345
|
var RELEASE_PREFIX = "release-";
|
|
20296
20346
|
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20297
20347
|
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|
|
@@ -20180,6 +20180,13 @@ function shellQuote(value) {
|
|
|
20180
20180
|
}
|
|
20181
20181
|
var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
|
|
20182
20182
|
var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
|
|
20183
|
+
var PRIM_CONFIG_SHELL_RESOLVER = [
|
|
20184
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
20185
|
+
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20186
|
+
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20187
|
+
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
20188
|
+
"fi; fi; "
|
|
20189
|
+
].join("");
|
|
20183
20190
|
function stableHookCommand(bin, args = "") {
|
|
20184
20191
|
if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
|
|
20185
20192
|
throw new Error("invalid stable hook command");
|
|
@@ -20189,11 +20196,7 @@ function stableHookCommand(bin, args = "") {
|
|
|
20189
20196
|
// it as inert data during the rolling window so an older uninstall or
|
|
20190
20197
|
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
20191
20198
|
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
20192
|
-
|
|
20193
|
-
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20194
|
-
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20195
|
-
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
20196
|
-
"fi; fi; ",
|
|
20199
|
+
PRIM_CONFIG_SHELL_RESOLVER,
|
|
20197
20200
|
`case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
|
|
20198
20201
|
'exec "$prim_launcher" "$@"'
|
|
20199
20202
|
].join("");
|
|
@@ -20822,6 +20825,53 @@ import {
|
|
|
20822
20825
|
writeFileSync as writeFileSync5
|
|
20823
20826
|
} from "fs";
|
|
20824
20827
|
import { delimiter, dirname as dirname10, isAbsolute as isAbsolute5, join as join13, resolve as resolve4 } from "path";
|
|
20828
|
+
|
|
20829
|
+
// src/lib/git-hook-contract.ts
|
|
20830
|
+
var GIT_HOOK_ENTRYPOINT_CONTENT = `#!/bin/sh
|
|
20831
|
+
# prim git hook entrypoint v1 \u2014 managed by prim; do not edit.
|
|
20832
|
+
# Run by the "# >>> prim <hook> hook >>>" block in a Git hook file. Acts only
|
|
20833
|
+
# where prim is active (git config prim.active true) and never fails the hook.
|
|
20834
|
+
case "$0" in */*) prim_dir=\${0%/*} ;; *) exit 0 ;; esac
|
|
20835
|
+
prim_launcher="$prim_dir/${STABLE_HOOK_LAUNCHER_NAME}"
|
|
20836
|
+
[ -x "$prim_launcher" ] || exit 0
|
|
20837
|
+
[ "$(git config --get prim.active 2>/dev/null)" = "true" ] || exit 0
|
|
20838
|
+
prim_hook=\${1-}
|
|
20839
|
+
if [ "$#" -gt 0 ]; then shift; fi
|
|
20840
|
+
case "$prim_hook" in
|
|
20841
|
+
pre-commit)
|
|
20842
|
+
"$prim_launcher" prim-pre-commit "$@" || :
|
|
20843
|
+
;;
|
|
20844
|
+
post-commit)
|
|
20845
|
+
prim_sha=$(git rev-parse --verify HEAD 2>/dev/null) || exit 0
|
|
20846
|
+
case "$prim_sha" in *[!0-9a-f]* | "") exit 0 ;; esac
|
|
20847
|
+
case "\${#prim_sha}" in 40 | 64) ;; *) exit 0 ;; esac
|
|
20848
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20849
|
+
prim_observed=$(mktemp "\${TMPDIR:-/tmp}/prim-post-commit-observed.XXXXXXXX" 2>/dev/null) || prim_observed=
|
|
20850
|
+
(
|
|
20851
|
+
trap '' HUP
|
|
20852
|
+
trap 'if [ -n "$prim_observed" ]; then rm -f "$prim_observed"; fi' 0
|
|
20853
|
+
PRIM_COMMIT_SHA=$prim_sha PRIM_COMMIT_BRANCH=$prim_branch PRIM_COMMIT_OBSERVED_FILE=$prim_observed "$prim_launcher" prim-post-commit
|
|
20854
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20855
|
+
;;
|
|
20856
|
+
post-rewrite)
|
|
20857
|
+
case "\${1-}" in amend | rebase) prim_source=$1 ;; *) exit 0 ;; esac
|
|
20858
|
+
prim_pairs=$(mktemp "\${TMPDIR:-/tmp}/prim-post-rewrite-pairs.XXXXXXXX" 2>/dev/null) || exit 0
|
|
20859
|
+
if ! chmod 600 "$prim_pairs" 2>/dev/null || ! cat >"$prim_pairs"; then
|
|
20860
|
+
rm -f "$prim_pairs"
|
|
20861
|
+
exit 0
|
|
20862
|
+
fi
|
|
20863
|
+
prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
|
|
20864
|
+
(
|
|
20865
|
+
trap '' HUP
|
|
20866
|
+
trap 'rm -f "$prim_pairs"' 0
|
|
20867
|
+
PRIM_REWRITE_SOURCE=$prim_source PRIM_REWRITE_BRANCH=$prim_branch PRIM_REWRITE_PAIRS_FILE=$prim_pairs "$prim_launcher" prim-post-rewrite
|
|
20868
|
+
) </dev/null >/dev/null 2>&1 &
|
|
20869
|
+
;;
|
|
20870
|
+
esac
|
|
20871
|
+
exit 0
|
|
20872
|
+
`;
|
|
20873
|
+
|
|
20874
|
+
// src/lib/hook-runtime.ts
|
|
20825
20875
|
var RELEASE_PREFIX = "release-";
|
|
20826
20876
|
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20827
20877
|
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|