@primitive.ai/prim 0.1.0-alpha.66 → 0.1.0-alpha.68
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/dist/chunk-I5BHJQH2.js +329 -0
- package/dist/chunk-K3AYW6VZ.js +300 -0
- package/dist/{chunk-CPX3BUOC.js → chunk-RTLFE6EZ.js} +6 -2
- package/dist/{chunk-KHZNYEUV.js → chunk-U6L2RU67.js} +1 -1
- package/dist/{chunk-HIMWM526.js → chunk-UN5O5SYG.js} +1 -1
- package/dist/chunk-XGADQPCI.js +26 -0
- package/dist/{chunk-DR66XM5L.js → chunk-XPVNH3J6.js} +1 -1
- package/dist/{chunk-WS3MCNFD.js → chunk-XUAP572Z.js} +1 -1
- package/dist/daemon/server.js +121 -26
- package/dist/hooks/post-commit.js +2 -2
- package/dist/hooks/post-rewrite.js +2 -2
- package/dist/hooks/post-tool-use.js +51 -21
- package/dist/hooks/pre-commit.js +2 -2
- package/dist/hooks/pre-tool-use.js +64 -25
- package/dist/hooks/prim-hook.js +67 -5
- package/dist/hooks/session-end.js +3 -3
- package/dist/hooks/session-start.js +28 -20
- package/dist/index.js +617 -107
- package/dist/statusline-main.js +16 -12
- package/package.json +1 -1
- package/dist/chunk-CZ24W5QU.js +0 -123
- package/dist/chunk-JQFN6LBO.js +0 -110
package/dist/statusline-main.js
CHANGED
|
@@ -245,9 +245,12 @@ function validDecisionUrl(value) {
|
|
|
245
245
|
return void 0;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
function decisionLink(label, decisionUrl) {
|
|
248
|
+
function decisionLink(label, decisionUrl, plain) {
|
|
249
249
|
const url = validDecisionUrl(decisionUrl);
|
|
250
|
-
|
|
250
|
+
if (plain || !url) {
|
|
251
|
+
return label;
|
|
252
|
+
}
|
|
253
|
+
return `\x1B]8;;${url}\x07\x1B[34;4m${label}\x1B[0m\x1B]8;;\x07`;
|
|
251
254
|
}
|
|
252
255
|
function formatLabeled(labels, cap) {
|
|
253
256
|
if (labels === void 0) {
|
|
@@ -264,13 +267,13 @@ function formatLabeled(labels, cap) {
|
|
|
264
267
|
function formatTeammates(names, cap) {
|
|
265
268
|
return formatLabeled(names?.map(stripControlChars), cap);
|
|
266
269
|
}
|
|
267
|
-
function formatTeammatesWithArea(teammates, cap) {
|
|
270
|
+
function formatTeammatesWithArea(teammates, cap, plainLinks = false) {
|
|
268
271
|
return formatLabeled(
|
|
269
272
|
teammates?.map((t) => {
|
|
270
273
|
const name = stripControlChars(t.name);
|
|
271
274
|
const area = stripControlChars(t.area ?? "").trim();
|
|
272
275
|
const label = area ? `${name} - ${area}` : name;
|
|
273
|
-
return decisionLink(label, t.decisionUrl);
|
|
276
|
+
return decisionLink(label, t.decisionUrl, plainLinks);
|
|
274
277
|
}),
|
|
275
278
|
cap
|
|
276
279
|
);
|
|
@@ -278,25 +281,26 @@ function formatTeammatesWithArea(teammates, cap) {
|
|
|
278
281
|
|
|
279
282
|
// src/lib/statusline-render.ts
|
|
280
283
|
var STATUSLINE_NAME_CAP = 3;
|
|
281
|
-
function formatStatusline(version, snapshot, resolveIngestionStatus) {
|
|
284
|
+
function formatStatusline(version, snapshot, resolveIngestionStatus, options = {}) {
|
|
285
|
+
const ingestionSuffix = (status) => status === void 0 ? "" : ` \xB7 Decision ingestion ${status}`;
|
|
286
|
+
const ingestionStatus = snapshot === null || snapshot.healthy === false ? options.includeIngestionWhenUnavailable ? resolveIngestionStatus() : void 0 : resolveIngestionStatus();
|
|
282
287
|
if (!snapshot) {
|
|
283
|
-
return `primitive ${version} (daemon: down)`;
|
|
288
|
+
return `primitive ${version} (daemon: down${ingestionSuffix(ingestionStatus)})`;
|
|
284
289
|
}
|
|
285
290
|
if (snapshot.healthy === false) {
|
|
286
291
|
if (snapshot.needsReauth) {
|
|
287
|
-
return `primitive ${version} (daemon: paused \xB7 run \`prim auth login
|
|
292
|
+
return `primitive ${version} (daemon: paused \xB7 run \`prim auth login\`${ingestionSuffix(ingestionStatus)})`;
|
|
288
293
|
}
|
|
289
294
|
if (snapshot.ingestion?.healthy === false) {
|
|
290
295
|
const pending = snapshot.ingestion.pendingCount;
|
|
291
296
|
const qualifier = snapshot.ingestion.pendingSampled ? "at least " : "";
|
|
292
|
-
return `primitive ${version} (daemon: degraded \xB7 delivery: stalled${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""})`;
|
|
297
|
+
return `primitive ${version} (daemon: degraded \xB7 delivery: stalled${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${ingestionSuffix(ingestionStatus)})`;
|
|
293
298
|
}
|
|
294
299
|
if (snapshot.heartbeat?.healthy === false) {
|
|
295
|
-
return `primitive ${version} (daemon: degraded \xB7 presence: unavailable)`;
|
|
300
|
+
return `primitive ${version} (daemon: degraded \xB7 presence: unavailable${ingestionSuffix(ingestionStatus)})`;
|
|
296
301
|
}
|
|
297
|
-
return `primitive ${version} (daemon: starting)`;
|
|
302
|
+
return `primitive ${version} (daemon: starting${ingestionSuffix(ingestionStatus)})`;
|
|
298
303
|
}
|
|
299
|
-
const ingestionStatus = resolveIngestionStatus();
|
|
300
304
|
if (snapshot.envMismatch) {
|
|
301
305
|
return `primitive ${version} (daemon: live, Decision ingestion ${ingestionStatus} \xB7 presence: other env)`;
|
|
302
306
|
}
|
|
@@ -305,7 +309,7 @@ function formatStatusline(version, snapshot, resolveIngestionStatus) {
|
|
|
305
309
|
}
|
|
306
310
|
let team;
|
|
307
311
|
if (snapshot.onlineTeammates !== void 0) {
|
|
308
|
-
team = `team: ${formatTeammatesWithArea(snapshot.onlineTeammates, STATUSLINE_NAME_CAP)}`;
|
|
312
|
+
team = `team: ${formatTeammatesWithArea(snapshot.onlineTeammates, STATUSLINE_NAME_CAP, options.plainLinks === true)}`;
|
|
309
313
|
} else if (snapshot.onlineNames !== void 0) {
|
|
310
314
|
team = `team: ${formatTeammates(snapshot.onlineNames, STATUSLINE_NAME_CAP)}`;
|
|
311
315
|
} else if (typeof snapshot.onlineCount === "number") {
|
package/package.json
CHANGED
package/dist/chunk-CZ24W5QU.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
// src/lib/bin-path.ts
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
3
|
-
import { dirname, isAbsolute, join } from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
var PKG_NAME = "@primitive.ai/prim";
|
|
6
|
-
var ROOT_WALK_LIMIT = 6;
|
|
7
|
-
var NPX_FALLBACK = `npx --yes -p ${PKG_NAME}@latest`;
|
|
8
|
-
var resolvedRoot;
|
|
9
|
-
function locateRoot() {
|
|
10
|
-
if (resolvedRoot !== void 0) {
|
|
11
|
-
return resolvedRoot;
|
|
12
|
-
}
|
|
13
|
-
let dir = dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
for (let depth = 0; depth < ROOT_WALK_LIMIT; depth++) {
|
|
15
|
-
const manifestPath = join(dir, "package.json");
|
|
16
|
-
if (existsSync(manifestPath)) {
|
|
17
|
-
try {
|
|
18
|
-
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
19
|
-
if (manifest.name === PKG_NAME && manifest.bin) {
|
|
20
|
-
resolvedRoot = { dir, version: manifest.version, bin: manifest.bin };
|
|
21
|
-
return resolvedRoot;
|
|
22
|
-
}
|
|
23
|
-
} catch {
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
const parent = dirname(dir);
|
|
27
|
-
if (parent === dir) {
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
dir = parent;
|
|
31
|
-
}
|
|
32
|
-
resolvedRoot = null;
|
|
33
|
-
return resolvedRoot;
|
|
34
|
-
}
|
|
35
|
-
function binFile(bin) {
|
|
36
|
-
const root = locateRoot();
|
|
37
|
-
const rel = root?.bin[bin];
|
|
38
|
-
if (!root || !rel) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
return isAbsolute(rel) ? rel : join(root.dir, rel);
|
|
42
|
-
}
|
|
43
|
-
function packageVersion() {
|
|
44
|
-
return locateRoot()?.version ?? null;
|
|
45
|
-
}
|
|
46
|
-
function shellQuote(value) {
|
|
47
|
-
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
48
|
-
}
|
|
49
|
-
function pinnedHookCommand(bin, args = "") {
|
|
50
|
-
const version = packageVersion();
|
|
51
|
-
if (!version) throw new Error("cannot determine Primitive package version");
|
|
52
|
-
const suffix = args ? ` ${args}` : "";
|
|
53
|
-
const fallback = `npx --yes -p ${PKG_NAME}@${version} ${bin}${suffix}`;
|
|
54
|
-
const file = binFile(bin);
|
|
55
|
-
if (!file) return fallback;
|
|
56
|
-
return `if [ -x ${shellQuote(process.execPath)} ] && [ -f ${shellQuote(file)} ]; then ${shellQuote(process.execPath)} ${shellQuote(file)}${suffix}; else ${fallback}; fi`;
|
|
57
|
-
}
|
|
58
|
-
function detachedHookShimCommand(bin, args = "") {
|
|
59
|
-
return `payload=$(cat); { trap '' HUP; export npm_config_fetch_retries=2 npm_config_fetch_retry_mintimeout=10000 npm_config_fetch_retry_maxtimeout=10000 npm_config_fetch_timeout=60000; printf '%s' "$payload" | { ${pinnedHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
|
|
60
|
-
}
|
|
61
|
-
function commandMatchesBin(command, bin) {
|
|
62
|
-
if (!command) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
const c = command.trim();
|
|
66
|
-
if (c === bin || c.startsWith(`${bin} `)) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
const exactBin = new RegExp(`(?:^|\\s)${bin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:\\s|;|$)`);
|
|
70
|
-
return c.includes(`command -v ${bin} `) || c.includes(`-p ${PKG_NAME}@`) && exactBin.test(c);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/lib/bin-cache.ts
|
|
74
|
-
import { chmodSync, mkdirSync, renameSync, writeFileSync } from "fs";
|
|
75
|
-
import { homedir } from "os";
|
|
76
|
-
import { join as join2 } from "path";
|
|
77
|
-
var CACHED_BINS = [
|
|
78
|
-
"prim",
|
|
79
|
-
"prim-hook",
|
|
80
|
-
"prim-pre-tool-use",
|
|
81
|
-
"prim-post-tool-use",
|
|
82
|
-
"prim-post-commit",
|
|
83
|
-
"prim-post-rewrite"
|
|
84
|
-
];
|
|
85
|
-
function binCacheDir() {
|
|
86
|
-
const base = process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");
|
|
87
|
-
return join2(base, "prim", "bin");
|
|
88
|
-
}
|
|
89
|
-
function writeAtomic(path, content) {
|
|
90
|
-
const tmp = `${path}.${process.pid}.tmp`;
|
|
91
|
-
writeFileSync(tmp, content, { mode: 384 });
|
|
92
|
-
renameSync(tmp, path);
|
|
93
|
-
}
|
|
94
|
-
function warmBinCache() {
|
|
95
|
-
try {
|
|
96
|
-
if (process.env.PRIM_BIN_CACHE_HIT) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (process.env.PRIM_BIN_CACHE === "0") {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const dir = binCacheDir();
|
|
103
|
-
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
104
|
-
chmodSync(dir, 448);
|
|
105
|
-
writeAtomic(join2(dir, "node"), process.execPath);
|
|
106
|
-
for (const bin of CACHED_BINS) {
|
|
107
|
-
const file = binFile(bin);
|
|
108
|
-
if (file) {
|
|
109
|
-
writeAtomic(join2(dir, bin), file);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
} catch {
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export {
|
|
117
|
-
binFile,
|
|
118
|
-
packageVersion,
|
|
119
|
-
pinnedHookCommand,
|
|
120
|
-
detachedHookShimCommand,
|
|
121
|
-
commandMatchesBin,
|
|
122
|
-
warmBinCache
|
|
123
|
-
};
|
package/dist/chunk-JQFN6LBO.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// src/lib/ansi.ts
|
|
2
|
-
var ANSI_CODES = {
|
|
3
|
-
yellow: "\x1B[33m",
|
|
4
|
-
magenta: "\x1B[35m",
|
|
5
|
-
blue: "\x1B[34m",
|
|
6
|
-
cyan: "\x1B[36m",
|
|
7
|
-
green: "\x1B[32m",
|
|
8
|
-
red: "\x1B[31m",
|
|
9
|
-
// 256-color approximation of the orange trigger marker (xterm 208).
|
|
10
|
-
orange: "\x1B[38;5;208m",
|
|
11
|
-
gray: "\x1B[90m"
|
|
12
|
-
};
|
|
13
|
-
var ANSI_RESET = "\x1B[0m";
|
|
14
|
-
var ANSI_DIM = "\x1B[2m";
|
|
15
|
-
var ANSI_BOLD = "\x1B[1m";
|
|
16
|
-
function supportsColor() {
|
|
17
|
-
if (process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "") {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
return process.stderr.isTTY === true;
|
|
21
|
-
}
|
|
22
|
-
function color(text, c) {
|
|
23
|
-
if (!supportsColor()) {
|
|
24
|
-
return text;
|
|
25
|
-
}
|
|
26
|
-
return `${ANSI_CODES[c]}${text}${ANSI_RESET}`;
|
|
27
|
-
}
|
|
28
|
-
function dim(text) {
|
|
29
|
-
if (!supportsColor()) {
|
|
30
|
-
return text;
|
|
31
|
-
}
|
|
32
|
-
return `${ANSI_DIM}${text}${ANSI_RESET}`;
|
|
33
|
-
}
|
|
34
|
-
function bold(text) {
|
|
35
|
-
if (!supportsColor()) {
|
|
36
|
-
return text;
|
|
37
|
-
}
|
|
38
|
-
return `${ANSI_BOLD}${text}${ANSI_RESET}`;
|
|
39
|
-
}
|
|
40
|
-
var AREA_COLORS = {
|
|
41
|
-
auth: "yellow",
|
|
42
|
-
data: "magenta",
|
|
43
|
-
mobile: "blue",
|
|
44
|
-
infra: "cyan",
|
|
45
|
-
ui: "green",
|
|
46
|
-
billing: "orange",
|
|
47
|
-
api: "blue",
|
|
48
|
-
docs: "gray",
|
|
49
|
-
testing: "gray"
|
|
50
|
-
};
|
|
51
|
-
function colorForArea(area) {
|
|
52
|
-
if (!area) {
|
|
53
|
-
return "gray";
|
|
54
|
-
}
|
|
55
|
-
return AREA_COLORS[area] ?? "gray";
|
|
56
|
-
}
|
|
57
|
-
function stripControlChars(text) {
|
|
58
|
-
let out = "";
|
|
59
|
-
for (const ch of text) {
|
|
60
|
-
const code = ch.codePointAt(0) ?? 0;
|
|
61
|
-
if (code > 31 && !(code >= 127 && code <= 159)) {
|
|
62
|
-
out += ch;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
var MAX_HEALTH_ERROR_LENGTH = 240;
|
|
68
|
-
function boundedHealthError(value) {
|
|
69
|
-
if (!value) return void 0;
|
|
70
|
-
const clean = stripControlChars(value).replace(/\s+/g, " ").trim();
|
|
71
|
-
if (!clean) return void 0;
|
|
72
|
-
return clean.length <= MAX_HEALTH_ERROR_LENGTH ? clean : `${clean.slice(0, MAX_HEALTH_ERROR_LENGTH - 1)}\u2026`;
|
|
73
|
-
}
|
|
74
|
-
function stripAnsi(text) {
|
|
75
|
-
return text.replace(/\u001b\[[0-9;]*m/g, "");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/ingest-response.ts
|
|
79
|
-
var IngestAcknowledgementError = class extends Error {
|
|
80
|
-
constructor(message) {
|
|
81
|
-
super(message);
|
|
82
|
-
this.name = "IngestAcknowledgementError";
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
function requireDurableIngestAcknowledgement(value, expected) {
|
|
86
|
-
if (typeof value !== "object" || value === null) {
|
|
87
|
-
throw new IngestAcknowledgementError("ingest response was not an object");
|
|
88
|
-
}
|
|
89
|
-
const response = value;
|
|
90
|
-
if (response.disposition !== "persisted") {
|
|
91
|
-
throw new IngestAcknowledgementError("ingest response did not confirm persistence");
|
|
92
|
-
}
|
|
93
|
-
if (response.acknowledged !== expected) {
|
|
94
|
-
throw new IngestAcknowledgementError(
|
|
95
|
-
`ingest acknowledged ${String(response.acknowledged)} of ${String(expected)} moves`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
return value;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export {
|
|
102
|
-
color,
|
|
103
|
-
dim,
|
|
104
|
-
bold,
|
|
105
|
-
colorForArea,
|
|
106
|
-
stripControlChars,
|
|
107
|
-
boundedHealthError,
|
|
108
|
-
stripAnsi,
|
|
109
|
-
requireDurableIngestAcknowledgement
|
|
110
|
-
};
|