@primitive.ai/prim 0.1.0-alpha.91 → 0.1.0-alpha.93

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.
Files changed (40) hide show
  1. package/README.md +34 -2
  2. package/dist/{chunk-67VNLLBN.js → chunk-2GP5UFV7.js} +1 -0
  3. package/dist/{chunk-VW3FDYRT.js → chunk-36TWVNBE.js} +6 -6
  4. package/dist/{chunk-HU4PW6I6.js → chunk-C3VAA5CG.js} +1 -1
  5. package/dist/{chunk-FOLKHXLJ.js → chunk-DCJN6LZH.js} +37 -5
  6. package/dist/{chunk-M6RIJVRE.js → chunk-DSWT6BCC.js} +78 -4
  7. package/dist/{chunk-FBAYCS3X.js → chunk-DXJQR4QI.js} +150 -38
  8. package/dist/{chunk-PCVGBE5B.js → chunk-G2VMA2QO.js} +2 -1
  9. package/dist/{chunk-NAHHFSLH.js → chunk-ICM2XCXS.js} +2 -2
  10. package/dist/{chunk-OAAP2MY6.js → chunk-K7D2EYBS.js} +2 -2
  11. package/dist/{chunk-5AFRMOPX.js → chunk-OH3EZXYX.js} +1 -1
  12. package/dist/{chunk-KFXF2V5G.js → chunk-OTHKG76J.js} +1 -1
  13. package/dist/chunk-OYHYCK4K.js +13 -0
  14. package/dist/{chunk-FKXFUUWJ.js → chunk-TYAHC25F.js} +1 -1
  15. package/dist/{chunk-5GYQ4J3D.js → chunk-UKUAAAXE.js} +2 -2
  16. package/dist/{chunk-EWZMDD44.js → chunk-X64HTHUF.js} +22 -3
  17. package/dist/{chunk-WX52U7Z2.js → chunk-ZU563PQI.js} +58 -2
  18. package/dist/daemon/server.js +382 -124
  19. package/dist/hook-runtime/daemon/server.js +382 -124
  20. package/dist/hook-runtime/hooks/post-commit.js +57 -39
  21. package/dist/hook-runtime/hooks/post-rewrite.js +58 -40
  22. package/dist/hook-runtime/hooks/post-tool-use.js +111 -78
  23. package/dist/hook-runtime/hooks/pre-tool-use.js +48 -26
  24. package/dist/hook-runtime/hooks/prim-hook.js +157 -117
  25. package/dist/hook-runtime/hooks/session-end.js +1 -1
  26. package/dist/hook-runtime/hooks/session-start.js +38 -4
  27. package/dist/hook-runtime/index.js +1293 -526
  28. package/dist/hook-runtime/statusline-main.js +23 -1
  29. package/dist/hooks/post-commit.js +11 -8
  30. package/dist/hooks/post-rewrite.js +11 -8
  31. package/dist/hooks/post-tool-use.js +13 -15
  32. package/dist/hooks/pre-commit.js +4 -4
  33. package/dist/hooks/pre-tool-use.js +10 -12
  34. package/dist/hooks/prim-hook.js +17 -14
  35. package/dist/hooks/session-end.js +4 -4
  36. package/dist/hooks/session-start.js +12 -36
  37. package/dist/index.js +867 -291
  38. package/dist/statusline-main.js +23 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-BTNNEH2W.js +0 -79
