@primitive.ai/prim 0.1.0-alpha.64 → 0.1.0-alpha.66

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 CHANGED
@@ -71,12 +71,13 @@ so the agent runs it directly — instead of fetching a doc and executing a comm
71
71
  it, which an auto-mode safety classifier blocks as untrusted-origin code:
72
72
 
73
73
  ```text
74
- Install the Primitive CLI: run `npx --yes @primitive.ai/prim@latest setup` and surface its output. It's an agent-first CLI — drive it yourself, don't hand the command back to me. The only thing I'll do is click "Authorize" in the browser if it asks. When it finishes, show me the welcome.
74
+ Install the Primitive CLI and activate passive decision capture for this repository: run `npx --yes @primitive.ai/prim@latest setup` and surface its output. Drive it yourself; I'll only click Authorize in the browser. This request authorizes setup's built-in activation of this repository and an idempotent retry of that step, but not activation in another repository or creation of a Decision. If enable or health fails, surface the actual error; do not claim fresh activation approval is required. Then show me the welcome.
75
75
  ```
76
76
 
77
- That single command runs the whole install in one process (auth → session hooks →
78
- daemon → git hooks → skill → welcome). The detailed step-by-step the agent follows —
79
- and the manual fallback — live in [`setup.md`](./setup.md).
77
+ That single command runs the whole install and current-repository activation in one
78
+ process (auth → session hooks → daemon → git hooks → skill → welcome). The detailed
79
+ step-by-step the agent follows — and the manual fallback — live in
80
+ [`setup.md`](./setup.md).
80
81
 
81
82
  ## Commands
82
83
 
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-G5D3FF3D.js";
5
5
  import {
6
6
  canonicalRepositoryPath
7
- } from "./chunk-XTNMSS4C.js";
7
+ } from "./chunk-TDRXHBEX.js";
8
8
 
9
9
  // src/hooks/file-refs.ts
10
10
  var MAX_PREFLIGHT_FILE_TARGETS = 25;
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-UVIWZWM6.js";
4
4
  import {
5
5
  isValidRepoSyncId
6
- } from "./chunk-XTNMSS4C.js";
6
+ } from "./chunk-TDRXHBEX.js";
7
7
 
8
8
  // src/hooks/prim-hook-core.ts
9
9
  import { createHash, randomUUID } from "crypto";
@@ -95,6 +95,9 @@ function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, reposito
95
95
  ...toolOutcome ? { toolOutcome } : {}
96
96
  };
97
97
  }
98
+ var MAX_REWRITE_PAIRS_PER_MOVE = 40;
99
+ var MAX_REWRITE_PAIRS_PER_HOOK = 2e3;
100
+ var FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
98
101
  var MAX_CLASSIFIER_ID_CHARS = 256;
99
102
  var INVALID_CLASSIFIER_ID_RE = /[\u0000-\u001f\u007f\uD800-\uDFFF]/u;
100
103
  function validSessionHint(value) {
@@ -152,6 +155,63 @@ function toCommitMove(commit, cliVersion, cwd, context = {}) {
152
155
  producer: validatedAttribution.producer
153
156
  } : { ...base, envelopeVersion: ENVELOPE_VERSION };
154
157
  }
158
+ function canonicalRewritePairs(pairs) {
159
+ const unique = /* @__PURE__ */ new Map();
160
+ for (const pair of pairs) {
161
+ const oldSha = pair.oldSha.toLowerCase();
162
+ const newSha = pair.newSha.toLowerCase();
163
+ if (!FULL_SHA_RE.test(oldSha) || !FULL_SHA_RE.test(newSha)) return null;
164
+ if (oldSha === newSha) continue;
165
+ unique.set(`${oldSha}\0${newSha}`, { oldSha, newSha });
166
+ }
167
+ return [...unique.values()].sort((left, right) => {
168
+ const leftKey = `${left.oldSha}\0${left.newSha}`;
169
+ const rightKey = `${right.oldSha}\0${right.newSha}`;
170
+ return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
171
+ }).slice(0, MAX_REWRITE_PAIRS_PER_HOOK);
172
+ }
173
+ function toRewriteMove(rewrite, cliVersion, cwd, context) {
174
+ const { repository, repoFullName, repoSyncId, workspaceId, capturedAt } = context;
175
+ if (rewrite.source !== "amend" && rewrite.source !== "rebase" || !isValidRepoSyncId(repoSyncId) || !workspaceId || !isCanonicalWorkspaceId(workspaceId)) {
176
+ return [];
177
+ }
178
+ const pairs = canonicalRewritePairs(rewrite.pairs);
179
+ if (!pairs || pairs.length === 0) return [];
180
+ const branch = rewrite.branch && rewrite.branch === rewrite.branch.trim() && ![...rewrite.branch].some((char) => char < " " || char === "\x7F") ? rewrite.branch : void 0;
181
+ const observedAt = typeof capturedAt === "number" && Number.isSafeInteger(capturedAt) && capturedAt > 0 ? capturedAt : Date.now();
182
+ const moves = [];
183
+ for (let offset = 0; offset < pairs.length; offset += MAX_REWRITE_PAIRS_PER_MOVE) {
184
+ const sortedPairs = pairs.slice(offset, offset + MAX_REWRITE_PAIRS_PER_MOVE);
185
+ const moveId = `rewrite:v1:${createHash("sha256").update(JSON.stringify(["rewrite:v1", repoSyncId, workspaceId, rewrite.source, sortedPairs])).digest("hex")}`;
186
+ moves.push({
187
+ moveId,
188
+ capturedAt: observedAt,
189
+ sessionId: "",
190
+ eventType: "git.rewrite",
191
+ payload: {
192
+ kind: "git.rewrite",
193
+ source: rewrite.source,
194
+ pairs: sortedPairs,
195
+ ...branch ? { branch } : {}
196
+ },
197
+ env: {
198
+ cwd,
199
+ cliVersion,
200
+ osPlatform: platform(),
201
+ ...repository ? {
202
+ repoRoot: repository.repoRoot,
203
+ repoKey: repository.repoKey,
204
+ gitRoot: repository.repoRoot
205
+ } : {},
206
+ ...repoFullName ? { repoFullName } : {},
207
+ repoSyncId,
208
+ workspaceId
209
+ },
210
+ envelopeVersion: ENVELOPE_VERSION
211
+ });
212
+ }
213
+ return moves;
214
+ }
155
215
  function shouldFlushAfter(eventType) {
156
216
  return eventType === "SessionEnd";
157
217
  }
@@ -162,5 +222,7 @@ export {
162
222
  toMove,
163
223
  commitAttributionFromEnvironment,
164
224
  toCommitMove,
225
+ canonicalRewritePairs,
226
+ toRewriteMove,
165
227
  shouldFlushAfter
166
228
  };
@@ -79,7 +79,8 @@ var CACHED_BINS = [
79
79
  "prim-hook",
80
80
  "prim-pre-tool-use",
81
81
  "prim-post-tool-use",
82
- "prim-post-commit"
82
+ "prim-post-commit",
83
+ "prim-post-rewrite"
83
84
  ];
84
85
  function binCacheDir() {
85
86
  const base = process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");