@primitive.ai/prim 0.1.0-alpha.67 → 0.1.0-alpha.69
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 +39 -1
- package/SKILL.md +1 -1
- package/dist/{chunk-XPVNH3J6.js → chunk-2KW7DVFJ.js} +121 -130
- package/dist/chunk-3EEFL6NJ.js +529 -0
- package/dist/chunk-4A2XB2PC.js +310 -0
- package/dist/{chunk-G5D3FF3D.js → chunk-BQUJ4AFJ.js} +1 -83
- package/dist/chunk-CUE2LKLR.js +155 -0
- package/dist/chunk-FI3LIRCB.js +262 -0
- package/dist/{chunk-CPSE3Y3T.js → chunk-H64F6QHV.js} +27 -8
- package/dist/chunk-KKP2NYZ3.js +505 -0
- package/dist/{chunk-JQFN6LBO.js → chunk-LEMX3IOG.js} +6 -37
- package/dist/{chunk-U6L2RU67.js → chunk-LMRYZL3D.js} +52 -45
- package/dist/{chunk-XUAP572Z.js → chunk-RO3F6JYV.js} +8 -7
- package/dist/{chunk-TDRXHBEX.js → chunk-TJTVHDJ5.js} +41 -18
- package/dist/{chunk-TCDUH7AN.js → chunk-WB7AUZ4C.js} +17 -0
- package/dist/chunk-XGADQPCI.js +26 -0
- package/dist/{chunk-UN5O5SYG.js → chunk-YWO7O6QG.js} +14 -53
- package/dist/chunk-Z7YPFWAZ.js +917 -0
- package/dist/{chunk-BDGQEJA5.js → chunk-ZOSNEO5N.js} +2 -2
- package/dist/daemon/server.js +11804 -470
- package/dist/hook-runtime/daemon/server.js +13353 -0
- package/dist/hook-runtime/hooks/post-commit.js +1128 -0
- package/dist/hook-runtime/hooks/post-rewrite.js +1148 -0
- package/dist/hook-runtime/hooks/post-tool-use.js +7586 -0
- package/dist/hook-runtime/hooks/pre-commit.js +1314 -0
- package/dist/hook-runtime/hooks/pre-tool-use.js +7099 -0
- package/dist/hook-runtime/hooks/prim-hook.js +7691 -0
- package/dist/hook-runtime/hooks/session-end.js +495 -0
- package/dist/hook-runtime/hooks/session-start.js +11284 -0
- package/dist/hook-runtime/index.js +42775 -0
- package/dist/hook-runtime/statusline-main.js +765 -0
- package/dist/hooks/post-commit.js +7 -4
- package/dist/hooks/post-rewrite.js +7 -4
- package/dist/hooks/post-tool-use.js +64 -32
- package/dist/hooks/pre-commit.js +4 -3
- package/dist/hooks/pre-tool-use.js +118 -38
- package/dist/hooks/prim-hook.js +72 -27
- package/dist/hooks/session-end.js +5 -4
- package/dist/hooks/session-start.js +36 -25
- package/dist/index.js +15039 -2555
- package/dist/statusline-main.js +488 -96
- package/package.json +11 -5
- package/dist/chunk-CZ24W5QU.js +0 -123
- package/dist/chunk-RTLFE6EZ.js +0 -518
- package/dist/chunk-UTKQTZHL.js +0 -88
package/dist/hooks/prim-hook.js
CHANGED
|
@@ -8,45 +8,86 @@ import {
|
|
|
8
8
|
acknowledgeDecisionFeedback,
|
|
9
9
|
leaseDecisionFeedback,
|
|
10
10
|
renderFeedback
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-LMRYZL3D.js";
|
|
12
12
|
import {
|
|
13
13
|
enrichHookPayloadWithFileRefs,
|
|
14
14
|
preserveHookFileMetadata
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-ZOSNEO5N.js";
|
|
16
16
|
import {
|
|
17
17
|
postToolInvocationId,
|
|
18
18
|
shouldFlushAfter,
|
|
19
19
|
toMove
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-H64F6QHV.js";
|
|
21
21
|
import {
|
|
22
22
|
appendMove,
|
|
23
23
|
resolveOrg
|
|
24
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-YWO7O6QG.js";
|
|
25
25
|
import {
|
|
26
26
|
getOrCreateWorkspaceId
|
|
27
27
|
} from "../chunk-UVIWZWM6.js";
|
|
28
|
+
import "../chunk-BQUJ4AFJ.js";
|
|
28
29
|
import {
|
|
29
|
-
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
prepareCodexContext
|
|
31
|
+
} from "../chunk-KKP2NYZ3.js";
|
|
32
|
+
import "../chunk-4A2XB2PC.js";
|
|
31
33
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
scrubFromCwd,
|
|
35
|
+
writeHookDebug
|
|
36
|
+
} from "../chunk-FI3LIRCB.js";
|
|
37
|
+
import "../chunk-LEMX3IOG.js";
|
|
34
38
|
import {
|
|
35
39
|
isRepoActiveForCapture,
|
|
36
40
|
repoSyncId,
|
|
37
41
|
resolveRepositoryContext
|
|
38
|
-
} from "../chunk-
|
|
39
|
-
import "../chunk-
|
|
42
|
+
} from "../chunk-TJTVHDJ5.js";
|
|
43
|
+
import "../chunk-Z7YPFWAZ.js";
|
|
40
44
|
import {
|
|
41
45
|
normalizeEnvelope,
|
|
42
46
|
parseAgent
|
|
43
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-WB7AUZ4C.js";
|
|
48
|
+
import "../chunk-CUE2LKLR.js";
|
|
49
|
+
import "../chunk-3EEFL6NJ.js";
|
|
44
50
|
|
|
45
51
|
// src/hooks/prim-hook.ts
|
|
46
52
|
import { spawn } from "child_process";
|
|
47
53
|
import { readFileSync } from "fs";
|
|
48
54
|
import { dirname, join } from "path";
|
|
49
55
|
import { fileURLToPath } from "url";
|
|
56
|
+
|
|
57
|
+
// src/hooks/codex-message-context.ts
|
|
58
|
+
var defaultDeps = { prepare: prepareCodexContext };
|
|
59
|
+
async function processCodexMessageContext(envelope, deps = defaultDeps) {
|
|
60
|
+
const event = envelope.hook_event_name;
|
|
61
|
+
if (event === "Stop") return { output: {} };
|
|
62
|
+
if (event !== "UserPromptSubmit") return { output: {} };
|
|
63
|
+
if (typeof envelope.session_id !== "string" || envelope.session_id.length === 0) {
|
|
64
|
+
return { output: {} };
|
|
65
|
+
}
|
|
66
|
+
let prepared;
|
|
67
|
+
try {
|
|
68
|
+
prepared = await deps.prepare({
|
|
69
|
+
cwd: typeof envelope.cwd === "string" ? envelope.cwd : process.cwd(),
|
|
70
|
+
sessionId: envelope.session_id
|
|
71
|
+
});
|
|
72
|
+
} catch {
|
|
73
|
+
return { output: {} };
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
output: prepared.context ? {
|
|
77
|
+
hookSpecificOutput: {
|
|
78
|
+
hookEventName: "UserPromptSubmit",
|
|
79
|
+
additionalContext: prepared.context
|
|
80
|
+
}
|
|
81
|
+
} : {},
|
|
82
|
+
// Even an empty prompt response is a successful handoff. Committing it
|
|
83
|
+
// advances verified feed state and report dedup without inventing output.
|
|
84
|
+
acknowledge: async () => {
|
|
85
|
+
await prepared.acknowledge(true);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/hooks/prim-hook.ts
|
|
50
91
|
var here = dirname(fileURLToPath(import.meta.url));
|
|
51
92
|
var outputAttempted = false;
|
|
52
93
|
function emitOutput(output, acknowledge) {
|
|
@@ -68,15 +109,8 @@ function spawnBackgroundFlush() {
|
|
|
68
109
|
stdio: "ignore"
|
|
69
110
|
}).unref();
|
|
70
111
|
}
|
|
71
|
-
function debug(area, error) {
|
|
72
|
-
if (!process.env.PRIM_HOOK_DEBUG) return;
|
|
73
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
74
|
-
process.stderr.write(`[prim-hook] ${area} failed: ${detail}
|
|
75
|
-
`);
|
|
76
|
-
}
|
|
77
112
|
async function main() {
|
|
78
113
|
const feedbackSignal = AbortSignal.timeout(FEEDBACK_DEADLINE_MS);
|
|
79
|
-
warmBinCache();
|
|
80
114
|
const agent = parseAgent(process.argv);
|
|
81
115
|
let raw;
|
|
82
116
|
let parsed;
|
|
@@ -84,14 +118,15 @@ async function main() {
|
|
|
84
118
|
raw = readFileSync(0, "utf-8");
|
|
85
119
|
parsed = normalizeEnvelope(JSON.parse(raw), agent);
|
|
86
120
|
} catch (error) {
|
|
87
|
-
|
|
121
|
+
writeHookDebug("capture failed", error);
|
|
88
122
|
await emitOutput(buildHookOutput({}));
|
|
89
123
|
return;
|
|
90
124
|
}
|
|
91
125
|
const cwd = parsed.cwd ?? process.cwd();
|
|
92
126
|
const isClaudeStop = agent === "claude_code" && parsed.hook_event_name === "Stop";
|
|
127
|
+
const isCodexContextEvent = agent === "codex" && (parsed.hook_event_name === "UserPromptSubmit" || parsed.hook_event_name === "Stop");
|
|
93
128
|
if (!isRepoActiveForCapture(cwd)) {
|
|
94
|
-
if (isClaudeStop) await emitOutput(buildHookOutput({}));
|
|
129
|
+
if (isClaudeStop || isCodexContextEvent) await emitOutput(buildHookOutput({}));
|
|
95
130
|
return;
|
|
96
131
|
}
|
|
97
132
|
const identity = getOrCreateWorkspaceId(cwd);
|
|
@@ -110,18 +145,23 @@ async function main() {
|
|
|
110
145
|
repository,
|
|
111
146
|
invocationId
|
|
112
147
|
);
|
|
113
|
-
const scrubbed = scrubFromCwd(enriched, cwd);
|
|
148
|
+
const scrubbed = await scrubFromCwd(enriched, cwd);
|
|
114
149
|
const move = {
|
|
115
150
|
...base,
|
|
116
151
|
payload: enrichment ? preserveHookFileMetadata(scrubbed, enrichment.resolution) : scrubbed
|
|
117
152
|
};
|
|
118
|
-
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd
|
|
153
|
+
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd });
|
|
119
154
|
appendMove(move, orgId);
|
|
120
155
|
if (shouldFlushAfter(move.eventType)) {
|
|
121
156
|
spawnBackgroundFlush();
|
|
122
157
|
}
|
|
123
158
|
} catch (error) {
|
|
124
|
-
|
|
159
|
+
writeHookDebug("capture failed", error);
|
|
160
|
+
}
|
|
161
|
+
if (isCodexContextEvent) {
|
|
162
|
+
const result = await processCodexMessageContext(parsed);
|
|
163
|
+
await emitOutput(result.output, result.acknowledge);
|
|
164
|
+
return;
|
|
125
165
|
}
|
|
126
166
|
if (!isClaudeStop) return;
|
|
127
167
|
const sessionId = typeof parsed.session_id === "string" ? parsed.session_id : "";
|
|
@@ -131,20 +171,25 @@ async function main() {
|
|
|
131
171
|
}
|
|
132
172
|
const lease = await leaseDecisionFeedback(
|
|
133
173
|
{ workspaceId, currentSessionId: sessionId, signal: feedbackSignal },
|
|
134
|
-
{ onError: (error) =>
|
|
174
|
+
{ onError: (error) => writeHookDebug("feedback failed", error) }
|
|
135
175
|
);
|
|
136
176
|
const rendered = lease ? renderFeedback(lease) : void 0;
|
|
137
177
|
await emitOutput(
|
|
138
178
|
buildHookOutput({ systemMessage: rendered?.systemMessage }),
|
|
139
179
|
rendered ? async () => {
|
|
140
180
|
await acknowledgeDecisionFeedback(
|
|
141
|
-
{
|
|
142
|
-
|
|
181
|
+
{
|
|
182
|
+
protocolVersion: rendered.protocolVersion,
|
|
183
|
+
workspaceId,
|
|
184
|
+
deliveries: rendered.deliveries,
|
|
185
|
+
signal: feedbackSignal
|
|
186
|
+
},
|
|
187
|
+
{ onError: (error) => writeHookDebug("feedback failed", error) }
|
|
143
188
|
);
|
|
144
189
|
} : void 0
|
|
145
190
|
);
|
|
146
191
|
}
|
|
147
192
|
void main().catch(async (error) => {
|
|
148
|
-
|
|
193
|
+
writeHookDebug("capture failed", error);
|
|
149
194
|
if (!outputAttempted) await emitOutput(buildHookOutput({}));
|
|
150
195
|
});
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
daemonRequest
|
|
4
|
-
} from "../chunk-UTKQTZHL.js";
|
|
5
2
|
import {
|
|
6
3
|
normalizeEnvelope,
|
|
7
4
|
parseAgent
|
|
8
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-WB7AUZ4C.js";
|
|
6
|
+
import {
|
|
7
|
+
daemonRequest
|
|
8
|
+
} from "../chunk-CUE2LKLR.js";
|
|
9
|
+
import "../chunk-3EEFL6NJ.js";
|
|
9
10
|
|
|
10
11
|
// src/hooks/session-end.ts
|
|
11
12
|
var STDIN_TIMEOUT_MS = 1e3;
|
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
ensureEffectivePostCommitHook,
|
|
5
5
|
ensureEffectivePostRewriteHook,
|
|
6
6
|
hasUsableCodexGuidance,
|
|
7
|
-
refreshClaudePlugins
|
|
8
|
-
|
|
7
|
+
refreshClaudePlugins,
|
|
8
|
+
warmBinCache
|
|
9
|
+
} from "../chunk-2KW7DVFJ.js";
|
|
9
10
|
import {
|
|
10
11
|
buildHookOutput,
|
|
11
12
|
handoffHookOutput
|
|
@@ -15,31 +16,34 @@ import {
|
|
|
15
16
|
acknowledgeDecisionFeedback,
|
|
16
17
|
leaseDecisionFeedback,
|
|
17
18
|
renderFeedback
|
|
18
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-LMRYZL3D.js";
|
|
19
20
|
import {
|
|
20
21
|
getOrCreateWorkspaceId
|
|
21
22
|
} from "../chunk-UVIWZWM6.js";
|
|
22
23
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
prepareCodexContext
|
|
25
|
+
} from "../chunk-KKP2NYZ3.js";
|
|
26
|
+
import {
|
|
27
|
+
binFile
|
|
28
|
+
} from "../chunk-4A2XB2PC.js";
|
|
26
29
|
import {
|
|
27
30
|
gitToplevel,
|
|
28
31
|
isRepoActiveForCapture,
|
|
29
32
|
repoActiveFlag,
|
|
30
33
|
setRepoActive
|
|
31
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-TJTVHDJ5.js";
|
|
32
35
|
import {
|
|
33
36
|
getSiteUrl,
|
|
34
37
|
isSessionEnded
|
|
35
|
-
} from "../chunk-
|
|
36
|
-
import {
|
|
37
|
-
daemonRequest
|
|
38
|
-
} from "../chunk-UTKQTZHL.js";
|
|
38
|
+
} from "../chunk-Z7YPFWAZ.js";
|
|
39
39
|
import {
|
|
40
40
|
normalizeEnvelope,
|
|
41
41
|
parseAgent
|
|
42
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-WB7AUZ4C.js";
|
|
43
|
+
import {
|
|
44
|
+
daemonRequest
|
|
45
|
+
} from "../chunk-CUE2LKLR.js";
|
|
46
|
+
import "../chunk-3EEFL6NJ.js";
|
|
43
47
|
|
|
44
48
|
// src/daemon/self-heal.ts
|
|
45
49
|
import { spawn } from "child_process";
|
|
@@ -68,7 +72,6 @@ function kickDaemonEnsure(options = {}) {
|
|
|
68
72
|
// src/hooks/reauth-notice.ts
|
|
69
73
|
var REAUTH_NOTICE = "[prim] authentication ended \u2014 run `prim auth login` to resume decision capture";
|
|
70
74
|
function reauthNoticeFields(agent) {
|
|
71
|
-
if (agent === "codex") return { additionalContext: REAUTH_NOTICE };
|
|
72
75
|
if (agent === "claude_code") return { systemMessage: REAUTH_NOTICE };
|
|
73
76
|
return;
|
|
74
77
|
}
|
|
@@ -138,7 +141,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
138
141
|
kickDaemonEnsure();
|
|
139
142
|
await daemonRequest(
|
|
140
143
|
"session_start",
|
|
141
|
-
{ sessionId: envelope.session_id },
|
|
144
|
+
{ sessionId: envelope.session_id, callerEnv: getSiteUrl() },
|
|
142
145
|
{ timeoutMs: DAEMON_TIMEOUT_MS }
|
|
143
146
|
);
|
|
144
147
|
const cwd = envelope.cwd ?? process.cwd();
|
|
@@ -156,7 +159,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
156
159
|
} catch {
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
|
-
if (isSessionEnded()) {
|
|
162
|
+
if (isSessionEnded() && agent !== "codex") {
|
|
160
163
|
const notice = reauthNoticeFields(agent);
|
|
161
164
|
if (notice) {
|
|
162
165
|
return {
|
|
@@ -165,14 +168,16 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
170
|
if (agent === "codex") {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
let context;
|
|
172
|
+
try {
|
|
173
|
+
context = await prepareCodexContext({
|
|
174
|
+
cwd,
|
|
175
|
+
sessionId: envelope.session_id,
|
|
176
|
+
startup: true,
|
|
177
|
+
includeDigest: false
|
|
178
|
+
});
|
|
179
|
+
} catch {
|
|
180
|
+
}
|
|
176
181
|
projectRoot = await activeProjectRoot(cwd);
|
|
177
182
|
active = projectRoot !== null;
|
|
178
183
|
let proactive = false;
|
|
@@ -180,8 +185,13 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
180
185
|
proactive = projectRoot !== null && active && hasUsableCodexGuidance(projectRoot);
|
|
181
186
|
} catch {
|
|
182
187
|
}
|
|
183
|
-
const additionalContext = [proactive ? CODEX_PRIM_REMINDER : void 0,
|
|
184
|
-
return {
|
|
188
|
+
const additionalContext = [proactive ? CODEX_PRIM_REMINDER : void 0, context?.context].filter((value) => value !== void 0).join("\n\n");
|
|
189
|
+
return {
|
|
190
|
+
output: buildHookOutput({ additionalContext }),
|
|
191
|
+
acknowledge: async () => {
|
|
192
|
+
await context?.acknowledge(true);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
185
195
|
}
|
|
186
196
|
if (agent === "claude_code") {
|
|
187
197
|
const additionalContext = active && skillState.installed > 0 ? PRIM_SKILL_REMINDER : void 0;
|
|
@@ -204,6 +214,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
|
|
|
204
214
|
}),
|
|
205
215
|
acknowledge: rendered ? async () => {
|
|
206
216
|
await acknowledgeDecisionFeedback({
|
|
217
|
+
protocolVersion: rendered.protocolVersion,
|
|
207
218
|
workspaceId: identity.workspaceId,
|
|
208
219
|
deliveries: rendered.deliveries,
|
|
209
220
|
signal
|