@primitive.ai/prim 0.1.0-alpha.62 → 0.1.0-alpha.64
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-QGVHLP5J.js → chunk-7X7SFOPJ.js} +54 -5
- package/dist/{chunk-I3HIPAIR.js → chunk-CPX3BUOC.js} +7 -4
- package/dist/chunk-G5D3FF3D.js +853 -0
- package/dist/{chunk-S4LFRVGD.js → chunk-HIMWM526.js} +1 -1
- package/dist/{chunk-R4CUX6FY.js → chunk-KHZNYEUV.js} +1 -1
- package/dist/{chunk-KBFFVYBC.js → chunk-LNU44OJV.js} +3 -5
- package/dist/{chunk-LOGW54W5.js → chunk-MCPHIB4W.js} +18 -7
- package/dist/{chunk-DA4BMHEB.js → chunk-VYGY3OOX.js} +2 -2
- package/dist/{chunk-YITJ2H3B.js → chunk-WS3MCNFD.js} +1 -1
- package/dist/daemon/server.js +343 -44
- package/dist/hooks/post-commit.js +30 -6
- package/dist/hooks/post-tool-use.js +32 -20
- package/dist/hooks/pre-commit.js +2 -2
- package/dist/hooks/pre-tool-use.js +11 -3
- package/dist/hooks/prim-hook.js +7 -7
- package/dist/hooks/session-start.js +15 -14
- package/dist/index.js +236 -139
- package/dist/statusline-main.js +50 -40
- package/package.json +1 -1
- package/dist/chunk-GF5QII7T.js +0 -411
|
@@ -15,15 +15,61 @@ var AGENT_ENVELOPE_VERSION = 3;
|
|
|
15
15
|
var ENVELOPE_VERSION = LEGACY_ENVELOPE_VERSION;
|
|
16
16
|
|
|
17
17
|
// src/hooks/prim-hook-core.ts
|
|
18
|
+
var CORRELATED_TOOL_EVENTS = /* @__PURE__ */ new Set([
|
|
19
|
+
"PostToolUse",
|
|
20
|
+
"PostToolUseFailure",
|
|
21
|
+
"post_tool_call",
|
|
22
|
+
"post_approval_response"
|
|
23
|
+
]);
|
|
18
24
|
function postToolInvocationId(parsed, agent) {
|
|
19
|
-
if (parsed.hook_event_name !== "
|
|
25
|
+
if (typeof parsed.hook_event_name !== "string" || !CORRELATED_TOOL_EVENTS.has(parsed.hook_event_name)) {
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
20
28
|
const raw = agent === "hermes" ? parsed.extra?.tool_call_id : parsed.tool_use_id;
|
|
21
29
|
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
22
30
|
}
|
|
31
|
+
function lowerString(value) {
|
|
32
|
+
return typeof value === "string" ? value.toLowerCase() : void 0;
|
|
33
|
+
}
|
|
34
|
+
function toolOutcomeFor(parsed, agent) {
|
|
35
|
+
const event = parsed.hook_event_name;
|
|
36
|
+
if (agent === "claude_code") {
|
|
37
|
+
if (event === "PostToolUseFailure") {
|
|
38
|
+
return parsed.is_interrupt === true ? "interrupted" : "failed";
|
|
39
|
+
}
|
|
40
|
+
return event === "PostToolUse" ? "succeeded" : void 0;
|
|
41
|
+
}
|
|
42
|
+
if (agent === "codex") {
|
|
43
|
+
return event === "PostToolUse" ? "returned" : void 0;
|
|
44
|
+
}
|
|
45
|
+
const extra = parsed.extra;
|
|
46
|
+
if (event === "post_approval_response") {
|
|
47
|
+
const choice = lowerString(extra?.choice);
|
|
48
|
+
return (choice === "deny" || choice === "smart_deny" || choice === "timeout") && postToolInvocationId(parsed, agent) ? "prevented" : void 0;
|
|
49
|
+
}
|
|
50
|
+
if (event !== "PostToolUse" && event !== "post_tool_call") {
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
const status = lowerString(extra?.status);
|
|
54
|
+
if (status === "ok" || status === "success") {
|
|
55
|
+
return "succeeded";
|
|
56
|
+
}
|
|
57
|
+
if (status === "error" || status === "timeout") {
|
|
58
|
+
return "failed";
|
|
59
|
+
}
|
|
60
|
+
if (status === "cancelled") {
|
|
61
|
+
return "interrupted";
|
|
62
|
+
}
|
|
63
|
+
if (status === "blocked") {
|
|
64
|
+
return "prevented";
|
|
65
|
+
}
|
|
66
|
+
return "unknown";
|
|
67
|
+
}
|
|
23
68
|
function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, repository, invocationId) {
|
|
24
69
|
const sessionId = parsed.session_id ?? "";
|
|
25
70
|
const eventType = parsed.hook_event_name ?? "unknown";
|
|
26
|
-
const
|
|
71
|
+
const toolOutcome = toolOutcomeFor(parsed, agent);
|
|
72
|
+
const moveId = CORRELATED_TOOL_EVENTS.has(eventType) && sessionId && invocationId ? `posttool:v1:${createHash("sha256").update(JSON.stringify([agent, sessionId, eventType, invocationId])).digest("hex")}` : randomUUID();
|
|
27
73
|
return {
|
|
28
74
|
moveId,
|
|
29
75
|
capturedAt: Date.now(),
|
|
@@ -45,7 +91,8 @@ function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, reposito
|
|
|
45
91
|
},
|
|
46
92
|
envelopeVersion: AGENT_ENVELOPE_VERSION,
|
|
47
93
|
producer: agent,
|
|
48
|
-
...invocationId ? { invocationId } : {}
|
|
94
|
+
...invocationId ? { invocationId } : {},
|
|
95
|
+
...toolOutcome ? { toolOutcome } : {}
|
|
49
96
|
};
|
|
50
97
|
}
|
|
51
98
|
var MAX_CLASSIFIER_ID_CHARS = 256;
|
|
@@ -63,17 +110,18 @@ function commitAttributionFromEnvironment(env, workspaceId) {
|
|
|
63
110
|
return candidates.length === 1 ? candidates[0] : void 0;
|
|
64
111
|
}
|
|
65
112
|
function toCommitMove(commit, cliVersion, cwd, context = {}) {
|
|
66
|
-
const { repository, repoFullName, repoSyncId, workspaceId, attribution } = context;
|
|
113
|
+
const { repository, repoFullName, repoSyncId, workspaceId, attribution, capturedAt } = context;
|
|
67
114
|
const validatedRepoSyncId = isValidRepoSyncId(repoSyncId) ? repoSyncId : void 0;
|
|
68
115
|
const validatedWorkspaceId = workspaceId && isCanonicalWorkspaceId(workspaceId) ? workspaceId : void 0;
|
|
69
116
|
const validatedAttribution = validatedWorkspaceId ? attribution : void 0;
|
|
117
|
+
const validatedCapturedAt = typeof capturedAt === "number" && Number.isSafeInteger(capturedAt) && capturedAt > 0 ? capturedAt : Date.now();
|
|
70
118
|
const fullSha = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u.test(commit.sha);
|
|
71
119
|
const moveId = validatedRepoSyncId && validatedWorkspaceId && fullSha ? `commit:v2:${createHash("sha256").update(
|
|
72
120
|
JSON.stringify(["commit:v2", validatedRepoSyncId, validatedWorkspaceId, commit.sha])
|
|
73
121
|
).digest("hex")}` : `commit:v2:unscoped:${randomUUID()}`;
|
|
74
122
|
const base = {
|
|
75
123
|
moveId,
|
|
76
|
-
capturedAt:
|
|
124
|
+
capturedAt: validatedCapturedAt,
|
|
77
125
|
sessionId: validatedAttribution?.sessionId ?? "",
|
|
78
126
|
eventType: "git.commit",
|
|
79
127
|
payload: {
|
|
@@ -110,6 +158,7 @@ function shouldFlushAfter(eventType) {
|
|
|
110
158
|
|
|
111
159
|
export {
|
|
112
160
|
postToolInvocationId,
|
|
161
|
+
toolOutcomeFor,
|
|
113
162
|
toMove,
|
|
114
163
|
commitAttributionFromEnvironment,
|
|
115
164
|
toCommitMove,
|
|
@@ -153,10 +153,10 @@ var CREDENTIAL_FILE_MODE = 384;
|
|
|
153
153
|
var REFRESH_THRESHOLD_MS = 6e4;
|
|
154
154
|
var DEFAULT_API_URL = "https://api.getprimitive.ai";
|
|
155
155
|
var AUTH_EXPIRED_MESSAGE = "Authentication expired. Run `prim auth login` to re-authenticate.";
|
|
156
|
-
function loadEnvFile() {
|
|
156
|
+
function loadEnvFile(cwd = process.cwd()) {
|
|
157
157
|
const envVars = {};
|
|
158
158
|
for (const file of [".env.local", ".env"]) {
|
|
159
|
-
const filePath = resolve(
|
|
159
|
+
const filePath = resolve(cwd, file);
|
|
160
160
|
if (!existsSync2(filePath)) continue;
|
|
161
161
|
const content = readFileSync2(filePath, "utf-8");
|
|
162
162
|
for (const line of content.split("\n")) {
|
|
@@ -194,8 +194,11 @@ function resolveAuthCredential() {
|
|
|
194
194
|
return envToken ? { token: envToken, source: "env_file" } : void 0;
|
|
195
195
|
}
|
|
196
196
|
function getSiteUrl() {
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
return getSiteUrlForCwd(process.cwd(), process.env.PRIM_API_URL);
|
|
198
|
+
}
|
|
199
|
+
function getSiteUrlForCwd(cwd, primApiUrl) {
|
|
200
|
+
if (primApiUrl) return primApiUrl;
|
|
201
|
+
return loadEnvFile(cwd).PRIM_API_URL ?? DEFAULT_API_URL;
|
|
199
202
|
}
|
|
200
203
|
function getJwtExpiry(token) {
|
|
201
204
|
const parts = token.split(".");
|