@primitive.ai/prim 0.1.0-alpha.92 → 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 +84 -10
- package/SKILL.md +5 -2
- package/dist/{chunk-67VNLLBN.js → chunk-2GP5UFV7.js} +1 -0
- package/dist/{chunk-26P57LAR.js → chunk-AXQQMX2U.js} +203 -9
- package/dist/{chunk-M6RIJVRE.js → chunk-DSWT6BCC.js} +78 -4
- package/dist/{chunk-FBAYCS3X.js → chunk-DXJQR4QI.js} +150 -38
- package/dist/chunk-FXF4JWK2.js +162 -0
- package/dist/{chunk-PCVGBE5B.js → chunk-G2VMA2QO.js} +2 -1
- package/dist/{chunk-NAHHFSLH.js → chunk-ICM2XCXS.js} +2 -2
- package/dist/{chunk-5HRR4AOR.js → chunk-IMK4JKTA.js} +1 -1
- package/dist/{chunk-OAAP2MY6.js → chunk-K7D2EYBS.js} +2 -2
- package/dist/{chunk-ADUTW66W.js → chunk-O7YAW7G6.js} +6 -6
- package/dist/{chunk-5AFRMOPX.js → chunk-OH3EZXYX.js} +1 -1
- package/dist/{chunk-KFXF2V5G.js → chunk-OTHKG76J.js} +1 -1
- package/dist/chunk-OYHYCK4K.js +13 -0
- package/dist/{chunk-FKXFUUWJ.js → chunk-TYAHC25F.js} +1 -1
- package/dist/{chunk-5GYQ4J3D.js → chunk-UKUAAAXE.js} +2 -2
- package/dist/{chunk-LGGMJYY4.js → chunk-WUXFLE7X.js} +720 -369
- package/dist/{chunk-WX52U7Z2.js → chunk-ZU563PQI.js} +58 -2
- package/dist/daemon/server.js +372 -123
- package/dist/hook-runtime/daemon/server.js +372 -123
- package/dist/hook-runtime/hooks/post-commit.js +192 -58
- package/dist/hook-runtime/hooks/post-rewrite.js +58 -40
- package/dist/hook-runtime/hooks/post-tool-use.js +150 -67
- package/dist/hook-runtime/hooks/pre-tool-use.js +87 -15
- package/dist/hook-runtime/hooks/prim-hook.js +197 -107
- package/dist/hook-runtime/hooks/session-end.js +53 -5
- package/dist/hook-runtime/hooks/session-start.js +880 -280
- package/dist/hook-runtime/index.js +4008 -2438
- package/dist/hook-runtime/statusline-main.js +23 -1
- package/dist/hooks/post-commit.js +15 -8
- package/dist/hooks/post-rewrite.js +11 -8
- package/dist/hooks/post-tool-use.js +13 -15
- package/dist/hooks/pre-commit.js +4 -4
- package/dist/hooks/pre-tool-use.js +10 -12
- package/dist/hooks/prim-hook.js +17 -14
- package/dist/hooks/session-end.js +4 -4
- package/dist/hooks/session-start.js +35 -45
- package/dist/index.js +1401 -620
- package/dist/statusline-main.js +23 -1
- package/package.json +1 -1
- package/dist/chunk-BTNNEH2W.js +0 -79
|
@@ -59,10 +59,10 @@ import {
|
|
|
59
59
|
fstatSync as fstatSync2,
|
|
60
60
|
lstatSync as lstatSync3,
|
|
61
61
|
openSync as openSync4,
|
|
62
|
-
readFileSync as
|
|
62
|
+
readFileSync as readFileSync10,
|
|
63
63
|
unlinkSync as unlinkSync2
|
|
64
64
|
} from "fs";
|
|
65
|
-
import { basename as
|
|
65
|
+
import { basename as basename3, dirname as dirname9, isAbsolute as isAbsolute4, join as join11 } from "path";
|
|
66
66
|
import { fileURLToPath } from "url";
|
|
67
67
|
|
|
68
68
|
// src/binding.ts
|
|
@@ -379,16 +379,16 @@ function resolveOrg(args) {
|
|
|
379
379
|
import {
|
|
380
380
|
appendFileSync,
|
|
381
381
|
closeSync as closeSync2,
|
|
382
|
-
existsSync as
|
|
382
|
+
existsSync as existsSync5,
|
|
383
383
|
fstatSync,
|
|
384
384
|
mkdirSync as mkdirSync4,
|
|
385
385
|
openSync as openSync2,
|
|
386
386
|
opendirSync,
|
|
387
|
-
readFileSync as
|
|
387
|
+
readFileSync as readFileSync6,
|
|
388
388
|
readSync,
|
|
389
|
-
readdirSync
|
|
389
|
+
readdirSync as readdirSync2
|
|
390
390
|
} from "fs";
|
|
391
|
-
import { dirname as
|
|
391
|
+
import { dirname as dirname6, join as join7 } from "path";
|
|
392
392
|
|
|
393
393
|
// src/client.ts
|
|
394
394
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -426,8 +426,19 @@ function getSiteUrlForEnvironment(primApiUrl) {
|
|
|
426
426
|
}
|
|
427
427
|
var CLI_MANAGEMENT_RESPONSE_MAX_BYTES = 2 * 1024 * 1024;
|
|
428
428
|
|
|
429
|
+
// src/drain-progress.ts
|
|
430
|
+
import {
|
|
431
|
+
chmodSync as chmodSync2,
|
|
432
|
+
existsSync as existsSync4,
|
|
433
|
+
readFileSync as readFileSync5,
|
|
434
|
+
readdirSync,
|
|
435
|
+
rmSync as rmSync4,
|
|
436
|
+
rmdirSync
|
|
437
|
+
} from "fs";
|
|
438
|
+
import { basename, dirname as dirname5, join as join6 } from "path";
|
|
439
|
+
|
|
429
440
|
// src/journal.ts
|
|
430
|
-
var JOURNAL_DIR =
|
|
441
|
+
var JOURNAL_DIR = join7(primConfigDirectory(), "moves");
|
|
431
442
|
var UNBOUND_BUCKET = "_unbound";
|
|
432
443
|
var JOURNAL_BASENAME = "journal.ndjson";
|
|
433
444
|
var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
|
|
@@ -439,15 +450,15 @@ function envSlug(apiUrl) {
|
|
|
439
450
|
return slug;
|
|
440
451
|
}
|
|
441
452
|
function currentEnvDir() {
|
|
442
|
-
return
|
|
453
|
+
return join7(JOURNAL_DIR, envSlug(getSiteUrl()));
|
|
443
454
|
}
|
|
444
455
|
var DIR_MODE = 448;
|
|
445
456
|
var FILE_MODE = 384;
|
|
446
457
|
var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
|
|
447
458
|
var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
|
|
448
459
|
function appendMoveToPath(path, move) {
|
|
449
|
-
const dir =
|
|
450
|
-
if (!
|
|
460
|
+
const dir = dirname6(path);
|
|
461
|
+
if (!existsSync5(dir)) {
|
|
451
462
|
mkdirSync4(dir, { recursive: true, mode: DIR_MODE });
|
|
452
463
|
}
|
|
453
464
|
appendFileSync(path, `${JSON.stringify(move)}
|
|
@@ -455,10 +466,10 @@ function appendMoveToPath(path, move) {
|
|
|
455
466
|
}
|
|
456
467
|
function bucketDir(orgId) {
|
|
457
468
|
const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
|
|
458
|
-
return
|
|
469
|
+
return join7(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
|
|
459
470
|
}
|
|
460
471
|
function journalPath(orgId) {
|
|
461
|
-
return
|
|
472
|
+
return join7(bucketDir(orgId), JOURNAL_BASENAME);
|
|
462
473
|
}
|
|
463
474
|
function appendMove(move, orgId) {
|
|
464
475
|
appendMoveToPath(journalPath(orgId), move);
|
|
@@ -467,15 +478,15 @@ var FLUSHING_PREFIX = `${JOURNAL_BASENAME}.flushing.`;
|
|
|
467
478
|
|
|
468
479
|
// src/lib/activation.ts
|
|
469
480
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
470
|
-
import { existsSync as
|
|
481
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
471
482
|
import { homedir as homedir2 } from "os";
|
|
472
|
-
import { join as
|
|
483
|
+
import { join as join8 } from "path";
|
|
473
484
|
|
|
474
485
|
// src/lib/git.ts
|
|
475
486
|
import { execFileSync } from "child_process";
|
|
476
487
|
import { createHash as createHash3 } from "crypto";
|
|
477
488
|
import { lstatSync, realpathSync } from "fs";
|
|
478
|
-
import { basename, dirname as
|
|
489
|
+
import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
|
|
479
490
|
var GIT_TIMEOUT_MS = 1e3;
|
|
480
491
|
var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
|
|
481
492
|
var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
|
|
@@ -623,10 +634,10 @@ function hasProjectPrimInstall(cwd) {
|
|
|
623
634
|
const root = gitToplevel(cwd);
|
|
624
635
|
if (root === null || root === homedir2()) return false;
|
|
625
636
|
for (const rel of PROJECT_INSTALL_FILES) {
|
|
626
|
-
const path =
|
|
627
|
-
if (
|
|
637
|
+
const path = join8(root, rel);
|
|
638
|
+
if (existsSync6(path)) {
|
|
628
639
|
try {
|
|
629
|
-
const content =
|
|
640
|
+
const content = readFileSync7(path, "utf-8");
|
|
630
641
|
if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
|
|
631
642
|
} catch {
|
|
632
643
|
}
|
|
@@ -18712,12 +18723,18 @@ function cachedCollectScopeAdmits(cwd, facts) {
|
|
|
18712
18723
|
);
|
|
18713
18724
|
}
|
|
18714
18725
|
|
|
18726
|
+
// src/lib/unattended.ts
|
|
18727
|
+
var UNATTENDED_ENV = "PRIM_UNATTENDED";
|
|
18728
|
+
function unattendedEnv(env = process.env) {
|
|
18729
|
+
return { ...env, [UNATTENDED_ENV]: "1" };
|
|
18730
|
+
}
|
|
18731
|
+
|
|
18715
18732
|
// src/lib/workspace-id.ts
|
|
18716
18733
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
18717
18734
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
18718
18735
|
import {
|
|
18719
18736
|
constants as constants2,
|
|
18720
|
-
chmodSync as
|
|
18737
|
+
chmodSync as chmodSync3,
|
|
18721
18738
|
closeSync as closeSync3,
|
|
18722
18739
|
fchmodSync as fchmodSync2,
|
|
18723
18740
|
fsyncSync as fsyncSync2,
|
|
@@ -18725,13 +18742,13 @@ import {
|
|
|
18725
18742
|
lstatSync as lstatSync2,
|
|
18726
18743
|
mkdirSync as mkdirSync5,
|
|
18727
18744
|
openSync as openSync3,
|
|
18728
|
-
readFileSync as
|
|
18745
|
+
readFileSync as readFileSync8,
|
|
18729
18746
|
statSync as statSync2,
|
|
18730
18747
|
unlinkSync,
|
|
18731
18748
|
writeFileSync as writeFileSync3
|
|
18732
18749
|
} from "fs";
|
|
18733
|
-
import { dirname as
|
|
18734
|
-
var WORKSPACE_ID_RELATIVE_PATH =
|
|
18750
|
+
import { dirname as dirname8, isAbsolute as isAbsolute3, join as join9, resolve as resolve3 } from "path";
|
|
18751
|
+
var WORKSPACE_ID_RELATIVE_PATH = join9("prim", "workspace-id");
|
|
18735
18752
|
var MAX_ANCESTORS = 64;
|
|
18736
18753
|
var MAX_GIT_FILE_BYTES = 4096;
|
|
18737
18754
|
var MAX_ID_FILE_BYTES = 128;
|
|
@@ -18790,19 +18807,19 @@ function resolveWorkspaceIdPath(cwd) {
|
|
|
18790
18807
|
function resolveFromFilesystem(cwd) {
|
|
18791
18808
|
let current = resolve3(cwd);
|
|
18792
18809
|
for (let depth = 0; depth < MAX_ANCESTORS; depth += 1) {
|
|
18793
|
-
const dotGit =
|
|
18810
|
+
const dotGit = join9(current, ".git");
|
|
18794
18811
|
try {
|
|
18795
18812
|
const stat = lstatSync2(dotGit);
|
|
18796
18813
|
if (stat.isDirectory() && isGitDirectory(dotGit)) {
|
|
18797
|
-
return
|
|
18814
|
+
return join9(dotGit, WORKSPACE_ID_RELATIVE_PATH);
|
|
18798
18815
|
}
|
|
18799
18816
|
if (stat.isFile() && stat.size <= MAX_GIT_FILE_BYTES) {
|
|
18800
|
-
const contents =
|
|
18817
|
+
const contents = readFileSync8(dotGit, "utf8");
|
|
18801
18818
|
const match = /^gitdir: (.+?)(?:\r?\n)?$/.exec(contents);
|
|
18802
18819
|
if (match?.[1]) {
|
|
18803
18820
|
const gitDirectory = isAbsolute3(match[1]) ? resolve3(match[1]) : resolve3(current, match[1]);
|
|
18804
18821
|
if (isGitDirectory(gitDirectory)) {
|
|
18805
|
-
return
|
|
18822
|
+
return join9(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
|
|
18806
18823
|
}
|
|
18807
18824
|
}
|
|
18808
18825
|
}
|
|
@@ -18813,7 +18830,7 @@ function resolveFromFilesystem(cwd) {
|
|
|
18813
18830
|
return null;
|
|
18814
18831
|
}
|
|
18815
18832
|
}
|
|
18816
|
-
const parent =
|
|
18833
|
+
const parent = dirname8(current);
|
|
18817
18834
|
if (parent === current) break;
|
|
18818
18835
|
current = parent;
|
|
18819
18836
|
}
|
|
@@ -18821,7 +18838,7 @@ function resolveFromFilesystem(cwd) {
|
|
|
18821
18838
|
}
|
|
18822
18839
|
function isGitDirectory(path) {
|
|
18823
18840
|
try {
|
|
18824
|
-
return statSync2(
|
|
18841
|
+
return statSync2(join9(path, "HEAD")).isFile();
|
|
18825
18842
|
} catch {
|
|
18826
18843
|
return false;
|
|
18827
18844
|
}
|
|
@@ -18840,7 +18857,7 @@ function inspectPath(path) {
|
|
|
18840
18857
|
return { status: "corrupt", path, reason: "invalid_content" };
|
|
18841
18858
|
}
|
|
18842
18859
|
try {
|
|
18843
|
-
const contents =
|
|
18860
|
+
const contents = readFileSync8(path, "utf8");
|
|
18844
18861
|
const workspaceId = contents.endsWith("\n") ? contents.slice(0, -1) : contents;
|
|
18845
18862
|
if ((contents === workspaceId || contents === `${workspaceId}
|
|
18846
18863
|
`) && isCanonicalWorkspaceId(workspaceId)) {
|
|
@@ -18857,14 +18874,14 @@ function inspectPath(path) {
|
|
|
18857
18874
|
}
|
|
18858
18875
|
}
|
|
18859
18876
|
function createWorkspaceId(path) {
|
|
18860
|
-
const parent =
|
|
18877
|
+
const parent = dirname8(path);
|
|
18861
18878
|
const workspaceId = randomUUID2();
|
|
18862
|
-
const temporaryPath =
|
|
18879
|
+
const temporaryPath = join9(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
|
|
18863
18880
|
let temporaryCreated = false;
|
|
18864
18881
|
let publishing = false;
|
|
18865
18882
|
try {
|
|
18866
18883
|
mkdirSync5(parent, { recursive: true, mode: 448 });
|
|
18867
|
-
|
|
18884
|
+
chmodSync3(parent, 448);
|
|
18868
18885
|
const fd = openSync3(
|
|
18869
18886
|
temporaryPath,
|
|
18870
18887
|
constants2.O_CREAT | constants2.O_EXCL | constants2.O_WRONLY,
|
|
@@ -18927,8 +18944,8 @@ var LEGACY_ENVELOPE_VERSION = 1;
|
|
|
18927
18944
|
var ENVELOPE_VERSION = LEGACY_ENVELOPE_VERSION;
|
|
18928
18945
|
|
|
18929
18946
|
// src/hooks/redact.ts
|
|
18930
|
-
import { existsSync as
|
|
18931
|
-
import { join as
|
|
18947
|
+
import { existsSync as existsSync7, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
|
|
18948
|
+
import { join as join10 } from "path";
|
|
18932
18949
|
import { Worker } from "worker_threads";
|
|
18933
18950
|
var USER_HOME_RULES = [
|
|
18934
18951
|
{
|
|
@@ -19107,7 +19124,7 @@ function toRewriteMove(rewrite, cliVersion, cwd, context) {
|
|
|
19107
19124
|
}
|
|
19108
19125
|
|
|
19109
19126
|
// src/hooks/post-rewrite.ts
|
|
19110
|
-
var here =
|
|
19127
|
+
var here = dirname9(fileURLToPath(import.meta.url));
|
|
19111
19128
|
var GIT_TIMEOUT_MS3 = 1e3;
|
|
19112
19129
|
var MAX_PAIRS_FILE_BYTES = 1048576;
|
|
19113
19130
|
var MAX_PAIRS_FILE_AGE_MS = 10 * 60 * 1e3;
|
|
@@ -19137,7 +19154,7 @@ function privatePairsFileStat(stat, now) {
|
|
|
19137
19154
|
}
|
|
19138
19155
|
function rewritePairsFromLauncher(env = process.env, now = Date.now()) {
|
|
19139
19156
|
const path = env.PRIM_REWRITE_PAIRS_FILE;
|
|
19140
|
-
if (!path || !isAbsolute4(path) || !PAIRS_FILE_RE.test(
|
|
19157
|
+
if (!path || !isAbsolute4(path) || !PAIRS_FILE_RE.test(basename3(path))) return;
|
|
19141
19158
|
let fd;
|
|
19142
19159
|
try {
|
|
19143
19160
|
const pathStat = lstatSync3(path);
|
|
@@ -19147,7 +19164,7 @@ function rewritePairsFromLauncher(env = process.env, now = Date.now()) {
|
|
|
19147
19164
|
if (!privatePairsFileStat(openStat, now) || openStat.dev !== pathStat.dev || openStat.ino !== pathStat.ino) {
|
|
19148
19165
|
return;
|
|
19149
19166
|
}
|
|
19150
|
-
const bytes =
|
|
19167
|
+
const bytes = readFileSync10(fd);
|
|
19151
19168
|
if (bytes.length !== openStat.size) return;
|
|
19152
19169
|
let text;
|
|
19153
19170
|
try {
|
|
@@ -19203,17 +19220,18 @@ function validBranch(value) {
|
|
|
19203
19220
|
}
|
|
19204
19221
|
function resolveCliVersion() {
|
|
19205
19222
|
try {
|
|
19206
|
-
const pkg = JSON.parse(
|
|
19223
|
+
const pkg = JSON.parse(readFileSync10(join11(here, "..", "..", "package.json"), "utf-8"));
|
|
19207
19224
|
return pkg.version ?? "unknown";
|
|
19208
19225
|
} catch {
|
|
19209
19226
|
return "unknown";
|
|
19210
19227
|
}
|
|
19211
19228
|
}
|
|
19212
19229
|
function spawnBackgroundFlush() {
|
|
19213
|
-
const entry =
|
|
19230
|
+
const entry = join11(here, "..", "index.js");
|
|
19214
19231
|
spawn(process.execPath, [entry, "moves", "flush"], {
|
|
19215
19232
|
detached: true,
|
|
19216
|
-
stdio: "ignore"
|
|
19233
|
+
stdio: "ignore",
|
|
19234
|
+
env: unattendedEnv()
|
|
19217
19235
|
}).unref();
|
|
19218
19236
|
}
|
|
19219
19237
|
function runPostRewrite() {
|
|
@@ -52,8 +52,8 @@ var require_ucs2length = __commonJS({
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
// src/hooks/post-tool-use.ts
|
|
55
|
-
import { readFileSync as
|
|
56
|
-
import { dirname as
|
|
55
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
56
|
+
import { dirname as dirname12, join as join17 } from "path";
|
|
57
57
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
58
58
|
|
|
59
59
|
// src/binding.ts
|
|
@@ -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("");
|
|
@@ -20022,6 +20025,67 @@ function detachedHookShimCommand(bin, args = "") {
|
|
|
20022
20025
|
return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
|
|
20023
20026
|
}
|
|
20024
20027
|
|
|
20028
|
+
// src/lib/ansi.ts
|
|
20029
|
+
var ANSI_CODES = {
|
|
20030
|
+
yellow: "\x1B[33m",
|
|
20031
|
+
magenta: "\x1B[35m",
|
|
20032
|
+
blue: "\x1B[34m",
|
|
20033
|
+
cyan: "\x1B[36m",
|
|
20034
|
+
green: "\x1B[32m",
|
|
20035
|
+
red: "\x1B[31m",
|
|
20036
|
+
// 256-color approximation of the orange trigger marker (xterm 208).
|
|
20037
|
+
orange: "\x1B[38;5;208m",
|
|
20038
|
+
gray: "\x1B[90m"
|
|
20039
|
+
};
|
|
20040
|
+
var ANSI_RESET = "\x1B[0m";
|
|
20041
|
+
var ANSI_BOLD = "\x1B[1m";
|
|
20042
|
+
function supportsColor() {
|
|
20043
|
+
if (process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "") {
|
|
20044
|
+
return false;
|
|
20045
|
+
}
|
|
20046
|
+
return process.stderr.isTTY === true;
|
|
20047
|
+
}
|
|
20048
|
+
function color(text, c) {
|
|
20049
|
+
if (!supportsColor()) {
|
|
20050
|
+
return text;
|
|
20051
|
+
}
|
|
20052
|
+
return `${ANSI_CODES[c]}${text}${ANSI_RESET}`;
|
|
20053
|
+
}
|
|
20054
|
+
function bold(text) {
|
|
20055
|
+
if (!supportsColor()) {
|
|
20056
|
+
return text;
|
|
20057
|
+
}
|
|
20058
|
+
return `${ANSI_BOLD}${text}${ANSI_RESET}`;
|
|
20059
|
+
}
|
|
20060
|
+
var MAX_HEALTH_ERROR_LENGTH = 240;
|
|
20061
|
+
function boundedHealthError(value) {
|
|
20062
|
+
if (!value) return void 0;
|
|
20063
|
+
const clean = terminalSafeLine(value);
|
|
20064
|
+
if (!clean) return void 0;
|
|
20065
|
+
return clean.length <= MAX_HEALTH_ERROR_LENGTH ? clean : `${clean.slice(0, MAX_HEALTH_ERROR_LENGTH - 1)}\u2026`;
|
|
20066
|
+
}
|
|
20067
|
+
|
|
20068
|
+
// src/lib/delivery-backlog.ts
|
|
20069
|
+
var MS_PER_SECOND = 1e3;
|
|
20070
|
+
var MS_PER_MINUTE = 60 * MS_PER_SECOND;
|
|
20071
|
+
var MS_PER_HOUR = 60 * MS_PER_MINUTE;
|
|
20072
|
+
var MS_PER_DAY = 24 * MS_PER_HOUR;
|
|
20073
|
+
function isNonNegativeInteger(value) {
|
|
20074
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
20075
|
+
}
|
|
20076
|
+
function isPositiveInteger(value) {
|
|
20077
|
+
return isNonNegativeInteger(value) && value > 0;
|
|
20078
|
+
}
|
|
20079
|
+
function deliveryBacklogState(ingestion) {
|
|
20080
|
+
if (ingestion?.healthy !== false) return void 0;
|
|
20081
|
+
const failures = ingestion.consecutiveFailures;
|
|
20082
|
+
const failedWithoutProgress = failures !== 0 && !(isPositiveInteger(failures) && isPositiveInteger(ingestion.lastFailedDrainAcknowledgedCount));
|
|
20083
|
+
if (failedWithoutProgress) return "failing";
|
|
20084
|
+
const retained = ingestion.lastRetainedBucketCount;
|
|
20085
|
+
if (!isNonNegativeInteger(retained)) return "failing";
|
|
20086
|
+
return retained > 0 ? "retained" : "draining";
|
|
20087
|
+
}
|
|
20088
|
+
|
|
20025
20089
|
// src/lib/presence.ts
|
|
20026
20090
|
var DECISION_ORIGIN = "https://app.getprimitive.ai";
|
|
20027
20091
|
function validDecisionUrl(value) {
|
|
@@ -20096,7 +20160,8 @@ function formatStatusline(version, snapshot, resolveIngestionStatus, options = {
|
|
|
20096
20160
|
if (snapshot.ingestion?.healthy === false) {
|
|
20097
20161
|
const pending = snapshot.ingestion.pendingCount;
|
|
20098
20162
|
const qualifier = snapshot.ingestion.pendingSampled ? "at least " : "";
|
|
20099
|
-
|
|
20163
|
+
const delivery = deliveryBacklogState(snapshot.ingestion) === "draining" && snapshot.heartbeat?.healthy === true ? "draining" : "stalled";
|
|
20164
|
+
return `primitive ${version} (daemon: degraded \xB7 delivery: ${delivery}${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
|
|
20100
20165
|
}
|
|
20101
20166
|
if (snapshot.heartbeat?.healthy === false) {
|
|
20102
20167
|
return `primitive ${version} (daemon: degraded \xB7 presence: unavailable${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
|
|
@@ -20599,6 +20664,53 @@ import {
|
|
|
20599
20664
|
writeFileSync as writeFileSync5
|
|
20600
20665
|
} from "fs";
|
|
20601
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
|
|
20602
20714
|
var RELEASE_PREFIX = "release-";
|
|
20603
20715
|
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20604
20716
|
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|
|
@@ -25682,17 +25794,30 @@ function requireDurableIngestAcknowledgement(value, expected, cwd = process.cwd(
|
|
|
25682
25794
|
import {
|
|
25683
25795
|
appendFileSync,
|
|
25684
25796
|
closeSync as closeSync3,
|
|
25685
|
-
existsSync as
|
|
25797
|
+
existsSync as existsSync11,
|
|
25686
25798
|
fstatSync,
|
|
25687
25799
|
mkdirSync as mkdirSync7,
|
|
25688
25800
|
openSync as openSync3,
|
|
25689
25801
|
opendirSync,
|
|
25690
|
-
readFileSync as
|
|
25802
|
+
readFileSync as readFileSync13,
|
|
25691
25803
|
readSync,
|
|
25692
|
-
readdirSync as
|
|
25804
|
+
readdirSync as readdirSync4
|
|
25693
25805
|
} from "fs";
|
|
25694
|
-
import { dirname as
|
|
25695
|
-
|
|
25806
|
+
import { dirname as dirname11, join as join15 } from "path";
|
|
25807
|
+
|
|
25808
|
+
// src/drain-progress.ts
|
|
25809
|
+
import {
|
|
25810
|
+
chmodSync as chmodSync5,
|
|
25811
|
+
existsSync as existsSync10,
|
|
25812
|
+
readFileSync as readFileSync12,
|
|
25813
|
+
readdirSync as readdirSync3,
|
|
25814
|
+
rmSync as rmSync6,
|
|
25815
|
+
rmdirSync
|
|
25816
|
+
} from "fs";
|
|
25817
|
+
import { basename as basename2, dirname as dirname10, join as join14 } from "path";
|
|
25818
|
+
|
|
25819
|
+
// src/journal.ts
|
|
25820
|
+
var JOURNAL_DIR = join15(primConfigDirectory(), "moves");
|
|
25696
25821
|
var UNBOUND_BUCKET = "_unbound";
|
|
25697
25822
|
var JOURNAL_BASENAME = "journal.ndjson";
|
|
25698
25823
|
var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
|
|
@@ -25704,15 +25829,15 @@ function envSlug(apiUrl) {
|
|
|
25704
25829
|
return slug;
|
|
25705
25830
|
}
|
|
25706
25831
|
function currentEnvDir() {
|
|
25707
|
-
return
|
|
25832
|
+
return join15(JOURNAL_DIR, envSlug(getSiteUrl()));
|
|
25708
25833
|
}
|
|
25709
25834
|
var DIR_MODE = 448;
|
|
25710
25835
|
var FILE_MODE2 = 384;
|
|
25711
25836
|
var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
|
|
25712
25837
|
var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
|
|
25713
25838
|
function appendMoveToPath(path, move) {
|
|
25714
|
-
const dir =
|
|
25715
|
-
if (!
|
|
25839
|
+
const dir = dirname11(path);
|
|
25840
|
+
if (!existsSync11(dir)) {
|
|
25716
25841
|
mkdirSync7(dir, { recursive: true, mode: DIR_MODE });
|
|
25717
25842
|
}
|
|
25718
25843
|
appendFileSync(path, `${JSON.stringify(move)}
|
|
@@ -25720,10 +25845,10 @@ function appendMoveToPath(path, move) {
|
|
|
25720
25845
|
}
|
|
25721
25846
|
function bucketDir(orgId) {
|
|
25722
25847
|
const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
|
|
25723
|
-
return
|
|
25848
|
+
return join15(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
|
|
25724
25849
|
}
|
|
25725
25850
|
function journalPath(orgId) {
|
|
25726
|
-
return
|
|
25851
|
+
return join15(bucketDir(orgId), JOURNAL_BASENAME);
|
|
25727
25852
|
}
|
|
25728
25853
|
function appendMove(move, orgId) {
|
|
25729
25854
|
appendMoveToPath(journalPath(orgId), move);
|
|
@@ -25750,51 +25875,9 @@ import { platform } from "os";
|
|
|
25750
25875
|
var AGENT_ENVELOPE_VERSION = 3;
|
|
25751
25876
|
|
|
25752
25877
|
// src/hooks/redact.ts
|
|
25753
|
-
import { existsSync as
|
|
25754
|
-
import { join as
|
|
25878
|
+
import { existsSync as existsSync12, readFileSync as readFileSync14, statSync as statSync5 } from "fs";
|
|
25879
|
+
import { join as join16 } from "path";
|
|
25755
25880
|
import { Worker } from "worker_threads";
|
|
25756
|
-
|
|
25757
|
-
// src/lib/ansi.ts
|
|
25758
|
-
var ANSI_CODES = {
|
|
25759
|
-
yellow: "\x1B[33m",
|
|
25760
|
-
magenta: "\x1B[35m",
|
|
25761
|
-
blue: "\x1B[34m",
|
|
25762
|
-
cyan: "\x1B[36m",
|
|
25763
|
-
green: "\x1B[32m",
|
|
25764
|
-
red: "\x1B[31m",
|
|
25765
|
-
// 256-color approximation of the orange trigger marker (xterm 208).
|
|
25766
|
-
orange: "\x1B[38;5;208m",
|
|
25767
|
-
gray: "\x1B[90m"
|
|
25768
|
-
};
|
|
25769
|
-
var ANSI_RESET = "\x1B[0m";
|
|
25770
|
-
var ANSI_BOLD = "\x1B[1m";
|
|
25771
|
-
function supportsColor() {
|
|
25772
|
-
if (process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "") {
|
|
25773
|
-
return false;
|
|
25774
|
-
}
|
|
25775
|
-
return process.stderr.isTTY === true;
|
|
25776
|
-
}
|
|
25777
|
-
function color(text, c) {
|
|
25778
|
-
if (!supportsColor()) {
|
|
25779
|
-
return text;
|
|
25780
|
-
}
|
|
25781
|
-
return `${ANSI_CODES[c]}${text}${ANSI_RESET}`;
|
|
25782
|
-
}
|
|
25783
|
-
function bold(text) {
|
|
25784
|
-
if (!supportsColor()) {
|
|
25785
|
-
return text;
|
|
25786
|
-
}
|
|
25787
|
-
return `${ANSI_BOLD}${text}${ANSI_RESET}`;
|
|
25788
|
-
}
|
|
25789
|
-
var MAX_HEALTH_ERROR_LENGTH = 240;
|
|
25790
|
-
function boundedHealthError(value) {
|
|
25791
|
-
if (!value) return void 0;
|
|
25792
|
-
const clean = terminalSafeLine(value);
|
|
25793
|
-
if (!clean) return void 0;
|
|
25794
|
-
return clean.length <= MAX_HEALTH_ERROR_LENGTH ? clean : `${clean.slice(0, MAX_HEALTH_ERROR_LENGTH - 1)}\u2026`;
|
|
25795
|
-
}
|
|
25796
|
-
|
|
25797
|
-
// src/hooks/redact.ts
|
|
25798
25881
|
var USER_HOME_RULES = [
|
|
25799
25882
|
{
|
|
25800
25883
|
pattern: /\/Users\/[^/\\\s"'`]+/g,
|
|
@@ -25869,15 +25952,15 @@ function normalizedWorkspaceFlags(value) {
|
|
|
25869
25952
|
return [...new Set(`g${requested}`)].sort().join("");
|
|
25870
25953
|
}
|
|
25871
25954
|
function loadWorkspaceRules(cwd) {
|
|
25872
|
-
const path =
|
|
25873
|
-
if (!
|
|
25955
|
+
const path = join16(cwd, WORKSPACE_FILE2);
|
|
25956
|
+
if (!existsSync12(path)) return [];
|
|
25874
25957
|
let cfg;
|
|
25875
25958
|
try {
|
|
25876
25959
|
if (statSync5(path).size > MAX_WORKSPACE_CONFIG_BYTES) {
|
|
25877
25960
|
debugRedaction(`ignoring oversized ${WORKSPACE_FILE2}`);
|
|
25878
25961
|
return [];
|
|
25879
25962
|
}
|
|
25880
|
-
cfg = JSON.parse(
|
|
25963
|
+
cfg = JSON.parse(readFileSync14(path, "utf-8"));
|
|
25881
25964
|
} catch {
|
|
25882
25965
|
debugRedaction(`ignoring unparseable ${WORKSPACE_FILE2}`);
|
|
25883
25966
|
return [];
|
|
@@ -26182,10 +26265,10 @@ function editingToolsFor(agent) {
|
|
|
26182
26265
|
}
|
|
26183
26266
|
return EDITING_TOOLS;
|
|
26184
26267
|
}
|
|
26185
|
-
var here =
|
|
26268
|
+
var here = dirname12(fileURLToPath2(import.meta.url));
|
|
26186
26269
|
function resolveCliVersion() {
|
|
26187
26270
|
try {
|
|
26188
|
-
const pkg = JSON.parse(
|
|
26271
|
+
const pkg = JSON.parse(readFileSync15(join17(here, "..", "..", "package.json"), "utf-8"));
|
|
26189
26272
|
return pkg.version ?? "unknown";
|
|
26190
26273
|
} catch {
|
|
26191
26274
|
return "unknown";
|