@primitive.ai/prim 0.1.0-alpha.90 → 0.1.0-alpha.91
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 +20 -12
- package/SKILL.md +6 -6
- package/dist/{chunk-LMRYZL3D.js → chunk-5AFRMOPX.js} +1 -1
- package/dist/{chunk-RO3F6JYV.js → chunk-5GYQ4J3D.js} +2 -2
- package/dist/{chunk-3EEFL6NJ.js → chunk-67VNLLBN.js} +261 -1
- package/dist/{chunk-LEMX3IOG.js → chunk-BTNNEH2W.js} +1 -1
- package/dist/chunk-EWZMDD44.js +1474 -0
- package/dist/{chunk-YWO7O6QG.js → chunk-FBAYCS3X.js} +2 -2
- package/dist/{chunk-R26A7TWY.js → chunk-FKXFUUWJ.js} +1 -1
- package/dist/{chunk-C7T7B45R.js → chunk-FOLKHXLJ.js} +150 -21
- package/dist/chunk-H4UNYFUC.js +196 -0
- package/dist/chunk-HU4PW6I6.js +264 -0
- package/dist/{chunk-CUE2LKLR.js → chunk-KFXF2V5G.js} +1 -1
- package/dist/{chunk-6IWNH776.js → chunk-LFFLHSQO.js} +4 -3
- package/dist/{chunk-MAZWKJGL.js → chunk-M6RIJVRE.js} +42 -232
- package/dist/{chunk-2JRX7ZR4.js → chunk-NAHHFSLH.js} +16 -5
- package/dist/{chunk-FI3LIRCB.js → chunk-OAAP2MY6.js} +2 -2
- package/dist/{chunk-Z7YPFWAZ.js → chunk-PCVGBE5B.js} +10 -268
- package/dist/{chunk-UZPBB7V4.js → chunk-VW3FDYRT.js} +60 -48
- package/dist/chunk-WX52U7Z2.js +112 -0
- package/dist/{chunk-PPQYQEIR.js → chunk-ZB4F75SZ.js} +28 -0
- package/dist/daemon/server.js +20 -20
- package/dist/hook-runtime/daemon/server.js +20 -20
- package/dist/hook-runtime/hooks/post-commit.js +20 -20
- package/dist/hook-runtime/hooks/post-rewrite.js +20 -20
- package/dist/hook-runtime/hooks/post-tool-use.js +651 -132
- package/dist/hook-runtime/hooks/pre-tool-use.js +644 -96
- package/dist/hook-runtime/hooks/prim-hook.js +612 -96
- package/dist/hook-runtime/hooks/session-end.js +610 -27
- package/dist/hook-runtime/hooks/session-start.js +1132 -533
- package/dist/hook-runtime/index.js +735 -264
- package/dist/hook-runtime/statusline-main.js +48 -4
- package/dist/hooks/post-commit.js +11 -9
- package/dist/hooks/post-rewrite.js +11 -9
- package/dist/hooks/post-tool-use.js +73 -48
- package/dist/hooks/pre-commit.js +4 -4
- package/dist/hooks/pre-tool-use.js +46 -44
- package/dist/hooks/prim-hook.js +47 -25
- package/dist/hooks/session-end.js +15 -26
- package/dist/hooks/session-start.js +59 -32
- package/dist/index.js +558 -1436
- package/dist/statusline-main.js +48 -4
- package/package.json +1 -1
- package/dist/chunk-PMRDE2DA.js +0 -310
- package/dist/chunk-WB7AUZ4C.js +0 -52
package/dist/hooks/prim-hook.js
CHANGED
|
@@ -8,47 +8,52 @@ import {
|
|
|
8
8
|
acknowledgeDecisionFeedback,
|
|
9
9
|
leaseDecisionFeedback,
|
|
10
10
|
renderFeedback
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-5AFRMOPX.js";
|
|
12
12
|
import {
|
|
13
13
|
enrichHookPayloadWithFileRefs,
|
|
14
14
|
preserveHookFileMetadata
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-LFFLHSQO.js";
|
|
16
16
|
import {
|
|
17
17
|
postToolInvocationId,
|
|
18
18
|
shouldFlushAfter,
|
|
19
19
|
toMove
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-NAHHFSLH.js";
|
|
21
21
|
import {
|
|
22
22
|
getOrCreateWorkspaceId
|
|
23
23
|
} from "../chunk-EZXEWFDG.js";
|
|
24
24
|
import {
|
|
25
25
|
appendMove,
|
|
26
26
|
resolveOrg
|
|
27
|
-
} from "../chunk-
|
|
28
|
-
import "../chunk-
|
|
27
|
+
} from "../chunk-FBAYCS3X.js";
|
|
28
|
+
import "../chunk-ZB4F75SZ.js";
|
|
29
29
|
import {
|
|
30
30
|
prepareCodexContext
|
|
31
|
-
} from "../chunk-
|
|
32
|
-
import "../chunk-
|
|
31
|
+
} from "../chunk-VW3FDYRT.js";
|
|
32
|
+
import "../chunk-WX52U7Z2.js";
|
|
33
33
|
import {
|
|
34
34
|
scrubFromCwd,
|
|
35
35
|
writeHookDebug
|
|
36
|
-
} from "../chunk-
|
|
37
|
-
import "../chunk-
|
|
36
|
+
} from "../chunk-OAAP2MY6.js";
|
|
37
|
+
import "../chunk-BTNNEH2W.js";
|
|
38
38
|
import {
|
|
39
39
|
cachedCollectScopeAdmits,
|
|
40
|
-
currentBranch,
|
|
41
40
|
isRepoActiveForCapture,
|
|
42
|
-
repoSyncId
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
import "../chunk-Z7YPFWAZ.js";
|
|
41
|
+
repoSyncId
|
|
42
|
+
} from "../chunk-M6RIJVRE.js";
|
|
43
|
+
import "../chunk-PCVGBE5B.js";
|
|
46
44
|
import {
|
|
47
45
|
normalizeEnvelope,
|
|
48
|
-
parseAgent
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
parseAgent,
|
|
47
|
+
readHookStdin,
|
|
48
|
+
shouldSuppressImportedCursorHandler
|
|
49
|
+
} from "../chunk-HU4PW6I6.js";
|
|
50
|
+
import "../chunk-EWZMDD44.js";
|
|
51
|
+
import {
|
|
52
|
+
currentBranch,
|
|
53
|
+
resolveRepositoryContext
|
|
54
|
+
} from "../chunk-H4UNYFUC.js";
|
|
55
|
+
import "../chunk-KFXF2V5G.js";
|
|
56
|
+
import "../chunk-67VNLLBN.js";
|
|
52
57
|
|
|
53
58
|
// src/hooks/prim-hook.ts
|
|
54
59
|
import { spawn } from "child_process";
|
|
@@ -117,18 +122,22 @@ async function main() {
|
|
|
117
122
|
let raw;
|
|
118
123
|
let parsed;
|
|
119
124
|
try {
|
|
120
|
-
raw =
|
|
121
|
-
|
|
125
|
+
raw = await readHookStdin();
|
|
126
|
+
const incoming = JSON.parse(raw);
|
|
127
|
+
if (agent !== "cursor" && shouldSuppressImportedCursorHandler(incoming, "prim-hook")) return;
|
|
128
|
+
parsed = normalizeEnvelope(incoming, agent);
|
|
122
129
|
} catch (error) {
|
|
123
130
|
writeHookDebug("capture failed", error);
|
|
124
|
-
await emitOutput(
|
|
131
|
+
await emitOutput(cursorPassiveOutput());
|
|
125
132
|
return;
|
|
126
133
|
}
|
|
127
134
|
const cwd = parsed.cwd ?? process.cwd();
|
|
128
135
|
const isClaudeStop = agent === "claude_code" && parsed.hook_event_name === "Stop";
|
|
129
136
|
const isCodexContextEvent = agent === "codex" && (parsed.hook_event_name === "UserPromptSubmit" || parsed.hook_event_name === "Stop");
|
|
130
137
|
if (!isRepoActiveForCapture(cwd)) {
|
|
131
|
-
if (isClaudeStop || isCodexContextEvent)
|
|
138
|
+
if (isClaudeStop || isCodexContextEvent || agent === "cursor") {
|
|
139
|
+
await emitOutput(cursorPassiveOutput());
|
|
140
|
+
}
|
|
132
141
|
return;
|
|
133
142
|
}
|
|
134
143
|
const identity = getOrCreateWorkspaceId(cwd);
|
|
@@ -140,7 +149,8 @@ async function main() {
|
|
|
140
149
|
const resolution = enrichment?.resolution;
|
|
141
150
|
const hasPathEvidence = resolution !== void 0 && (resolution.fileRefs.length > 0 || resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved");
|
|
142
151
|
const pathsComplete = resolution !== void 0 && !resolution.targetsIncomplete && !resolution.targetsTruncated && resolution.rejected.length === 0 && resolution.shellMutation !== "unresolved";
|
|
143
|
-
|
|
152
|
+
const cursorAmbiguousTargets = agent === "cursor" && resolution !== void 0 && (resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved");
|
|
153
|
+
if (!cursorAmbiguousTargets && cachedCollectScopeAdmits(cwd, {
|
|
144
154
|
repository: resolvedRepository?.repoFullName,
|
|
145
155
|
branch: currentBranch(cwd),
|
|
146
156
|
agent,
|
|
@@ -163,7 +173,7 @@ async function main() {
|
|
|
163
173
|
};
|
|
164
174
|
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd });
|
|
165
175
|
appendMove(move, orgId);
|
|
166
|
-
if (shouldFlushAfter(move.eventType)) {
|
|
176
|
+
if (shouldFlushAfter(move.eventType, agent)) {
|
|
167
177
|
spawnBackgroundFlush();
|
|
168
178
|
}
|
|
169
179
|
}
|
|
@@ -175,6 +185,10 @@ async function main() {
|
|
|
175
185
|
await emitOutput(result.output, result.acknowledge);
|
|
176
186
|
return;
|
|
177
187
|
}
|
|
188
|
+
if (agent === "cursor") {
|
|
189
|
+
await emitOutput(cursorPassiveOutput());
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
178
192
|
if (!isClaudeStop) return;
|
|
179
193
|
const sessionId = typeof parsed.session_id === "string" ? parsed.session_id : "";
|
|
180
194
|
if (!workspaceId || !sessionId) {
|
|
@@ -203,5 +217,13 @@ async function main() {
|
|
|
203
217
|
}
|
|
204
218
|
void main().catch(async (error) => {
|
|
205
219
|
writeHookDebug("capture failed", error);
|
|
206
|
-
if (!outputAttempted) await emitOutput(
|
|
220
|
+
if (!outputAttempted) await emitOutput(cursorPassiveOutput());
|
|
207
221
|
});
|
|
222
|
+
function cursorPassiveOutput() {
|
|
223
|
+
if (parseAgent(process.argv) !== "cursor") return buildHookOutput({});
|
|
224
|
+
const index = process.argv.indexOf("--event");
|
|
225
|
+
const event = index === -1 ? void 0 : process.argv[index + 1];
|
|
226
|
+
if (event === "beforeSubmitPrompt") return { continue: true };
|
|
227
|
+
if (event === "preToolUse") return { permission: "allow" };
|
|
228
|
+
return {};
|
|
229
|
+
}
|
|
@@ -1,33 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
normalizeEnvelope,
|
|
4
|
-
parseAgent
|
|
5
|
-
|
|
4
|
+
parseAgent,
|
|
5
|
+
readHookStdin,
|
|
6
|
+
shouldSuppressImportedCursorHandler
|
|
7
|
+
} from "../chunk-HU4PW6I6.js";
|
|
8
|
+
import "../chunk-EWZMDD44.js";
|
|
9
|
+
import "../chunk-H4UNYFUC.js";
|
|
6
10
|
import {
|
|
7
11
|
daemonRequest
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-KFXF2V5G.js";
|
|
13
|
+
import "../chunk-67VNLLBN.js";
|
|
10
14
|
|
|
11
15
|
// src/hooks/session-end.ts
|
|
12
16
|
var STDIN_TIMEOUT_MS = 1e3;
|
|
13
17
|
var DAEMON_TIMEOUT_MS = 250;
|
|
14
|
-
function readStdin() {
|
|
15
|
-
return new Promise((resolve, reject) => {
|
|
16
|
-
const chunks = [];
|
|
17
|
-
const timer = setTimeout(() => {
|
|
18
|
-
reject(new Error("stdin read timeout"));
|
|
19
|
-
}, STDIN_TIMEOUT_MS);
|
|
20
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
21
|
-
process.stdin.on("end", () => {
|
|
22
|
-
clearTimeout(timer);
|
|
23
|
-
resolve(Buffer.concat(chunks).toString("utf-8"));
|
|
24
|
-
});
|
|
25
|
-
process.stdin.on("error", (err) => {
|
|
26
|
-
clearTimeout(timer);
|
|
27
|
-
reject(err);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
18
|
function emit() {
|
|
32
19
|
process.stdout.write("{}\n");
|
|
33
20
|
}
|
|
@@ -35,17 +22,19 @@ async function main() {
|
|
|
35
22
|
const agent = parseAgent(process.argv);
|
|
36
23
|
let raw;
|
|
37
24
|
try {
|
|
38
|
-
raw = await
|
|
25
|
+
raw = await readHookStdin(STDIN_TIMEOUT_MS);
|
|
39
26
|
} catch {
|
|
40
27
|
emit();
|
|
41
28
|
return;
|
|
42
29
|
}
|
|
43
30
|
let envelope;
|
|
44
31
|
try {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
const incoming = JSON.parse(raw);
|
|
33
|
+
if (agent !== "cursor" && shouldSuppressImportedCursorHandler(incoming, "prim-session-end")) {
|
|
34
|
+
emit();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
envelope = normalizeEnvelope(incoming, agent);
|
|
49
38
|
} catch {
|
|
50
39
|
emit();
|
|
51
40
|
return;
|
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
ensureEffectivePostCommitHook,
|
|
5
5
|
ensureEffectivePostRewriteHook,
|
|
6
6
|
hasUsableCodexGuidance,
|
|
7
|
+
hasUsableCursorSkill,
|
|
7
8
|
refreshClaudePlugins,
|
|
8
9
|
warmBinCache
|
|
9
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-FOLKHXLJ.js";
|
|
10
11
|
import {
|
|
11
12
|
buildHookOutput,
|
|
12
13
|
handoffHookOutput
|
|
@@ -16,35 +17,40 @@ import {
|
|
|
16
17
|
acknowledgeDecisionFeedback,
|
|
17
18
|
leaseDecisionFeedback,
|
|
18
19
|
renderFeedback
|
|
19
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-5AFRMOPX.js";
|
|
20
21
|
import {
|
|
21
22
|
getOrCreateWorkspaceId
|
|
22
23
|
} from "../chunk-EZXEWFDG.js";
|
|
23
24
|
import {
|
|
24
25
|
prepareCodexContext
|
|
25
|
-
} from "../chunk-
|
|
26
|
-
import
|
|
27
|
-
binFile
|
|
28
|
-
} from "../chunk-PMRDE2DA.js";
|
|
26
|
+
} from "../chunk-VW3FDYRT.js";
|
|
27
|
+
import "../chunk-WX52U7Z2.js";
|
|
29
28
|
import {
|
|
30
29
|
fetchAndCacheCollectScope,
|
|
31
|
-
gitToplevel,
|
|
32
30
|
isRepoActiveForCapture,
|
|
33
31
|
repoActiveFlag,
|
|
34
32
|
setRepoActive
|
|
35
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-M6RIJVRE.js";
|
|
36
34
|
import {
|
|
37
35
|
getSiteUrl,
|
|
38
36
|
isSessionEnded
|
|
39
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-PCVGBE5B.js";
|
|
40
38
|
import {
|
|
41
39
|
normalizeEnvelope,
|
|
42
|
-
parseAgent
|
|
43
|
-
|
|
40
|
+
parseAgent,
|
|
41
|
+
readHookStdin,
|
|
42
|
+
shouldSuppressImportedCursorHandler
|
|
43
|
+
} from "../chunk-HU4PW6I6.js";
|
|
44
|
+
import {
|
|
45
|
+
binFile
|
|
46
|
+
} from "../chunk-EWZMDD44.js";
|
|
47
|
+
import {
|
|
48
|
+
gitToplevel
|
|
49
|
+
} from "../chunk-H4UNYFUC.js";
|
|
44
50
|
import {
|
|
45
51
|
daemonRequest
|
|
46
|
-
} from "../chunk-
|
|
47
|
-
import "../chunk-
|
|
52
|
+
} from "../chunk-KFXF2V5G.js";
|
|
53
|
+
import "../chunk-67VNLLBN.js";
|
|
48
54
|
|
|
49
55
|
// src/daemon/self-heal.ts
|
|
50
56
|
import { spawn } from "child_process";
|
|
@@ -174,7 +180,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
174
180
|
} catch {
|
|
175
181
|
}
|
|
176
182
|
}
|
|
177
|
-
if (isSessionEnded() && agent !== "codex") {
|
|
183
|
+
if (isSessionEnded() && agent !== "codex" && agent !== "cursor") {
|
|
178
184
|
const notice = reauthNoticeFields(agent);
|
|
179
185
|
if (notice) {
|
|
180
186
|
return {
|
|
@@ -208,6 +214,34 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
208
214
|
}
|
|
209
215
|
};
|
|
210
216
|
}
|
|
217
|
+
if (agent === "cursor") {
|
|
218
|
+
const activeProject = await activeProjectRoot(cwd);
|
|
219
|
+
projectRoot = activeProject?.root ?? null;
|
|
220
|
+
active = projectRoot !== null;
|
|
221
|
+
let context;
|
|
222
|
+
try {
|
|
223
|
+
context = await prepareCodexContext({
|
|
224
|
+
cwd,
|
|
225
|
+
sessionId: envelope.session_id,
|
|
226
|
+
startup: true,
|
|
227
|
+
includeDigest: true,
|
|
228
|
+
namespace: "cursor"
|
|
229
|
+
});
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
let proactive = false;
|
|
233
|
+
try {
|
|
234
|
+
proactive = projectRoot !== null && active && hasUsableCursorSkill(projectRoot);
|
|
235
|
+
} catch {
|
|
236
|
+
}
|
|
237
|
+
const additionalContext = [proactive ? CODEX_PRIM_REMINDER : void 0, context?.context].filter((value) => value !== void 0).join("\n\n");
|
|
238
|
+
return {
|
|
239
|
+
output: additionalContext ? { additional_context: additionalContext } : {},
|
|
240
|
+
acknowledge: async () => {
|
|
241
|
+
await context?.acknowledge(true);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
211
245
|
if (agent === "claude_code") {
|
|
212
246
|
const additionalContext = [
|
|
213
247
|
claudeBinding ? claudeBindingReminder(claudeBinding) : void 0,
|
|
@@ -254,33 +288,26 @@ function emitOutput(output, acknowledge) {
|
|
|
254
288
|
outputAttempted = true;
|
|
255
289
|
return handoffHookOutput(output, acknowledge);
|
|
256
290
|
}
|
|
257
|
-
function readStdin() {
|
|
258
|
-
return new Promise((resolve, reject) => {
|
|
259
|
-
const chunks = [];
|
|
260
|
-
const timer = setTimeout(() => {
|
|
261
|
-
reject(new Error("stdin read timeout"));
|
|
262
|
-
}, STDIN_TIMEOUT_MS);
|
|
263
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
264
|
-
process.stdin.on("end", () => {
|
|
265
|
-
clearTimeout(timer);
|
|
266
|
-
resolve(Buffer.concat(chunks).toString("utf-8"));
|
|
267
|
-
});
|
|
268
|
-
process.stdin.on("error", (err) => {
|
|
269
|
-
clearTimeout(timer);
|
|
270
|
-
reject(err);
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
291
|
async function main() {
|
|
275
292
|
warmBinCache();
|
|
276
293
|
const agent = parseAgent(process.argv);
|
|
277
294
|
let raw;
|
|
278
295
|
try {
|
|
279
|
-
raw = await
|
|
296
|
+
raw = await readHookStdin(STDIN_TIMEOUT_MS);
|
|
280
297
|
} catch {
|
|
281
298
|
await emitOutput(buildHookOutput({}));
|
|
282
299
|
return;
|
|
283
300
|
}
|
|
301
|
+
if (agent !== "cursor") {
|
|
302
|
+
try {
|
|
303
|
+
const incoming = JSON.parse(raw);
|
|
304
|
+
if (shouldSuppressImportedCursorHandler(incoming, "prim-session-start")) {
|
|
305
|
+
await emitOutput({});
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
}
|
|
310
|
+
}
|
|
284
311
|
const result = await processSessionStart(raw, agent);
|
|
285
312
|
await emitOutput(result.output, result.acknowledge);
|
|
286
313
|
}
|