@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.
Files changed (45) hide show
  1. package/README.md +20 -12
  2. package/SKILL.md +6 -6
  3. package/dist/{chunk-LMRYZL3D.js → chunk-5AFRMOPX.js} +1 -1
  4. package/dist/{chunk-RO3F6JYV.js → chunk-5GYQ4J3D.js} +2 -2
  5. package/dist/{chunk-3EEFL6NJ.js → chunk-67VNLLBN.js} +261 -1
  6. package/dist/{chunk-LEMX3IOG.js → chunk-BTNNEH2W.js} +1 -1
  7. package/dist/chunk-EWZMDD44.js +1474 -0
  8. package/dist/{chunk-YWO7O6QG.js → chunk-FBAYCS3X.js} +2 -2
  9. package/dist/{chunk-R26A7TWY.js → chunk-FKXFUUWJ.js} +1 -1
  10. package/dist/{chunk-C7T7B45R.js → chunk-FOLKHXLJ.js} +150 -21
  11. package/dist/chunk-H4UNYFUC.js +196 -0
  12. package/dist/chunk-HU4PW6I6.js +264 -0
  13. package/dist/{chunk-CUE2LKLR.js → chunk-KFXF2V5G.js} +1 -1
  14. package/dist/{chunk-6IWNH776.js → chunk-LFFLHSQO.js} +4 -3
  15. package/dist/{chunk-MAZWKJGL.js → chunk-M6RIJVRE.js} +42 -232
  16. package/dist/{chunk-2JRX7ZR4.js → chunk-NAHHFSLH.js} +16 -5
  17. package/dist/{chunk-FI3LIRCB.js → chunk-OAAP2MY6.js} +2 -2
  18. package/dist/{chunk-Z7YPFWAZ.js → chunk-PCVGBE5B.js} +10 -268
  19. package/dist/{chunk-UZPBB7V4.js → chunk-VW3FDYRT.js} +60 -48
  20. package/dist/chunk-WX52U7Z2.js +112 -0
  21. package/dist/{chunk-PPQYQEIR.js → chunk-ZB4F75SZ.js} +28 -0
  22. package/dist/daemon/server.js +20 -20
  23. package/dist/hook-runtime/daemon/server.js +20 -20
  24. package/dist/hook-runtime/hooks/post-commit.js +20 -20
  25. package/dist/hook-runtime/hooks/post-rewrite.js +20 -20
  26. package/dist/hook-runtime/hooks/post-tool-use.js +651 -132
  27. package/dist/hook-runtime/hooks/pre-tool-use.js +644 -96
  28. package/dist/hook-runtime/hooks/prim-hook.js +612 -96
  29. package/dist/hook-runtime/hooks/session-end.js +610 -27
  30. package/dist/hook-runtime/hooks/session-start.js +1132 -533
  31. package/dist/hook-runtime/index.js +735 -264
  32. package/dist/hook-runtime/statusline-main.js +48 -4
  33. package/dist/hooks/post-commit.js +11 -9
  34. package/dist/hooks/post-rewrite.js +11 -9
  35. package/dist/hooks/post-tool-use.js +73 -48
  36. package/dist/hooks/pre-commit.js +4 -4
  37. package/dist/hooks/pre-tool-use.js +46 -44
  38. package/dist/hooks/prim-hook.js +47 -25
  39. package/dist/hooks/session-end.js +15 -26
  40. package/dist/hooks/session-start.js +59 -32
  41. package/dist/index.js +558 -1436
  42. package/dist/statusline-main.js +48 -4
  43. package/package.json +1 -1
  44. package/dist/chunk-PMRDE2DA.js +0 -310
  45. package/dist/chunk-WB7AUZ4C.js +0 -52
@@ -8,47 +8,52 @@ import {
8
8
  acknowledgeDecisionFeedback,
9
9
  leaseDecisionFeedback,
10
10
  renderFeedback
11
- } from "../chunk-LMRYZL3D.js";
11
+ } from "../chunk-5AFRMOPX.js";
12
12
  import {
13
13
  enrichHookPayloadWithFileRefs,
14
14
  preserveHookFileMetadata
15
- } from "../chunk-6IWNH776.js";
15
+ } from "../chunk-LFFLHSQO.js";
16
16
  import {
17
17
  postToolInvocationId,
18
18
  shouldFlushAfter,
19
19
  toMove
20
- } from "../chunk-2JRX7ZR4.js";
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-YWO7O6QG.js";
28
- import "../chunk-PPQYQEIR.js";
27
+ } from "../chunk-FBAYCS3X.js";
28
+ import "../chunk-ZB4F75SZ.js";
29
29
  import {
30
30
  prepareCodexContext
31
- } from "../chunk-UZPBB7V4.js";
32
- import "../chunk-PMRDE2DA.js";
31
+ } from "../chunk-VW3FDYRT.js";
32
+ import "../chunk-WX52U7Z2.js";
33
33
  import {
34
34
  scrubFromCwd,
35
35
  writeHookDebug
36
- } from "../chunk-FI3LIRCB.js";
37
- import "../chunk-LEMX3IOG.js";
36
+ } from "../chunk-OAAP2MY6.js";
37
+ import "../chunk-BTNNEH2W.js";
38
38
  import {
39
39
  cachedCollectScopeAdmits,
40
- currentBranch,
41
40
  isRepoActiveForCapture,
42
- repoSyncId,
43
- resolveRepositoryContext
44
- } from "../chunk-MAZWKJGL.js";
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
- } from "../chunk-WB7AUZ4C.js";
50
- import "../chunk-CUE2LKLR.js";
51
- import "../chunk-3EEFL6NJ.js";
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 = readFileSync(0, "utf-8");
121
- parsed = normalizeEnvelope(JSON.parse(raw), agent);
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(buildHookOutput({}));
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) await emitOutput(buildHookOutput({}));
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
- if (cachedCollectScopeAdmits(cwd, {
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(buildHookOutput({}));
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
- } from "../chunk-WB7AUZ4C.js";
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-CUE2LKLR.js";
9
- import "../chunk-3EEFL6NJ.js";
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 readStdin();
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
- envelope = normalizeEnvelope(
46
- JSON.parse(raw),
47
- agent
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-C7T7B45R.js";
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-LMRYZL3D.js";
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-UZPBB7V4.js";
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-MAZWKJGL.js";
33
+ } from "../chunk-M6RIJVRE.js";
36
34
  import {
37
35
  getSiteUrl,
38
36
  isSessionEnded
39
- } from "../chunk-Z7YPFWAZ.js";
37
+ } from "../chunk-PCVGBE5B.js";
40
38
  import {
41
39
  normalizeEnvelope,
42
- parseAgent
43
- } from "../chunk-WB7AUZ4C.js";
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-CUE2LKLR.js";
47
- import "../chunk-3EEFL6NJ.js";
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 readStdin();
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
  }