@@ -53,8 +53,8 @@ var require_ucs2length = __commonJS({
53
53
 
54
54
  // src/hooks/prim-hook.ts
55
55
  import { spawn } from "child_process";
56
- import { readFileSync as readFileSync14 } from "fs";
57
- import { dirname as dirname11, join as join16 } from "path";
56
+ import { readFileSync as readFileSync15 } from "fs";
57
+ import { dirname as dirname12, join as join17 } from "path";
58
58
  import { fileURLToPath as fileURLToPath2 } from "url";
59
59
 
60
60
  // src/binding.ts
@@ -1342,17 +1342,30 @@ async function acknowledgeDecisionFeedback(input, dependencies = {}) {
1342
1342
  import {
1343
1343
  appendFileSync,
1344
1344
  closeSync as closeSync2,
1345
- existsSync as existsSync4,
1345
+ existsSync as existsSync5,
1346
1346
  fstatSync,
1347
1347
  mkdirSync as mkdirSync4,
1348
1348
  openSync as openSync2,
1349
1349
  opendirSync,
1350
- readFileSync as readFileSync5,
1350
+ readFileSync as readFileSync6,
1351
1351
  readSync,
1352
- readdirSync
1352
+ readdirSync as readdirSync2
1353
1353
  } from "fs";
1354
- import { dirname as dirname5, join as join6 } from "path";
1355
- var JOURNAL_DIR = join6(primConfigDirectory(), "moves");
1354
+ import { dirname as dirname6, join as join7 } from "path";
1355
+
1356
+ // src/drain-progress.ts
1357
+ import {
1358
+ chmodSync as chmodSync2,
1359
+ existsSync as existsSync4,
1360
+ readFileSync as readFileSync5,
1361
+ readdirSync,
1362
+ rmSync as rmSync4,
1363
+ rmdirSync
1364
+ } from "fs";
1365
+ import { basename, dirname as dirname5, join as join6 } from "path";
1366
+
1367
+ // src/journal.ts
1368
+ var JOURNAL_DIR = join7(primConfigDirectory(), "moves");
1356
1369
  var UNBOUND_BUCKET = "_unbound";
1357
1370
  var JOURNAL_BASENAME = "journal.ndjson";
1358
1371
  var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
@@ -1364,15 +1377,15 @@ function envSlug(apiUrl) {
1364
1377
  return slug;
1365
1378
  }
1366
1379
  function currentEnvDir() {
1367
- return join6(JOURNAL_DIR, envSlug(getSiteUrl()));
1380
+ return join7(JOURNAL_DIR, envSlug(getSiteUrl()));
1368
1381
  }
1369
1382
  var DIR_MODE = 448;
1370
1383
  var FILE_MODE2 = 384;
1371
1384
  var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
1372
1385
  var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
1373
1386
  function appendMoveToPath(path, move) {
1374
- const dir = dirname5(path);
1375
- if (!existsSync4(dir)) {
1387
+ const dir = dirname6(path);
1388
+ if (!existsSync5(dir)) {
1376
1389
  mkdirSync4(dir, { recursive: true, mode: DIR_MODE });
1377
1390
  }
1378
1391
  appendFileSync(path, `${JSON.stringify(move)}
@@ -1380,10 +1393,10 @@ function appendMoveToPath(path, move) {
1380
1393
  }
1381
1394
  function bucketDir(orgId) {
1382
1395
  const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
1383
- return join6(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
1396
+ return join7(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
1384
1397
  }
1385
1398
  function journalPath(orgId) {
1386
- return join6(bucketDir(orgId), JOURNAL_BASENAME);
1399
+ return join7(bucketDir(orgId), JOURNAL_BASENAME);
1387
1400
  }
1388
1401
  function appendMove(move, orgId) {
1389
1402
  appendMoveToPath(journalPath(orgId), move);
@@ -1392,15 +1405,15 @@ var FLUSHING_PREFIX = `${JOURNAL_BASENAME}.flushing.`;
1392
1405
 
1393
1406
  // src/lib/activation.ts
1394
1407
  import { execFileSync as execFileSync2 } from "child_process";
1395
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
1408
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
1396
1409
  import { homedir as homedir2 } from "os";
1397
- import { join as join7 } from "path";
1410
+ import { join as join8 } from "path";
1398
1411
 
1399
1412
  // src/lib/git.ts
1400
1413
  import { execFileSync } from "child_process";
1401
1414
  import { createHash as createHash3 } from "crypto";
1402
1415
  import { lstatSync, realpathSync } from "fs";
1403
- import { basename, dirname as dirname6, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
1416
+ import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
1404
1417
  var GIT_TIMEOUT_MS = 1e3;
1405
1418
  var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
1406
1419
  var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
@@ -1519,7 +1532,7 @@ function nearestExistingAncestor(path) {
1519
1532
  } catch (error) {
1520
1533
  const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
1521
1534
  if (code !== "ENOENT" && code !== "ENOTDIR") return null;
1522
- const parent = dirname6(cursor);
1535
+ const parent = dirname7(cursor);
1523
1536
  if (parent === cursor) return null;
1524
1537
  suffix.unshift(cursor.slice(parent.length + (parent.endsWith(sep) ? 0 : 1)));
1525
1538
  cursor = parent;
@@ -1560,9 +1573,9 @@ function canonicalRepositoryPathLegacy(filePath, cwd, repositoryRoot = canonical
1560
1573
  return null;
1561
1574
  }
1562
1575
  try {
1563
- const parent = realpathSync.native(dirname6(absolute));
1576
+ const parent = realpathSync.native(dirname7(absolute));
1564
1577
  if (!lstatSync(parent).isDirectory()) return null;
1565
- target = resolve2(parent, basename(absolute));
1578
+ target = resolve2(parent, basename2(absolute));
1566
1579
  } catch {
1567
1580
  return null;
1568
1581
  }
@@ -1643,10 +1656,10 @@ function hasProjectPrimInstall(cwd) {
1643
1656
  const root = gitToplevel(cwd);
1644
1657
  if (root === null || root === homedir2()) return false;
1645
1658
  for (const rel of PROJECT_INSTALL_FILES) {
1646
- const path = join7(root, rel);
1647
- if (existsSync5(path)) {
1659
+ const path = join8(root, rel);
1660
+ if (existsSync6(path)) {
1648
1661
  try {
1649
- const content = readFileSync6(path, "utf-8");
1662
+ const content = readFileSync7(path, "utf-8");
1650
1663
  if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
1651
1664
  } catch {
1652
1665
  }
@@ -19735,12 +19748,18 @@ function cachedCollectScopeAdmits(cwd, facts) {
19735
19748
  );
19736
19749
  }
19737
19750
 
19751
+ // src/lib/unattended.ts
19752
+ var UNATTENDED_ENV = "PRIM_UNATTENDED";
19753
+ function unattendedEnv(env = process.env) {
19754
+ return { ...env, [UNATTENDED_ENV]: "1" };
19755
+ }
19756
+
19738
19757
  // src/lib/workspace-id.ts
19739
19758
  import { execFileSync as execFileSync3 } from "child_process";
19740
19759
  import { randomUUID as randomUUID2 } from "crypto";
19741
19760
  import {
19742
19761
  constants as constants2,
19743
- chmodSync as chmodSync2,
19762
+ chmodSync as chmodSync3,
19744
19763
  closeSync as closeSync3,
19745
19764
  fchmodSync as fchmodSync2,
19746
19765
  fsyncSync as fsyncSync2,
@@ -19748,13 +19767,13 @@ import {
19748
19767
  lstatSync as lstatSync2,
19749
19768
  mkdirSync as mkdirSync5,
19750
19769
  openSync as openSync3,
19751
- readFileSync as readFileSync7,
19770
+ readFileSync as readFileSync8,
19752
19771
  statSync as statSync2,
19753
19772
  unlinkSync,
19754
19773
  writeFileSync as writeFileSync3
19755
19774
  } from "fs";
19756
- import { dirname as dirname7, isAbsolute as isAbsolute3, join as join8, resolve as resolve3 } from "path";
19757
- var WORKSPACE_ID_RELATIVE_PATH = join8("prim", "workspace-id");
19775
+ import { dirname as dirname8, isAbsolute as isAbsolute3, join as join9, resolve as resolve3 } from "path";
19776
+ var WORKSPACE_ID_RELATIVE_PATH = join9("prim", "workspace-id");
19758
19777
  var MAX_ANCESTORS = 64;
19759
19778
  var MAX_GIT_FILE_BYTES = 4096;
19760
19779
  var MAX_ID_FILE_BYTES = 128;
@@ -19813,19 +19832,19 @@ function resolveWorkspaceIdPath(cwd) {
19813
19832
  function resolveFromFilesystem(cwd) {
19814
19833
  let current = resolve3(cwd);
19815
19834
  for (let depth = 0; depth < MAX_ANCESTORS; depth += 1) {
19816
- const dotGit = join8(current, ".git");
19835
+ const dotGit = join9(current, ".git");
19817
19836
  try {
19818
19837
  const stat = lstatSync2(dotGit);
19819
19838
  if (stat.isDirectory() && isGitDirectory(dotGit)) {
19820
- return join8(dotGit, WORKSPACE_ID_RELATIVE_PATH);
19839
+ return join9(dotGit, WORKSPACE_ID_RELATIVE_PATH);
19821
19840
  }
19822
19841
  if (stat.isFile() && stat.size <= MAX_GIT_FILE_BYTES) {
19823
- const contents = readFileSync7(dotGit, "utf8");
19842
+ const contents = readFileSync8(dotGit, "utf8");
19824
19843
  const match = /^gitdir: (.+?)(?:\r?\n)?$/.exec(contents);
19825
19844
  if (match?.[1]) {
19826
19845
  const gitDirectory = isAbsolute3(match[1]) ? resolve3(match[1]) : resolve3(current, match[1]);
19827
19846
  if (isGitDirectory(gitDirectory)) {
19828
- return join8(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
19847
+ return join9(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
19829
19848
  }
19830
19849
  }
19831
19850
  }
@@ -19836,7 +19855,7 @@ function resolveFromFilesystem(cwd) {
19836
19855
  return null;
19837
19856
  }
19838
19857
  }
19839
- const parent = dirname7(current);
19858
+ const parent = dirname8(current);
19840
19859
  if (parent === current) break;
19841
19860
  current = parent;
19842
19861
  }
@@ -19844,7 +19863,7 @@ function resolveFromFilesystem(cwd) {
19844
19863
  }
19845
19864
  function isGitDirectory(path) {
19846
19865
  try {
19847
- return statSync2(join8(path, "HEAD")).isFile();
19866
+ return statSync2(join9(path, "HEAD")).isFile();
19848
19867
  } catch {
19849
19868
  return false;
19850
19869
  }
@@ -19863,7 +19882,7 @@ function inspectPath(path) {
19863
19882
  return { status: "corrupt", path, reason: "invalid_content" };
19864
19883
  }
19865
19884
  try {
19866
- const contents = readFileSync7(path, "utf8");
19885
+ const contents = readFileSync8(path, "utf8");
19867
19886
  const workspaceId = contents.endsWith("\n") ? contents.slice(0, -1) : contents;
19868
19887
  if ((contents === workspaceId || contents === `${workspaceId}
19869
19888
  `) && isCanonicalWorkspaceId(workspaceId)) {
@@ -19880,14 +19899,14 @@ function inspectPath(path) {
19880
19899
  }
19881
19900
  }
19882
19901
  function createWorkspaceId(path) {
19883
- const parent = dirname7(path);
19902
+ const parent = dirname8(path);
19884
19903
  const workspaceId = randomUUID2();
19885
- const temporaryPath = join8(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
19904
+ const temporaryPath = join9(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
19886
19905
  let temporaryCreated = false;
19887
19906
  let publishing = false;
19888
19907
  try {
19889
19908
  mkdirSync5(parent, { recursive: true, mode: 448 });
19890
- chmodSync2(parent, 448);
19909
+ chmodSync3(parent, 448);
19891
19910
  const fd = openSync3(
19892
19911
  temporaryPath,
19893
19912
  constants2.O_CREAT | constants2.O_EXCL | constants2.O_WRONLY,
@@ -19954,22 +19973,22 @@ function parseAgent(argv) {
19954
19973
  // src/hooks/codex-context.ts
19955
19974
  import { createHash as createHash5, randomBytes as randomBytes3 } from "crypto";
19956
19975
  import {
19957
- chmodSync as chmodSync3,
19958
- existsSync as existsSync7,
19976
+ chmodSync as chmodSync4,
19977
+ existsSync as existsSync8,
19959
19978
  mkdirSync as mkdirSync6,
19960
- readFileSync as readFileSync9,
19961
- readdirSync as readdirSync2,
19979
+ readFileSync as readFileSync10,
19980
+ readdirSync as readdirSync3,
19962
19981
  renameSync as renameSync2,
19963
- rmSync as rmSync4,
19982
+ rmSync as rmSync5,
19964
19983
  statSync as statSync3,
19965
19984
  unlinkSync as unlinkSync2,
19966
19985
  writeFileSync as writeFileSync4
19967
19986
  } from "fs";
19968
- import { join as join11 } from "path";
19987
+ import { join as join12 } from "path";
19969
19988
 
19970
19989
  // src/daemon/client.ts
19971
19990
  import { createConnection } from "net";
19972
- import { join as join9 } from "path";
19991
+ import { join as join10 } from "path";
19973
19992
 
19974
19993
  // src/daemon/principal.ts
19975
19994
  import { createHash as createHash4 } from "crypto";
@@ -20019,7 +20038,7 @@ function parseDaemonResponseEnvelope(value) {
20019
20038
  }
20020
20039
 
20021
20040
  // src/daemon/client.ts
20022
- var SOCK_PATH = join9(primConfigDirectory(), "sock");
20041
+ var SOCK_PATH = join10(primConfigDirectory(), "sock");
20023
20042
  var DEFAULT_TIMEOUT_MS2 = 250;
20024
20043
  var nextRequestId = 1;
20025
20044
  function daemonRequest(method, params = {}, opts = {}) {
@@ -20120,8 +20139,8 @@ function isActionablePrivateDraft(row) {
20120
20139
  }
20121
20140
 
20122
20141
  // src/lib/bin-path.ts
20123
- import { existsSync as existsSync6, readFileSync as readFileSync8 } from "fs";
20124
- import { dirname as dirname8, isAbsolute as isAbsolute4, join as join10 } from "path";
20142
+ import { existsSync as existsSync7, readFileSync as readFileSync9 } from "fs";
20143
+ import { dirname as dirname9, isAbsolute as isAbsolute4, join as join11 } from "path";
20125
20144
  import { fileURLToPath } from "url";
20126
20145
  var PKG_NAME = "@primitive.ai/prim";
20127
20146
  var ROOT_WALK_LIMIT = 6;
@@ -20131,12 +20150,12 @@ function locateRoot() {
20131
20150
  if (resolvedRoot !== void 0) {
20132
20151
  return resolvedRoot;
20133
20152
  }
20134
- let dir = dirname8(fileURLToPath(import.meta.url));
20153
+ let dir = dirname9(fileURLToPath(import.meta.url));
20135
20154
  for (let depth = 0; depth < ROOT_WALK_LIMIT; depth++) {
20136
- const manifestPath = join10(dir, "package.json");
20137
- if (existsSync6(manifestPath)) {
20155
+ const manifestPath = join11(dir, "package.json");
20156
+ if (existsSync7(manifestPath)) {
20138
20157
  try {
20139
- const manifest = JSON.parse(readFileSync8(manifestPath, "utf-8"));
20158
+ const manifest = JSON.parse(readFileSync9(manifestPath, "utf-8"));
20140
20159
  if (manifest.name === PKG_NAME && manifest.bin) {
20141
20160
  resolvedRoot = { dir, version: manifest.version, bin: manifest.bin };
20142
20161
  return resolvedRoot;
@@ -20144,7 +20163,7 @@ function locateRoot() {
20144
20163
  } catch {
20145
20164
  }
20146
20165
  }
20147
- const parent = dirname8(dir);
20166
+ const parent = dirname9(dir);
20148
20167
  if (parent === dir) {
20149
20168
  break;
20150
20169
  }
@@ -20185,6 +20204,36 @@ function detachedHookShimCommand(bin, args = "") {
20185
20204
  return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
20186
20205
  }
20187
20206
 
20207
+ // src/lib/ansi.ts
20208
+ var MAX_HEALTH_ERROR_LENGTH = 240;
20209
+ function boundedHealthError(value) {
20210
+ if (!value) return void 0;
20211
+ const clean = terminalSafeLine(value);
20212
+ if (!clean) return void 0;
20213
+ return clean.length <= MAX_HEALTH_ERROR_LENGTH ? clean : `${clean.slice(0, MAX_HEALTH_ERROR_LENGTH - 1)}\u2026`;
20214
+ }
20215
+
20216
+ // src/lib/delivery-backlog.ts
20217
+ var MS_PER_SECOND = 1e3;
20218
+ var MS_PER_MINUTE = 60 * MS_PER_SECOND;
20219
+ var MS_PER_HOUR = 60 * MS_PER_MINUTE;
20220
+ var MS_PER_DAY = 24 * MS_PER_HOUR;
20221
+ function isNonNegativeInteger(value) {
20222
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
20223
+ }
20224
+ function isPositiveInteger(value) {
20225
+ return isNonNegativeInteger(value) && value > 0;
20226
+ }
20227
+ function deliveryBacklogState(ingestion) {
20228
+ if (ingestion?.healthy !== false) return void 0;
20229
+ const failures = ingestion.consecutiveFailures;
20230
+ const failedWithoutProgress = failures !== 0 && !(isPositiveInteger(failures) && isPositiveInteger(ingestion.lastFailedDrainAcknowledgedCount));
20231
+ if (failedWithoutProgress) return "failing";
20232
+ const retained = ingestion.lastRetainedBucketCount;
20233
+ if (!isNonNegativeInteger(retained)) return "failing";
20234
+ return retained > 0 ? "retained" : "draining";
20235
+ }
20236
+
20188
20237
  // src/lib/presence.ts
20189
20238
  var DECISION_ORIGIN = "https://app.getprimitive.ai";
20190
20239
  function validDecisionUrl(value) {
@@ -20259,7 +20308,8 @@ function formatStatusline(version, snapshot, resolveIngestionStatus, options = {
20259
20308
  if (snapshot.ingestion?.healthy === false) {
20260
20309
  const pending = snapshot.ingestion.pendingCount;
20261
20310
  const qualifier = snapshot.ingestion.pendingSampled ? "at least " : "";
20262
- return `primitive ${version} (daemon: degraded \xB7 delivery: stalled${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
20311
+ const delivery = deliveryBacklogState(snapshot.ingestion) === "draining" && snapshot.heartbeat?.healthy === true ? "draining" : "stalled";
20312
+ return `primitive ${version} (daemon: degraded \xB7 delivery: ${delivery}${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
20263
20313
  }
20264
20314
  if (snapshot.heartbeat?.healthy === false) {
20265
20315
  return `primitive ${version} (daemon: degraded \xB7 presence: unavailable${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
@@ -20301,10 +20351,10 @@ var STATE_VERSION = 1;
20301
20351
  var DRAFT_STATE_VERSION = 2;
20302
20352
  var NO_CURSOR = -1;
20303
20353
  function stateRoot(namespace) {
20304
- return join11(primConfigDirectory(), namespace, "decision-digests");
20354
+ return join12(primConfigDirectory(), namespace, "decision-digests");
20305
20355
  }
20306
20356
  function draftStateRoot(namespace) {
20307
- return join11(primConfigDirectory(), namespace, "decision-draft-deliveries");
20357
+ return join12(primConfigDirectory(), namespace, "decision-draft-deliveries");
20308
20358
  }
20309
20359
  function workspaceFor(cwd) {
20310
20360
  try {
@@ -20316,12 +20366,12 @@ function workspaceFor(cwd) {
20316
20366
  function statePath(args) {
20317
20367
  const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}`;
20318
20368
  const key = createHash5("sha256").update(identity).digest("hex");
20319
- return join11(stateRoot(args.namespace), `${key}.json`);
20369
+ return join12(stateRoot(args.namespace), `${key}.json`);
20320
20370
  }
20321
20371
  function draftStatePath(args) {
20322
20372
  const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}\0${args.principalId}\0${args.organizationId}\0${args.credentialFingerprint}`;
20323
20373
  const key = createHash5("sha256").update(identity).digest("hex");
20324
- return join11(draftStateRoot(args.namespace), `${key}.json`);
20374
+ return join12(draftStateRoot(args.namespace), `${key}.json`);
20325
20375
  }
20326
20376
  function parseState(value) {
20327
20377
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
@@ -20360,25 +20410,25 @@ function parseDraftState(value) {
20360
20410
  };
20361
20411
  }
20362
20412
  function readState(path) {
20363
- if (!existsSync7(path)) return void 0;
20413
+ if (!existsSync8(path)) return void 0;
20364
20414
  try {
20365
- return parseState(JSON.parse(readFileSync9(path, "utf8")));
20415
+ return parseState(JSON.parse(readFileSync10(path, "utf8")));
20366
20416
  } catch {
20367
20417
  return void 0;
20368
20418
  }
20369
20419
  }
20370
20420
  function readDraftState(path) {
20371
- if (!existsSync7(path)) return void 0;
20421
+ if (!existsSync8(path)) return void 0;
20372
20422
  try {
20373
- return parseDraftState(JSON.parse(readFileSync9(path, "utf8")));
20423
+ return parseDraftState(JSON.parse(readFileSync10(path, "utf8")));
20374
20424
  } catch {
20375
20425
  return void 0;
20376
20426
  }
20377
20427
  }
20378
20428
  function writeStateFile(path, directory, state) {
20379
20429
  mkdirSync6(directory, { recursive: true, mode: 448 });
20380
- chmodSync3(directory, 448);
20381
- const temporary = join11(
20430
+ chmodSync4(directory, 448);
20431
+ const temporary = join12(
20382
20432
  directory,
20383
20433
  `.${path.slice(directory.length + 1)}.tmp-${process.pid}-${randomBytes3(8).toString("hex")}`
20384
20434
  );
@@ -20389,7 +20439,7 @@ function writeStateFile(path, directory, state) {
20389
20439
  mode: 384,
20390
20440
  flag: "wx"
20391
20441
  });
20392
- chmodSync3(temporary, 384);
20442
+ chmodSync4(temporary, 384);
20393
20443
  renameSync2(temporary, path);
20394
20444
  } finally {
20395
20445
  try {
@@ -20399,17 +20449,17 @@ function writeStateFile(path, directory, state) {
20399
20449
  }
20400
20450
  }
20401
20451
  function cleanupStateFiles(directory, now) {
20402
- if (!existsSync7(directory)) return;
20452
+ if (!existsSync8(directory)) return;
20403
20453
  let names;
20404
20454
  try {
20405
- names = readdirSync2(directory);
20455
+ names = readdirSync3(directory);
20406
20456
  } catch {
20407
20457
  return;
20408
20458
  }
20409
20459
  const files = [];
20410
20460
  const residue = [];
20411
20461
  for (const name of names) {
20412
- const path = join11(directory, name);
20462
+ const path = join12(directory, name);
20413
20463
  try {
20414
20464
  const mtimeMs = statSync3(path).mtimeMs;
20415
20465
  if (name.endsWith(".json")) {
@@ -20431,7 +20481,7 @@ function cleanupStateFiles(directory, now) {
20431
20481
  for (const path of residue) {
20432
20482
  try {
20433
20483
  if (now - statSync3(path).mtimeMs > CODEX_DIGEST_STATE_RETENTION_MS) {
20434
- rmSync4(path, { recursive: true, force: true });
20484
+ rmSync5(path, { recursive: true, force: true });
20435
20485
  }
20436
20486
  } catch {
20437
20487
  }
@@ -20747,31 +20797,31 @@ async function processCodexMessageContext(envelope, deps = defaultDeps) {
20747
20797
  }
20748
20798
 
20749
20799
  // src/commands/cursor-install.ts
20750
- import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
20800
+ import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
20751
20801
  import { homedir as homedir4 } from "os";
20752
- import { isAbsolute as isAbsolute6, join as join14 } from "path";
20802
+ import { isAbsolute as isAbsolute6, join as join15 } from "path";
20753
20803
 
20754
20804
  // src/lib/hook-runtime.ts
20755
20805
  import { createHash as createHash6, randomBytes as randomBytes4 } from "crypto";
20756
20806
  import {
20757
20807
  constants as constants3,
20758
20808
  accessSync,
20759
- chmodSync as chmodSync4,
20809
+ chmodSync as chmodSync5,
20760
20810
  copyFileSync,
20761
- existsSync as existsSync8,
20811
+ existsSync as existsSync9,
20762
20812
  lstatSync as lstatSync3,
20763
20813
  mkdirSync as mkdirSync7,
20764
20814
  mkdtempSync,
20765
- readFileSync as readFileSync10,
20766
- readdirSync as readdirSync3,
20815
+ readFileSync as readFileSync11,
20816
+ readdirSync as readdirSync4,
20767
20817
  realpathSync as realpathSync2,
20768
20818
  renameSync as renameSync3,
20769
- rmSync as rmSync5,
20819
+ rmSync as rmSync6,
20770
20820
  statSync as statSync4,
20771
20821
  utimesSync,
20772
20822
  writeFileSync as writeFileSync5
20773
20823
  } from "fs";
20774
- import { dirname as dirname9, isAbsolute as isAbsolute5, join as join12, resolve as resolve4 } from "path";
20824
+ import { delimiter, dirname as dirname10, isAbsolute as isAbsolute5, join as join13, resolve as resolve4 } from "path";
20775
20825
  var RELEASE_PREFIX = "release-";
20776
20826
  var MAX_MANIFEST_BYTES = 64 * 1024;
20777
20827
  var RELEASE_GRACE_MS = 10 * 60 * 1e3;
@@ -20817,9 +20867,9 @@ exec "$prim_node" "$prim_entry" "$@"
20817
20867
  `;
20818
20868
 
20819
20869
  // src/commands/claude-install.ts
20820
- import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
20870
+ import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
20821
20871
  import { homedir as homedir3 } from "os";
20822
- import { join as join13 } from "path";
20872
+ import { join as join14 } from "path";
20823
20873
  var CAPTURE_BIN = "prim-hook";
20824
20874
  var GATE_BIN = "prim-pre-tool-use";
20825
20875
  var POST_TOOL_USE_BIN = "prim-post-tool-use";
@@ -20828,7 +20878,7 @@ var SESSION_END_BIN = "prim-session-end";
20828
20878
  var STATUSLINE_BIN = "prim-statusline";
20829
20879
  var STATUSLINE_ARGS = "";
20830
20880
  var STATUSLINE_COMMAND = stableHookCommand(STATUSLINE_BIN, STATUSLINE_ARGS);
20831
- var USER_SCOPE_PATH = join13(homedir3(), ".claude", "settings.json");
20881
+ var USER_SCOPE_PATH = join14(homedir3(), ".claude", "settings.json");
20832
20882
  function projectRoot() {
20833
20883
  return gitToplevel() ?? process.cwd();
20834
20884
  }
@@ -20907,20 +20957,20 @@ function cursorConfigDirectory(env = process.env, home = homedir4(), platform2 =
20907
20957
  const explicit = env.CURSOR_CONFIG_DIR?.trim();
20908
20958
  if (explicit && isAbsolute6(explicit)) return explicit;
20909
20959
  const xdg = env.XDG_CONFIG_HOME?.trim();
20910
- if (platform2 !== "darwin" && xdg && isAbsolute6(xdg)) return join14(xdg, "cursor");
20911
- return join14(home, ".cursor");
20960
+ if (platform2 !== "darwin" && xdg && isAbsolute6(xdg)) return join15(xdg, "cursor");
20961
+ return join15(home, ".cursor");
20912
20962
  }
20913
20963
  function cursorHooksPath(scope, root = projectRoot()) {
20914
- return scope === "user" ? join14(cursorConfigDirectory(), "hooks.json") : join14(root, ".cursor", "hooks.json");
20964
+ return scope === "user" ? join15(cursorConfigDirectory(), "hooks.json") : join15(root, ".cursor", "hooks.json");
20915
20965
  }
20916
20966
  function plainObject(value) {
20917
20967
  return typeof value === "object" && value !== null && !Array.isArray(value);
20918
20968
  }
20919
20969
  function readCursorHooks(path) {
20920
- if (!existsSync10(path)) return {};
20970
+ if (!existsSync11(path)) return {};
20921
20971
  let parsed;
20922
20972
  try {
20923
- parsed = JSON.parse(readFileSync12(path, "utf8"));
20973
+ parsed = JSON.parse(readFileSync13(path, "utf8"));
20924
20974
  } catch {
20925
20975
  throw new Error(`invalid Cursor hooks JSON at ${path}`);
20926
20976
  }
@@ -22465,16 +22515,16 @@ var Lexer = class {
22465
22515
  readHereDocDelimiter() {
22466
22516
  const src = this.src;
22467
22517
  const len = this.srcEnd;
22468
- let delimiter = "";
22518
+ let delimiter2 = "";
22469
22519
  if (this.pos < len && src.charCodeAt(this.pos) === CH_SQUOTE) {
22470
22520
  this.pos++;
22471
22521
  const start = this.pos;
22472
22522
  while (this.pos < len && src.charCodeAt(this.pos) !== CH_SQUOTE)
22473
22523
  this.pos++;
22474
- delimiter = src.slice(start, this.pos);
22524
+ delimiter2 = src.slice(start, this.pos);
22475
22525
  if (this.pos < len)
22476
22526
  this.pos++;
22477
- this._hereDelim = delimiter;
22527
+ this._hereDelim = delimiter2;
22478
22528
  this._hereQuoted = true;
22479
22529
  return;
22480
22530
  } else if (this.pos < len && src.charCodeAt(this.pos) === CH_DQUOTE) {
@@ -22482,12 +22532,12 @@ var Lexer = class {
22482
22532
  while (this.pos < len && src.charCodeAt(this.pos) !== CH_DQUOTE) {
22483
22533
  if (src.charCodeAt(this.pos) === CH_BACKSLASH)
22484
22534
  this.pos++;
22485
- delimiter += src[this.pos];
22535
+ delimiter2 += src[this.pos];
22486
22536
  this.pos++;
22487
22537
  }
22488
22538
  if (this.pos < len)
22489
22539
  this.pos++;
22490
- this._hereDelim = delimiter;
22540
+ this._hereDelim = delimiter2;
22491
22541
  this._hereQuoted = true;
22492
22542
  return;
22493
22543
  } else if (this.pos < len && src.charCodeAt(this.pos) === CH_BACKSLASH) {
@@ -22498,11 +22548,11 @@ var Lexer = class {
22498
22548
  if (c === CH_BACKSLASH)
22499
22549
  this.pos++;
22500
22550
  if (this.pos < len) {
22501
- delimiter += src[this.pos];
22551
+ delimiter2 += src[this.pos];
22502
22552
  this.pos++;
22503
22553
  }
22504
22554
  }
22505
- this._hereDelim = delimiter;
22555
+ this._hereDelim = delimiter2;
22506
22556
  this._hereQuoted = true;
22507
22557
  return;
22508
22558
  } else {
@@ -22534,9 +22584,9 @@ var Lexer = class {
22534
22584
  }
22535
22585
  this.pendingHereDocs.length = 0;
22536
22586
  }
22537
- readHereDocBody(delimiter, strip) {
22587
+ readHereDocBody(delimiter2, strip) {
22538
22588
  const bodyStart = this.pos;
22539
- const bodyEnd = this.skipHereDocBody(delimiter, strip);
22589
+ const bodyEnd = this.skipHereDocBody(delimiter2, strip);
22540
22590
  return this.src.slice(bodyStart, bodyEnd);
22541
22591
  }
22542
22592
  // Advance past the heredoc body and its delimiter line; return the body end
@@ -22544,10 +22594,10 @@ var Lexer = class {
22544
22594
  // With parenEnds (inside $(...)), a line starting with the delimiter directly
22545
22595
  // followed by ")" also terminates the body, resuming at the ")" — bash treats
22546
22596
  // the substitution's closing paren as end-of-file for its heredocs.
22547
- skipHereDocBody(delimiter, strip, parenEnds = false) {
22597
+ skipHereDocBody(delimiter2, strip, parenEnds = false) {
22548
22598
  const src = this.src;
22549
22599
  const len = this.srcEnd;
22550
- const dLen = delimiter.length;
22600
+ const dLen = delimiter2.length;
22551
22601
  while (this.pos < len) {
22552
22602
  let lineStart = this.pos;
22553
22603
  let lineEnd = src.indexOf("\n", this.pos);
@@ -22557,12 +22607,12 @@ var Lexer = class {
22557
22607
  while (lineStart < lineEnd && src.charCodeAt(lineStart) === CH_TAB)
22558
22608
  lineStart++;
22559
22609
  }
22560
- if (lineEnd - lineStart === dLen && src.startsWith(delimiter, lineStart)) {
22610
+ if (lineEnd - lineStart === dLen && src.startsWith(delimiter2, lineStart)) {
22561
22611
  const bodyEnd = this.pos;
22562
22612
  this.pos = lineEnd < len ? lineEnd + 1 : lineEnd;
22563
22613
  return bodyEnd;
22564
22614
  }
22565
- if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(delimiter, lineStart)) {
22615
+ if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(delimiter2, lineStart)) {
22566
22616
  const bodyEnd = this.pos;
22567
22617
  this.pos = lineStart + dLen;
22568
22618
  return bodyEnd;
@@ -25274,7 +25324,7 @@ function safeSedProgram(program) {
25274
25324
  return true;
25275
25325
  const match = /^(?:(?:\d+|\$)(?:,(?:\d+|\$))?)?s(.)(.*)$/s.exec(program);
25276
25326
  if (!match || /[\\\nA-Za-z0-9]/.test(match[1])) return false;
25277
- const delimiter = match[1];
25327
+ const delimiter2 = match[1];
25278
25328
  const tail = match[2];
25279
25329
  let offset = 0;
25280
25330
  for (let section = 0; section < 2; section += 1) {
@@ -25282,7 +25332,7 @@ function safeSedProgram(program) {
25282
25332
  while (offset < tail.length) {
25283
25333
  if (tail[offset] === "\\") {
25284
25334
  offset += 2;
25285
- } else if (tail[offset] === delimiter) {
25335
+ } else if (tail[offset] === delimiter2) {
25286
25336
  offset += 1;
25287
25337
  closed = true;
25288
25338
  break;
@@ -25881,20 +25931,9 @@ import { platform } from "os";
25881
25931
  var AGENT_ENVELOPE_VERSION = 3;
25882
25932
 
25883
25933
  // src/hooks/redact.ts
25884
- import { existsSync as existsSync11, readFileSync as readFileSync13, statSync as statSync5 } from "fs";
25885
- import { join as join15 } from "path";
25934
+ import { existsSync as existsSync12, readFileSync as readFileSync14, statSync as statSync5 } from "fs";
25935
+ import { join as join16 } from "path";
25886
25936
  import { Worker } from "worker_threads";
25887
-
25888
- // src/lib/ansi.ts
25889
- var MAX_HEALTH_ERROR_LENGTH = 240;
25890
- function boundedHealthError(value) {
25891
- if (!value) return void 0;
25892
- const clean = terminalSafeLine(value);
25893
- if (!clean) return void 0;
25894
- return clean.length <= MAX_HEALTH_ERROR_LENGTH ? clean : `${clean.slice(0, MAX_HEALTH_ERROR_LENGTH - 1)}\u2026`;
25895
- }
25896
-
25897
- // src/hooks/redact.ts
25898
25937
  var USER_HOME_RULES = [
25899
25938
  {
25900
25939
  pattern: /\/Users\/[^/\\\s"'`]+/g,
@@ -25969,15 +26008,15 @@ function normalizedWorkspaceFlags(value) {
25969
26008
  return [...new Set(`g${requested}`)].sort().join("");
25970
26009
  }
25971
26010
  function loadWorkspaceRules(cwd) {
25972
- const path = join15(cwd, WORKSPACE_FILE2);
25973
- if (!existsSync11(path)) return [];
26011
+ const path = join16(cwd, WORKSPACE_FILE2);
26012
+ if (!existsSync12(path)) return [];
25974
26013
  let cfg;
25975
26014
  try {
25976
26015
  if (statSync5(path).size > MAX_WORKSPACE_CONFIG_BYTES) {
25977
26016
  debugRedaction(`ignoring oversized ${WORKSPACE_FILE2}`);
25978
26017
  return [];
25979
26018
  }
25980
- cfg = JSON.parse(readFileSync13(path, "utf-8"));
26019
+ cfg = JSON.parse(readFileSync14(path, "utf-8"));
25981
26020
  } catch {
25982
26021
  debugRedaction(`ignoring unparseable ${WORKSPACE_FILE2}`);
25983
26022
  return [];
@@ -26252,7 +26291,7 @@ function shouldFlushAfter(eventType, agent = "claude_code") {
26252
26291
  }
26253
26292
 
26254
26293
  // src/hooks/prim-hook.ts
26255
- var here = dirname11(fileURLToPath2(import.meta.url));
26294
+ var here = dirname12(fileURLToPath2(import.meta.url));
26256
26295
  var outputAttempted = false;
26257
26296
  function emitOutput(output, acknowledge) {
26258
26297
  outputAttempted = true;
@@ -26260,17 +26299,18 @@ function emitOutput(output, acknowledge) {
26260
26299
  }
26261
26300
  function resolveCliVersion() {
26262
26301
  try {
26263
- const pkg = JSON.parse(readFileSync14(join16(here, "..", "..", "package.json"), "utf-8"));
26302
+ const pkg = JSON.parse(readFileSync15(join17(here, "..", "..", "package.json"), "utf-8"));
26264
26303
  return pkg.version ?? "unknown";
26265
26304
  } catch {
26266
26305
  return "unknown";
26267
26306
  }
26268
26307
  }
26269
26308
  function spawnBackgroundFlush() {
26270
- const entry = join16(here, "..", "index.js");
26309
+ const entry = join17(here, "..", "index.js");
26271
26310
  spawn(process.execPath, [entry, "moves", "flush"], {
26272
26311
  detached: true,
26273
- stdio: "ignore"
26312
+ stdio: "ignore",
26313
+ env: unattendedEnv()
26274
26314
  }).unref();
26275
26315
  }
26276
26316
  async function main() {