@primitive.ai/prim 0.1.0-alpha.61 → 0.1.0-alpha.62
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-DA4BMHEB.js +77 -0
- package/dist/{chunk-B4SHJYIN.js → chunk-GF5QII7T.js} +83 -110
- package/dist/{chunk-YIMUIPMD.js → chunk-KBFFVYBC.js} +7 -1
- package/dist/chunk-LOGW54W5.js +1244 -0
- package/dist/chunk-QGVHLP5J.js +117 -0
- package/dist/{chunk-IMAIBPUC.js → chunk-UVIWZWM6.js} +1 -0
- package/dist/chunk-XTNMSS4C.js +283 -0
- package/dist/hooks/post-commit.js +82 -16
- package/dist/hooks/post-tool-use.js +40 -24
- package/dist/hooks/pre-tool-use.js +103 -11
- package/dist/hooks/prim-hook.js +30 -9
- package/dist/hooks/session-start.js +22 -5
- package/dist/index.js +176 -30
- package/dist/statusline-main.js +7 -2
- package/package.json +1 -1
- package/dist/chunk-GUXBUBQ7.js +0 -84
- package/dist/chunk-LDQZASIF.js +0 -166
- package/dist/chunk-N4R7EXZT.js +0 -620
- package/dist/chunk-YDBZTFW5.js +0 -67
|
@@ -1,34 +1,126 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
DEFAULT_RULES,
|
|
4
|
+
analyzeShellTargets,
|
|
4
5
|
buildCodexOutput,
|
|
5
6
|
buildHermesOutput,
|
|
6
7
|
buildHookOutput,
|
|
7
8
|
demoteForMode,
|
|
9
|
+
extractFileTargets,
|
|
8
10
|
failOpenCodex,
|
|
9
11
|
failOpenHermes,
|
|
10
12
|
failOpenOutput,
|
|
11
|
-
proposalFor,
|
|
12
13
|
readHookMode,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
resultForPreflight,
|
|
16
|
-
unverifiedResult
|
|
17
|
-
} from "../chunk-B4SHJYIN.js";
|
|
18
|
-
import "../chunk-GUXBUBQ7.js";
|
|
14
|
+
scrub
|
|
15
|
+
} from "../chunk-GF5QII7T.js";
|
|
19
16
|
import {
|
|
20
17
|
warmBinCache
|
|
21
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-KBFFVYBC.js";
|
|
22
19
|
import {
|
|
20
|
+
canonicalGitRoot,
|
|
21
|
+
canonicalRepositoryPath,
|
|
23
22
|
isRepoActive,
|
|
24
23
|
repoSyncId
|
|
25
|
-
} from "../chunk-
|
|
26
|
-
import
|
|
24
|
+
} from "../chunk-XTNMSS4C.js";
|
|
25
|
+
import {
|
|
26
|
+
getClient
|
|
27
|
+
} from "../chunk-I3HIPAIR.js";
|
|
27
28
|
import {
|
|
28
29
|
normalizeEnvelope,
|
|
29
30
|
parseAgent
|
|
30
31
|
} from "../chunk-TCDUH7AN.js";
|
|
31
32
|
|
|
33
|
+
// src/hooks/preflight-v3.ts
|
|
34
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
35
|
+
var PREFLIGHT_PROTOCOL_VERSION = 3;
|
|
36
|
+
var PREFLIGHT_TIMEOUT_MS = 6500;
|
|
37
|
+
var MAX_PREFLIGHT_PATHS = 32;
|
|
38
|
+
var MAX_PROPOSAL_BYTES = 6144;
|
|
39
|
+
function resolvePreflightTargets(args) {
|
|
40
|
+
let rawPaths;
|
|
41
|
+
let coverage = "complete";
|
|
42
|
+
let mutation = "present";
|
|
43
|
+
if (args.agent === "claude_code" && args.toolName === "Bash") {
|
|
44
|
+
const command = args.toolInput && typeof args.toolInput === "object" ? args.toolInput.command : void 0;
|
|
45
|
+
if (typeof command !== "string") {
|
|
46
|
+
return { paths: [], coverage: "unverified", mutation: "present" };
|
|
47
|
+
}
|
|
48
|
+
const shell = analyzeShellTargets(command);
|
|
49
|
+
rawPaths = shell.paths;
|
|
50
|
+
coverage = shell.coverage;
|
|
51
|
+
mutation = shell.mutation;
|
|
52
|
+
} else {
|
|
53
|
+
const extracted = extractFileTargets(args.toolName, args.toolInput, args.agent);
|
|
54
|
+
if (!extracted) return { paths: [], coverage: "complete", mutation: "none" };
|
|
55
|
+
rawPaths = extracted.paths;
|
|
56
|
+
if (!extracted.complete) coverage = "unverified";
|
|
57
|
+
}
|
|
58
|
+
const root = canonicalGitRoot(args.cwd);
|
|
59
|
+
const paths = /* @__PURE__ */ new Set();
|
|
60
|
+
for (const rawPath of rawPaths) {
|
|
61
|
+
const canonical = canonicalRepositoryPath(rawPath, args.cwd, root);
|
|
62
|
+
if (canonical) paths.add(canonical);
|
|
63
|
+
else coverage = "unverified";
|
|
64
|
+
}
|
|
65
|
+
const bounded = [...paths];
|
|
66
|
+
if (bounded.length > MAX_PREFLIGHT_PATHS) coverage = "unverified";
|
|
67
|
+
return { paths: bounded.slice(0, MAX_PREFLIGHT_PATHS), coverage, mutation };
|
|
68
|
+
}
|
|
69
|
+
function truncateUtf8(value, maxBytes) {
|
|
70
|
+
const encoded = Buffer2.from(value);
|
|
71
|
+
if (encoded.byteLength <= maxBytes) return value;
|
|
72
|
+
return encoded.subarray(0, maxBytes).toString("utf8").replace(/\uFFFD$/u, "");
|
|
73
|
+
}
|
|
74
|
+
function proposalFor(toolInput) {
|
|
75
|
+
const redacted = scrub(toolInput, DEFAULT_RULES);
|
|
76
|
+
return truncateUtf8(JSON.stringify(redacted) ?? "", MAX_PROPOSAL_BYTES);
|
|
77
|
+
}
|
|
78
|
+
function parsePreflightResponse(value) {
|
|
79
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
80
|
+
const response = value;
|
|
81
|
+
const verdicts = /* @__PURE__ */ new Set(["allow", "warn", "ask", "block", "unavailable"]);
|
|
82
|
+
if (response.protocolVersion !== PREFLIGHT_PROTOCOL_VERSION || typeof response.verdict !== "string" || !verdicts.has(response.verdict) || typeof response.reasonCode !== "string" || typeof response.message !== "string" || !Array.isArray(response.conflicts) || !Array.isArray(response.bypassed)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return response;
|
|
86
|
+
}
|
|
87
|
+
async function requestPreflight(request, signal = AbortSignal.timeout(PREFLIGHT_TIMEOUT_MS)) {
|
|
88
|
+
const response = await getClient().post("/api/cli/decisions/conflict-check", request, {
|
|
89
|
+
signal,
|
|
90
|
+
quietRefresh: true
|
|
91
|
+
});
|
|
92
|
+
return parsePreflightResponse(response);
|
|
93
|
+
}
|
|
94
|
+
function resultForPreflight(response) {
|
|
95
|
+
const verdict = response.verdict === "block" ? "deny" : response.verdict;
|
|
96
|
+
const safe = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
97
|
+
const directives = response.conflicts.flatMap((value) => {
|
|
98
|
+
if (!value || typeof value !== "object") return [];
|
|
99
|
+
const { decisionId, shortId } = value;
|
|
100
|
+
const id = typeof shortId === "string" && safe.test(shortId) ? `dec_${shortId}` : typeof decisionId === "string" && safe.test(decisionId) ? decisionId : void 0;
|
|
101
|
+
return id ? [`To reconcile, run: prim reconcile ${id}`] : [];
|
|
102
|
+
});
|
|
103
|
+
const reason = [response.message, ...new Set(directives)].filter(Boolean).join("\n");
|
|
104
|
+
return {
|
|
105
|
+
verdict,
|
|
106
|
+
conflicts: response.conflicts,
|
|
107
|
+
reason,
|
|
108
|
+
additionalContext: ["warn", "ask", "block"].includes(response.verdict) ? reason : "",
|
|
109
|
+
truncated: false,
|
|
110
|
+
unavailable: response.verdict === "unavailable" ? response.message || response.reasonCode : void 0
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function unverifiedResult(message) {
|
|
114
|
+
return {
|
|
115
|
+
verdict: "unavailable",
|
|
116
|
+
conflicts: [],
|
|
117
|
+
reason: "",
|
|
118
|
+
additionalContext: "",
|
|
119
|
+
truncated: false,
|
|
120
|
+
unavailable: message
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
32
124
|
// src/hooks/pre-tool-use.ts
|
|
33
125
|
var STDIN_TIMEOUT_MS = 1e3;
|
|
34
126
|
async function readStdin() {
|
package/dist/hooks/prim-hook.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
enrichHookPayloadWithFileRefs,
|
|
4
|
+
preserveHookFileMetadata
|
|
5
|
+
} from "../chunk-DA4BMHEB.js";
|
|
2
6
|
import {
|
|
3
7
|
postToolInvocationId,
|
|
4
8
|
shouldFlushAfter,
|
|
5
9
|
toMove
|
|
6
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-QGVHLP5J.js";
|
|
7
11
|
import {
|
|
8
12
|
appendMove,
|
|
9
13
|
resolveOrg
|
|
10
14
|
} from "../chunk-S4LFRVGD.js";
|
|
11
15
|
import {
|
|
12
16
|
scrubFromCwd
|
|
13
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-GF5QII7T.js";
|
|
14
18
|
import {
|
|
15
19
|
buildHookOutput,
|
|
16
20
|
handoffHookOutput
|
|
@@ -23,13 +27,15 @@ import {
|
|
|
23
27
|
} from "../chunk-R4CUX6FY.js";
|
|
24
28
|
import {
|
|
25
29
|
getOrCreateWorkspaceId
|
|
26
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-UVIWZWM6.js";
|
|
27
31
|
import {
|
|
28
32
|
warmBinCache
|
|
29
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-KBFFVYBC.js";
|
|
30
34
|
import {
|
|
31
|
-
isRepoActiveForCapture
|
|
32
|
-
|
|
35
|
+
isRepoActiveForCapture,
|
|
36
|
+
repoSyncId,
|
|
37
|
+
resolveRepositoryContext
|
|
38
|
+
} from "../chunk-XTNMSS4C.js";
|
|
33
39
|
import "../chunk-I3HIPAIR.js";
|
|
34
40
|
import {
|
|
35
41
|
normalizeEnvelope,
|
|
@@ -90,10 +96,25 @@ async function main() {
|
|
|
90
96
|
}
|
|
91
97
|
const identity = getOrCreateWorkspaceId(cwd);
|
|
92
98
|
const workspaceId = identity.status === "ready" ? identity.workspaceId : void 0;
|
|
99
|
+
const resolvedRepository = resolveRepositoryContext(cwd);
|
|
100
|
+
const repository = resolvedRepository ? { ...resolvedRepository, repoSyncId: repoSyncId(cwd) } : null;
|
|
93
101
|
try {
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
const
|
|
102
|
+
const enrichment = repository ? enrichHookPayloadWithFileRefs({ parsed, agent, cwd, repository }) : void 0;
|
|
103
|
+
const enriched = enrichment?.parsed ?? parsed;
|
|
104
|
+
const invocationId = postToolInvocationId(enriched, agent);
|
|
105
|
+
const base = toMove(
|
|
106
|
+
enriched,
|
|
107
|
+
resolveCliVersion(),
|
|
108
|
+
agent,
|
|
109
|
+
workspaceId,
|
|
110
|
+
repository,
|
|
111
|
+
invocationId
|
|
112
|
+
);
|
|
113
|
+
const scrubbed = scrubFromCwd(enriched, cwd);
|
|
114
|
+
const move = {
|
|
115
|
+
...base,
|
|
116
|
+
payload: enrichment ? preserveHookFileMetadata(scrubbed, enrichment.resolution) : scrubbed
|
|
117
|
+
};
|
|
97
118
|
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd: move.env.cwd });
|
|
98
119
|
appendMove(move, orgId);
|
|
99
120
|
if (shouldFlushAfter(move.eventType)) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
bindRepository,
|
|
4
|
+
ensureEffectivePostCommitHook,
|
|
4
5
|
hasUsableCodexGuidance,
|
|
5
6
|
refreshClaudePlugins
|
|
6
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-LOGW54W5.js";
|
|
7
8
|
import {
|
|
8
9
|
buildHookOutput,
|
|
9
10
|
handoffHookOutput
|
|
@@ -16,16 +17,18 @@ import {
|
|
|
16
17
|
} from "../chunk-R4CUX6FY.js";
|
|
17
18
|
import {
|
|
18
19
|
getOrCreateWorkspaceId
|
|
19
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-UVIWZWM6.js";
|
|
20
21
|
import {
|
|
21
22
|
binFile,
|
|
22
23
|
warmBinCache
|
|
23
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-KBFFVYBC.js";
|
|
24
25
|
import {
|
|
25
26
|
gitToplevel,
|
|
26
27
|
isRepoActiveForCapture,
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
repoActiveFlag,
|
|
29
|
+
repoSyncId,
|
|
30
|
+
setRepoActive
|
|
31
|
+
} from "../chunk-XTNMSS4C.js";
|
|
29
32
|
import {
|
|
30
33
|
getSiteUrl,
|
|
31
34
|
isSessionEnded
|
|
@@ -81,6 +84,20 @@ async function activeProjectRoot(cwd) {
|
|
|
81
84
|
try {
|
|
82
85
|
const root = gitToplevel(cwd);
|
|
83
86
|
if (!root || !isRepoActiveForCapture(cwd)) return null;
|
|
87
|
+
let shellGateActive = repoActiveFlag(root) === "true";
|
|
88
|
+
if (!shellGateActive) {
|
|
89
|
+
try {
|
|
90
|
+
setRepoActive(root, true);
|
|
91
|
+
shellGateActive = true;
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (shellGateActive) {
|
|
96
|
+
try {
|
|
97
|
+
ensureEffectivePostCommitHook(root);
|
|
98
|
+
} catch {
|
|
99
|
+
}
|
|
100
|
+
}
|
|
84
101
|
if (!repoSyncId(root)) {
|
|
85
102
|
try {
|
|
86
103
|
await bindRepository(root, {
|