@primitive.ai/prim 0.1.0-alpha.65 → 0.1.0-alpha.67
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-5CKL5EYQ.js → chunk-CPSE3Y3T.js} +62 -0
- package/dist/{chunk-LNU44OJV.js → chunk-CZ24W5QU.js} +2 -1
- 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-CPHJUQNE.js → chunk-XPVNH3J6.js} +229 -89
- package/dist/{chunk-WS3MCNFD.js → chunk-XUAP572Z.js} +1 -1
- package/dist/daemon/server.js +6 -2
- package/dist/hooks/post-commit.js +3 -3
- package/dist/hooks/post-rewrite.js +194 -0
- package/dist/hooks/post-tool-use.js +7 -7
- package/dist/hooks/pre-commit.js +2 -2
- package/dist/hooks/pre-tool-use.js +2 -2
- package/dist/hooks/prim-hook.js +17 -17
- package/dist/hooks/session-start.js +9 -4
- package/dist/index.js +699 -62
- package/package.json +5 -4
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
commitAttributionFromEnvironment,
|
|
4
4
|
toCommitMove
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-CPSE3Y3T.js";
|
|
6
6
|
import {
|
|
7
7
|
appendMove,
|
|
8
8
|
resolveOrg
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-UN5O5SYG.js";
|
|
10
10
|
import {
|
|
11
11
|
getOrCreateWorkspaceId
|
|
12
12
|
} from "../chunk-UVIWZWM6.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
repoSyncId,
|
|
17
17
|
resolveRepositoryContext
|
|
18
18
|
} from "../chunk-TDRXHBEX.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-RTLFE6EZ.js";
|
|
20
20
|
|
|
21
21
|
// src/hooks/post-commit.ts
|
|
22
22
|
import { execFileSync, spawn } from "child_process";
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
canonicalRewritePairs,
|
|
4
|
+
toRewriteMove
|
|
5
|
+
} from "../chunk-CPSE3Y3T.js";
|
|
6
|
+
import {
|
|
7
|
+
appendMove,
|
|
8
|
+
resolveOrg
|
|
9
|
+
} from "../chunk-UN5O5SYG.js";
|
|
10
|
+
import {
|
|
11
|
+
getOrCreateWorkspaceId
|
|
12
|
+
} from "../chunk-UVIWZWM6.js";
|
|
13
|
+
import {
|
|
14
|
+
githubRepositoryFullName,
|
|
15
|
+
isRepoActiveForCapture,
|
|
16
|
+
repoSyncId,
|
|
17
|
+
resolveRepositoryContext
|
|
18
|
+
} from "../chunk-TDRXHBEX.js";
|
|
19
|
+
import "../chunk-RTLFE6EZ.js";
|
|
20
|
+
|
|
21
|
+
// src/hooks/post-rewrite.ts
|
|
22
|
+
import { execFileSync, spawn } from "child_process";
|
|
23
|
+
import {
|
|
24
|
+
constants,
|
|
25
|
+
closeSync,
|
|
26
|
+
fstatSync,
|
|
27
|
+
lstatSync,
|
|
28
|
+
openSync,
|
|
29
|
+
readFileSync,
|
|
30
|
+
unlinkSync
|
|
31
|
+
} from "fs";
|
|
32
|
+
import { basename, dirname, isAbsolute, join } from "path";
|
|
33
|
+
import { fileURLToPath } from "url";
|
|
34
|
+
var here = dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
var GIT_TIMEOUT_MS = 1e3;
|
|
36
|
+
var MAX_PAIRS_FILE_BYTES = 1048576;
|
|
37
|
+
var MAX_PAIRS_FILE_AGE_MS = 10 * 60 * 1e3;
|
|
38
|
+
var MAX_PAIRS_FILE_FUTURE_SKEW_MS = 5e3;
|
|
39
|
+
var PAIRS_FILE_RE = /^prim-post-rewrite-pairs\.[A-Za-z0-9]+$/u;
|
|
40
|
+
var FULL_SHA_SOURCE = "(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})";
|
|
41
|
+
var REWRITE_PAIR_RE = new RegExp(
|
|
42
|
+
`^(${FULL_SHA_SOURCE}) (${FULL_SHA_SOURCE})(?: ([^\\s]+))?$`,
|
|
43
|
+
"u"
|
|
44
|
+
);
|
|
45
|
+
function parseRewritePairs(value) {
|
|
46
|
+
if (value.length === 0) return [];
|
|
47
|
+
const body = value.endsWith("\n") ? value.slice(0, -1) : value;
|
|
48
|
+
if (body.length === 0) return [];
|
|
49
|
+
const parsed = [];
|
|
50
|
+
for (const line of body.split("\n")) {
|
|
51
|
+
const match = REWRITE_PAIR_RE.exec(line);
|
|
52
|
+
if (!match?.[1] || !match[2]) return;
|
|
53
|
+
parsed.push({ oldSha: match[1], newSha: match[2] });
|
|
54
|
+
}
|
|
55
|
+
return canonicalRewritePairs(parsed) ?? void 0;
|
|
56
|
+
}
|
|
57
|
+
function privatePairsFileStat(stat, now) {
|
|
58
|
+
const capturedAt = Math.trunc(stat.mtimeMs);
|
|
59
|
+
const uid = process.getuid?.();
|
|
60
|
+
return stat.isFile() && !stat.isSymbolicLink() && stat.size <= MAX_PAIRS_FILE_BYTES && stat.nlink === 1 && (stat.mode & 511) === 384 && (uid === void 0 || stat.uid === uid) && Number.isSafeInteger(capturedAt) && capturedAt > 0 && capturedAt >= now - MAX_PAIRS_FILE_AGE_MS && capturedAt <= now + MAX_PAIRS_FILE_FUTURE_SKEW_MS;
|
|
61
|
+
}
|
|
62
|
+
function rewritePairsFromLauncher(env = process.env, now = Date.now()) {
|
|
63
|
+
const path = env.PRIM_REWRITE_PAIRS_FILE;
|
|
64
|
+
if (!path || !isAbsolute(path) || !PAIRS_FILE_RE.test(basename(path))) return;
|
|
65
|
+
let fd;
|
|
66
|
+
try {
|
|
67
|
+
const pathStat = lstatSync(path);
|
|
68
|
+
if (!privatePairsFileStat(pathStat, now)) return;
|
|
69
|
+
fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
70
|
+
const openStat = fstatSync(fd);
|
|
71
|
+
if (!privatePairsFileStat(openStat, now) || openStat.dev !== pathStat.dev || openStat.ino !== pathStat.ino) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const bytes = readFileSync(fd);
|
|
75
|
+
if (bytes.length !== openStat.size) return;
|
|
76
|
+
let text;
|
|
77
|
+
try {
|
|
78
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
79
|
+
} catch {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const pairs = parseRewritePairs(text);
|
|
83
|
+
if (!pairs) return;
|
|
84
|
+
return {
|
|
85
|
+
path,
|
|
86
|
+
dev: openStat.dev,
|
|
87
|
+
ino: openStat.ino,
|
|
88
|
+
capturedAt: Math.trunc(openStat.mtimeMs),
|
|
89
|
+
pairs
|
|
90
|
+
};
|
|
91
|
+
} catch {
|
|
92
|
+
return;
|
|
93
|
+
} finally {
|
|
94
|
+
if (fd !== void 0) {
|
|
95
|
+
try {
|
|
96
|
+
closeSync(fd);
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function unlinkSnapshot(snapshot) {
|
|
103
|
+
try {
|
|
104
|
+
const current = lstatSync(snapshot.path);
|
|
105
|
+
if (current.isFile() && !current.isSymbolicLink() && current.dev === snapshot.dev && current.ino === snapshot.ino) {
|
|
106
|
+
unlinkSync(snapshot.path);
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function gitText(args) {
|
|
112
|
+
try {
|
|
113
|
+
return execFileSync("git", args, {
|
|
114
|
+
encoding: "utf-8",
|
|
115
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
116
|
+
timeout: GIT_TIMEOUT_MS
|
|
117
|
+
}).trim();
|
|
118
|
+
} catch {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function validSource(value) {
|
|
123
|
+
return value === "amend" || value === "rebase";
|
|
124
|
+
}
|
|
125
|
+
function validBranch(value) {
|
|
126
|
+
return value && value === value.trim() && ![...value].some((char) => char < " " || char === "\x7F") ? value : void 0;
|
|
127
|
+
}
|
|
128
|
+
function resolveCliVersion() {
|
|
129
|
+
try {
|
|
130
|
+
const pkg = JSON.parse(readFileSync(join(here, "..", "..", "package.json"), "utf-8"));
|
|
131
|
+
return pkg.version ?? "unknown";
|
|
132
|
+
} catch {
|
|
133
|
+
return "unknown";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function spawnBackgroundFlush() {
|
|
137
|
+
const entry = join(here, "..", "index.js");
|
|
138
|
+
spawn(process.execPath, [entry, "moves", "flush"], {
|
|
139
|
+
detached: true,
|
|
140
|
+
stdio: "ignore"
|
|
141
|
+
}).unref();
|
|
142
|
+
}
|
|
143
|
+
function runPostRewrite() {
|
|
144
|
+
const snapshot = rewritePairsFromLauncher();
|
|
145
|
+
if (!snapshot) return;
|
|
146
|
+
try {
|
|
147
|
+
const source = process.env.PRIM_REWRITE_SOURCE;
|
|
148
|
+
if (!validSource(source) || snapshot.pairs.length === 0) return;
|
|
149
|
+
const cwd = gitText(["rev-parse", "--show-toplevel"]) ?? process.cwd();
|
|
150
|
+
if (!isRepoActiveForCapture(cwd)) return;
|
|
151
|
+
const repository = resolveRepositoryContext(cwd);
|
|
152
|
+
const identity = getOrCreateWorkspaceId(cwd);
|
|
153
|
+
const workspaceId = identity.status === "ready" ? identity.workspaceId : void 0;
|
|
154
|
+
const moves = toRewriteMove(
|
|
155
|
+
{
|
|
156
|
+
source,
|
|
157
|
+
pairs: snapshot.pairs,
|
|
158
|
+
branch: validBranch(process.env.PRIM_REWRITE_BRANCH)
|
|
159
|
+
},
|
|
160
|
+
resolveCliVersion(),
|
|
161
|
+
cwd,
|
|
162
|
+
{
|
|
163
|
+
repository,
|
|
164
|
+
repoFullName: githubRepositoryFullName(cwd) ?? void 0,
|
|
165
|
+
repoSyncId: repoSyncId(cwd),
|
|
166
|
+
workspaceId,
|
|
167
|
+
capturedAt: snapshot.capturedAt
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
if (moves.length === 0) return;
|
|
171
|
+
const { orgId } = resolveOrg({ sessionId: "", cwd });
|
|
172
|
+
for (const move of moves) appendMove(move, orgId);
|
|
173
|
+
spawnBackgroundFlush();
|
|
174
|
+
} finally {
|
|
175
|
+
unlinkSnapshot(snapshot);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (!process.env.VITEST) {
|
|
179
|
+
try {
|
|
180
|
+
runPostRewrite();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (process.env.PRIM_HOOK_DEBUG) {
|
|
183
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
184
|
+
process.stderr.write(`[prim-post-rewrite] capture failed: ${detail}
|
|
185
|
+
`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
process.exit(0);
|
|
189
|
+
}
|
|
190
|
+
export {
|
|
191
|
+
parseRewritePairs,
|
|
192
|
+
rewritePairsFromLauncher,
|
|
193
|
+
runPostRewrite
|
|
194
|
+
};
|
|
@@ -12,20 +12,20 @@ import {
|
|
|
12
12
|
postToolInvocationId,
|
|
13
13
|
toMove,
|
|
14
14
|
toolOutcomeFor
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-CPSE3Y3T.js";
|
|
16
16
|
import {
|
|
17
17
|
appendMove,
|
|
18
18
|
resolveOrg
|
|
19
|
-
} from "../chunk-
|
|
20
|
-
import {
|
|
21
|
-
scrubFromCwd
|
|
22
|
-
} from "../chunk-G5D3FF3D.js";
|
|
19
|
+
} from "../chunk-UN5O5SYG.js";
|
|
23
20
|
import {
|
|
24
21
|
getOrCreateWorkspaceId
|
|
25
22
|
} from "../chunk-UVIWZWM6.js";
|
|
23
|
+
import {
|
|
24
|
+
scrubFromCwd
|
|
25
|
+
} from "../chunk-G5D3FF3D.js";
|
|
26
26
|
import {
|
|
27
27
|
warmBinCache
|
|
28
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-CZ24W5QU.js";
|
|
29
29
|
import {
|
|
30
30
|
isRepoActiveForCapture,
|
|
31
31
|
repoSyncId,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
} from "../chunk-TDRXHBEX.js";
|
|
34
34
|
import {
|
|
35
35
|
getClient
|
|
36
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-RTLFE6EZ.js";
|
|
37
37
|
import {
|
|
38
38
|
normalizeEnvelope,
|
|
39
39
|
parseAgent
|
package/dist/hooks/pre-commit.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
packageVersion,
|
|
18
18
|
warmBinCache
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-CZ24W5QU.js";
|
|
20
20
|
import {
|
|
21
21
|
canonicalGitRoot,
|
|
22
22
|
canonicalRepositoryPath,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "../chunk-TDRXHBEX.js";
|
|
26
26
|
import {
|
|
27
27
|
getClient
|
|
28
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-RTLFE6EZ.js";
|
|
29
29
|
import {
|
|
30
30
|
normalizeEnvelope,
|
|
31
31
|
parseAgent
|
package/dist/hooks/prim-hook.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildHookOutput,
|
|
4
|
+
handoffHookOutput
|
|
5
|
+
} from "../chunk-4GLVJLEQ.js";
|
|
6
|
+
import {
|
|
7
|
+
FEEDBACK_DEADLINE_MS,
|
|
8
|
+
acknowledgeDecisionFeedback,
|
|
9
|
+
leaseDecisionFeedback,
|
|
10
|
+
renderFeedback
|
|
11
|
+
} from "../chunk-U6L2RU67.js";
|
|
2
12
|
import {
|
|
3
13
|
enrichHookPayloadWithFileRefs,
|
|
4
14
|
preserveHookFileMetadata
|
|
@@ -7,36 +17,26 @@ import {
|
|
|
7
17
|
postToolInvocationId,
|
|
8
18
|
shouldFlushAfter,
|
|
9
19
|
toMove
|
|
10
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-CPSE3Y3T.js";
|
|
11
21
|
import {
|
|
12
22
|
appendMove,
|
|
13
23
|
resolveOrg
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import {
|
|
16
|
-
scrubFromCwd
|
|
17
|
-
} from "../chunk-G5D3FF3D.js";
|
|
18
|
-
import {
|
|
19
|
-
buildHookOutput,
|
|
20
|
-
handoffHookOutput
|
|
21
|
-
} from "../chunk-4GLVJLEQ.js";
|
|
22
|
-
import {
|
|
23
|
-
FEEDBACK_DEADLINE_MS,
|
|
24
|
-
acknowledgeDecisionFeedback,
|
|
25
|
-
leaseDecisionFeedback,
|
|
26
|
-
renderFeedback
|
|
27
|
-
} from "../chunk-KHZNYEUV.js";
|
|
24
|
+
} from "../chunk-UN5O5SYG.js";
|
|
28
25
|
import {
|
|
29
26
|
getOrCreateWorkspaceId
|
|
30
27
|
} from "../chunk-UVIWZWM6.js";
|
|
28
|
+
import {
|
|
29
|
+
scrubFromCwd
|
|
30
|
+
} from "../chunk-G5D3FF3D.js";
|
|
31
31
|
import {
|
|
32
32
|
warmBinCache
|
|
33
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-CZ24W5QU.js";
|
|
34
34
|
import {
|
|
35
35
|
isRepoActiveForCapture,
|
|
36
36
|
repoSyncId,
|
|
37
37
|
resolveRepositoryContext
|
|
38
38
|
} from "../chunk-TDRXHBEX.js";
|
|
39
|
-
import "../chunk-
|
|
39
|
+
import "../chunk-RTLFE6EZ.js";
|
|
40
40
|
import {
|
|
41
41
|
normalizeEnvelope,
|
|
42
42
|
parseAgent
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
bindRepository,
|
|
4
4
|
ensureEffectivePostCommitHook,
|
|
5
|
+
ensureEffectivePostRewriteHook,
|
|
5
6
|
hasUsableCodexGuidance,
|
|
6
7
|
refreshClaudePlugins
|
|
7
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-XPVNH3J6.js";
|
|
8
9
|
import {
|
|
9
10
|
buildHookOutput,
|
|
10
11
|
handoffHookOutput
|
|
@@ -14,14 +15,14 @@ import {
|
|
|
14
15
|
acknowledgeDecisionFeedback,
|
|
15
16
|
leaseDecisionFeedback,
|
|
16
17
|
renderFeedback
|
|
17
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-U6L2RU67.js";
|
|
18
19
|
import {
|
|
19
20
|
getOrCreateWorkspaceId
|
|
20
21
|
} from "../chunk-UVIWZWM6.js";
|
|
21
22
|
import {
|
|
22
23
|
binFile,
|
|
23
24
|
warmBinCache
|
|
24
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-CZ24W5QU.js";
|
|
25
26
|
import {
|
|
26
27
|
gitToplevel,
|
|
27
28
|
isRepoActiveForCapture,
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
import {
|
|
32
33
|
getSiteUrl,
|
|
33
34
|
isSessionEnded
|
|
34
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-RTLFE6EZ.js";
|
|
35
36
|
import {
|
|
36
37
|
daemonRequest
|
|
37
38
|
} from "../chunk-UTKQTZHL.js";
|
|
@@ -100,6 +101,10 @@ async function activeProjectRoot(cwd) {
|
|
|
100
101
|
ensureEffectivePostCommitHook(root);
|
|
101
102
|
} catch {
|
|
102
103
|
}
|
|
104
|
+
try {
|
|
105
|
+
ensureEffectivePostRewriteHook(root);
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
103
108
|
}
|
|
104
109
|
try {
|
|
105
110
|
await bindRepository(root, {
|