@primitive.ai/prim 0.1.0-alpha.93 → 0.1.0-alpha.96

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 (41) hide show
  1. package/README.md +57 -12
  2. package/SKILL.md +5 -2
  3. package/dist/{chunk-UKUAAAXE.js → chunk-27ADT6FQ.js} +2 -2
  4. package/dist/{chunk-OTHKG76J.js → chunk-35FMRWJH.js} +1 -1
  5. package/dist/{chunk-DXJQR4QI.js → chunk-4GHANPWQ.js} +2 -2
  6. package/dist/{chunk-DCJN6LZH.js → chunk-7KABYYWG.js} +747 -430
  7. package/dist/{chunk-LFFLHSQO.js → chunk-CU7RW7XU.js} +63 -6
  8. package/dist/{chunk-H4UNYFUC.js → chunk-DHOQGHKQ.js} +184 -1
  9. package/dist/{chunk-2GP5UFV7.js → chunk-DWRSEC34.js} +5 -3
  10. package/dist/{chunk-36TWVNBE.js → chunk-FVDBULGZ.js} +9 -11
  11. package/dist/{chunk-G2VMA2QO.js → chunk-LY6NJ7KL.js} +6 -4
  12. package/dist/{chunk-ZB4F75SZ.js → chunk-MXVCP33E.js} +5 -1
  13. package/dist/{chunk-TYAHC25F.js → chunk-QCBB5HFX.js} +1 -1
  14. package/dist/{chunk-C3VAA5CG.js → chunk-RK4ZS3HG.js} +2 -2
  15. package/dist/{chunk-ZU563PQI.js → chunk-ROLYLXJS.js} +2 -2
  16. package/dist/{chunk-OH3EZXYX.js → chunk-UO2U6IKF.js} +1 -1
  17. package/dist/{chunk-K7D2EYBS.js → chunk-URLLSALP.js} +2 -2
  18. package/dist/chunk-XEDJ5N3M.js +177 -0
  19. package/dist/{chunk-X64HTHUF.js → chunk-Y5W4TZM7.js} +202 -10
  20. package/dist/{chunk-ICM2XCXS.js → chunk-YYE2NLWX.js} +2 -2
  21. package/dist/{chunk-DSWT6BCC.js → chunk-Z6NPNLOT.js} +825 -665
  22. package/dist/daemon/server.js +836 -540
  23. package/dist/hook-runtime/daemon/server.js +836 -540
  24. package/dist/hook-runtime/hooks/post-commit.js +978 -566
  25. package/dist/hook-runtime/hooks/post-rewrite.js +836 -540
  26. package/dist/hook-runtime/hooks/post-tool-use.js +1215 -796
  27. package/dist/hook-runtime/hooks/pre-tool-use.js +2100 -1741
  28. package/dist/hook-runtime/hooks/prim-hook.js +1312 -861
  29. package/dist/hook-runtime/hooks/session-end.js +232 -134
  30. package/dist/hook-runtime/hooks/session-start.js +1799 -935
  31. package/dist/hook-runtime/index.js +3628 -2461
  32. package/dist/hooks/post-commit.js +14 -10
  33. package/dist/hooks/post-rewrite.js +10 -10
  34. package/dist/hooks/post-tool-use.js +20 -20
  35. package/dist/hooks/pre-commit.js +4 -4
  36. package/dist/hooks/pre-tool-use.js +29 -17
  37. package/dist/hooks/prim-hook.js +22 -18
  38. package/dist/hooks/session-end.js +11 -5
  39. package/dist/hooks/session-start.js +46 -28
  40. package/dist/index.js +623 -390
  41. package/package.json +1 -1
@@ -51,623 +51,597 @@ var require_ucs2length = __commonJS({
51
51
  }
52
52
  });
53
53
 
54
- // src/lib/activation.ts
55
- import { execFileSync as execFileSync2 } from "child_process";
56
- import { existsSync, readFileSync } from "fs";
57
- import { homedir } from "os";
58
- import { join } from "path";
54
+ // src/client.ts
55
+ import { createHash as createHash2 } from "crypto";
56
+ import { chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync as rmSync3 } from "fs";
57
+ import { dirname as dirname3 } from "path";
59
58
 
60
- // src/lib/git.ts
61
- import { execFileSync } from "child_process";
62
- import { createHash } from "crypto";
63
- import { lstatSync, realpathSync } from "fs";
64
- import { basename, dirname, isAbsolute, relative, resolve, sep } from "path";
65
- var GIT_TIMEOUT_MS = 1e3;
66
- var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
67
- var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
68
- function gitToplevel(cwd) {
59
+ // src/lib/atomic-file.ts
60
+ import { randomUUID } from "crypto";
61
+ import {
62
+ constants,
63
+ closeSync,
64
+ fchmodSync,
65
+ fsyncSync,
66
+ mkdirSync,
67
+ openSync,
68
+ renameSync,
69
+ rmSync,
70
+ writeFileSync
71
+ } from "fs";
72
+ import { dirname } from "path";
73
+ var DEFAULT_FILE_MODE = 438;
74
+ function syncDirectory(path) {
75
+ const fd = openSync(path, constants.O_RDONLY);
69
76
  try {
70
- return execFileSync("git", ["rev-parse", "--show-toplevel"], {
71
- cwd,
72
- encoding: "utf-8",
73
- stdio: ["ignore", "pipe", "ignore"],
74
- timeout: GIT_TIMEOUT_MS
75
- }).trim();
76
- } catch {
77
- return null;
77
+ fsyncSync(fd);
78
+ } finally {
79
+ closeSync(fd);
78
80
  }
79
81
  }
80
- function gitValue(cwd, args) {
81
- try {
82
- const value = execFileSync("git", args, {
83
- cwd,
84
- encoding: "utf-8",
85
- stdio: ["ignore", "pipe", "ignore"],
86
- timeout: GIT_TIMEOUT_MS
87
- }).trim();
88
- return value || void 0;
89
- } catch {
90
- return void 0;
82
+ function syncCreatedParentChain(firstCreatedParent, parent) {
83
+ const createdDirectories = [];
84
+ let current = parent;
85
+ while (current !== firstCreatedParent) {
86
+ createdDirectories.push(current);
87
+ const next = dirname(current);
88
+ if (next === current) {
89
+ throw new Error("recursive mkdir returned a path outside the target parent chain");
90
+ }
91
+ current = next;
92
+ }
93
+ createdDirectories.push(firstCreatedParent);
94
+ syncDirectory(dirname(firstCreatedParent));
95
+ for (const directory of createdDirectories.reverse().slice(0, -1)) {
96
+ syncDirectory(directory);
91
97
  }
92
98
  }
93
- function currentBranch(cwd) {
94
- return gitValue(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
95
- }
96
- function githubRepositoryFullName(cwd) {
97
- const remote = gitValue(cwd, ["config", "--get", "remote.origin.url"]);
98
- if (!remote || [...remote].some((char) => char < " " || char === "\x7F")) return null;
99
- const match = /^(?:git@github\.com:([^?#]+)|(?:https|ssh):\/\/(?:[^/@]+@)?github\.com(?::\d+)?\/([^?#]+))$/i.exec(
100
- remote
101
- );
102
- const path = match?.[1] ?? match?.[2];
103
- if (!path) return null;
104
- const parts = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "").split("/");
105
- if (parts.length !== 2 || !GITHUB_OWNER_PATTERN.test(parts[0] ?? "") || !GITHUB_REPOSITORY_PATTERN.test(parts[1] ?? "")) {
106
- return null;
99
+ function ensureDurableDirectory(path, mode) {
100
+ const firstCreatedParent = mkdirSync(path, { recursive: true, mode });
101
+ if (firstCreatedParent) {
102
+ syncCreatedParentChain(firstCreatedParent, path);
107
103
  }
108
- return `${parts[0]}/${parts[1]}`;
109
104
  }
110
- function canonicalGitRoot(cwd) {
105
+ function atomicWriteFile(target, content, options = {}) {
106
+ const parent = dirname(target);
107
+ if (options.ensureParent) {
108
+ ensureDurableDirectory(parent);
109
+ }
110
+ const temporaryPath = `${target}.${randomUUID()}.tmp`;
111
+ let temporaryCreated = false;
111
112
  try {
112
- const top = gitToplevel(cwd);
113
- return top ? realpathSync.native(top) : null;
114
- } catch {
115
- return null;
113
+ const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
114
+ const fd = openSync(temporaryPath, flags, options.mode ?? DEFAULT_FILE_MODE);
115
+ temporaryCreated = true;
116
+ try {
117
+ if (options.mode !== void 0) fchmodSync(fd, options.mode);
118
+ writeFileSync(fd, content);
119
+ fsyncSync(fd);
120
+ } finally {
121
+ closeSync(fd);
122
+ }
123
+ options.validate?.(temporaryPath);
124
+ renameSync(temporaryPath, target);
125
+ syncDirectory(parent);
126
+ } catch (error) {
127
+ if (temporaryCreated) {
128
+ try {
129
+ rmSync(temporaryPath, { force: true });
130
+ } catch {
131
+ }
132
+ }
133
+ throw error;
116
134
  }
117
135
  }
118
- function normalizeOriginRemote(remote) {
119
- const value = remote.trim();
120
- if (!value) return void 0;
121
- const scp = !value.includes("://") ? /^(?:[^@/\s]+@)?(?<host>[^:/\s]+):(?<path>.+)$/.exec(value)?.groups : void 0;
122
- if (scp?.host && scp.path) {
123
- const path = scp.path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
124
- return path ? `${scp.host.toLowerCase()}/${path}` : void 0;
136
+
137
+ // src/lib/credentials.ts
138
+ import { createHash } from "crypto";
139
+ import { readFileSync } from "fs";
140
+ import { join as join2 } from "path";
141
+
142
+ // src/lib/paths.ts
143
+ import { homedir } from "os";
144
+ import { isAbsolute, join, normalize } from "path";
145
+ var UNSAFE_CONFIG_PATH_CHARACTERS = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
146
+ function absolutePath(value, variable) {
147
+ if (value !== void 0 && UNSAFE_CONFIG_PATH_CHARACTERS.test(value)) {
148
+ throw new Error(`${variable} contains unsafe characters`);
125
149
  }
126
- try {
127
- const url = new URL(value);
128
- url.username = "";
129
- url.password = "";
130
- url.search = "";
131
- url.hash = "";
132
- const path = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
133
- if (url.host && path) return `${url.host.toLowerCase()}/${path}`;
134
- return void 0;
135
- } catch {
136
- return void 0;
150
+ if (!value || value.trim() !== value || !isAbsolute(value)) return;
151
+ const normalized = normalize(value);
152
+ return normalized === value ? value : void 0;
153
+ }
154
+ function resolvePrimConfigDirectory(options = {}) {
155
+ const env = options.env ?? process.env;
156
+ const explicit = absolutePath(env.PRIM_CONFIG_DIR, "PRIM_CONFIG_DIR");
157
+ if (explicit) return { path: explicit, source: "explicit" };
158
+ const xdgConfigHome = absolutePath(env.XDG_CONFIG_HOME, "XDG_CONFIG_HOME");
159
+ if (xdgConfigHome) return { path: join(xdgConfigHome, "prim"), source: "xdg" };
160
+ const home = absolutePath(options.homeDir ?? homedir(), "HOME");
161
+ if (!home) {
162
+ throw new Error("cannot resolve Primitive config directory: HOME is not an absolute path");
137
163
  }
164
+ return { path: join(home, ".config", "prim"), source: "default" };
138
165
  }
139
- function opaqueRepoKey(source, value) {
140
- return `repo_v1_${createHash("sha256").update(`${source}\0${value}`).digest("hex")}`;
166
+ function primConfigDirectory(options = {}) {
167
+ return resolvePrimConfigDirectory(options).path;
141
168
  }
142
- function resolveRepositoryContext(cwd = process.cwd()) {
143
- const top = gitToplevel(cwd);
144
- if (!top) return null;
145
- let repoRoot;
146
- try {
147
- repoRoot = realpathSync.native(top);
148
- } catch {
149
- repoRoot = resolve(top);
169
+
170
+ // src/lib/workos-connect.ts
171
+ var TOKEN_PATH = "/oauth2/token";
172
+ var DISCOVERY_MAX_BYTES = 16 * 1024;
173
+ var WORKOS_CONNECT_RESPONSE_MAX_BYTES = 64 * 1024;
174
+ var MAX_DEVICE_LIFETIME_SECONDS = 60 * 60;
175
+ var MAX_TOKEN_LIFETIME_SECONDS = 24 * 60 * 60;
176
+ var MAX_URL_LENGTH = 2048;
177
+ var MAX_CLIENT_ID_LENGTH = 256;
178
+ var CONNECT_CLIENT_ID_PATTERN = /^client_[A-Za-z0-9_-]+$/u;
179
+ var WorkosConnectProtocolError = class extends Error {
180
+ code;
181
+ constructor(code, message) {
182
+ super(message);
183
+ this.name = "WorkosConnectProtocolError";
184
+ this.code = code;
150
185
  }
151
- const origin = gitValue(repoRoot, ["config", "--get", "remote.origin.url"]);
152
- const repoFullName = githubRepositoryFullName(repoRoot) ?? void 0;
153
- const normalizedOrigin = origin ? normalizeOriginRemote(origin) : void 0;
154
- if (normalizedOrigin) {
155
- return {
156
- repoRoot,
157
- repoKey: opaqueRepoKey("origin", normalizedOrigin),
158
- identitySource: "origin",
159
- repoFullName
160
- };
186
+ };
187
+ function recordFrom(value, label) {
188
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
189
+ throw new WorkosConnectProtocolError("invalid_response", `${label} must be an object`);
161
190
  }
162
- const roots = gitValue(repoRoot, ["rev-list", "--max-parents=0", "HEAD"])?.split(/\s+/).filter(Boolean).sort();
163
- if (roots && roots.length > 0) {
164
- return {
165
- repoRoot,
166
- repoKey: opaqueRepoKey("root_commit", roots.join("\n")),
167
- identitySource: "root_commit",
168
- repoFullName
169
- };
191
+ return value;
192
+ }
193
+ function exactString(value, field, maxLength) {
194
+ const containsControl = typeof value === "string" && [...value].some((character) => {
195
+ const code = character.charCodeAt(0);
196
+ return code <= 31 || code === 127;
197
+ });
198
+ if (typeof value !== "string" || value.length === 0 || value.length > maxLength || value.trim() !== value || containsControl) {
199
+ throw new WorkosConnectProtocolError("invalid_response", `${field} is invalid`);
170
200
  }
171
- return { repoRoot, repoFullName };
201
+ return value;
172
202
  }
173
- function nearestExistingAncestor(path) {
174
- const suffix = [];
175
- let cursor = path;
176
- while (true) {
177
- try {
178
- lstatSync(cursor);
179
- break;
180
- } catch (error) {
181
- const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
182
- if (code !== "ENOENT" && code !== "ENOTDIR") return null;
183
- const parent = dirname(cursor);
184
- if (parent === cursor) return null;
185
- suffix.unshift(cursor.slice(parent.length + (parent.endsWith(sep) ? 0 : 1)));
186
- cursor = parent;
187
- }
203
+ function safeInteger(value, field, minimum, maximum) {
204
+ if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
205
+ throw new WorkosConnectProtocolError("invalid_response", `${field} is invalid`);
188
206
  }
207
+ return value;
208
+ }
209
+ function canonicalIssuer(value) {
210
+ const issuer = exactString(value, "issuer", MAX_URL_LENGTH);
211
+ let parsed;
189
212
  try {
190
- return { real: realpathSync.native(cursor), suffix };
213
+ parsed = new URL(issuer);
191
214
  } catch {
192
- return null;
193
- }
194
- }
195
- function canonicalRepositoryPathScoped(filePath, context, baseDir) {
196
- if (!filePath || filePath !== filePath.trim() || filePath.includes("\0")) {
197
- return { ok: false, reason: "invalid_path" };
215
+ throw new WorkosConnectProtocolError("invalid_response", "issuer must be an HTTPS origin");
198
216
  }
199
- const absolute = resolve(baseDir, filePath);
200
- const resolved = nearestExistingAncestor(absolute);
201
- if (!resolved) return { ok: false, reason: "invalid_path" };
202
- const target = resolve(resolved.real, ...resolved.suffix);
203
- const rel = relative(context.repoRoot, target);
204
- if (!rel || rel === ".") return { ok: false, reason: "invalid_path" };
205
- if (isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`)) {
206
- return { ok: false, reason: "outside_repository" };
217
+ if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash || parsed.origin !== issuer) {
218
+ throw new WorkosConnectProtocolError("invalid_response", "issuer must be an HTTPS origin");
207
219
  }
208
- return { ok: true, file: sep === "/" ? rel : rel.split(sep).join("/") };
220
+ return issuer;
209
221
  }
210
- function canonicalRepositoryPathLegacy(filePath, cwd, repositoryRoot = canonicalGitRoot(cwd)) {
211
- if (!repositoryRoot || !filePath || [...filePath].some((char) => char < " " || char === "\x7F" || "~*?[]{}$`\\".includes(char)))
212
- return null;
213
- const absolute = resolve(cwd, filePath);
214
- let target;
215
- try {
216
- const stat = lstatSync(absolute);
217
- if (!stat.isFile() || stat.isSymbolicLink()) return null;
218
- target = realpathSync.native(absolute);
219
- } catch (error) {
220
- if (!(error instanceof Error) || error.code !== "ENOENT") {
221
- return null;
222
- }
223
- try {
224
- const parent = realpathSync.native(dirname(absolute));
225
- if (!lstatSync(parent).isDirectory()) return null;
226
- target = resolve(parent, basename(absolute));
227
- } catch {
228
- return null;
229
- }
222
+ function parseWorkosConnectCredentialMetadata(value) {
223
+ const record = recordFrom(value, "credential metadata");
224
+ if (record.version !== 1 || record.family !== "workos_connect") {
225
+ throw new WorkosConnectProtocolError("invalid_metadata", "credential metadata is invalid");
230
226
  }
231
- const rel = relative(repositoryRoot, target);
232
- if (!rel || isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`)) {
233
- return null;
227
+ const issuer = canonicalIssuer(record.issuer);
228
+ const clientId = exactString(record.clientId, "clientId", MAX_CLIENT_ID_LENGTH);
229
+ const accessTokenHash = exactString(record.accessTokenHash, "accessTokenHash", 64);
230
+ const refreshTokenHash = exactString(record.refreshTokenHash, "refreshTokenHash", 64);
231
+ if (!CONNECT_CLIENT_ID_PATTERN.test(clientId)) {
232
+ throw new WorkosConnectProtocolError("invalid_metadata", "credential clientId is invalid");
234
233
  }
235
- return sep === "/" ? rel : rel.split(sep).join("/");
236
- }
237
- function canonicalRepositoryPath(filePath, contextOrCwd, baseDirOrRoot) {
238
- if (typeof contextOrCwd === "string") {
239
- return canonicalRepositoryPathLegacy(filePath, contextOrCwd, baseDirOrRoot);
234
+ if (!/^[a-f0-9]{64}$/u.test(accessTokenHash)) {
235
+ throw new WorkosConnectProtocolError(
236
+ "invalid_metadata",
237
+ "credential accessTokenHash is invalid"
238
+ );
240
239
  }
241
- return canonicalRepositoryPathScoped(
242
- filePath,
243
- contextOrCwd,
244
- baseDirOrRoot ?? contextOrCwd.repoRoot
245
- );
240
+ if (!/^[a-f0-9]{64}$/u.test(refreshTokenHash)) {
241
+ throw new WorkosConnectProtocolError(
242
+ "invalid_metadata",
243
+ "credential refreshTokenHash is invalid"
244
+ );
245
+ }
246
+ return {
247
+ version: 1,
248
+ family: "workos_connect",
249
+ issuer,
250
+ clientId,
251
+ accessTokenHash,
252
+ refreshTokenHash
253
+ };
246
254
  }
247
-
248
- // src/lib/activation.ts
249
- var PRIM_ACTIVE_KEY = "prim.active";
250
- var PRIM_REPO_SYNC_ID_KEY = "prim.repoSyncId";
251
- var PRIM_REPO_SYNC_REPOSITORY_KEY = "prim.repoSyncRepository";
252
- var PRIM_REPO_BINDING_STATE_KEY = "prim.repoBindingState";
253
- var GIT_TIMEOUT_MS2 = 1e3;
254
- var REPO_SYNC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
255
- var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
256
- var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
257
- function repoActiveFlag(cwd) {
255
+ async function readBoundedJson(response, maxBytes) {
256
+ const contentLength = response.headers.get("content-length");
257
+ if (contentLength !== null) {
258
+ if (!/^\d+$/u.test(contentLength) || Number(contentLength) > maxBytes) {
259
+ throw new WorkosConnectProtocolError("invalid_response", "response body is too large");
260
+ }
261
+ }
262
+ if (!response.body) {
263
+ throw new WorkosConnectProtocolError("invalid_response", "response body is missing");
264
+ }
265
+ const reader = response.body.getReader();
266
+ const chunks = [];
267
+ let total = 0;
258
268
  try {
259
- const value = execFileSync2("git", ["config", "--get", PRIM_ACTIVE_KEY], {
260
- cwd,
261
- encoding: "utf-8",
262
- stdio: ["ignore", "pipe", "ignore"],
263
- timeout: GIT_TIMEOUT_MS2
264
- }).trim();
265
- if (value === "true") return "true";
266
- if (value === "false") return "false";
267
- return void 0;
269
+ while (true) {
270
+ const result = await reader.read();
271
+ if (result.done) break;
272
+ total += result.value.byteLength;
273
+ if (total > maxBytes) {
274
+ await reader.cancel();
275
+ throw new WorkosConnectProtocolError("invalid_response", "response body is too large");
276
+ }
277
+ chunks.push(result.value);
278
+ }
279
+ } finally {
280
+ reader.releaseLock();
281
+ }
282
+ const bytes = new Uint8Array(total);
283
+ let offset = 0;
284
+ for (const chunk of chunks) {
285
+ bytes.set(chunk, offset);
286
+ offset += chunk.byteLength;
287
+ }
288
+ let text;
289
+ try {
290
+ text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
291
+ return JSON.parse(text);
268
292
  } catch {
269
- return void 0;
293
+ throw new WorkosConnectProtocolError("invalid_response", "response body is not valid JSON");
270
294
  }
271
295
  }
272
- function isRepoActive(cwd) {
273
- return repoActiveFlag(cwd) === "true";
296
+ function workosConnectTokenEndpoint(issuer) {
297
+ return `${issuer}${TOKEN_PATH}`;
274
298
  }
275
- function isValidRepoSyncId(value) {
276
- return typeof value === "string" && REPO_SYNC_ID_RE.test(value);
299
+ function parseWorkosConnectTokens(value, options = {}) {
300
+ const record = recordFrom(value, "token response");
301
+ const accessToken = exactString(
302
+ record.access_token,
303
+ "access_token",
304
+ WORKOS_CONNECT_RESPONSE_MAX_BYTES
305
+ );
306
+ const refreshToken2 = record.refresh_token === void 0 && options.fallbackRefreshToken !== void 0 ? options.fallbackRefreshToken : exactString(record.refresh_token, "refresh_token", WORKOS_CONNECT_RESPONSE_MAX_BYTES);
307
+ return {
308
+ accessToken,
309
+ refreshToken: refreshToken2,
310
+ expiresIn: record.expires_in === void 0 ? void 0 : safeInteger(record.expires_in, "expires_in", 1, MAX_TOKEN_LIFETIME_SECONDS)
311
+ };
277
312
  }
278
- function localGitConfigValue(cwd, key) {
313
+
314
+ // src/lib/credentials.ts
315
+ var CONFIG_DIRECTORY = primConfigDirectory();
316
+ var TOKEN_FILE_PATH = join2(CONFIG_DIRECTORY, "token");
317
+ var REFRESH_TOKEN_PATH = join2(CONFIG_DIRECTORY, "refresh_token");
318
+ var TOKEN_EXPIRES_PATH = join2(CONFIG_DIRECTORY, "token_expires_at");
319
+ var TERMINAL_REFRESH_PATH = join2(CONFIG_DIRECTORY, "refresh_terminal");
320
+ var CREDENTIAL_METADATA_PATH = join2(CONFIG_DIRECTORY, "credential_metadata.json");
321
+ var CREDENTIAL_FAMILY_PATH = join2(CONFIG_DIRECTORY, "credential_family.json");
322
+ var CREDENTIAL_MIGRATION_PATH = join2(CONFIG_DIRECTORY, "credential_migration.json");
323
+ var CREDENTIAL_LOCK_PATH = join2(CONFIG_DIRECTORY, "credentials.lock");
324
+ var MAX_CREDENTIAL_METADATA_BYTES = 4096;
325
+ var CREDENTIAL_MIGRATION_VERSION = 1;
326
+ var CREDENTIAL_MIGRATION_STATE = "family_bound";
327
+ function readTrimmed(path) {
279
328
  try {
280
- const value = execFileSync2("git", ["config", "--local", "--get", key], {
281
- cwd,
282
- encoding: "utf-8",
283
- stdio: ["ignore", "pipe", "ignore"],
284
- timeout: GIT_TIMEOUT_MS2
285
- }).trim();
329
+ const value = readFileSync(path, "utf8").trim();
286
330
  return value || void 0;
287
331
  } catch {
288
332
  return void 0;
289
333
  }
290
334
  }
291
- function repoSyncId(cwd) {
292
- const value = localGitConfigValue(cwd, PRIM_REPO_SYNC_ID_KEY);
293
- if (!isValidRepoSyncId(value)) return void 0;
294
- const repositoryFullName = localGitConfigValue(cwd, PRIM_REPO_SYNC_REPOSITORY_KEY);
295
- return repositoryFullName === githubRepositoryFullName(cwd) ? value : void 0;
296
- }
297
- function repositoryBindingState(cwd) {
298
- const rawId = localGitConfigValue(cwd, PRIM_REPO_SYNC_ID_KEY);
299
- const marker = localGitConfigValue(cwd, PRIM_REPO_BINDING_STATE_KEY);
300
- if (rawId !== void 0 && !isValidRepoSyncId(rawId)) return "invalid";
301
- if (marker === "unbound" || marker === "invalid") return marker;
302
- if (marker === "connected") return repoSyncId(cwd) ? "connected" : "invalid";
303
- if (marker !== void 0) return "invalid";
304
- return rawId === void 0 ? "unbound" : repoSyncId(cwd) ? void 0 : "unbound";
305
- }
306
- function hasProjectPrimInstall(cwd) {
307
- const root = gitToplevel(cwd);
308
- if (root === null || root === homedir()) return false;
309
- for (const rel of PROJECT_INSTALL_FILES) {
310
- const path = join(root, rel);
311
- if (existsSync(path)) {
312
- try {
313
- const content = readFileSync(path, "utf-8");
314
- if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
315
- } catch {
335
+ function resolveAuthCredential(options = {}) {
336
+ const envToken = (options.env ?? process.env).PRIM_TOKEN?.trim();
337
+ if (envToken) return { token: envToken, source: "environment" };
338
+ const stored = readTrimmed(options.tokenFilePath ?? TOKEN_FILE_PATH);
339
+ if (!stored) return void 0;
340
+ const metadata = readStoredCredentialMetadata(
341
+ options.metadataPath ?? CREDENTIAL_METADATA_PATH,
342
+ options.familyPath ?? CREDENTIAL_FAMILY_PATH,
343
+ options.migrationPath ?? CREDENTIAL_MIGRATION_PATH
344
+ );
345
+ if (metadata.state === "legacy_broker") {
346
+ if (metadata.metadata) {
347
+ const refreshToken3 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
348
+ if (!refreshToken3 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken3)) {
349
+ return void 0;
316
350
  }
317
351
  }
352
+ return { token: stored, source: "token_file" };
318
353
  }
319
- return false;
320
- }
321
- function isRepoActiveForCapture(cwd) {
322
- const flag = repoActiveFlag(cwd);
323
- if (flag === "true") return true;
324
- if (flag === "false") return false;
325
- return hasProjectPrimInstall(cwd);
354
+ if (metadata.state === "invalid") return void 0;
355
+ const refreshToken2 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
356
+ if (!refreshToken2 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken2)) {
357
+ return void 0;
358
+ }
359
+ return { token: stored, source: "token_file" };
326
360
  }
327
- function decisionIngestionStatus(cwd) {
328
- return isRepoActiveForCapture(cwd) ? "enabled" : "disabled";
361
+ function credentialFingerprint(value) {
362
+ return createHash("sha256").update(value).digest("hex");
329
363
  }
330
-
331
- // src/lib/bin-path.ts
332
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
333
- import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2 } from "path";
334
- import { fileURLToPath } from "url";
335
- var PKG_NAME = "@primitive.ai/prim";
336
- var ROOT_WALK_LIMIT = 6;
337
- var STABLE_HOOK_LAUNCHER_NAME = "prim-hook-launcher-v1";
338
- var resolvedRoot;
339
- function locateRoot() {
340
- if (resolvedRoot !== void 0) {
341
- return resolvedRoot;
364
+ function parseLegacyBrokerCredentialMetadata(value) {
365
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
366
+ throw new Error("credential family is invalid");
342
367
  }
343
- let dir = dirname2(fileURLToPath(import.meta.url));
344
- for (let depth = 0; depth < ROOT_WALK_LIMIT; depth++) {
345
- const manifestPath = join2(dir, "package.json");
346
- if (existsSync2(manifestPath)) {
347
- try {
348
- const manifest = JSON.parse(readFileSync2(manifestPath, "utf-8"));
349
- if (manifest.name === PKG_NAME && manifest.bin) {
350
- resolvedRoot = { dir, version: manifest.version, bin: manifest.bin };
351
- return resolvedRoot;
352
- }
353
- } catch {
354
- }
355
- }
356
- const parent = dirname2(dir);
357
- if (parent === dir) {
358
- break;
359
- }
360
- dir = parent;
368
+ const record = value;
369
+ if (record.version !== 1 || record.family !== "legacy_broker" || typeof record.accessTokenHash !== "string" || typeof record.refreshTokenHash !== "string" || !/^[a-f0-9]{64}$/u.test(record.accessTokenHash) || !/^[a-f0-9]{64}$/u.test(record.refreshTokenHash)) {
370
+ throw new Error("credential family is invalid");
361
371
  }
362
- resolvedRoot = null;
363
- return resolvedRoot;
364
- }
365
- function packageVersion() {
366
- return locateRoot()?.version ?? null;
367
- }
368
- function shellQuote(value) {
369
- return `'${value.replaceAll("'", `'"'"'`)}'`;
372
+ return {
373
+ version: 1,
374
+ family: "legacy_broker",
375
+ accessTokenHash: record.accessTokenHash,
376
+ refreshTokenHash: record.refreshTokenHash
377
+ };
370
378
  }
371
- var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
372
- var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
373
- function stableHookCommand(bin, args = "") {
374
- if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
375
- throw new Error("invalid stable hook command");
379
+ function readBoundedCredentialJson(path) {
380
+ let raw;
381
+ try {
382
+ raw = readFileSync(path, "utf8");
383
+ } catch (error) {
384
+ return error.code === "ENOENT" ? void 0 : null;
376
385
  }
377
- const resolver = [
378
- // #242 and earlier identify managed commands by this package marker. Keep
379
- // it as inert data during the rolling window so an older uninstall or
380
- // reinstall can remove the stable entry without invoking npm or PATH.
381
- `prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
382
- 'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
383
- 'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
384
- 'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
385
- 'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
386
- "fi; fi; ",
387
- `case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
388
- 'exec "$prim_launcher" "$@"'
389
- ].join("");
390
- const suffix = args ? ` ${args}` : "";
391
- return `/bin/sh -c ${shellQuote(resolver)} ${STABLE_HOOK_LAUNCHER_NAME} ${bin}${suffix}`;
392
- }
393
- function detachedHookShimCommand(bin, args = "") {
394
- return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
395
- }
396
-
397
- // src/client.ts
398
- import { createHash as createHash3 } from "crypto";
399
- import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, rmSync as rmSync3 } from "fs";
400
- import { dirname as dirname5 } from "path";
401
-
402
- // src/lib/atomic-file.ts
403
- import { randomUUID } from "crypto";
404
- import {
405
- constants,
406
- closeSync,
407
- fchmodSync,
408
- fsyncSync,
409
- mkdirSync,
410
- openSync,
411
- renameSync,
412
- rmSync,
413
- writeFileSync
414
- } from "fs";
415
- import { dirname as dirname3 } from "path";
416
- var DEFAULT_FILE_MODE = 438;
417
- function syncDirectory(path) {
418
- const fd = openSync(path, constants.O_RDONLY);
386
+ if (Buffer.byteLength(raw, "utf8") > MAX_CREDENTIAL_METADATA_BYTES) return null;
419
387
  try {
420
- fsyncSync(fd);
421
- } finally {
422
- closeSync(fd);
388
+ return JSON.parse(raw);
389
+ } catch {
390
+ return null;
423
391
  }
424
392
  }
425
- function syncCreatedParentChain(firstCreatedParent, parent) {
426
- const createdDirectories = [];
427
- let current = parent;
428
- while (current !== firstCreatedParent) {
429
- createdDirectories.push(current);
430
- const next = dirname3(current);
431
- if (next === current) {
432
- throw new Error("recursive mkdir returned a path outside the target parent chain");
393
+ function readCredentialFamily(path) {
394
+ const parsed = readBoundedCredentialJson(path);
395
+ if (parsed === void 0) return void 0;
396
+ if (parsed === null) return { state: "invalid" };
397
+ try {
398
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.family === "legacy_broker") {
399
+ return { state: "legacy_broker", metadata: parseLegacyBrokerCredentialMetadata(parsed) };
433
400
  }
434
- current = next;
435
- }
436
- createdDirectories.push(firstCreatedParent);
437
- syncDirectory(dirname3(firstCreatedParent));
438
- for (const directory of createdDirectories.reverse().slice(0, -1)) {
439
- syncDirectory(directory);
401
+ return {
402
+ state: "workos_connect",
403
+ metadata: parseWorkosConnectCredentialMetadata(parsed)
404
+ };
405
+ } catch {
406
+ return { state: "invalid" };
440
407
  }
441
408
  }
442
- function ensureDurableDirectory(path, mode) {
443
- const firstCreatedParent = mkdirSync(path, { recursive: true, mode });
444
- if (firstCreatedParent) {
445
- syncCreatedParentChain(firstCreatedParent, path);
446
- }
409
+ function isCredentialMigrationSentinel(value) {
410
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
411
+ const record = value;
412
+ const keys = Object.keys(record).sort();
413
+ return keys.length === 2 && keys[0] === "state" && keys[1] === "version" && record.version === CREDENTIAL_MIGRATION_VERSION && record.state === CREDENTIAL_MIGRATION_STATE;
447
414
  }
448
- function atomicWriteFile(target, content, options = {}) {
449
- const parent = dirname3(target);
450
- if (options.ensureParent) {
451
- ensureDurableDirectory(parent);
415
+ function readCredentialMigrationState(path = CREDENTIAL_MIGRATION_PATH) {
416
+ const parsed = readBoundedCredentialJson(path);
417
+ if (parsed === void 0) return "absent";
418
+ return parsed !== null && isCredentialMigrationSentinel(parsed) ? "valid" : "invalid";
419
+ }
420
+ function readStoredCredentialMetadata(metadataPath = CREDENTIAL_METADATA_PATH, familyPath = CREDENTIAL_FAMILY_PATH, migrationPath = CREDENTIAL_MIGRATION_PATH) {
421
+ const family = readCredentialFamily(familyPath);
422
+ if (family) return family;
423
+ const parsed = readBoundedCredentialJson(metadataPath);
424
+ if (parsed === void 0) {
425
+ return readCredentialMigrationState(migrationPath) === "absent" ? { state: "legacy_broker" } : { state: "invalid" };
452
426
  }
453
- const temporaryPath = `${target}.${randomUUID()}.tmp`;
454
- let temporaryCreated = false;
427
+ if (parsed === null) return { state: "invalid" };
455
428
  try {
456
- const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
457
- const fd = openSync(temporaryPath, flags, options.mode ?? DEFAULT_FILE_MODE);
458
- temporaryCreated = true;
459
- try {
460
- if (options.mode !== void 0) fchmodSync(fd, options.mode);
461
- writeFileSync(fd, content);
462
- fsyncSync(fd);
463
- } finally {
464
- closeSync(fd);
465
- }
466
- options.validate?.(temporaryPath);
467
- renameSync(temporaryPath, target);
468
- syncDirectory(parent);
469
- } catch (error) {
470
- if (temporaryCreated) {
471
- try {
472
- rmSync(temporaryPath, { force: true });
473
- } catch {
474
- }
475
- }
476
- throw error;
477
- }
478
- }
479
-
480
- // src/lib/credentials.ts
481
- import { createHash as createHash2 } from "crypto";
482
- import { readFileSync as readFileSync3 } from "fs";
483
- import { join as join4 } from "path";
484
-
485
- // src/lib/paths.ts
486
- import { homedir as homedir2 } from "os";
487
- import { isAbsolute as isAbsolute3, join as join3, normalize } from "path";
488
- var UNSAFE_CONFIG_PATH_CHARACTERS = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
489
- function absolutePath(value, variable) {
490
- if (value !== void 0 && UNSAFE_CONFIG_PATH_CHARACTERS.test(value)) {
491
- throw new Error(`${variable} contains unsafe characters`);
429
+ return {
430
+ state: "workos_connect",
431
+ metadata: parseWorkosConnectCredentialMetadata(parsed)
432
+ };
433
+ } catch {
434
+ return { state: "invalid" };
492
435
  }
493
- if (!value || value.trim() !== value || !isAbsolute3(value)) return;
494
- const normalized = normalize(value);
495
- return normalized === value ? value : void 0;
496
436
  }
497
- function resolvePrimConfigDirectory(options = {}) {
498
- const env = options.env ?? process.env;
499
- const explicit = absolutePath(env.PRIM_CONFIG_DIR, "PRIM_CONFIG_DIR");
500
- if (explicit) return { path: explicit, source: "explicit" };
501
- const xdgConfigHome = absolutePath(env.XDG_CONFIG_HOME, "XDG_CONFIG_HOME");
502
- if (xdgConfigHome) return { path: join3(xdgConfigHome, "prim"), source: "xdg" };
503
- const home = absolutePath(options.homeDir ?? homedir2(), "HOME");
504
- if (!home) {
505
- throw new Error("cannot resolve Primitive config directory: HOME is not an absolute path");
437
+ function decodeJwtPayload(token) {
438
+ const parts = token.split(".");
439
+ if (parts.length !== 3) return void 0;
440
+ try {
441
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
442
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return void 0;
443
+ return payload;
444
+ } catch {
445
+ return void 0;
506
446
  }
507
- return { path: join3(home, ".config", "prim"), source: "default" };
508
447
  }
509
- function primConfigDirectory(options = {}) {
510
- return resolvePrimConfigDirectory(options).path;
448
+ function jwtExpiresAt(token) {
449
+ const exp = decodeJwtPayload(token)?.exp;
450
+ return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : void 0;
511
451
  }
512
452
 
513
- // src/lib/workos-connect.ts
514
- var TOKEN_PATH = "/oauth2/token";
515
- var DISCOVERY_MAX_BYTES = 16 * 1024;
516
- var WORKOS_CONNECT_RESPONSE_MAX_BYTES = 64 * 1024;
517
- var MAX_DEVICE_LIFETIME_SECONDS = 60 * 60;
518
- var MAX_TOKEN_LIFETIME_SECONDS = 24 * 60 * 60;
519
- var MAX_URL_LENGTH = 2048;
520
- var MAX_CLIENT_ID_LENGTH = 256;
521
- var CONNECT_CLIENT_ID_PATTERN = /^client_[A-Za-z0-9_-]+$/u;
522
- var WorkosConnectProtocolError = class extends Error {
523
- code;
524
- constructor(code, message) {
525
- super(message);
526
- this.name = "WorkosConnectProtocolError";
527
- this.code = code;
528
- }
529
- };
530
- function recordFrom(value, label) {
531
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
532
- throw new WorkosConnectProtocolError("invalid_response", `${label} must be an object`);
453
+ // src/lib/file-lock.ts
454
+ import { randomBytes } from "crypto";
455
+ import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync as rmSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
456
+ import { dirname as dirname2, join as join3 } from "path";
457
+
458
+ // src/lib/process-liveness.ts
459
+ function processIsAlive(pid, probe = process.kill) {
460
+ if (!Number.isSafeInteger(pid) || pid <= 0) return false;
461
+ try {
462
+ probe(pid, 0);
463
+ return true;
464
+ } catch (error) {
465
+ return error.code === "EPERM";
533
466
  }
534
- return value;
535
467
  }
536
- function exactString(value, field, maxLength) {
537
- const containsControl = typeof value === "string" && [...value].some((character) => {
538
- const code = character.charCodeAt(0);
539
- return code <= 31 || code === 127;
540
- });
541
- if (typeof value !== "string" || value.length === 0 || value.length > maxLength || value.trim() !== value || containsControl) {
542
- throw new WorkosConnectProtocolError("invalid_response", `${field} is invalid`);
543
- }
544
- return value;
468
+
469
+ // src/lib/file-lock.ts
470
+ var DEFAULT_TIMEOUT_MS = 3e4;
471
+ var DEFAULT_POLL_MS = 50;
472
+ var DEFAULT_INIT_GRACE_MS = 2e3;
473
+ var DIRECTORY_MODE = 448;
474
+ var FILE_MODE = 384;
475
+ function ownerPath(lockDir) {
476
+ return join3(lockDir, "owner.json");
545
477
  }
546
- function safeInteger(value, field, minimum, maximum) {
547
- if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
548
- throw new WorkosConnectProtocolError("invalid_response", `${field} is invalid`);
478
+ function readOwner(lockDir) {
479
+ try {
480
+ const owner = JSON.parse(readFileSync2(ownerPath(lockDir), "utf8"));
481
+ if (!Number.isInteger(owner.pid) || owner.pid <= 0 || typeof owner.nonce !== "string" || typeof owner.createdAt !== "number") {
482
+ return null;
483
+ }
484
+ return owner;
485
+ } catch {
486
+ return null;
549
487
  }
550
- return value;
551
488
  }
552
- function canonicalIssuer(value) {
553
- const issuer = exactString(value, "issuer", MAX_URL_LENGTH);
554
- let parsed;
489
+ function sameOwner(a, b) {
490
+ return a?.pid === b.pid && a.nonce === b.nonce && a.createdAt === b.createdAt;
491
+ }
492
+ function tryTakeLock(lockDir, now) {
555
493
  try {
556
- parsed = new URL(issuer);
557
- } catch {
558
- throw new WorkosConnectProtocolError("invalid_response", "issuer must be an HTTPS origin");
494
+ mkdirSync2(lockDir, { mode: DIRECTORY_MODE });
495
+ } catch (error) {
496
+ if (error.code === "EEXIST") return null;
497
+ throw error;
559
498
  }
560
- if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash || parsed.origin !== issuer) {
561
- throw new WorkosConnectProtocolError("invalid_response", "issuer must be an HTTPS origin");
499
+ const owner = {
500
+ pid: process.pid,
501
+ nonce: randomBytes(16).toString("hex"),
502
+ createdAt: now
503
+ };
504
+ try {
505
+ writeFileSync2(ownerPath(lockDir), `${JSON.stringify(owner)}
506
+ `, {
507
+ encoding: "utf8",
508
+ mode: FILE_MODE,
509
+ flag: "wx"
510
+ });
511
+ return owner;
512
+ } catch (error) {
513
+ rmSync2(lockDir, { recursive: true, force: true });
514
+ throw error;
562
515
  }
563
- return issuer;
564
516
  }
565
- function parseWorkosConnectCredentialMetadata(value) {
566
- const record = recordFrom(value, "credential metadata");
567
- if (record.version !== 1 || record.family !== "workos_connect") {
568
- throw new WorkosConnectProtocolError("invalid_metadata", "credential metadata is invalid");
569
- }
570
- const issuer = canonicalIssuer(record.issuer);
571
- const clientId = exactString(record.clientId, "clientId", MAX_CLIENT_ID_LENGTH);
572
- const accessTokenHash = exactString(record.accessTokenHash, "accessTokenHash", 64);
573
- const refreshTokenHash = exactString(record.refreshTokenHash, "refreshTokenHash", 64);
574
- if (!CONNECT_CLIENT_ID_PATTERN.test(clientId)) {
575
- throw new WorkosConnectProtocolError("invalid_metadata", "credential clientId is invalid");
517
+ function recoverStaleLock(lockDir, now, alive, initGraceMs) {
518
+ const owner = readOwner(lockDir);
519
+ if (owner) {
520
+ if (alive(owner.pid)) return false;
521
+ if (!sameOwner(readOwner(lockDir), owner)) return false;
522
+ rmSync2(lockDir, { recursive: true, force: true });
523
+ return true;
576
524
  }
577
- if (!/^[a-f0-9]{64}$/u.test(accessTokenHash)) {
578
- throw new WorkosConnectProtocolError(
579
- "invalid_metadata",
580
- "credential accessTokenHash is invalid"
581
- );
525
+ try {
526
+ const before = statSync(lockDir).mtimeMs;
527
+ if (now - before < initGraceMs) return false;
528
+ if (readOwner(lockDir)) return false;
529
+ if (statSync(lockDir).mtimeMs !== before) return false;
530
+ rmSync2(lockDir, { recursive: true, force: true });
531
+ return true;
532
+ } catch {
533
+ return true;
582
534
  }
583
- if (!/^[a-f0-9]{64}$/u.test(refreshTokenHash)) {
584
- throw new WorkosConnectProtocolError(
585
- "invalid_metadata",
586
- "credential refreshTokenHash is invalid"
587
- );
535
+ }
536
+ function abortError(signal) {
537
+ if (signal.reason instanceof Error) return signal.reason;
538
+ const error = new Error("The operation was aborted");
539
+ error.name = "AbortError";
540
+ return error;
541
+ }
542
+ function throwIfAborted(signal) {
543
+ if (signal?.aborted) throw abortError(signal);
544
+ }
545
+ async function defaultSleep(ms, signal) {
546
+ if (!signal) {
547
+ await new Promise((resolve5) => setTimeout(resolve5, ms));
548
+ return;
588
549
  }
589
- return {
590
- version: 1,
591
- family: "workos_connect",
592
- issuer,
593
- clientId,
594
- accessTokenHash,
595
- refreshTokenHash
596
- };
550
+ throwIfAborted(signal);
551
+ await new Promise((resolve5, reject) => {
552
+ const timer = setTimeout(() => {
553
+ signal.removeEventListener("abort", onAbort);
554
+ resolve5();
555
+ }, ms);
556
+ const onAbort = () => {
557
+ clearTimeout(timer);
558
+ reject(abortError(signal));
559
+ };
560
+ signal.addEventListener("abort", onAbort, { once: true });
561
+ });
597
562
  }
598
- async function readBoundedJson(response, maxBytes) {
599
- const contentLength = response.headers.get("content-length");
600
- if (contentLength !== null) {
601
- if (!/^\d+$/u.test(contentLength) || Number(contentLength) > maxBytes) {
602
- throw new WorkosConnectProtocolError("invalid_response", "response body is too large");
563
+ var syncSleeper = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
564
+ async function withFileLock(lockDir, operation, options = {}) {
565
+ mkdirSync2(dirname2(lockDir), { recursive: true, mode: DIRECTORY_MODE });
566
+ const nowMs = options.nowMs ?? Date.now;
567
+ const alive = options.processAlive ?? processIsAlive;
568
+ const deadline = nowMs() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
569
+ let owner = null;
570
+ while (!owner) {
571
+ throwIfAborted(options.signal);
572
+ const now = nowMs();
573
+ owner = tryTakeLock(lockDir, now);
574
+ if (owner) break;
575
+ recoverStaleLock(lockDir, now, alive, options.initGraceMs ?? DEFAULT_INIT_GRACE_MS);
576
+ if (now >= deadline) {
577
+ throw new Error(`timed out waiting for file lock ${lockDir}`);
578
+ }
579
+ if (options.sleep) {
580
+ await options.sleep(options.pollMs ?? DEFAULT_POLL_MS);
581
+ throwIfAborted(options.signal);
582
+ } else {
583
+ await defaultSleep(options.pollMs ?? DEFAULT_POLL_MS, options.signal);
603
584
  }
604
585
  }
605
- if (!response.body) {
606
- throw new WorkosConnectProtocolError("invalid_response", "response body is missing");
607
- }
608
- const reader = response.body.getReader();
609
- const chunks = [];
610
- let total = 0;
611
586
  try {
612
- while (true) {
613
- const result = await reader.read();
614
- if (result.done) break;
615
- total += result.value.byteLength;
616
- if (total > maxBytes) {
617
- await reader.cancel();
618
- throw new WorkosConnectProtocolError("invalid_response", "response body is too large");
619
- }
620
- chunks.push(result.value);
621
- }
587
+ throwIfAborted(options.signal);
588
+ return await operation();
622
589
  } finally {
623
- reader.releaseLock();
624
- }
625
- const bytes = new Uint8Array(total);
626
- let offset = 0;
627
- for (const chunk of chunks) {
628
- bytes.set(chunk, offset);
629
- offset += chunk.byteLength;
590
+ if (sameOwner(readOwner(lockDir), owner)) {
591
+ rmSync2(lockDir, { recursive: true, force: true });
592
+ }
630
593
  }
631
- let text;
632
- try {
633
- text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
634
- return JSON.parse(text);
635
- } catch {
636
- throw new WorkosConnectProtocolError("invalid_response", "response body is not valid JSON");
594
+ }
595
+
596
+ // src/lib/terminal-safe.ts
597
+ function replaceIsolatedSurrogates(value) {
598
+ let out = "";
599
+ for (let index = 0; index < value.length; index += 1) {
600
+ const unit = value.charCodeAt(index);
601
+ if (unit >= 55296 && unit <= 56319) {
602
+ const next = value.charCodeAt(index + 1);
603
+ if (next >= 56320 && next <= 57343) {
604
+ out += value[index] + value[index + 1];
605
+ index += 1;
606
+ } else {
607
+ out += "\uFFFD";
608
+ }
609
+ } else if (unit >= 56320 && unit <= 57343) {
610
+ out += "\uFFFD";
611
+ } else {
612
+ out += value[index];
613
+ }
637
614
  }
615
+ return out;
638
616
  }
639
- function workosConnectTokenEndpoint(issuer) {
640
- return `${issuer}${TOKEN_PATH}`;
617
+ function isUnsafeTerminalCodePoint(point) {
618
+ const c0OrC1 = point <= 31 || point >= 127 && point <= 159;
619
+ const bidiOrZeroWidth = point === 173 || // soft hyphen
620
+ point === 1564 || // Arabic letter mark
621
+ point === 6158 || // Mongolian vowel separator
622
+ point >= 8203 && point <= 8207 || // zero-width + directional marks
623
+ point >= 8234 && point <= 8238 || // bidi embeddings/overrides
624
+ point >= 8288 && point <= 8303 || // word joiner + bidi isolates/controls
625
+ point >= 65529 && point <= 65531 || // interlinear annotation controls
626
+ point === 65279 || // zero-width no-break space / BOM
627
+ point >= 917504 && point <= 917631;
628
+ return c0OrC1 || bidiOrZeroWidth;
641
629
  }
642
- function parseWorkosConnectTokens(value, options = {}) {
643
- const record = recordFrom(value, "token response");
644
- const accessToken = exactString(
645
- record.access_token,
646
- "access_token",
647
- WORKOS_CONNECT_RESPONSE_MAX_BYTES
648
- );
649
- const refreshToken2 = record.refresh_token === void 0 && options.fallbackRefreshToken !== void 0 ? options.fallbackRefreshToken : exactString(record.refresh_token, "refresh_token", WORKOS_CONNECT_RESPONSE_MAX_BYTES);
650
- return {
651
- accessToken,
652
- refreshToken: refreshToken2,
653
- expiresIn: record.expires_in === void 0 ? void 0 : safeInteger(record.expires_in, "expires_in", 1, MAX_TOKEN_LIFETIME_SECONDS)
654
- };
630
+ function terminalSafeText(value) {
631
+ return Array.from(replaceIsolatedSurrogates(value)).filter((character) => !isUnsafeTerminalCodePoint(character.codePointAt(0) ?? 0)).join("");
632
+ }
633
+ function terminalSafeLine(value) {
634
+ return terminalSafeText(value.replace(/\s+/gu, " ")).replace(/\s+/gu, " ").trim();
655
635
  }
636
+ var stripControlChars = terminalSafeText;
656
637
 
657
- // src/lib/credentials.ts
658
- var CONFIG_DIRECTORY = primConfigDirectory();
659
- var TOKEN_FILE_PATH = join4(CONFIG_DIRECTORY, "token");
660
- var REFRESH_TOKEN_PATH = join4(CONFIG_DIRECTORY, "refresh_token");
661
- var TOKEN_EXPIRES_PATH = join4(CONFIG_DIRECTORY, "token_expires_at");
662
- var TERMINAL_REFRESH_PATH = join4(CONFIG_DIRECTORY, "refresh_terminal");
663
- var CREDENTIAL_METADATA_PATH = join4(CONFIG_DIRECTORY, "credential_metadata.json");
664
- var CREDENTIAL_FAMILY_PATH = join4(CONFIG_DIRECTORY, "credential_family.json");
665
- var CREDENTIAL_MIGRATION_PATH = join4(CONFIG_DIRECTORY, "credential_migration.json");
666
- var CREDENTIAL_LOCK_PATH = join4(CONFIG_DIRECTORY, "credentials.lock");
667
- var MAX_CREDENTIAL_METADATA_BYTES = 4096;
668
- var CREDENTIAL_MIGRATION_VERSION = 1;
669
- var CREDENTIAL_MIGRATION_STATE = "family_bound";
670
- function readTrimmed(path) {
638
+ // src/client.ts
639
+ var CONFIG_DIR_MODE = 448;
640
+ var CREDENTIAL_FILE_MODE = 384;
641
+ var REFRESH_THRESHOLD_MS = 6e4;
642
+ var DEFAULT_API_URL = "https://api.getprimitive.ai";
643
+ var AUTH_EXPIRED_MESSAGE = "Authentication expired. Run `prim auth login` to re-authenticate.";
644
+ function readTrimmed2(path) {
671
645
  try {
672
646
  const value = readFileSync3(path, "utf8").trim();
673
647
  return value || void 0;
@@ -675,757 +649,786 @@ function readTrimmed(path) {
675
649
  return void 0;
676
650
  }
677
651
  }
678
- function resolveAuthCredential(options = {}) {
679
- const envToken = (options.env ?? process.env).PRIM_TOKEN?.trim();
680
- if (envToken) return { token: envToken, source: "environment" };
681
- const stored = readTrimmed(options.tokenFilePath ?? TOKEN_FILE_PATH);
682
- if (!stored) return void 0;
683
- const metadata = readStoredCredentialMetadata(
684
- options.metadataPath ?? CREDENTIAL_METADATA_PATH,
685
- options.familyPath ?? CREDENTIAL_FAMILY_PATH,
686
- options.migrationPath ?? CREDENTIAL_MIGRATION_PATH
687
- );
688
- if (metadata.state === "legacy_broker") {
689
- if (metadata.metadata) {
690
- const refreshToken3 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
691
- if (!refreshToken3 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken3)) {
692
- return void 0;
693
- }
694
- }
695
- return { token: stored, source: "token_file" };
696
- }
697
- if (metadata.state === "invalid") return void 0;
698
- const refreshToken2 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
699
- if (!refreshToken2 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken2)) {
700
- return void 0;
701
- }
702
- return { token: stored, source: "token_file" };
652
+ function getSiteUrl() {
653
+ return getSiteUrlForEnvironment(process.env.PRIM_API_URL);
703
654
  }
704
- function credentialFingerprint(value) {
705
- return createHash2("sha256").update(value).digest("hex");
655
+ function getSiteUrlForEnvironment(primApiUrl) {
656
+ return primApiUrl?.trim() || DEFAULT_API_URL;
706
657
  }
707
- function parseLegacyBrokerCredentialMetadata(value) {
708
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
709
- throw new Error("credential family is invalid");
710
- }
711
- const record = value;
712
- if (record.version !== 1 || record.family !== "legacy_broker" || typeof record.accessTokenHash !== "string" || typeof record.refreshTokenHash !== "string" || !/^[a-f0-9]{64}$/u.test(record.accessTokenHash) || !/^[a-f0-9]{64}$/u.test(record.refreshTokenHash)) {
713
- throw new Error("credential family is invalid");
714
- }
658
+ function expiresAtFor(token, expiresIn) {
659
+ return expiresIn === void 0 ? jwtExpiresAt(token) : Date.now() + expiresIn * 1e3;
660
+ }
661
+ function ensureConfigDirectory() {
662
+ const directory = dirname3(TOKEN_FILE_PATH);
663
+ mkdirSync3(directory, { recursive: true, mode: CONFIG_DIR_MODE });
664
+ chmodSync(directory, CONFIG_DIR_MODE);
665
+ }
666
+ function atomicWrite(path, content) {
667
+ ensureConfigDirectory();
668
+ atomicWriteFile(path, content, { mode: CREDENTIAL_FILE_MODE });
669
+ }
670
+ function removeCredentialFile(path) {
671
+ if (!existsSync2(path)) return false;
672
+ rmSync3(path, { force: true });
673
+ return true;
674
+ }
675
+ function getTokenExpiresAt() {
676
+ const stored = readTrimmed2(TOKEN_EXPIRES_PATH);
677
+ if (stored === void 0) return void 0;
678
+ const value = Number(stored);
679
+ return Number.isNaN(value) ? void 0 : value;
680
+ }
681
+ function isTokenExpiringSoon(credential) {
682
+ if (credential.source !== "token_file") return false;
683
+ const expiresAt = getTokenExpiresAt();
684
+ return expiresAt !== void 0 && Date.now() >= expiresAt - REFRESH_THRESHOLD_MS;
685
+ }
686
+ function refreshFingerprint(refreshToken2) {
687
+ return createHash2("sha256").update(refreshToken2).digest("hex");
688
+ }
689
+ function legacyBrokerCredentialMetadata(accessToken, refreshToken2) {
715
690
  return {
716
691
  version: 1,
717
692
  family: "legacy_broker",
718
- accessTokenHash: record.accessTokenHash,
719
- refreshTokenHash: record.refreshTokenHash
693
+ accessTokenHash: refreshFingerprint(accessToken),
694
+ refreshTokenHash: refreshFingerprint(refreshToken2)
720
695
  };
721
696
  }
722
- function readBoundedCredentialJson(path) {
723
- let raw;
724
- try {
725
- raw = readFileSync3(path, "utf8");
726
- } catch (error) {
727
- return error.code === "ENOENT" ? void 0 : null;
728
- }
729
- if (Buffer.byteLength(raw, "utf8") > MAX_CREDENTIAL_METADATA_BYTES) return null;
730
- try {
731
- return JSON.parse(raw);
732
- } catch {
733
- return null;
734
- }
735
- }
736
- function readCredentialFamily(path) {
737
- const parsed = readBoundedCredentialJson(path);
738
- if (parsed === void 0) return void 0;
739
- if (parsed === null) return { state: "invalid" };
740
- try {
741
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.family === "legacy_broker") {
742
- return { state: "legacy_broker", metadata: parseLegacyBrokerCredentialMetadata(parsed) };
743
- }
744
- return {
745
- state: "workos_connect",
746
- metadata: parseWorkosConnectCredentialMetadata(parsed)
747
- };
748
- } catch {
749
- return { state: "invalid" };
750
- }
751
- }
752
- function isCredentialMigrationSentinel(value) {
753
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
754
- const record = value;
755
- const keys = Object.keys(record).sort();
756
- return keys.length === 2 && keys[0] === "state" && keys[1] === "version" && record.version === CREDENTIAL_MIGRATION_VERSION && record.state === CREDENTIAL_MIGRATION_STATE;
697
+ function credentialFamilyMetadata(accessToken, refreshToken2, metadata) {
698
+ const hashes = {
699
+ accessTokenHash: refreshFingerprint(accessToken),
700
+ refreshTokenHash: refreshFingerprint(refreshToken2)
701
+ };
702
+ return metadata === void 0 ? legacyBrokerCredentialMetadata(accessToken, refreshToken2) : { ...metadata, ...hashes };
757
703
  }
758
- function readCredentialMigrationState(path = CREDENTIAL_MIGRATION_PATH) {
759
- const parsed = readBoundedCredentialJson(path);
760
- if (parsed === void 0) return "absent";
761
- return parsed !== null && isCredentialMigrationSentinel(parsed) ? "valid" : "invalid";
704
+ function writeCredentialMigrationSentinel() {
705
+ atomicWrite(
706
+ CREDENTIAL_MIGRATION_PATH,
707
+ `${JSON.stringify({
708
+ version: CREDENTIAL_MIGRATION_VERSION,
709
+ state: CREDENTIAL_MIGRATION_STATE
710
+ })}
711
+ `
712
+ );
762
713
  }
763
- function readStoredCredentialMetadata(metadataPath = CREDENTIAL_METADATA_PATH, familyPath = CREDENTIAL_FAMILY_PATH, migrationPath = CREDENTIAL_MIGRATION_PATH) {
764
- const family = readCredentialFamily(familyPath);
765
- if (family) return family;
766
- const parsed = readBoundedCredentialJson(metadataPath);
767
- if (parsed === void 0) {
768
- return readCredentialMigrationState(migrationPath) === "absent" ? { state: "legacy_broker" } : { state: "invalid" };
714
+ function bindLegacyBrokerGeneration(accessToken, refreshToken2, metadata) {
715
+ if (metadata.state !== "legacy_broker" || !accessToken || !refreshToken2) {
716
+ return { state: "invalid" };
769
717
  }
770
- if (parsed === null) return { state: "invalid" };
771
- try {
772
- return {
773
- state: "workos_connect",
774
- metadata: parseWorkosConnectCredentialMetadata(parsed)
775
- };
776
- } catch {
718
+ const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
719
+ if (metadata.metadata !== void 0 && (metadata.metadata.accessTokenHash !== familyMetadata.accessTokenHash || metadata.metadata.refreshTokenHash !== familyMetadata.refreshTokenHash)) {
777
720
  return { state: "invalid" };
778
721
  }
779
- }
780
- function decodeJwtPayload(token) {
781
- const parts = token.split(".");
782
- if (parts.length !== 3) return void 0;
783
- try {
784
- const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
785
- if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return void 0;
786
- return payload;
787
- } catch {
788
- return void 0;
722
+ if (metadata.metadata === void 0) {
723
+ atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
724
+ `);
789
725
  }
726
+ const migrationState = readCredentialMigrationState();
727
+ if (migrationState === "invalid") return { state: "invalid" };
728
+ if (migrationState === "absent") writeCredentialMigrationSentinel();
729
+ return { state: "legacy_broker", metadata: familyMetadata };
790
730
  }
791
- function jwtExpiresAt(token) {
792
- const exp = decodeJwtPayload(token)?.exp;
793
- return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : void 0;
731
+ function preserveMarkerlessLegacyGeneration() {
732
+ const metadata = readStoredCredentialMetadata();
733
+ if (metadata.state !== "legacy_broker" || metadata.metadata !== void 0) return;
734
+ const accessToken = readTrimmed2(TOKEN_FILE_PATH);
735
+ const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
736
+ if (!(accessToken && refreshToken2)) return;
737
+ const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
738
+ atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
739
+ `);
794
740
  }
795
-
796
- // src/lib/file-lock.ts
797
- import { randomBytes } from "crypto";
798
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync as rmSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
799
- import { dirname as dirname4, join as join5 } from "path";
800
-
801
- // src/lib/process-liveness.ts
802
- function processIsAlive(pid, probe = process.kill) {
803
- if (!Number.isSafeInteger(pid) || pid <= 0) return false;
804
- try {
805
- probe(pid, 0);
806
- return true;
807
- } catch (error) {
808
- return error.code === "EPERM";
809
- }
741
+ function terminalFingerprint() {
742
+ return readTrimmed2(TERMINAL_REFRESH_PATH);
810
743
  }
811
-
812
- // src/lib/file-lock.ts
813
- var DEFAULT_TIMEOUT_MS = 3e4;
814
- var DEFAULT_POLL_MS = 50;
815
- var DEFAULT_INIT_GRACE_MS = 2e3;
816
- var DIRECTORY_MODE = 448;
817
- var FILE_MODE = 384;
818
- function ownerPath(lockDir) {
819
- return join5(lockDir, "owner.json");
744
+ function writeTerminalFingerprint(refreshToken2) {
745
+ atomicWrite(TERMINAL_REFRESH_PATH, `${refreshFingerprint(refreshToken2)}
746
+ `);
820
747
  }
821
- function readOwner(lockDir) {
822
- try {
823
- const owner = JSON.parse(readFileSync4(ownerPath(lockDir), "utf8"));
824
- if (!Number.isInteger(owner.pid) || owner.pid <= 0 || typeof owner.nonce !== "string" || typeof owner.createdAt !== "number") {
825
- return null;
826
- }
827
- return owner;
828
- } catch {
829
- return null;
830
- }
748
+ function clearTerminalFingerprint() {
749
+ removeCredentialFile(TERMINAL_REFRESH_PATH);
831
750
  }
832
- function sameOwner(a, b) {
833
- return a?.pid === b.pid && a.nonce === b.nonce && a.createdAt === b.createdAt;
751
+ function isSessionEnded() {
752
+ if (resolveAuthCredential()?.source !== "token_file") return false;
753
+ const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
754
+ const ended = terminalFingerprint();
755
+ return Boolean(refreshToken2 && ended && refreshFingerprint(refreshToken2) === ended);
834
756
  }
835
- function tryTakeLock(lockDir, now) {
836
- try {
837
- mkdirSync2(lockDir, { mode: DIRECTORY_MODE });
838
- } catch (error) {
839
- if (error.code === "EEXIST") return null;
840
- throw error;
757
+ function withCredentialLock(operation, options = {}) {
758
+ return withFileLock(CREDENTIAL_LOCK_PATH, operation, options);
759
+ }
760
+ function commitCredentialsUnlocked(credentials) {
761
+ const accessToken = credentials.accessToken.trim();
762
+ const refreshToken2 = credentials.refreshToken.trim();
763
+ if (!accessToken || !refreshToken2) {
764
+ throw new Error("OAuth credentials require both access and refresh tokens");
841
765
  }
842
- const owner = {
843
- pid: process.pid,
844
- nonce: randomBytes(16).toString("hex"),
845
- createdAt: now
846
- };
847
- try {
848
- writeFileSync2(ownerPath(lockDir), `${JSON.stringify(owner)}
849
- `, {
850
- encoding: "utf8",
851
- mode: FILE_MODE,
852
- flag: "wx"
853
- });
854
- return owner;
855
- } catch (error) {
856
- rmSync2(lockDir, { recursive: true, force: true });
857
- throw error;
766
+ const familyMetadata = credentialFamilyMetadata(accessToken, refreshToken2, credentials.metadata);
767
+ if (credentials.metadata !== void 0) {
768
+ preserveMarkerlessLegacyGeneration();
769
+ writeCredentialMigrationSentinel();
770
+ atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
771
+ `);
772
+ atomicWrite(CREDENTIAL_METADATA_PATH, `${JSON.stringify(familyMetadata)}
773
+ `);
774
+ atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
775
+ `);
776
+ } else {
777
+ atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
778
+ `);
779
+ atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
780
+ `);
781
+ removeCredentialFile(CREDENTIAL_METADATA_PATH);
858
782
  }
783
+ const expiresAt = expiresAtFor(accessToken, credentials.expiresIn);
784
+ if (expiresAt === void 0) removeCredentialFile(TOKEN_EXPIRES_PATH);
785
+ else atomicWrite(TOKEN_EXPIRES_PATH, `${expiresAt}
786
+ `);
787
+ atomicWrite(TOKEN_FILE_PATH, `${accessToken}
788
+ `);
789
+ clearTerminalFingerprint();
790
+ _cachedCredential = { token: accessToken, source: "token_file" };
859
791
  }
860
- function recoverStaleLock(lockDir, now, alive, initGraceMs) {
861
- const owner = readOwner(lockDir);
862
- if (owner) {
863
- if (alive(owner.pid)) return false;
864
- if (!sameOwner(readOwner(lockDir), owner)) return false;
865
- rmSync2(lockDir, { recursive: true, force: true });
866
- return true;
867
- }
792
+ function isTerminalRefreshResponse(response, detail) {
793
+ if (detail.includes("invalid_grant") || detail.includes("Session has already ended")) return true;
868
794
  try {
869
- const before = statSync(lockDir).mtimeMs;
870
- if (now - before < initGraceMs) return false;
871
- if (readOwner(lockDir)) return false;
872
- if (statSync(lockDir).mtimeMs !== before) return false;
873
- rmSync2(lockDir, { recursive: true, force: true });
874
- return true;
795
+ const error = JSON.parse(detail).error;
796
+ return error === "invalid_grant" || response.status === 401 && error === "Invalid or expired refresh token";
875
797
  } catch {
876
- return true;
798
+ return response.status === 401 && detail.includes("Invalid or expired refresh token");
877
799
  }
878
800
  }
879
- function abortError(signal) {
880
- if (signal.reason instanceof Error) return signal.reason;
881
- const error = new Error("The operation was aborted");
882
- error.name = "AbortError";
883
- return error;
801
+ function workosConnectRefreshErrorCode(value) {
802
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return "";
803
+ return value.error === "invalid_grant" ? "invalid_grant" : "";
884
804
  }
885
- function throwIfAborted(signal) {
886
- if (signal?.aborted) throw abortError(signal);
805
+ function refreshDiagnostic(response, detail, quiet, provider) {
806
+ if (quiet) return;
807
+ const statusText = terminalSafeLine(response.statusText).slice(0, 120);
808
+ const safeDetail = terminalSafeLine(detail).slice(0, 200);
809
+ process.stderr.write(
810
+ `[prim] token refresh rejected by ${provider}: ${response.status}${statusText ? ` ${statusText}` : ""}${safeDetail ? ` \u2014 ${safeDetail}` : ""}
811
+ `
812
+ );
887
813
  }
888
- async function defaultSleep(ms, signal) {
889
- if (!signal) {
890
- await new Promise((resolve5) => setTimeout(resolve5, ms));
891
- return;
814
+ function metadataMatchesCredentialGeneration(expected, accessToken, refreshToken2) {
815
+ const current = readStoredCredentialMetadata();
816
+ if (expected.state === "legacy_broker") {
817
+ if (current.state !== "legacy_broker") return false;
818
+ if (!expected.metadata) return current.metadata === void 0;
819
+ return current.metadata !== void 0 && current.metadata.accessTokenHash === refreshFingerprint(accessToken) && current.metadata.accessTokenHash === expected.metadata.accessTokenHash && current.metadata.refreshTokenHash === refreshFingerprint(refreshToken2) && current.metadata.refreshTokenHash === expected.metadata.refreshTokenHash;
892
820
  }
893
- throwIfAborted(signal);
894
- await new Promise((resolve5, reject) => {
895
- const timer = setTimeout(() => {
896
- signal.removeEventListener("abort", onAbort);
897
- resolve5();
898
- }, ms);
899
- const onAbort = () => {
900
- clearTimeout(timer);
901
- reject(abortError(signal));
902
- };
903
- signal.addEventListener("abort", onAbort, { once: true });
904
- });
821
+ if (expected.state !== "workos_connect" || current.state !== "workos_connect") return false;
822
+ return current.metadata.issuer === expected.metadata.issuer && current.metadata.clientId === expected.metadata.clientId && current.metadata.accessTokenHash === refreshFingerprint(accessToken) && current.metadata.accessTokenHash === expected.metadata.accessTokenHash && current.metadata.refreshTokenHash === refreshFingerprint(refreshToken2) && current.metadata.refreshTokenHash === expected.metadata.refreshTokenHash;
905
823
  }
906
- var syncSleeper = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
907
- async function withFileLock(lockDir, operation, options = {}) {
908
- mkdirSync2(dirname4(lockDir), { recursive: true, mode: DIRECTORY_MODE });
909
- const nowMs = options.nowMs ?? Date.now;
910
- const alive = options.processAlive ?? processIsAlive;
911
- const deadline = nowMs() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
912
- let owner = null;
913
- while (!owner) {
914
- throwIfAborted(options.signal);
915
- const now = nowMs();
916
- owner = tryTakeLock(lockDir, now);
917
- if (owner) break;
918
- recoverStaleLock(lockDir, now, alive, options.initGraceMs ?? DEFAULT_INIT_GRACE_MS);
919
- if (now >= deadline) {
920
- throw new Error(`timed out waiting for file lock ${lockDir}`);
921
- }
922
- if (options.sleep) {
923
- await options.sleep(options.pollMs ?? DEFAULT_POLL_MS);
924
- throwIfAborted(options.signal);
925
- } else {
926
- await defaultSleep(options.pollMs ?? DEFAULT_POLL_MS, options.signal);
927
- }
928
- }
929
- try {
930
- throwIfAborted(options.signal);
931
- return await operation();
932
- } finally {
933
- if (sameOwner(readOwner(lockDir), owner)) {
934
- rmSync2(lockDir, { recursive: true, force: true });
935
- }
824
+ function uncoordinatedLegacyWinnerAccessToken(expected, currentGeneration) {
825
+ if (!expected || readCredentialMigrationState() !== "valid") return void 0;
826
+ const stored = readStoredCredentialMetadata();
827
+ if (stored.state !== "legacy_broker" || stored.metadata === void 0 || stored.metadata.accessTokenHash !== expected.accessTokenHash || stored.metadata.refreshTokenHash !== expected.refreshTokenHash) {
828
+ return void 0;
936
829
  }
830
+ const replacementRefreshToken = readTrimmed2(REFRESH_TOKEN_PATH);
831
+ if (!replacementRefreshToken || replacementRefreshToken === currentGeneration) return void 0;
832
+ return readTrimmed2(TOKEN_FILE_PATH);
937
833
  }
938
-
939
- // src/lib/terminal-safe.ts
940
- function replaceIsolatedSurrogates(value) {
941
- let out = "";
942
- for (let index = 0; index < value.length; index += 1) {
943
- const unit = value.charCodeAt(index);
944
- if (unit >= 55296 && unit <= 56319) {
945
- const next = value.charCodeAt(index + 1);
946
- if (next >= 56320 && next <= 57343) {
947
- out += value[index] + value[index + 1];
948
- index += 1;
834
+ function winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration) {
835
+ if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) return void 0;
836
+ const winner = resolveAuthCredential();
837
+ return (winner?.source === "token_file" ? winner.token : void 0) ?? uncoordinatedLegacyWinnerAccessToken(expectedLegacyGeneration, currentGeneration);
838
+ }
839
+ async function performTokenRefresh(options = {}) {
840
+ const selected = resolveAuthCredential();
841
+ if (selected?.source !== "token_file") return void 0;
842
+ const startingGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
843
+ if (!startingGeneration || isSessionEnded()) return void 0;
844
+ const startingAccessToken = selected.token;
845
+ return withCredentialLock(
846
+ async () => {
847
+ const currentCredential = resolveAuthCredential();
848
+ if (currentCredential?.source !== "token_file") return void 0;
849
+ const currentGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
850
+ if (!currentGeneration) return void 0;
851
+ if (currentGeneration !== startingGeneration) {
852
+ return currentCredential.token;
853
+ }
854
+ if (currentCredential.token !== startingAccessToken) {
855
+ return currentCredential.token;
856
+ }
857
+ if (isSessionEnded()) return void 0;
858
+ let metadata = readStoredCredentialMetadata();
859
+ const markerlessLegacyAtStart = metadata.state === "legacy_broker" && metadata.metadata === void 0;
860
+ if (metadata.state === "invalid" || metadata.state === "workos_connect" && (metadata.metadata.accessTokenHash !== refreshFingerprint(currentCredential.token) || metadata.metadata.refreshTokenHash !== refreshFingerprint(currentGeneration))) {
861
+ return void 0;
862
+ }
863
+ if (metadata.state === "legacy_broker") {
864
+ try {
865
+ metadata = bindLegacyBrokerGeneration(
866
+ currentCredential.token,
867
+ currentGeneration,
868
+ metadata
869
+ );
870
+ } catch {
871
+ return void 0;
872
+ }
873
+ if (metadata.state !== "legacy_broker") return void 0;
874
+ }
875
+ const expectedLegacyGeneration = markerlessLegacyAtStart && metadata.state === "legacy_broker" ? metadata.metadata : void 0;
876
+ const connectContext = metadata.state === "workos_connect" ? {
877
+ version: 1,
878
+ family: "workos_connect",
879
+ issuer: metadata.metadata.issuer,
880
+ clientId: metadata.metadata.clientId
881
+ } : void 0;
882
+ const response = await fetch(
883
+ connectContext ? workosConnectTokenEndpoint(connectContext.issuer) : `${getSiteUrl()}/mcp/broker/refresh`,
884
+ connectContext ? {
885
+ method: "POST",
886
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
887
+ body: new URLSearchParams({
888
+ grant_type: "refresh_token",
889
+ refresh_token: currentGeneration,
890
+ client_id: connectContext.clientId
891
+ }),
892
+ signal: options.signal
893
+ } : {
894
+ method: "POST",
895
+ headers: { "Content-Type": "application/json" },
896
+ body: JSON.stringify({ refresh_token: currentGeneration }),
897
+ signal: options.signal
898
+ }
899
+ );
900
+ let directResponse;
901
+ if (connectContext) {
902
+ try {
903
+ directResponse = await readBoundedJson(response, WORKOS_CONNECT_RESPONSE_MAX_BYTES);
904
+ } catch {
905
+ if (response.ok && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
906
+ metadata,
907
+ currentCredential.token,
908
+ currentGeneration
909
+ )) {
910
+ writeTerminalFingerprint(currentGeneration);
911
+ }
912
+ return void 0;
913
+ }
914
+ }
915
+ if (!response.ok) {
916
+ let detail = "";
917
+ if (connectContext) {
918
+ detail = workosConnectRefreshErrorCode(directResponse);
919
+ } else {
920
+ detail = (await response.text().catch(() => "")).slice(0, 200);
921
+ }
922
+ if (isTerminalRefreshResponse(response, detail) && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
923
+ writeTerminalFingerprint(currentGeneration);
924
+ }
925
+ refreshDiagnostic(
926
+ response,
927
+ detail,
928
+ options.quiet,
929
+ connectContext ? "WorkOS Connect" : "broker"
930
+ );
931
+ return winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
932
+ }
933
+ let accessToken;
934
+ let replacementRefreshToken;
935
+ let expiresIn;
936
+ if (connectContext) {
937
+ try {
938
+ const tokens = parseWorkosConnectTokens(directResponse, {
939
+ fallbackRefreshToken: currentGeneration
940
+ });
941
+ accessToken = tokens.accessToken;
942
+ replacementRefreshToken = tokens.refreshToken;
943
+ expiresIn = tokens.expiresIn;
944
+ } catch {
945
+ if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
946
+ metadata,
947
+ currentCredential.token,
948
+ currentGeneration
949
+ )) {
950
+ writeTerminalFingerprint(currentGeneration);
951
+ }
952
+ return void 0;
953
+ }
949
954
  } else {
950
- out += "\uFFFD";
955
+ let data;
956
+ try {
957
+ data = await response.json();
958
+ } catch {
959
+ if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
960
+ writeTerminalFingerprint(currentGeneration);
961
+ }
962
+ return void 0;
963
+ }
964
+ const record = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
965
+ accessToken = typeof record?.access_token === "string" ? record.access_token.trim() : "";
966
+ replacementRefreshToken = typeof record?.refresh_token === "string" ? record.refresh_token.trim() : "";
967
+ expiresIn = typeof record?.expires_in === "number" && Number.isFinite(record.expires_in) ? record.expires_in : void 0;
968
+ if (!(accessToken && replacementRefreshToken)) {
969
+ if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
970
+ writeTerminalFingerprint(currentGeneration);
971
+ }
972
+ return void 0;
973
+ }
951
974
  }
952
- } else if (unit >= 56320 && unit <= 57343) {
953
- out += "\uFFFD";
954
- } else {
955
- out += value[index];
956
- }
975
+ const latestCredential = resolveAuthCredential();
976
+ if (readTrimmed2(REFRESH_TOKEN_PATH) !== currentGeneration || latestCredential?.source !== "token_file" || latestCredential.token !== currentCredential.token || !metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
977
+ return latestCredential?.source === "token_file" ? latestCredential.token : winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
978
+ }
979
+ commitCredentialsUnlocked({
980
+ accessToken,
981
+ refreshToken: replacementRefreshToken,
982
+ expiresIn,
983
+ metadata: connectContext
984
+ });
985
+ return accessToken;
986
+ },
987
+ { signal: options.signal }
988
+ );
989
+ }
990
+ var _refreshInFlight;
991
+ function refreshToken(options = {}) {
992
+ if (_refreshInFlight) return _refreshInFlight;
993
+ const attempt = performTokenRefresh(options).then((token) => {
994
+ if (token) _cachedCredential = { token, source: "token_file" };
995
+ return token;
996
+ }).finally(() => {
997
+ if (_refreshInFlight === attempt) _refreshInFlight = void 0;
998
+ });
999
+ _refreshInFlight = attempt;
1000
+ return attempt;
1001
+ }
1002
+ var HttpError = class extends Error {
1003
+ status;
1004
+ body;
1005
+ constructor(status, message, body) {
1006
+ super(message);
1007
+ this.name = "HttpError";
1008
+ this.status = status;
1009
+ this.body = body;
957
1010
  }
958
- return out;
1011
+ };
1012
+ var CLI_MANAGEMENT_RESPONSE_MAX_BYTES = 2 * 1024 * 1024;
1013
+ var _cachedCredential;
1014
+ function selectedCredential() {
1015
+ const resolved = resolveAuthCredential();
1016
+ if (!_cachedCredential || resolved?.token !== _cachedCredential.token || resolved?.source !== _cachedCredential.source) {
1017
+ _cachedCredential = resolved;
1018
+ }
1019
+ return _cachedCredential;
959
1020
  }
960
- function isUnsafeTerminalCodePoint(point) {
961
- const c0OrC1 = point <= 31 || point >= 127 && point <= 159;
962
- const bidiOrZeroWidth = point === 173 || // soft hyphen
963
- point === 1564 || // Arabic letter mark
964
- point === 6158 || // Mongolian vowel separator
965
- point >= 8203 && point <= 8207 || // zero-width + directional marks
966
- point >= 8234 && point <= 8238 || // bidi embeddings/overrides
967
- point >= 8288 && point <= 8303 || // word joiner + bidi isolates/controls
968
- point >= 65529 && point <= 65531 || // interlinear annotation controls
969
- point === 65279 || // zero-width no-break space / BOM
970
- point >= 917504 && point <= 917631;
971
- return c0OrC1 || bidiOrZeroWidth;
1021
+ function fetchWithToken(method, path, body, options, token, siteUrl) {
1022
+ return fetch(`${siteUrl}${path}`, {
1023
+ method,
1024
+ headers: {
1025
+ Authorization: `Bearer ${token}`,
1026
+ "Content-Type": "application/json"
1027
+ },
1028
+ body: body === void 0 ? void 0 : JSON.stringify(body),
1029
+ signal: options?.signal
1030
+ });
972
1031
  }
973
- function terminalSafeText(value) {
974
- return Array.from(replaceIsolatedSurrogates(value)).filter((character) => !isUnsafeTerminalCodePoint(character.codePointAt(0) ?? 0)).join("");
1032
+ async function responseValue(response) {
1033
+ if (!response.ok) {
1034
+ if (response.status === 401) {
1035
+ throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1036
+ }
1037
+ const errorBody = await response.json().catch(() => null);
1038
+ const errorRecord = typeof errorBody === "object" && errorBody !== null && !Array.isArray(errorBody) ? errorBody : void 0;
1039
+ const message = typeof errorRecord?.error === "string" ? errorRecord.error : `HTTP ${response.status}`;
1040
+ throw new HttpError(response.status, message, errorBody);
1041
+ }
1042
+ return response.json();
975
1043
  }
976
- function terminalSafeLine(value) {
977
- return terminalSafeText(value.replace(/\s+/gu, " ")).replace(/\s+/gu, " ").trim();
1044
+ async function request(method, path, body, options) {
1045
+ const siteUrl = getSiteUrl();
1046
+ let credential = selectedCredential();
1047
+ let refreshAttempted = false;
1048
+ if (credential && isTokenExpiringSoon(credential)) {
1049
+ refreshAttempted = true;
1050
+ const token = await refreshToken({
1051
+ signal: options?.signal,
1052
+ quiet: options?.quietRefresh
1053
+ });
1054
+ if (token) credential = { token, source: "token_file" };
1055
+ }
1056
+ if (!credential) {
1057
+ throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1058
+ }
1059
+ if (isTokenExpiringSoon(credential) && isSessionEnded()) {
1060
+ throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1061
+ }
1062
+ const tokenUsed = credential.token;
1063
+ let response = await fetchWithToken(method, path, body, options, tokenUsed, siteUrl);
1064
+ if (response.status === 401) {
1065
+ const latest = resolveAuthCredential();
1066
+ let retryToken = latest?.token !== tokenUsed ? latest?.token : void 0;
1067
+ if (!retryToken && latest?.source === "token_file" && !refreshAttempted) {
1068
+ refreshAttempted = true;
1069
+ retryToken = await refreshToken({ signal: options?.signal, quiet: options?.quietRefresh });
1070
+ }
1071
+ if (retryToken) {
1072
+ _cachedCredential = {
1073
+ token: retryToken,
1074
+ source: latest?.source === "token_file" ? "token_file" : latest?.source ?? "token_file"
1075
+ };
1076
+ response = await fetchWithToken(method, path, body, options, retryToken, siteUrl);
1077
+ }
1078
+ }
1079
+ return responseValue(response);
1080
+ }
1081
+ function getClient() {
1082
+ return {
1083
+ get: (path, options) => request("GET", path, void 0, options),
1084
+ post: (path, body, options) => request("POST", path, body, options)
1085
+ };
978
1086
  }
979
- var stripControlChars = terminalSafeText;
980
1087
 
981
- // src/client.ts
982
- var CONFIG_DIR_MODE = 448;
983
- var CREDENTIAL_FILE_MODE = 384;
984
- var REFRESH_THRESHOLD_MS = 6e4;
985
- var DEFAULT_API_URL = "https://api.getprimitive.ai";
986
- var AUTH_EXPIRED_MESSAGE = "Authentication expired. Run `prim auth login` to re-authenticate.";
987
- function readTrimmed2(path) {
1088
+ // src/lib/activation.ts
1089
+ import { execFileSync as execFileSync2 } from "child_process";
1090
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
1091
+ import { homedir as homedir2 } from "os";
1092
+ import { join as join5 } from "path";
1093
+
1094
+ // src/lib/git.ts
1095
+ import { execFileSync } from "child_process";
1096
+ import { createHash as createHash3 } from "crypto";
1097
+ import { lstatSync, realpathSync } from "fs";
1098
+ import { basename, dirname as dirname4, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
1099
+ var GIT_TIMEOUT_MS = 1e3;
1100
+ var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
1101
+ var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
1102
+ function gitToplevel(cwd) {
1103
+ try {
1104
+ return execFileSync("git", ["rev-parse", "--show-toplevel"], {
1105
+ cwd,
1106
+ encoding: "utf-8",
1107
+ stdio: ["ignore", "pipe", "ignore"],
1108
+ timeout: GIT_TIMEOUT_MS
1109
+ }).trim();
1110
+ } catch {
1111
+ return null;
1112
+ }
1113
+ }
1114
+ function gitValue(cwd, args) {
988
1115
  try {
989
- const value = readFileSync5(path, "utf8").trim();
1116
+ const value = execFileSync("git", args, {
1117
+ cwd,
1118
+ encoding: "utf-8",
1119
+ stdio: ["ignore", "pipe", "ignore"],
1120
+ timeout: GIT_TIMEOUT_MS
1121
+ }).trim();
990
1122
  return value || void 0;
991
1123
  } catch {
992
1124
  return void 0;
993
1125
  }
994
1126
  }
995
- function getSiteUrl() {
996
- return getSiteUrlForEnvironment(process.env.PRIM_API_URL);
997
- }
998
- function getSiteUrlForEnvironment(primApiUrl) {
999
- return primApiUrl?.trim() || DEFAULT_API_URL;
1000
- }
1001
- function expiresAtFor(token, expiresIn) {
1002
- return expiresIn === void 0 ? jwtExpiresAt(token) : Date.now() + expiresIn * 1e3;
1003
- }
1004
- function ensureConfigDirectory() {
1005
- const directory = dirname5(TOKEN_FILE_PATH);
1006
- mkdirSync3(directory, { recursive: true, mode: CONFIG_DIR_MODE });
1007
- chmodSync(directory, CONFIG_DIR_MODE);
1008
- }
1009
- function atomicWrite(path, content) {
1010
- ensureConfigDirectory();
1011
- atomicWriteFile(path, content, { mode: CREDENTIAL_FILE_MODE });
1012
- }
1013
- function removeCredentialFile(path) {
1014
- if (!existsSync4(path)) return false;
1015
- rmSync3(path, { force: true });
1016
- return true;
1017
- }
1018
- function getTokenExpiresAt() {
1019
- const stored = readTrimmed2(TOKEN_EXPIRES_PATH);
1020
- if (stored === void 0) return void 0;
1021
- const value = Number(stored);
1022
- return Number.isNaN(value) ? void 0 : value;
1023
- }
1024
- function isTokenExpiringSoon(credential) {
1025
- if (credential.source !== "token_file") return false;
1026
- const expiresAt = getTokenExpiresAt();
1027
- return expiresAt !== void 0 && Date.now() >= expiresAt - REFRESH_THRESHOLD_MS;
1028
- }
1029
- function refreshFingerprint(refreshToken2) {
1030
- return createHash3("sha256").update(refreshToken2).digest("hex");
1031
- }
1032
- function legacyBrokerCredentialMetadata(accessToken, refreshToken2) {
1033
- return {
1034
- version: 1,
1035
- family: "legacy_broker",
1036
- accessTokenHash: refreshFingerprint(accessToken),
1037
- refreshTokenHash: refreshFingerprint(refreshToken2)
1038
- };
1039
- }
1040
- function credentialFamilyMetadata(accessToken, refreshToken2, metadata) {
1041
- const hashes = {
1042
- accessTokenHash: refreshFingerprint(accessToken),
1043
- refreshTokenHash: refreshFingerprint(refreshToken2)
1044
- };
1045
- return metadata === void 0 ? legacyBrokerCredentialMetadata(accessToken, refreshToken2) : { ...metadata, ...hashes };
1127
+ function currentBranch(cwd) {
1128
+ return gitValue(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
1046
1129
  }
1047
- function writeCredentialMigrationSentinel() {
1048
- atomicWrite(
1049
- CREDENTIAL_MIGRATION_PATH,
1050
- `${JSON.stringify({
1051
- version: CREDENTIAL_MIGRATION_VERSION,
1052
- state: CREDENTIAL_MIGRATION_STATE
1053
- })}
1054
- `
1130
+ function githubRepositoryFullName(cwd) {
1131
+ const remote = gitValue(cwd, ["config", "--get", "remote.origin.url"]);
1132
+ if (!remote || [...remote].some((char) => char < " " || char === "\x7F")) return null;
1133
+ const match = /^(?:git@github\.com:([^?#]+)|(?:https|ssh):\/\/(?:[^/@]+@)?github\.com(?::\d+)?\/([^?#]+))$/i.exec(
1134
+ remote
1055
1135
  );
1136
+ const path = match?.[1] ?? match?.[2];
1137
+ if (!path) return null;
1138
+ const parts = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "").split("/");
1139
+ if (parts.length !== 2 || !GITHUB_OWNER_PATTERN.test(parts[0] ?? "") || !GITHUB_REPOSITORY_PATTERN.test(parts[1] ?? "")) {
1140
+ return null;
1141
+ }
1142
+ return `${parts[0]}/${parts[1]}`;
1056
1143
  }
1057
- function bindLegacyBrokerGeneration(accessToken, refreshToken2, metadata) {
1058
- if (metadata.state !== "legacy_broker" || !accessToken || !refreshToken2) {
1059
- return { state: "invalid" };
1144
+ function canonicalGitRoot(cwd) {
1145
+ try {
1146
+ const top = gitToplevel(cwd);
1147
+ return top ? realpathSync.native(top) : null;
1148
+ } catch {
1149
+ return null;
1060
1150
  }
1061
- const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
1062
- if (metadata.metadata !== void 0 && (metadata.metadata.accessTokenHash !== familyMetadata.accessTokenHash || metadata.metadata.refreshTokenHash !== familyMetadata.refreshTokenHash)) {
1063
- return { state: "invalid" };
1151
+ }
1152
+ function normalizeOriginRemote(remote) {
1153
+ const value = remote.trim();
1154
+ if (!value) return void 0;
1155
+ const scp = !value.includes("://") ? /^(?:[^@/\s]+@)?(?<host>[^:/\s]+):(?<path>.+)$/.exec(value)?.groups : void 0;
1156
+ if (scp?.host && scp.path) {
1157
+ const path = scp.path.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
1158
+ return path ? `${scp.host.toLowerCase()}/${path}` : void 0;
1064
1159
  }
1065
- if (metadata.metadata === void 0) {
1066
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1067
- `);
1160
+ try {
1161
+ const url = new URL(value);
1162
+ url.username = "";
1163
+ url.password = "";
1164
+ url.search = "";
1165
+ url.hash = "";
1166
+ const path = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
1167
+ if (url.host && path) return `${url.host.toLowerCase()}/${path}`;
1168
+ return void 0;
1169
+ } catch {
1170
+ return void 0;
1068
1171
  }
1069
- const migrationState = readCredentialMigrationState();
1070
- if (migrationState === "invalid") return { state: "invalid" };
1071
- if (migrationState === "absent") writeCredentialMigrationSentinel();
1072
- return { state: "legacy_broker", metadata: familyMetadata };
1073
- }
1074
- function preserveMarkerlessLegacyGeneration() {
1075
- const metadata = readStoredCredentialMetadata();
1076
- if (metadata.state !== "legacy_broker" || metadata.metadata !== void 0) return;
1077
- const accessToken = readTrimmed2(TOKEN_FILE_PATH);
1078
- const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
1079
- if (!(accessToken && refreshToken2)) return;
1080
- const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
1081
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1082
- `);
1083
- }
1084
- function terminalFingerprint() {
1085
- return readTrimmed2(TERMINAL_REFRESH_PATH);
1086
- }
1087
- function writeTerminalFingerprint(refreshToken2) {
1088
- atomicWrite(TERMINAL_REFRESH_PATH, `${refreshFingerprint(refreshToken2)}
1089
- `);
1090
- }
1091
- function clearTerminalFingerprint() {
1092
- removeCredentialFile(TERMINAL_REFRESH_PATH);
1093
- }
1094
- function isSessionEnded() {
1095
- if (resolveAuthCredential()?.source !== "token_file") return false;
1096
- const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
1097
- const ended = terminalFingerprint();
1098
- return Boolean(refreshToken2 && ended && refreshFingerprint(refreshToken2) === ended);
1099
1172
  }
1100
- function withCredentialLock(operation, options = {}) {
1101
- return withFileLock(CREDENTIAL_LOCK_PATH, operation, options);
1173
+ function opaqueRepoKey(source, value) {
1174
+ return `repo_v1_${createHash3("sha256").update(`${source}\0${value}`).digest("hex")}`;
1102
1175
  }
1103
- function commitCredentialsUnlocked(credentials) {
1104
- const accessToken = credentials.accessToken.trim();
1105
- const refreshToken2 = credentials.refreshToken.trim();
1106
- if (!accessToken || !refreshToken2) {
1107
- throw new Error("OAuth credentials require both access and refresh tokens");
1176
+ function resolveRepositoryContext(cwd = process.cwd()) {
1177
+ const top = gitToplevel(cwd);
1178
+ if (!top) return null;
1179
+ let repoRoot;
1180
+ try {
1181
+ repoRoot = realpathSync.native(top);
1182
+ } catch {
1183
+ repoRoot = resolve2(top);
1108
1184
  }
1109
- const familyMetadata = credentialFamilyMetadata(accessToken, refreshToken2, credentials.metadata);
1110
- if (credentials.metadata !== void 0) {
1111
- preserveMarkerlessLegacyGeneration();
1112
- writeCredentialMigrationSentinel();
1113
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1114
- `);
1115
- atomicWrite(CREDENTIAL_METADATA_PATH, `${JSON.stringify(familyMetadata)}
1116
- `);
1117
- atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
1118
- `);
1119
- } else {
1120
- atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
1121
- `);
1122
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1123
- `);
1124
- removeCredentialFile(CREDENTIAL_METADATA_PATH);
1185
+ const origin = gitValue(repoRoot, ["config", "--get", "remote.origin.url"]);
1186
+ const repoFullName = githubRepositoryFullName(repoRoot) ?? void 0;
1187
+ const normalizedOrigin = origin ? normalizeOriginRemote(origin) : void 0;
1188
+ if (normalizedOrigin) {
1189
+ return {
1190
+ repoRoot,
1191
+ repoKey: opaqueRepoKey("origin", normalizedOrigin),
1192
+ identitySource: "origin",
1193
+ repoFullName
1194
+ };
1125
1195
  }
1126
- const expiresAt = expiresAtFor(accessToken, credentials.expiresIn);
1127
- if (expiresAt === void 0) removeCredentialFile(TOKEN_EXPIRES_PATH);
1128
- else atomicWrite(TOKEN_EXPIRES_PATH, `${expiresAt}
1129
- `);
1130
- atomicWrite(TOKEN_FILE_PATH, `${accessToken}
1131
- `);
1132
- clearTerminalFingerprint();
1133
- _cachedCredential = { token: accessToken, source: "token_file" };
1196
+ const roots = gitValue(repoRoot, ["rev-list", "--max-parents=0", "HEAD"])?.split(/\s+/).filter(Boolean).sort();
1197
+ if (roots && roots.length > 0) {
1198
+ return {
1199
+ repoRoot,
1200
+ repoKey: opaqueRepoKey("root_commit", roots.join("\n")),
1201
+ identitySource: "root_commit",
1202
+ repoFullName
1203
+ };
1204
+ }
1205
+ return { repoRoot, repoFullName };
1134
1206
  }
1135
- function isTerminalRefreshResponse(response, detail) {
1136
- if (detail.includes("invalid_grant") || detail.includes("Session has already ended")) return true;
1207
+ function nearestExistingAncestor(path) {
1208
+ const suffix = [];
1209
+ let cursor = path;
1210
+ while (true) {
1211
+ try {
1212
+ lstatSync(cursor);
1213
+ break;
1214
+ } catch (error) {
1215
+ const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
1216
+ if (code !== "ENOENT" && code !== "ENOTDIR") return null;
1217
+ const parent = dirname4(cursor);
1218
+ if (parent === cursor) return null;
1219
+ suffix.unshift(cursor.slice(parent.length + (parent.endsWith(sep) ? 0 : 1)));
1220
+ cursor = parent;
1221
+ }
1222
+ }
1137
1223
  try {
1138
- const error = JSON.parse(detail).error;
1139
- return error === "invalid_grant" || response.status === 401 && error === "Invalid or expired refresh token";
1224
+ return { real: realpathSync.native(cursor), suffix };
1140
1225
  } catch {
1141
- return response.status === 401 && detail.includes("Invalid or expired refresh token");
1226
+ return null;
1142
1227
  }
1143
1228
  }
1144
- function workosConnectRefreshErrorCode(value) {
1145
- if (value === null || typeof value !== "object" || Array.isArray(value)) return "";
1146
- return value.error === "invalid_grant" ? "invalid_grant" : "";
1147
- }
1148
- function refreshDiagnostic(response, detail, quiet, provider) {
1149
- if (quiet) return;
1150
- const statusText = terminalSafeLine(response.statusText).slice(0, 120);
1151
- const safeDetail = terminalSafeLine(detail).slice(0, 200);
1152
- process.stderr.write(
1153
- `[prim] token refresh rejected by ${provider}: ${response.status}${statusText ? ` ${statusText}` : ""}${safeDetail ? ` \u2014 ${safeDetail}` : ""}
1154
- `
1155
- );
1156
- }
1157
- function metadataMatchesCredentialGeneration(expected, accessToken, refreshToken2) {
1158
- const current = readStoredCredentialMetadata();
1159
- if (expected.state === "legacy_broker") {
1160
- if (current.state !== "legacy_broker") return false;
1161
- if (!expected.metadata) return current.metadata === void 0;
1162
- return current.metadata !== void 0 && current.metadata.accessTokenHash === refreshFingerprint(accessToken) && current.metadata.accessTokenHash === expected.metadata.accessTokenHash && current.metadata.refreshTokenHash === refreshFingerprint(refreshToken2) && current.metadata.refreshTokenHash === expected.metadata.refreshTokenHash;
1229
+ function canonicalRepositoryPathScoped(filePath, context, baseDir) {
1230
+ if (!filePath || filePath !== filePath.trim() || filePath.includes("\0")) {
1231
+ return { ok: false, reason: "invalid_path" };
1163
1232
  }
1164
- if (expected.state !== "workos_connect" || current.state !== "workos_connect") return false;
1165
- return current.metadata.issuer === expected.metadata.issuer && current.metadata.clientId === expected.metadata.clientId && current.metadata.accessTokenHash === refreshFingerprint(accessToken) && current.metadata.accessTokenHash === expected.metadata.accessTokenHash && current.metadata.refreshTokenHash === refreshFingerprint(refreshToken2) && current.metadata.refreshTokenHash === expected.metadata.refreshTokenHash;
1166
- }
1167
- function uncoordinatedLegacyWinnerAccessToken(expected, currentGeneration) {
1168
- if (!expected || readCredentialMigrationState() !== "valid") return void 0;
1169
- const stored = readStoredCredentialMetadata();
1170
- if (stored.state !== "legacy_broker" || stored.metadata === void 0 || stored.metadata.accessTokenHash !== expected.accessTokenHash || stored.metadata.refreshTokenHash !== expected.refreshTokenHash) {
1171
- return void 0;
1233
+ const absolute = resolve2(baseDir, filePath);
1234
+ const resolved = nearestExistingAncestor(absolute);
1235
+ if (!resolved) return { ok: false, reason: "invalid_path" };
1236
+ const target = resolve2(resolved.real, ...resolved.suffix);
1237
+ const rel = relative(context.repoRoot, target);
1238
+ if (!rel || rel === ".") return { ok: false, reason: "invalid_path" };
1239
+ if (isAbsolute2(rel) || rel === ".." || rel.startsWith(`..${sep}`)) {
1240
+ return { ok: false, reason: "outside_repository" };
1172
1241
  }
1173
- const replacementRefreshToken = readTrimmed2(REFRESH_TOKEN_PATH);
1174
- if (!replacementRefreshToken || replacementRefreshToken === currentGeneration) return void 0;
1175
- return readTrimmed2(TOKEN_FILE_PATH);
1242
+ return { ok: true, file: sep === "/" ? rel : rel.split(sep).join("/") };
1176
1243
  }
1177
- function winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration) {
1178
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) return void 0;
1179
- const winner = resolveAuthCredential();
1180
- return (winner?.source === "token_file" ? winner.token : void 0) ?? uncoordinatedLegacyWinnerAccessToken(expectedLegacyGeneration, currentGeneration);
1244
+ function canonicalRepositoryPathLegacy(filePath, cwd, repositoryRoot = canonicalGitRoot(cwd)) {
1245
+ if (!repositoryRoot || !filePath || [...filePath].some((char) => char < " " || char === "\x7F" || "~*?[]{}$`\\".includes(char)))
1246
+ return null;
1247
+ const absolute = resolve2(cwd, filePath);
1248
+ let target;
1249
+ try {
1250
+ const stat = lstatSync(absolute);
1251
+ if (!stat.isFile() || stat.isSymbolicLink()) return null;
1252
+ target = realpathSync.native(absolute);
1253
+ } catch (error) {
1254
+ if (!(error instanceof Error) || error.code !== "ENOENT") {
1255
+ return null;
1256
+ }
1257
+ try {
1258
+ const parent = realpathSync.native(dirname4(absolute));
1259
+ if (!lstatSync(parent).isDirectory()) return null;
1260
+ target = resolve2(parent, basename(absolute));
1261
+ } catch {
1262
+ return null;
1263
+ }
1264
+ }
1265
+ const rel = relative(repositoryRoot, target);
1266
+ if (!rel || isAbsolute2(rel) || rel === ".." || rel.startsWith(`..${sep}`)) {
1267
+ return null;
1268
+ }
1269
+ return sep === "/" ? rel : rel.split(sep).join("/");
1181
1270
  }
1182
- async function performTokenRefresh(options = {}) {
1183
- const selected = resolveAuthCredential();
1184
- if (selected?.source !== "token_file") return void 0;
1185
- const startingGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
1186
- if (!startingGeneration || isSessionEnded()) return void 0;
1187
- const startingAccessToken = selected.token;
1188
- return withCredentialLock(
1189
- async () => {
1190
- const currentCredential = resolveAuthCredential();
1191
- if (currentCredential?.source !== "token_file") return void 0;
1192
- const currentGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
1193
- if (!currentGeneration) return void 0;
1194
- if (currentGeneration !== startingGeneration) {
1195
- return currentCredential.token;
1196
- }
1197
- if (currentCredential.token !== startingAccessToken) {
1198
- return currentCredential.token;
1199
- }
1200
- if (isSessionEnded()) return void 0;
1201
- let metadata = readStoredCredentialMetadata();
1202
- const markerlessLegacyAtStart = metadata.state === "legacy_broker" && metadata.metadata === void 0;
1203
- if (metadata.state === "invalid" || metadata.state === "workos_connect" && (metadata.metadata.accessTokenHash !== refreshFingerprint(currentCredential.token) || metadata.metadata.refreshTokenHash !== refreshFingerprint(currentGeneration))) {
1204
- return void 0;
1205
- }
1206
- if (metadata.state === "legacy_broker") {
1207
- try {
1208
- metadata = bindLegacyBrokerGeneration(
1209
- currentCredential.token,
1210
- currentGeneration,
1211
- metadata
1212
- );
1213
- } catch {
1214
- return void 0;
1215
- }
1216
- if (metadata.state !== "legacy_broker") return void 0;
1217
- }
1218
- const expectedLegacyGeneration = markerlessLegacyAtStart && metadata.state === "legacy_broker" ? metadata.metadata : void 0;
1219
- const connectContext = metadata.state === "workos_connect" ? {
1220
- version: 1,
1221
- family: "workos_connect",
1222
- issuer: metadata.metadata.issuer,
1223
- clientId: metadata.metadata.clientId
1224
- } : void 0;
1225
- const response = await fetch(
1226
- connectContext ? workosConnectTokenEndpoint(connectContext.issuer) : `${getSiteUrl()}/mcp/broker/refresh`,
1227
- connectContext ? {
1228
- method: "POST",
1229
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1230
- body: new URLSearchParams({
1231
- grant_type: "refresh_token",
1232
- refresh_token: currentGeneration,
1233
- client_id: connectContext.clientId
1234
- }),
1235
- signal: options.signal
1236
- } : {
1237
- method: "POST",
1238
- headers: { "Content-Type": "application/json" },
1239
- body: JSON.stringify({ refresh_token: currentGeneration }),
1240
- signal: options.signal
1241
- }
1242
- );
1243
- let directResponse;
1244
- if (connectContext) {
1245
- try {
1246
- directResponse = await readBoundedJson(response, WORKOS_CONNECT_RESPONSE_MAX_BYTES);
1247
- } catch {
1248
- if (response.ok && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
1249
- metadata,
1250
- currentCredential.token,
1251
- currentGeneration
1252
- )) {
1253
- writeTerminalFingerprint(currentGeneration);
1254
- }
1255
- return void 0;
1256
- }
1257
- }
1258
- if (!response.ok) {
1259
- let detail = "";
1260
- if (connectContext) {
1261
- detail = workosConnectRefreshErrorCode(directResponse);
1262
- } else {
1263
- detail = (await response.text().catch(() => "")).slice(0, 200);
1264
- }
1265
- if (isTerminalRefreshResponse(response, detail) && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
1266
- writeTerminalFingerprint(currentGeneration);
1267
- }
1268
- refreshDiagnostic(
1269
- response,
1270
- detail,
1271
- options.quiet,
1272
- connectContext ? "WorkOS Connect" : "broker"
1273
- );
1274
- return winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
1275
- }
1276
- let accessToken;
1277
- let replacementRefreshToken;
1278
- let expiresIn;
1279
- if (connectContext) {
1280
- try {
1281
- const tokens = parseWorkosConnectTokens(directResponse, {
1282
- fallbackRefreshToken: currentGeneration
1283
- });
1284
- accessToken = tokens.accessToken;
1285
- replacementRefreshToken = tokens.refreshToken;
1286
- expiresIn = tokens.expiresIn;
1287
- } catch {
1288
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
1289
- metadata,
1290
- currentCredential.token,
1291
- currentGeneration
1292
- )) {
1293
- writeTerminalFingerprint(currentGeneration);
1294
- }
1295
- return void 0;
1296
- }
1297
- } else {
1298
- let data;
1299
- try {
1300
- data = await response.json();
1301
- } catch {
1302
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
1303
- writeTerminalFingerprint(currentGeneration);
1304
- }
1305
- return void 0;
1306
- }
1307
- const record = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
1308
- accessToken = typeof record?.access_token === "string" ? record.access_token.trim() : "";
1309
- replacementRefreshToken = typeof record?.refresh_token === "string" ? record.refresh_token.trim() : "";
1310
- expiresIn = typeof record?.expires_in === "number" && Number.isFinite(record.expires_in) ? record.expires_in : void 0;
1311
- if (!(accessToken && replacementRefreshToken)) {
1312
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
1313
- writeTerminalFingerprint(currentGeneration);
1314
- }
1315
- return void 0;
1316
- }
1317
- }
1318
- const latestCredential = resolveAuthCredential();
1319
- if (readTrimmed2(REFRESH_TOKEN_PATH) !== currentGeneration || latestCredential?.source !== "token_file" || latestCredential.token !== currentCredential.token || !metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
1320
- return latestCredential?.source === "token_file" ? latestCredential.token : winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
1321
- }
1322
- commitCredentialsUnlocked({
1323
- accessToken,
1324
- refreshToken: replacementRefreshToken,
1325
- expiresIn,
1326
- metadata: connectContext
1327
- });
1328
- return accessToken;
1329
- },
1330
- { signal: options.signal }
1271
+ function canonicalRepositoryPath(filePath, contextOrCwd, baseDirOrRoot) {
1272
+ if (typeof contextOrCwd === "string") {
1273
+ return canonicalRepositoryPathLegacy(filePath, contextOrCwd, baseDirOrRoot);
1274
+ }
1275
+ return canonicalRepositoryPathScoped(
1276
+ filePath,
1277
+ contextOrCwd,
1278
+ baseDirOrRoot ?? contextOrCwd.repoRoot
1331
1279
  );
1332
1280
  }
1333
- var _refreshInFlight;
1334
- function refreshToken(options = {}) {
1335
- if (_refreshInFlight) return _refreshInFlight;
1336
- const attempt = performTokenRefresh(options).then((token) => {
1337
- if (token) _cachedCredential = { token, source: "token_file" };
1338
- return token;
1339
- }).finally(() => {
1340
- if (_refreshInFlight === attempt) _refreshInFlight = void 0;
1341
- });
1342
- _refreshInFlight = attempt;
1343
- return attempt;
1344
- }
1345
- var HttpError = class extends Error {
1346
- status;
1347
- body;
1348
- constructor(status, message, body) {
1349
- super(message);
1350
- this.name = "HttpError";
1351
- this.status = status;
1352
- this.body = body;
1281
+
1282
+ // src/lib/activation.ts
1283
+ var PRIM_ACTIVE_KEY = "prim.active";
1284
+ var PRIM_REPO_SYNC_ID_KEY = "prim.repoSyncId";
1285
+ var PRIM_REPO_SYNC_REPOSITORY_KEY = "prim.repoSyncRepository";
1286
+ var PRIM_REPO_BINDING_STATE_KEY = "prim.repoBindingState";
1287
+ var GIT_TIMEOUT_MS2 = 1e3;
1288
+ var REPO_SYNC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
1289
+ var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
1290
+ var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
1291
+ function repoActiveFlag(cwd) {
1292
+ try {
1293
+ const value = execFileSync2("git", ["config", "--get", PRIM_ACTIVE_KEY], {
1294
+ cwd,
1295
+ encoding: "utf-8",
1296
+ stdio: ["ignore", "pipe", "ignore"],
1297
+ timeout: GIT_TIMEOUT_MS2
1298
+ }).trim();
1299
+ if (value === "true") return "true";
1300
+ if (value === "false") return "false";
1301
+ return void 0;
1302
+ } catch {
1303
+ return void 0;
1353
1304
  }
1354
- };
1355
- var CLI_MANAGEMENT_RESPONSE_MAX_BYTES = 2 * 1024 * 1024;
1356
- var _cachedCredential;
1357
- function selectedCredential() {
1358
- const resolved = resolveAuthCredential();
1359
- if (!_cachedCredential || resolved?.token !== _cachedCredential.token || resolved?.source !== _cachedCredential.source) {
1360
- _cachedCredential = resolved;
1305
+ }
1306
+ function isRepoActive(cwd) {
1307
+ return repoActiveFlag(cwd) === "true";
1308
+ }
1309
+ function isValidRepoSyncId(value) {
1310
+ return typeof value === "string" && REPO_SYNC_ID_RE.test(value);
1311
+ }
1312
+ function localGitConfigValue(cwd, key) {
1313
+ try {
1314
+ const value = execFileSync2("git", ["config", "--local", "--get", key], {
1315
+ cwd,
1316
+ encoding: "utf-8",
1317
+ stdio: ["ignore", "pipe", "ignore"],
1318
+ timeout: GIT_TIMEOUT_MS2
1319
+ }).trim();
1320
+ return value || void 0;
1321
+ } catch {
1322
+ return void 0;
1361
1323
  }
1362
- return _cachedCredential;
1363
1324
  }
1364
- function fetchWithToken(method, path, body, options, token, siteUrl) {
1365
- return fetch(`${siteUrl}${path}`, {
1366
- method,
1367
- headers: {
1368
- Authorization: `Bearer ${token}`,
1369
- "Content-Type": "application/json"
1370
- },
1371
- body: body === void 0 ? void 0 : JSON.stringify(body),
1372
- signal: options?.signal
1373
- });
1325
+ function repoSyncId(cwd) {
1326
+ const value = localGitConfigValue(cwd, PRIM_REPO_SYNC_ID_KEY);
1327
+ if (!isValidRepoSyncId(value)) return void 0;
1328
+ const repositoryFullName = localGitConfigValue(cwd, PRIM_REPO_SYNC_REPOSITORY_KEY);
1329
+ return repositoryFullName === githubRepositoryFullName(cwd) ? value : void 0;
1374
1330
  }
1375
- async function responseValue(response) {
1376
- if (!response.ok) {
1377
- if (response.status === 401) {
1378
- throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1331
+ function repositoryBindingState(cwd) {
1332
+ const rawId = localGitConfigValue(cwd, PRIM_REPO_SYNC_ID_KEY);
1333
+ const marker = localGitConfigValue(cwd, PRIM_REPO_BINDING_STATE_KEY);
1334
+ if (rawId !== void 0 && !isValidRepoSyncId(rawId)) return "invalid";
1335
+ if (marker === "unbound" || marker === "invalid") return marker;
1336
+ if (marker === "connected") return repoSyncId(cwd) ? "connected" : "invalid";
1337
+ if (marker !== void 0) return "invalid";
1338
+ return rawId === void 0 ? "unbound" : repoSyncId(cwd) ? void 0 : "unbound";
1339
+ }
1340
+ function hasProjectPrimInstall(cwd) {
1341
+ const root = gitToplevel(cwd);
1342
+ if (root === null || root === homedir2()) return false;
1343
+ for (const rel of PROJECT_INSTALL_FILES) {
1344
+ const path = join5(root, rel);
1345
+ if (existsSync3(path)) {
1346
+ try {
1347
+ const content = readFileSync4(path, "utf-8");
1348
+ if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
1349
+ } catch {
1350
+ }
1379
1351
  }
1380
- const errorBody = await response.json().catch(() => null);
1381
- const errorRecord = typeof errorBody === "object" && errorBody !== null && !Array.isArray(errorBody) ? errorBody : void 0;
1382
- const message = typeof errorRecord?.error === "string" ? errorRecord.error : `HTTP ${response.status}`;
1383
- throw new HttpError(response.status, message, errorBody);
1384
1352
  }
1385
- return response.json();
1353
+ return false;
1386
1354
  }
1387
- async function request(method, path, body, options) {
1388
- const siteUrl = getSiteUrl();
1389
- let credential = selectedCredential();
1390
- let refreshAttempted = false;
1391
- if (credential && isTokenExpiringSoon(credential)) {
1392
- refreshAttempted = true;
1393
- const token = await refreshToken({
1394
- signal: options?.signal,
1395
- quiet: options?.quietRefresh
1396
- });
1397
- if (token) credential = { token, source: "token_file" };
1398
- }
1399
- if (!credential) {
1400
- throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1401
- }
1402
- if (isTokenExpiringSoon(credential) && isSessionEnded()) {
1403
- throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1355
+ function isRepoActiveForCapture(cwd) {
1356
+ const flag = repoActiveFlag(cwd);
1357
+ if (flag === "true") return true;
1358
+ if (flag === "false") return false;
1359
+ return hasProjectPrimInstall(cwd);
1360
+ }
1361
+ function decisionIngestionStatus(cwd) {
1362
+ return isRepoActiveForCapture(cwd) ? "enabled" : "disabled";
1363
+ }
1364
+
1365
+ // src/lib/bin-path.ts
1366
+ import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
1367
+ import { dirname as dirname5, isAbsolute as isAbsolute3, join as join6 } from "path";
1368
+ import { fileURLToPath } from "url";
1369
+ var PKG_NAME = "@primitive.ai/prim";
1370
+ var ROOT_WALK_LIMIT = 6;
1371
+ var STABLE_HOOK_LAUNCHER_NAME = "prim-hook-launcher-v1";
1372
+ var resolvedRoot;
1373
+ function locateRoot() {
1374
+ if (resolvedRoot !== void 0) {
1375
+ return resolvedRoot;
1404
1376
  }
1405
- const tokenUsed = credential.token;
1406
- let response = await fetchWithToken(method, path, body, options, tokenUsed, siteUrl);
1407
- if (response.status === 401) {
1408
- const latest = resolveAuthCredential();
1409
- let retryToken = latest?.token !== tokenUsed ? latest?.token : void 0;
1410
- if (!retryToken && latest?.source === "token_file" && !refreshAttempted) {
1411
- refreshAttempted = true;
1412
- retryToken = await refreshToken({ signal: options?.signal, quiet: options?.quietRefresh });
1377
+ let dir = dirname5(fileURLToPath(import.meta.url));
1378
+ for (let depth = 0; depth < ROOT_WALK_LIMIT; depth++) {
1379
+ const manifestPath = join6(dir, "package.json");
1380
+ if (existsSync4(manifestPath)) {
1381
+ try {
1382
+ const manifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
1383
+ if (manifest.name === PKG_NAME && manifest.bin) {
1384
+ resolvedRoot = { dir, version: manifest.version, bin: manifest.bin };
1385
+ return resolvedRoot;
1386
+ }
1387
+ } catch {
1388
+ }
1413
1389
  }
1414
- if (retryToken) {
1415
- _cachedCredential = {
1416
- token: retryToken,
1417
- source: latest?.source === "token_file" ? "token_file" : latest?.source ?? "token_file"
1418
- };
1419
- response = await fetchWithToken(method, path, body, options, retryToken, siteUrl);
1390
+ const parent = dirname5(dir);
1391
+ if (parent === dir) {
1392
+ break;
1420
1393
  }
1394
+ dir = parent;
1421
1395
  }
1422
- return responseValue(response);
1396
+ resolvedRoot = null;
1397
+ return resolvedRoot;
1423
1398
  }
1424
- function getClient() {
1425
- return {
1426
- get: (path, options) => request("GET", path, void 0, options),
1427
- post: (path, body, options) => request("POST", path, body, options)
1428
- };
1399
+ function packageVersion() {
1400
+ return locateRoot()?.version ?? null;
1401
+ }
1402
+ function shellQuote(value) {
1403
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
1404
+ }
1405
+ var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
1406
+ var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
1407
+ var PRIM_CONFIG_SHELL_RESOLVER = [
1408
+ 'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
1409
+ 'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
1410
+ 'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
1411
+ 'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
1412
+ "fi; fi; "
1413
+ ].join("");
1414
+ function stableHookCommand(bin, args = "") {
1415
+ if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
1416
+ throw new Error("invalid stable hook command");
1417
+ }
1418
+ const resolver = [
1419
+ // #242 and earlier identify managed commands by this package marker. Keep
1420
+ // it as inert data during the rolling window so an older uninstall or
1421
+ // reinstall can remove the stable entry without invoking npm or PATH.
1422
+ `prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
1423
+ PRIM_CONFIG_SHELL_RESOLVER,
1424
+ `case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
1425
+ 'exec "$prim_launcher" "$@"'
1426
+ ].join("");
1427
+ const suffix = args ? ` ${args}` : "";
1428
+ return `/bin/sh -c ${shellQuote(resolver)} ${STABLE_HOOK_LAUNCHER_NAME} ${bin}${suffix}`;
1429
+ }
1430
+ function detachedHookShimCommand(bin, args = "") {
1431
+ return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
1429
1432
  }
1430
1433
 
1431
1434
  // src/generated/cli-http-v1.validators.js
@@ -12507,7 +12510,6 @@ function validate45(data, { instancePath = "", parentData, parentDataProperty, r
12507
12510
  return errors === 0;
12508
12511
  }
12509
12512
  validate45.evaluated = { "dynamicProps": true, "dynamicItems": false };
12510
- var schema83 = { "anyOf": [{ "type": "object", "properties": { "error": { "type": "string", "const": "Unauthorized" } }, "required": ["error"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "const": "interactive_workos_authority_required" } }, "required": ["error"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "const": "feature_disabled" }, "feature": { "type": "string", "const": "github-connect" } }, "required": ["error", "feature"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "enum": ["github_connect_unavailable", "feature_check_unavailable"] }, "feature": { "type": "string", "const": "github-connect" } }, "required": ["error", "feature"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "const": "WorkOS identity authority is temporarily unavailable" } }, "required": ["error"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "const": "github_install_intent_conflict" } }, "required": ["error"], "additionalProperties": false }, { "type": "object", "properties": { "error": { "type": "string", "const": "github_install_intent_rate_limited" }, "retryAt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["error", "retryAt"], "additionalProperties": false }] };
12511
12513
  function validate46(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
12512
12514
  ;
12513
12515
  let vErrors = null;
@@ -12657,7 +12659,7 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12657
12659
  if (errors === _errs12) {
12658
12660
  if (data && typeof data == "object" && !Array.isArray(data)) {
12659
12661
  let missing2;
12660
- if (data.error === void 0 && (missing2 = "error") || data.feature === void 0 && (missing2 = "feature")) {
12662
+ if (data.error === void 0 && (missing2 = "error")) {
12661
12663
  const err10 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/required", keyword: "required", params: { missingProperty: missing2 }, message: "must have required property '" + missing2 + "'" };
12662
12664
  if (vErrors === null) {
12663
12665
  vErrors = [err10];
@@ -12668,7 +12670,7 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12668
12670
  } else {
12669
12671
  const _errs14 = errors;
12670
12672
  for (const key2 in data) {
12671
- if (!(key2 === "error" || key2 === "feature")) {
12673
+ if (!(key2 === "error")) {
12672
12674
  const err11 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key2 }, message: "must NOT have additional properties" };
12673
12675
  if (vErrors === null) {
12674
12676
  vErrors = [err11];
@@ -12680,219 +12682,90 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12680
12682
  }
12681
12683
  }
12682
12684
  if (_errs14 === errors) {
12683
- if (data.error !== void 0) {
12684
- let data2 = data.error;
12685
- const _errs15 = errors;
12686
- if (typeof data2 !== "string") {
12687
- const err12 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12688
- if (vErrors === null) {
12689
- vErrors = [err12];
12690
- } else {
12691
- vErrors.push(err12);
12692
- }
12693
- errors++;
12694
- }
12695
- if ("feature_disabled" !== data2) {
12696
- const err13 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/error/const", keyword: "const", params: { allowedValue: "feature_disabled" }, message: "must be equal to constant" };
12697
- if (vErrors === null) {
12698
- vErrors = [err13];
12699
- } else {
12700
- vErrors.push(err13);
12701
- }
12702
- errors++;
12703
- }
12704
- var valid4 = _errs15 === errors;
12705
- } else {
12706
- var valid4 = true;
12707
- }
12708
- if (valid4) {
12709
- if (data.feature !== void 0) {
12710
- let data3 = data.feature;
12711
- const _errs17 = errors;
12712
- if (typeof data3 !== "string") {
12713
- const err14 = { instancePath: instancePath + "/feature", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/feature/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12714
- if (vErrors === null) {
12715
- vErrors = [err14];
12716
- } else {
12717
- vErrors.push(err14);
12718
- }
12719
- errors++;
12720
- }
12721
- if ("github-connect" !== data3) {
12722
- const err15 = { instancePath: instancePath + "/feature", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/feature/const", keyword: "const", params: { allowedValue: "github-connect" }, message: "must be equal to constant" };
12723
- if (vErrors === null) {
12724
- vErrors = [err15];
12725
- } else {
12726
- vErrors.push(err15);
12727
- }
12728
- errors++;
12729
- }
12730
- var valid4 = _errs17 === errors;
12731
- } else {
12732
- var valid4 = true;
12733
- }
12734
- }
12735
- }
12736
- }
12737
- } else {
12738
- const err16 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12739
- if (vErrors === null) {
12740
- vErrors = [err16];
12741
- } else {
12742
- vErrors.push(err16);
12743
- }
12744
- errors++;
12745
- }
12746
- }
12747
- var _valid0 = _errs12 === errors;
12748
- valid1 = valid1 || _valid0;
12749
- if (_valid0) {
12750
- if (props0 !== true) {
12751
- props0 = true;
12752
- }
12753
- }
12754
- const _errs19 = errors;
12755
- if (errors === _errs19) {
12756
- if (data && typeof data == "object" && !Array.isArray(data)) {
12757
- let missing3;
12758
- if (data.error === void 0 && (missing3 = "error") || data.feature === void 0 && (missing3 = "feature")) {
12759
- const err17 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/required", keyword: "required", params: { missingProperty: missing3 }, message: "must have required property '" + missing3 + "'" };
12760
- if (vErrors === null) {
12761
- vErrors = [err17];
12762
- } else {
12763
- vErrors.push(err17);
12764
- }
12765
- errors++;
12766
- } else {
12767
- const _errs21 = errors;
12768
- for (const key3 in data) {
12769
- if (!(key3 === "error" || key3 === "feature")) {
12770
- const err18 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key3 }, message: "must NOT have additional properties" };
12771
- if (vErrors === null) {
12772
- vErrors = [err18];
12773
- } else {
12774
- vErrors.push(err18);
12775
- }
12776
- errors++;
12777
- break;
12778
- }
12779
- }
12780
- if (_errs21 === errors) {
12781
- if (data.error !== void 0) {
12782
- let data4 = data.error;
12783
- const _errs22 = errors;
12784
- if (typeof data4 !== "string") {
12785
- const err19 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12685
+ if (data.error !== void 0) {
12686
+ let data2 = data.error;
12687
+ if (typeof data2 !== "string") {
12688
+ const err12 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12786
12689
  if (vErrors === null) {
12787
- vErrors = [err19];
12690
+ vErrors = [err12];
12788
12691
  } else {
12789
- vErrors.push(err19);
12692
+ vErrors.push(err12);
12790
12693
  }
12791
12694
  errors++;
12792
12695
  }
12793
- if (!(data4 === "github_connect_unavailable" || data4 === "feature_check_unavailable")) {
12794
- const err20 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/error/enum", keyword: "enum", params: { allowedValues: schema83.anyOf[3].properties.error.enum }, message: "must be equal to one of the allowed values" };
12696
+ if ("github_connect_unavailable" !== data2) {
12697
+ const err13 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/properties/error/const", keyword: "const", params: { allowedValue: "github_connect_unavailable" }, message: "must be equal to constant" };
12795
12698
  if (vErrors === null) {
12796
- vErrors = [err20];
12699
+ vErrors = [err13];
12797
12700
  } else {
12798
- vErrors.push(err20);
12701
+ vErrors.push(err13);
12799
12702
  }
12800
12703
  errors++;
12801
12704
  }
12802
- var valid5 = _errs22 === errors;
12803
- } else {
12804
- var valid5 = true;
12805
- }
12806
- if (valid5) {
12807
- if (data.feature !== void 0) {
12808
- let data5 = data.feature;
12809
- const _errs24 = errors;
12810
- if (typeof data5 !== "string") {
12811
- const err21 = { instancePath: instancePath + "/feature", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/feature/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12812
- if (vErrors === null) {
12813
- vErrors = [err21];
12814
- } else {
12815
- vErrors.push(err21);
12816
- }
12817
- errors++;
12818
- }
12819
- if ("github-connect" !== data5) {
12820
- const err22 = { instancePath: instancePath + "/feature", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/feature/const", keyword: "const", params: { allowedValue: "github-connect" }, message: "must be equal to constant" };
12821
- if (vErrors === null) {
12822
- vErrors = [err22];
12823
- } else {
12824
- vErrors.push(err22);
12825
- }
12826
- errors++;
12827
- }
12828
- var valid5 = _errs24 === errors;
12829
- } else {
12830
- var valid5 = true;
12831
- }
12832
12705
  }
12833
12706
  }
12834
12707
  }
12835
12708
  } else {
12836
- const err23 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12709
+ const err14 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/2/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12837
12710
  if (vErrors === null) {
12838
- vErrors = [err23];
12711
+ vErrors = [err14];
12839
12712
  } else {
12840
- vErrors.push(err23);
12713
+ vErrors.push(err14);
12841
12714
  }
12842
12715
  errors++;
12843
12716
  }
12844
12717
  }
12845
- var _valid0 = _errs19 === errors;
12718
+ var _valid0 = _errs12 === errors;
12846
12719
  valid1 = valid1 || _valid0;
12847
12720
  if (_valid0) {
12848
12721
  if (props0 !== true) {
12849
12722
  props0 = true;
12850
12723
  }
12851
12724
  }
12852
- const _errs26 = errors;
12853
- if (errors === _errs26) {
12725
+ const _errs17 = errors;
12726
+ if (errors === _errs17) {
12854
12727
  if (data && typeof data == "object" && !Array.isArray(data)) {
12855
- let missing4;
12856
- if (data.error === void 0 && (missing4 = "error")) {
12857
- const err24 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/required", keyword: "required", params: { missingProperty: missing4 }, message: "must have required property '" + missing4 + "'" };
12728
+ let missing3;
12729
+ if (data.error === void 0 && (missing3 = "error")) {
12730
+ const err15 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/required", keyword: "required", params: { missingProperty: missing3 }, message: "must have required property '" + missing3 + "'" };
12858
12731
  if (vErrors === null) {
12859
- vErrors = [err24];
12732
+ vErrors = [err15];
12860
12733
  } else {
12861
- vErrors.push(err24);
12734
+ vErrors.push(err15);
12862
12735
  }
12863
12736
  errors++;
12864
12737
  } else {
12865
- const _errs28 = errors;
12866
- for (const key4 in data) {
12867
- if (!(key4 === "error")) {
12868
- const err25 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key4 }, message: "must NOT have additional properties" };
12738
+ const _errs19 = errors;
12739
+ for (const key3 in data) {
12740
+ if (!(key3 === "error")) {
12741
+ const err16 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key3 }, message: "must NOT have additional properties" };
12869
12742
  if (vErrors === null) {
12870
- vErrors = [err25];
12743
+ vErrors = [err16];
12871
12744
  } else {
12872
- vErrors.push(err25);
12745
+ vErrors.push(err16);
12873
12746
  }
12874
12747
  errors++;
12875
12748
  break;
12876
12749
  }
12877
12750
  }
12878
- if (_errs28 === errors) {
12751
+ if (_errs19 === errors) {
12879
12752
  if (data.error !== void 0) {
12880
- let data6 = data.error;
12881
- if (typeof data6 !== "string") {
12882
- const err26 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12753
+ let data3 = data.error;
12754
+ if (typeof data3 !== "string") {
12755
+ const err17 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12883
12756
  if (vErrors === null) {
12884
- vErrors = [err26];
12757
+ vErrors = [err17];
12885
12758
  } else {
12886
- vErrors.push(err26);
12759
+ vErrors.push(err17);
12887
12760
  }
12888
12761
  errors++;
12889
12762
  }
12890
- if ("WorkOS identity authority is temporarily unavailable" !== data6) {
12891
- const err27 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/properties/error/const", keyword: "const", params: { allowedValue: "WorkOS identity authority is temporarily unavailable" }, message: "must be equal to constant" };
12763
+ if ("WorkOS identity authority is temporarily unavailable" !== data3) {
12764
+ const err18 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/properties/error/const", keyword: "const", params: { allowedValue: "WorkOS identity authority is temporarily unavailable" }, message: "must be equal to constant" };
12892
12765
  if (vErrors === null) {
12893
- vErrors = [err27];
12766
+ vErrors = [err18];
12894
12767
  } else {
12895
- vErrors.push(err27);
12768
+ vErrors.push(err18);
12896
12769
  }
12897
12770
  errors++;
12898
12771
  }
@@ -12900,66 +12773,66 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12900
12773
  }
12901
12774
  }
12902
12775
  } else {
12903
- const err28 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12776
+ const err19 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/3/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12904
12777
  if (vErrors === null) {
12905
- vErrors = [err28];
12778
+ vErrors = [err19];
12906
12779
  } else {
12907
- vErrors.push(err28);
12780
+ vErrors.push(err19);
12908
12781
  }
12909
12782
  errors++;
12910
12783
  }
12911
12784
  }
12912
- var _valid0 = _errs26 === errors;
12785
+ var _valid0 = _errs17 === errors;
12913
12786
  valid1 = valid1 || _valid0;
12914
12787
  if (_valid0) {
12915
12788
  if (props0 !== true) {
12916
12789
  props0 = true;
12917
12790
  }
12918
12791
  }
12919
- const _errs31 = errors;
12920
- if (errors === _errs31) {
12792
+ const _errs22 = errors;
12793
+ if (errors === _errs22) {
12921
12794
  if (data && typeof data == "object" && !Array.isArray(data)) {
12922
- let missing5;
12923
- if (data.error === void 0 && (missing5 = "error")) {
12924
- const err29 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/required", keyword: "required", params: { missingProperty: missing5 }, message: "must have required property '" + missing5 + "'" };
12795
+ let missing4;
12796
+ if (data.error === void 0 && (missing4 = "error")) {
12797
+ const err20 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/required", keyword: "required", params: { missingProperty: missing4 }, message: "must have required property '" + missing4 + "'" };
12925
12798
  if (vErrors === null) {
12926
- vErrors = [err29];
12799
+ vErrors = [err20];
12927
12800
  } else {
12928
- vErrors.push(err29);
12801
+ vErrors.push(err20);
12929
12802
  }
12930
12803
  errors++;
12931
12804
  } else {
12932
- const _errs33 = errors;
12933
- for (const key5 in data) {
12934
- if (!(key5 === "error")) {
12935
- const err30 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key5 }, message: "must NOT have additional properties" };
12805
+ const _errs24 = errors;
12806
+ for (const key4 in data) {
12807
+ if (!(key4 === "error")) {
12808
+ const err21 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key4 }, message: "must NOT have additional properties" };
12936
12809
  if (vErrors === null) {
12937
- vErrors = [err30];
12810
+ vErrors = [err21];
12938
12811
  } else {
12939
- vErrors.push(err30);
12812
+ vErrors.push(err21);
12940
12813
  }
12941
12814
  errors++;
12942
12815
  break;
12943
12816
  }
12944
12817
  }
12945
- if (_errs33 === errors) {
12818
+ if (_errs24 === errors) {
12946
12819
  if (data.error !== void 0) {
12947
- let data7 = data.error;
12948
- if (typeof data7 !== "string") {
12949
- const err31 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12820
+ let data4 = data.error;
12821
+ if (typeof data4 !== "string") {
12822
+ const err22 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12950
12823
  if (vErrors === null) {
12951
- vErrors = [err31];
12824
+ vErrors = [err22];
12952
12825
  } else {
12953
- vErrors.push(err31);
12826
+ vErrors.push(err22);
12954
12827
  }
12955
12828
  errors++;
12956
12829
  }
12957
- if ("github_install_intent_conflict" !== data7) {
12958
- const err32 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/error/const", keyword: "const", params: { allowedValue: "github_install_intent_conflict" }, message: "must be equal to constant" };
12830
+ if ("github_install_intent_conflict" !== data4) {
12831
+ const err23 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/properties/error/const", keyword: "const", params: { allowedValue: "github_install_intent_conflict" }, message: "must be equal to constant" };
12959
12832
  if (vErrors === null) {
12960
- vErrors = [err32];
12833
+ vErrors = [err23];
12961
12834
  } else {
12962
- vErrors.push(err32);
12835
+ vErrors.push(err23);
12963
12836
  }
12964
12837
  errors++;
12965
12838
  }
@@ -12967,128 +12840,128 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12967
12840
  }
12968
12841
  }
12969
12842
  } else {
12970
- const err33 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12843
+ const err24 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/4/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12971
12844
  if (vErrors === null) {
12972
- vErrors = [err33];
12845
+ vErrors = [err24];
12973
12846
  } else {
12974
- vErrors.push(err33);
12847
+ vErrors.push(err24);
12975
12848
  }
12976
12849
  errors++;
12977
12850
  }
12978
12851
  }
12979
- var _valid0 = _errs31 === errors;
12852
+ var _valid0 = _errs22 === errors;
12980
12853
  valid1 = valid1 || _valid0;
12981
12854
  if (_valid0) {
12982
12855
  if (props0 !== true) {
12983
12856
  props0 = true;
12984
12857
  }
12985
12858
  }
12986
- const _errs36 = errors;
12987
- if (errors === _errs36) {
12859
+ const _errs27 = errors;
12860
+ if (errors === _errs27) {
12988
12861
  if (data && typeof data == "object" && !Array.isArray(data)) {
12989
- let missing6;
12990
- if (data.error === void 0 && (missing6 = "error") || data.retryAt === void 0 && (missing6 = "retryAt")) {
12991
- const err34 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/required", keyword: "required", params: { missingProperty: missing6 }, message: "must have required property '" + missing6 + "'" };
12862
+ let missing5;
12863
+ if (data.error === void 0 && (missing5 = "error") || data.retryAt === void 0 && (missing5 = "retryAt")) {
12864
+ const err25 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/required", keyword: "required", params: { missingProperty: missing5 }, message: "must have required property '" + missing5 + "'" };
12992
12865
  if (vErrors === null) {
12993
- vErrors = [err34];
12866
+ vErrors = [err25];
12994
12867
  } else {
12995
- vErrors.push(err34);
12868
+ vErrors.push(err25);
12996
12869
  }
12997
12870
  errors++;
12998
12871
  } else {
12999
- const _errs38 = errors;
13000
- for (const key6 in data) {
13001
- if (!(key6 === "error" || key6 === "retryAt")) {
13002
- const err35 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key6 }, message: "must NOT have additional properties" };
12872
+ const _errs29 = errors;
12873
+ for (const key5 in data) {
12874
+ if (!(key5 === "error" || key5 === "retryAt")) {
12875
+ const err26 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key5 }, message: "must NOT have additional properties" };
13003
12876
  if (vErrors === null) {
13004
- vErrors = [err35];
12877
+ vErrors = [err26];
13005
12878
  } else {
13006
- vErrors.push(err35);
12879
+ vErrors.push(err26);
13007
12880
  }
13008
12881
  errors++;
13009
12882
  break;
13010
12883
  }
13011
12884
  }
13012
- if (_errs38 === errors) {
12885
+ if (_errs29 === errors) {
13013
12886
  if (data.error !== void 0) {
13014
- let data8 = data.error;
13015
- const _errs39 = errors;
13016
- if (typeof data8 !== "string") {
13017
- const err36 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
12887
+ let data5 = data.error;
12888
+ const _errs30 = errors;
12889
+ if (typeof data5 !== "string") {
12890
+ const err27 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" };
13018
12891
  if (vErrors === null) {
13019
- vErrors = [err36];
12892
+ vErrors = [err27];
13020
12893
  } else {
13021
- vErrors.push(err36);
12894
+ vErrors.push(err27);
13022
12895
  }
13023
12896
  errors++;
13024
12897
  }
13025
- if ("github_install_intent_rate_limited" !== data8) {
13026
- const err37 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/properties/error/const", keyword: "const", params: { allowedValue: "github_install_intent_rate_limited" }, message: "must be equal to constant" };
12898
+ if ("github_install_intent_rate_limited" !== data5) {
12899
+ const err28 = { instancePath: instancePath + "/error", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/error/const", keyword: "const", params: { allowedValue: "github_install_intent_rate_limited" }, message: "must be equal to constant" };
13027
12900
  if (vErrors === null) {
13028
- vErrors = [err37];
12901
+ vErrors = [err28];
13029
12902
  } else {
13030
- vErrors.push(err37);
12903
+ vErrors.push(err28);
13031
12904
  }
13032
12905
  errors++;
13033
12906
  }
13034
- var valid8 = _errs39 === errors;
12907
+ var valid7 = _errs30 === errors;
13035
12908
  } else {
13036
- var valid8 = true;
12909
+ var valid7 = true;
13037
12910
  }
13038
- if (valid8) {
12911
+ if (valid7) {
13039
12912
  if (data.retryAt !== void 0) {
13040
- let data9 = data.retryAt;
13041
- const _errs41 = errors;
13042
- if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9))) {
13043
- const err38 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/properties/retryAt/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
12913
+ let data6 = data.retryAt;
12914
+ const _errs32 = errors;
12915
+ if (!(typeof data6 == "number" && (!(data6 % 1) && !isNaN(data6)) && isFinite(data6))) {
12916
+ const err29 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/retryAt/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
13044
12917
  if (vErrors === null) {
13045
- vErrors = [err38];
12918
+ vErrors = [err29];
13046
12919
  } else {
13047
- vErrors.push(err38);
12920
+ vErrors.push(err29);
13048
12921
  }
13049
12922
  errors++;
13050
12923
  }
13051
- if (errors === _errs41) {
13052
- if (typeof data9 == "number" && isFinite(data9)) {
13053
- if (data9 > 9007199254740991 || isNaN(data9)) {
13054
- const err39 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/properties/retryAt/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
12924
+ if (errors === _errs32) {
12925
+ if (typeof data6 == "number" && isFinite(data6)) {
12926
+ if (data6 > 9007199254740991 || isNaN(data6)) {
12927
+ const err30 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/retryAt/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
13055
12928
  if (vErrors === null) {
13056
- vErrors = [err39];
12929
+ vErrors = [err30];
13057
12930
  } else {
13058
- vErrors.push(err39);
12931
+ vErrors.push(err30);
13059
12932
  }
13060
12933
  errors++;
13061
12934
  } else {
13062
- if (data9 < 0 || isNaN(data9)) {
13063
- const err40 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/properties/retryAt/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" };
12935
+ if (data6 < 0 || isNaN(data6)) {
12936
+ const err31 = { instancePath: instancePath + "/retryAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/properties/retryAt/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" };
13064
12937
  if (vErrors === null) {
13065
- vErrors = [err40];
12938
+ vErrors = [err31];
13066
12939
  } else {
13067
- vErrors.push(err40);
12940
+ vErrors.push(err31);
13068
12941
  }
13069
12942
  errors++;
13070
12943
  }
13071
12944
  }
13072
12945
  }
13073
12946
  }
13074
- var valid8 = _errs41 === errors;
12947
+ var valid7 = _errs32 === errors;
13075
12948
  } else {
13076
- var valid8 = true;
12949
+ var valid7 = true;
13077
12950
  }
13078
12951
  }
13079
12952
  }
13080
12953
  }
13081
12954
  } else {
13082
- const err41 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/6/type", keyword: "type", params: { type: "object" }, message: "must be object" };
12955
+ const err32 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf/5/type", keyword: "type", params: { type: "object" }, message: "must be object" };
13083
12956
  if (vErrors === null) {
13084
- vErrors = [err41];
12957
+ vErrors = [err32];
13085
12958
  } else {
13086
- vErrors.push(err41);
12959
+ vErrors.push(err32);
13087
12960
  }
13088
12961
  errors++;
13089
12962
  }
13090
12963
  }
13091
- var _valid0 = _errs36 === errors;
12964
+ var _valid0 = _errs27 === errors;
13092
12965
  valid1 = valid1 || _valid0;
13093
12966
  if (_valid0) {
13094
12967
  if (props0 !== true) {
@@ -13096,11 +12969,11 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
13096
12969
  }
13097
12970
  }
13098
12971
  if (!valid1) {
13099
- const err42 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf", keyword: "anyOf", params: {}, message: "must match a schema in anyOf" };
12972
+ const err33 = { instancePath, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/GitHubInstallIntentStartErrorResponse/anyOf", keyword: "anyOf", params: {}, message: "must match a schema in anyOf" };
13100
12973
  if (vErrors === null) {
13101
- vErrors = [err42];
12974
+ vErrors = [err33];
13102
12975
  } else {
13103
- vErrors.push(err42);
12976
+ vErrors.push(err33);
13104
12977
  }
13105
12978
  errors++;
13106
12979
  validate46.errors = vErrors;
@@ -15202,7 +15075,7 @@ function validate50(data, { instancePath = "", parentData, parentDataProperty, r
15202
15075
  return errors === 0;
15203
15076
  }
15204
15077
  validate50.evaluated = { "dynamicProps": true, "dynamicItems": false };
15205
- var schema93 = { "type": "object", "properties": { "batch": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "const": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType", "capturedOrganizationId", "captureAuthorityKind", "decisionLifecycleProtocolVersion", "envelopeVersion"], "additionalProperties": {} }, { "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "exclusiveMaximum": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType"], "additionalProperties": {} }] } } }, "required": ["batch"], "additionalProperties": {} };
15078
+ var schema93 = { "type": "object", "properties": { "batch": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "repositoryContext": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "repository_bound" }, "repoSyncId": { "type": "string", "minLength": 1, "maxLength": 128 } }, "required": ["kind", "repoSyncId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "non_repository" } }, "required": ["kind"], "additionalProperties": false }] }, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "const": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType", "capturedOrganizationId", "captureAuthorityKind", "decisionLifecycleProtocolVersion", "envelopeVersion"], "additionalProperties": {} }, { "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "repositoryContext": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "repository_bound" }, "repoSyncId": { "type": "string", "minLength": 1, "maxLength": 128 } }, "required": ["kind", "repoSyncId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "non_repository" } }, "required": ["kind"], "additionalProperties": false }] }, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "exclusiveMaximum": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType"], "additionalProperties": {} }] } } }, "required": ["batch"], "additionalProperties": {} };
15206
15079
  var pattern8 = new RegExp("^[A-Za-z0-9_-]+$", "u");
15207
15080
  function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
15208
15081
  ;
@@ -15329,13 +15202,18 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15329
15202
  var valid4 = true;
15330
15203
  }
15331
15204
  if (valid4) {
15332
- if (data1.capturedOrganizationId !== void 0) {
15333
- let data7 = data1.capturedOrganizationId;
15205
+ if (data1.repositoryContext !== void 0) {
15206
+ let data7 = data1.repositoryContext;
15334
15207
  const _errs20 = errors;
15335
- if (errors === _errs20) {
15336
- if (typeof data7 === "string") {
15337
- if (func1(data7) > 128) {
15338
- const err6 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15208
+ const _errs21 = errors;
15209
+ let valid5 = false;
15210
+ let passing0 = null;
15211
+ const _errs22 = errors;
15212
+ if (errors === _errs22) {
15213
+ if (data7 && typeof data7 == "object" && !Array.isArray(data7)) {
15214
+ let missing2;
15215
+ if (data7.kind === void 0 && (missing2 = "kind") || data7.repoSyncId === void 0 && (missing2 = "repoSyncId")) {
15216
+ const err6 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/required", keyword: "required", params: { missingProperty: missing2 }, message: "must have required property '" + missing2 + "'" };
15339
15217
  if (vErrors === null) {
15340
15218
  vErrors = [err6];
15341
15219
  } else {
@@ -15343,184 +15221,392 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15343
15221
  }
15344
15222
  errors++;
15345
15223
  } else {
15346
- if (func1(data7) < 1) {
15347
- const err7 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15348
- if (vErrors === null) {
15349
- vErrors = [err7];
15350
- } else {
15351
- vErrors.push(err7);
15352
- }
15353
- errors++;
15354
- } else {
15355
- if (!pattern8.test(data7)) {
15356
- const err8 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' };
15224
+ const _errs24 = errors;
15225
+ for (const key0 in data7) {
15226
+ if (!(key0 === "kind" || key0 === "repoSyncId")) {
15227
+ const err7 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" };
15357
15228
  if (vErrors === null) {
15358
- vErrors = [err8];
15229
+ vErrors = [err7];
15359
15230
  } else {
15360
- vErrors.push(err8);
15231
+ vErrors.push(err7);
15361
15232
  }
15362
15233
  errors++;
15234
+ break;
15235
+ }
15236
+ }
15237
+ if (_errs24 === errors) {
15238
+ if (data7.kind !== void 0) {
15239
+ let data8 = data7.kind;
15240
+ const _errs25 = errors;
15241
+ if (typeof data8 !== "string") {
15242
+ const err8 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/properties/kind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15243
+ if (vErrors === null) {
15244
+ vErrors = [err8];
15245
+ } else {
15246
+ vErrors.push(err8);
15247
+ }
15248
+ errors++;
15249
+ }
15250
+ if ("repository_bound" !== data8) {
15251
+ const err9 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/properties/kind/const", keyword: "const", params: { allowedValue: "repository_bound" }, message: "must be equal to constant" };
15252
+ if (vErrors === null) {
15253
+ vErrors = [err9];
15254
+ } else {
15255
+ vErrors.push(err9);
15256
+ }
15257
+ errors++;
15258
+ }
15259
+ var valid6 = _errs25 === errors;
15260
+ } else {
15261
+ var valid6 = true;
15262
+ }
15263
+ if (valid6) {
15264
+ if (data7.repoSyncId !== void 0) {
15265
+ let data9 = data7.repoSyncId;
15266
+ const _errs27 = errors;
15267
+ if (errors === _errs27) {
15268
+ if (typeof data9 === "string") {
15269
+ if (func1(data9) > 128) {
15270
+ const err10 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/properties/repoSyncId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15271
+ if (vErrors === null) {
15272
+ vErrors = [err10];
15273
+ } else {
15274
+ vErrors.push(err10);
15275
+ }
15276
+ errors++;
15277
+ } else {
15278
+ if (func1(data9) < 1) {
15279
+ const err11 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/properties/repoSyncId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15280
+ if (vErrors === null) {
15281
+ vErrors = [err11];
15282
+ } else {
15283
+ vErrors.push(err11);
15284
+ }
15285
+ errors++;
15286
+ }
15287
+ }
15288
+ } else {
15289
+ const err12 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/properties/repoSyncId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15290
+ if (vErrors === null) {
15291
+ vErrors = [err12];
15292
+ } else {
15293
+ vErrors.push(err12);
15294
+ }
15295
+ errors++;
15296
+ }
15297
+ }
15298
+ var valid6 = _errs27 === errors;
15299
+ } else {
15300
+ var valid6 = true;
15301
+ }
15363
15302
  }
15364
15303
  }
15365
15304
  }
15366
15305
  } else {
15367
- const err9 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15306
+ const err13 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/0/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15368
15307
  if (vErrors === null) {
15369
- vErrors = [err9];
15308
+ vErrors = [err13];
15370
15309
  } else {
15371
- vErrors.push(err9);
15310
+ vErrors.push(err13);
15372
15311
  }
15373
15312
  errors++;
15374
15313
  }
15375
15314
  }
15376
- var valid4 = _errs20 === errors;
15377
- } else {
15378
- var valid4 = true;
15379
- }
15380
- if (valid4) {
15381
- if (data1.captureAuthorityKind !== void 0) {
15382
- let data8 = data1.captureAuthorityKind;
15383
- const _errs22 = errors;
15384
- if (typeof data8 !== "string") {
15385
- const err10 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/captureAuthorityKind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15386
- if (vErrors === null) {
15387
- vErrors = [err10];
15315
+ var _valid1 = _errs22 === errors;
15316
+ if (_valid1) {
15317
+ valid5 = true;
15318
+ passing0 = 0;
15319
+ var props0 = true;
15320
+ }
15321
+ const _errs29 = errors;
15322
+ if (errors === _errs29) {
15323
+ if (data7 && typeof data7 == "object" && !Array.isArray(data7)) {
15324
+ let missing3;
15325
+ if (data7.kind === void 0 && (missing3 = "kind")) {
15326
+ const err14 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/1/required", keyword: "required", params: { missingProperty: missing3 }, message: "must have required property '" + missing3 + "'" };
15327
+ if (vErrors === null) {
15328
+ vErrors = [err14];
15329
+ } else {
15330
+ vErrors.push(err14);
15331
+ }
15332
+ errors++;
15388
15333
  } else {
15389
- vErrors.push(err10);
15334
+ const _errs31 = errors;
15335
+ for (const key1 in data7) {
15336
+ if (!(key1 === "kind")) {
15337
+ const err15 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/1/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key1 }, message: "must NOT have additional properties" };
15338
+ if (vErrors === null) {
15339
+ vErrors = [err15];
15340
+ } else {
15341
+ vErrors.push(err15);
15342
+ }
15343
+ errors++;
15344
+ break;
15345
+ }
15346
+ }
15347
+ if (_errs31 === errors) {
15348
+ if (data7.kind !== void 0) {
15349
+ let data10 = data7.kind;
15350
+ if (typeof data10 !== "string") {
15351
+ const err16 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/1/properties/kind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15352
+ if (vErrors === null) {
15353
+ vErrors = [err16];
15354
+ } else {
15355
+ vErrors.push(err16);
15356
+ }
15357
+ errors++;
15358
+ }
15359
+ if ("non_repository" !== data10) {
15360
+ const err17 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/1/properties/kind/const", keyword: "const", params: { allowedValue: "non_repository" }, message: "must be equal to constant" };
15361
+ if (vErrors === null) {
15362
+ vErrors = [err17];
15363
+ } else {
15364
+ vErrors.push(err17);
15365
+ }
15366
+ errors++;
15367
+ }
15368
+ }
15369
+ }
15390
15370
  }
15391
- errors++;
15392
- }
15393
- if (!(data8 === "workos" || data8 === "service_token")) {
15394
- const err11 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/captureAuthorityKind/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.captureAuthorityKind.enum }, message: "must be equal to one of the allowed values" };
15371
+ } else {
15372
+ const err18 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf/1/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15395
15373
  if (vErrors === null) {
15396
- vErrors = [err11];
15374
+ vErrors = [err18];
15397
15375
  } else {
15398
- vErrors.push(err11);
15376
+ vErrors.push(err18);
15399
15377
  }
15400
15378
  errors++;
15401
15379
  }
15402
- var valid4 = _errs22 === errors;
15380
+ }
15381
+ var _valid1 = _errs29 === errors;
15382
+ if (_valid1 && valid5) {
15383
+ valid5 = false;
15384
+ passing0 = [passing0, 1];
15403
15385
  } else {
15404
- var valid4 = true;
15386
+ if (_valid1) {
15387
+ valid5 = true;
15388
+ passing0 = 1;
15389
+ if (props0 !== true) {
15390
+ props0 = true;
15391
+ }
15392
+ }
15405
15393
  }
15406
- if (valid4) {
15407
- if (data1.decisionLifecycleProtocolVersion !== void 0) {
15408
- let data9 = data1.decisionLifecycleProtocolVersion;
15409
- const _errs24 = errors;
15410
- if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9))) {
15411
- const err12 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
15412
- if (vErrors === null) {
15413
- vErrors = [err12];
15414
- } else {
15415
- vErrors.push(err12);
15416
- }
15417
- errors++;
15394
+ if (!valid5) {
15395
+ const err19 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/repositoryContext/oneOf", keyword: "oneOf", params: { passingSchemas: passing0 }, message: "must match exactly one schema in oneOf" };
15396
+ if (vErrors === null) {
15397
+ vErrors = [err19];
15398
+ } else {
15399
+ vErrors.push(err19);
15400
+ }
15401
+ errors++;
15402
+ } else {
15403
+ errors = _errs21;
15404
+ if (vErrors !== null) {
15405
+ if (_errs21) {
15406
+ vErrors.length = _errs21;
15407
+ } else {
15408
+ vErrors = null;
15418
15409
  }
15419
- if (errors === _errs24) {
15420
- if (typeof data9 == "number" && isFinite(data9)) {
15421
- if (data9 > 9007199254740991 || isNaN(data9)) {
15422
- const err13 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
15410
+ }
15411
+ }
15412
+ var valid4 = _errs20 === errors;
15413
+ } else {
15414
+ var valid4 = true;
15415
+ }
15416
+ if (valid4) {
15417
+ if (data1.capturedOrganizationId !== void 0) {
15418
+ let data11 = data1.capturedOrganizationId;
15419
+ const _errs34 = errors;
15420
+ if (errors === _errs34) {
15421
+ if (typeof data11 === "string") {
15422
+ if (func1(data11) > 128) {
15423
+ const err20 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15424
+ if (vErrors === null) {
15425
+ vErrors = [err20];
15426
+ } else {
15427
+ vErrors.push(err20);
15428
+ }
15429
+ errors++;
15430
+ } else {
15431
+ if (func1(data11) < 1) {
15432
+ const err21 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15423
15433
  if (vErrors === null) {
15424
- vErrors = [err13];
15434
+ vErrors = [err21];
15425
15435
  } else {
15426
- vErrors.push(err13);
15436
+ vErrors.push(err21);
15427
15437
  }
15428
15438
  errors++;
15429
15439
  } else {
15430
- if (data9 < 1 || isNaN(data9)) {
15431
- const err14 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" };
15440
+ if (!pattern8.test(data11)) {
15441
+ const err22 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' };
15432
15442
  if (vErrors === null) {
15433
- vErrors = [err14];
15443
+ vErrors = [err22];
15434
15444
  } else {
15435
- vErrors.push(err14);
15445
+ vErrors.push(err22);
15436
15446
  }
15437
15447
  errors++;
15438
15448
  }
15439
15449
  }
15440
15450
  }
15451
+ } else {
15452
+ const err23 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/capturedOrganizationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15453
+ if (vErrors === null) {
15454
+ vErrors = [err23];
15455
+ } else {
15456
+ vErrors.push(err23);
15457
+ }
15458
+ errors++;
15459
+ }
15460
+ }
15461
+ var valid4 = _errs34 === errors;
15462
+ } else {
15463
+ var valid4 = true;
15464
+ }
15465
+ if (valid4) {
15466
+ if (data1.captureAuthorityKind !== void 0) {
15467
+ let data12 = data1.captureAuthorityKind;
15468
+ const _errs36 = errors;
15469
+ if (typeof data12 !== "string") {
15470
+ const err24 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/captureAuthorityKind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15471
+ if (vErrors === null) {
15472
+ vErrors = [err24];
15473
+ } else {
15474
+ vErrors.push(err24);
15475
+ }
15476
+ errors++;
15477
+ }
15478
+ if (!(data12 === "workos" || data12 === "service_token")) {
15479
+ const err25 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/captureAuthorityKind/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.captureAuthorityKind.enum }, message: "must be equal to one of the allowed values" };
15480
+ if (vErrors === null) {
15481
+ vErrors = [err25];
15482
+ } else {
15483
+ vErrors.push(err25);
15484
+ }
15485
+ errors++;
15441
15486
  }
15442
- var valid4 = _errs24 === errors;
15487
+ var valid4 = _errs36 === errors;
15443
15488
  } else {
15444
15489
  var valid4 = true;
15445
15490
  }
15446
15491
  if (valid4) {
15447
- if (data1.producer !== void 0) {
15448
- let data10 = data1.producer;
15449
- const _errs26 = errors;
15450
- if (typeof data10 !== "string") {
15451
- const err15 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/producer/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15492
+ if (data1.decisionLifecycleProtocolVersion !== void 0) {
15493
+ let data13 = data1.decisionLifecycleProtocolVersion;
15494
+ const _errs38 = errors;
15495
+ if (!(typeof data13 == "number" && (!(data13 % 1) && !isNaN(data13)) && isFinite(data13))) {
15496
+ const err26 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
15452
15497
  if (vErrors === null) {
15453
- vErrors = [err15];
15498
+ vErrors = [err26];
15454
15499
  } else {
15455
- vErrors.push(err15);
15500
+ vErrors.push(err26);
15456
15501
  }
15457
15502
  errors++;
15458
15503
  }
15459
- if (!(data10 === "claude_code" || data10 === "codex" || data10 === "cursor" || data10 === "hermes")) {
15460
- const err16 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.producer.enum }, message: "must be equal to one of the allowed values" };
15461
- if (vErrors === null) {
15462
- vErrors = [err16];
15463
- } else {
15464
- vErrors.push(err16);
15504
+ if (errors === _errs38) {
15505
+ if (typeof data13 == "number" && isFinite(data13)) {
15506
+ if (data13 > 9007199254740991 || isNaN(data13)) {
15507
+ const err27 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
15508
+ if (vErrors === null) {
15509
+ vErrors = [err27];
15510
+ } else {
15511
+ vErrors.push(err27);
15512
+ }
15513
+ errors++;
15514
+ } else {
15515
+ if (data13 < 1 || isNaN(data13)) {
15516
+ const err28 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/decisionLifecycleProtocolVersion/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" };
15517
+ if (vErrors === null) {
15518
+ vErrors = [err28];
15519
+ } else {
15520
+ vErrors.push(err28);
15521
+ }
15522
+ errors++;
15523
+ }
15524
+ }
15465
15525
  }
15466
- errors++;
15467
15526
  }
15468
- var valid4 = _errs26 === errors;
15527
+ var valid4 = _errs38 === errors;
15469
15528
  } else {
15470
15529
  var valid4 = true;
15471
15530
  }
15472
15531
  if (valid4) {
15473
- if (data1.toolOutcome !== void 0) {
15474
- let data11 = data1.toolOutcome;
15475
- const _errs28 = errors;
15476
- if (typeof data11 !== "string") {
15477
- const err17 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/toolOutcome/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15532
+ if (data1.producer !== void 0) {
15533
+ let data14 = data1.producer;
15534
+ const _errs40 = errors;
15535
+ if (typeof data14 !== "string") {
15536
+ const err29 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/producer/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15478
15537
  if (vErrors === null) {
15479
- vErrors = [err17];
15538
+ vErrors = [err29];
15480
15539
  } else {
15481
- vErrors.push(err17);
15540
+ vErrors.push(err29);
15482
15541
  }
15483
15542
  errors++;
15484
15543
  }
15485
- if (!(data11 === "succeeded" || data11 === "returned" || data11 === "failed" || data11 === "interrupted" || data11 === "prevented" || data11 === "unknown")) {
15486
- const err18 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/toolOutcome/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.toolOutcome.enum }, message: "must be equal to one of the allowed values" };
15544
+ if (!(data14 === "claude_code" || data14 === "codex" || data14 === "cursor" || data14 === "hermes")) {
15545
+ const err30 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.producer.enum }, message: "must be equal to one of the allowed values" };
15487
15546
  if (vErrors === null) {
15488
- vErrors = [err18];
15547
+ vErrors = [err30];
15489
15548
  } else {
15490
- vErrors.push(err18);
15549
+ vErrors.push(err30);
15491
15550
  }
15492
15551
  errors++;
15493
15552
  }
15494
- var valid4 = _errs28 === errors;
15553
+ var valid4 = _errs40 === errors;
15495
15554
  } else {
15496
15555
  var valid4 = true;
15497
15556
  }
15498
15557
  if (valid4) {
15499
- if (data1.envelopeVersion !== void 0) {
15500
- let data12 = data1.envelopeVersion;
15501
- const _errs30 = errors;
15502
- if (!(typeof data12 == "number" && isFinite(data12))) {
15503
- const err19 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/envelopeVersion/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15558
+ if (data1.toolOutcome !== void 0) {
15559
+ let data15 = data1.toolOutcome;
15560
+ const _errs42 = errors;
15561
+ if (typeof data15 !== "string") {
15562
+ const err31 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/toolOutcome/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15504
15563
  if (vErrors === null) {
15505
- vErrors = [err19];
15564
+ vErrors = [err31];
15506
15565
  } else {
15507
- vErrors.push(err19);
15566
+ vErrors.push(err31);
15508
15567
  }
15509
15568
  errors++;
15510
15569
  }
15511
- if (4 !== data12) {
15512
- const err20 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/envelopeVersion/const", keyword: "const", params: { allowedValue: 4 }, message: "must be equal to constant" };
15570
+ if (!(data15 === "succeeded" || data15 === "returned" || data15 === "failed" || data15 === "interrupted" || data15 === "prevented" || data15 === "unknown")) {
15571
+ const err32 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/toolOutcome/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.toolOutcome.enum }, message: "must be equal to one of the allowed values" };
15513
15572
  if (vErrors === null) {
15514
- vErrors = [err20];
15573
+ vErrors = [err32];
15515
15574
  } else {
15516
- vErrors.push(err20);
15575
+ vErrors.push(err32);
15517
15576
  }
15518
15577
  errors++;
15519
15578
  }
15520
- var valid4 = _errs30 === errors;
15579
+ var valid4 = _errs42 === errors;
15521
15580
  } else {
15522
15581
  var valid4 = true;
15523
15582
  }
15583
+ if (valid4) {
15584
+ if (data1.envelopeVersion !== void 0) {
15585
+ let data16 = data1.envelopeVersion;
15586
+ const _errs44 = errors;
15587
+ if (!(typeof data16 == "number" && isFinite(data16))) {
15588
+ const err33 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/envelopeVersion/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15589
+ if (vErrors === null) {
15590
+ vErrors = [err33];
15591
+ } else {
15592
+ vErrors.push(err33);
15593
+ }
15594
+ errors++;
15595
+ }
15596
+ if (4 !== data16) {
15597
+ const err34 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/envelopeVersion/const", keyword: "const", params: { allowedValue: 4 }, message: "must be equal to constant" };
15598
+ if (vErrors === null) {
15599
+ vErrors = [err34];
15600
+ } else {
15601
+ vErrors.push(err34);
15602
+ }
15603
+ errors++;
15604
+ }
15605
+ var valid4 = _errs44 === errors;
15606
+ } else {
15607
+ var valid4 = true;
15608
+ }
15609
+ }
15524
15610
  }
15525
15611
  }
15526
15612
  }
@@ -15533,11 +15619,11 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15533
15619
  }
15534
15620
  }
15535
15621
  } else {
15536
- const err21 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15622
+ const err35 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15537
15623
  if (vErrors === null) {
15538
- vErrors = [err21];
15624
+ vErrors = [err35];
15539
15625
  } else {
15540
- vErrors.push(err21);
15626
+ vErrors.push(err35);
15541
15627
  }
15542
15628
  errors++;
15543
15629
  }
@@ -15545,296 +15631,509 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15545
15631
  var _valid0 = _errs7 === errors;
15546
15632
  valid3 = valid3 || _valid0;
15547
15633
  if (_valid0) {
15548
- var props0 = true;
15634
+ var props1 = true;
15549
15635
  }
15550
- const _errs32 = errors;
15551
- if (errors === _errs32) {
15636
+ const _errs46 = errors;
15637
+ if (errors === _errs46) {
15552
15638
  if (data1 && typeof data1 == "object" && !Array.isArray(data1)) {
15553
- let missing2;
15554
- if (data1.moveId === void 0 && (missing2 = "moveId") || data1.capturedAt === void 0 && (missing2 = "capturedAt") || data1.sessionId === void 0 && (missing2 = "sessionId") || data1.eventType === void 0 && (missing2 = "eventType")) {
15555
- const err22 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/required", keyword: "required", params: { missingProperty: missing2 }, message: "must have required property '" + missing2 + "'" };
15639
+ let missing4;
15640
+ if (data1.moveId === void 0 && (missing4 = "moveId") || data1.capturedAt === void 0 && (missing4 = "capturedAt") || data1.sessionId === void 0 && (missing4 = "sessionId") || data1.eventType === void 0 && (missing4 = "eventType")) {
15641
+ const err36 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/required", keyword: "required", params: { missingProperty: missing4 }, message: "must have required property '" + missing4 + "'" };
15556
15642
  if (vErrors === null) {
15557
- vErrors = [err22];
15643
+ vErrors = [err36];
15558
15644
  } else {
15559
- vErrors.push(err22);
15645
+ vErrors.push(err36);
15560
15646
  }
15561
15647
  errors++;
15562
15648
  } else {
15563
15649
  if (data1.moveId !== void 0) {
15564
- const _errs35 = errors;
15650
+ const _errs49 = errors;
15565
15651
  if (typeof data1.moveId !== "string") {
15566
- const err23 = { instancePath: instancePath + "/batch/" + i0 + "/moveId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/moveId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15652
+ const err37 = { instancePath: instancePath + "/batch/" + i0 + "/moveId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/moveId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15567
15653
  if (vErrors === null) {
15568
- vErrors = [err23];
15654
+ vErrors = [err37];
15569
15655
  } else {
15570
- vErrors.push(err23);
15656
+ vErrors.push(err37);
15571
15657
  }
15572
15658
  errors++;
15573
15659
  }
15574
- var valid5 = _errs35 === errors;
15660
+ var valid8 = _errs49 === errors;
15575
15661
  } else {
15576
- var valid5 = true;
15662
+ var valid8 = true;
15577
15663
  }
15578
- if (valid5) {
15664
+ if (valid8) {
15579
15665
  if (data1.capturedAt !== void 0) {
15580
- let data14 = data1.capturedAt;
15581
- const _errs37 = errors;
15582
- if (!(typeof data14 == "number" && isFinite(data14))) {
15583
- const err24 = { instancePath: instancePath + "/batch/" + i0 + "/capturedAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedAt/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15666
+ let data18 = data1.capturedAt;
15667
+ const _errs51 = errors;
15668
+ if (!(typeof data18 == "number" && isFinite(data18))) {
15669
+ const err38 = { instancePath: instancePath + "/batch/" + i0 + "/capturedAt", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedAt/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15584
15670
  if (vErrors === null) {
15585
- vErrors = [err24];
15671
+ vErrors = [err38];
15586
15672
  } else {
15587
- vErrors.push(err24);
15673
+ vErrors.push(err38);
15588
15674
  }
15589
15675
  errors++;
15590
15676
  }
15591
- var valid5 = _errs37 === errors;
15677
+ var valid8 = _errs51 === errors;
15592
15678
  } else {
15593
- var valid5 = true;
15679
+ var valid8 = true;
15594
15680
  }
15595
- if (valid5) {
15681
+ if (valid8) {
15596
15682
  if (data1.sessionId !== void 0) {
15597
- const _errs39 = errors;
15683
+ const _errs53 = errors;
15598
15684
  if (typeof data1.sessionId !== "string") {
15599
- const err25 = { instancePath: instancePath + "/batch/" + i0 + "/sessionId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/sessionId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15685
+ const err39 = { instancePath: instancePath + "/batch/" + i0 + "/sessionId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/sessionId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15600
15686
  if (vErrors === null) {
15601
- vErrors = [err25];
15687
+ vErrors = [err39];
15602
15688
  } else {
15603
- vErrors.push(err25);
15689
+ vErrors.push(err39);
15604
15690
  }
15605
15691
  errors++;
15606
15692
  }
15607
- var valid5 = _errs39 === errors;
15693
+ var valid8 = _errs53 === errors;
15608
15694
  } else {
15609
- var valid5 = true;
15695
+ var valid8 = true;
15610
15696
  }
15611
- if (valid5) {
15697
+ if (valid8) {
15612
15698
  if (data1.invocationId !== void 0) {
15613
- const _errs41 = errors;
15699
+ const _errs55 = errors;
15614
15700
  if (typeof data1.invocationId !== "string") {
15615
- const err26 = { instancePath: instancePath + "/batch/" + i0 + "/invocationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/invocationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15701
+ const err40 = { instancePath: instancePath + "/batch/" + i0 + "/invocationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/invocationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15616
15702
  if (vErrors === null) {
15617
- vErrors = [err26];
15703
+ vErrors = [err40];
15618
15704
  } else {
15619
- vErrors.push(err26);
15705
+ vErrors.push(err40);
15620
15706
  }
15621
15707
  errors++;
15622
15708
  }
15623
- var valid5 = _errs41 === errors;
15709
+ var valid8 = _errs55 === errors;
15624
15710
  } else {
15625
- var valid5 = true;
15711
+ var valid8 = true;
15626
15712
  }
15627
- if (valid5) {
15713
+ if (valid8) {
15628
15714
  if (data1.eventType !== void 0) {
15629
- const _errs43 = errors;
15715
+ const _errs57 = errors;
15630
15716
  if (typeof data1.eventType !== "string") {
15631
- const err27 = { instancePath: instancePath + "/batch/" + i0 + "/eventType", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/eventType/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15717
+ const err41 = { instancePath: instancePath + "/batch/" + i0 + "/eventType", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/eventType/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15632
15718
  if (vErrors === null) {
15633
- vErrors = [err27];
15719
+ vErrors = [err41];
15634
15720
  } else {
15635
- vErrors.push(err27);
15721
+ vErrors.push(err41);
15636
15722
  }
15637
15723
  errors++;
15638
15724
  }
15639
- var valid5 = _errs43 === errors;
15725
+ var valid8 = _errs57 === errors;
15640
15726
  } else {
15641
- var valid5 = true;
15727
+ var valid8 = true;
15642
15728
  }
15643
- if (valid5) {
15644
- if (data1.capturedOrganizationId !== void 0) {
15645
- let data18 = data1.capturedOrganizationId;
15646
- const _errs45 = errors;
15647
- if (errors === _errs45) {
15648
- if (typeof data18 === "string") {
15649
- if (func1(data18) > 128) {
15650
- const err28 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15729
+ if (valid8) {
15730
+ if (data1.repositoryContext !== void 0) {
15731
+ let data22 = data1.repositoryContext;
15732
+ const _errs59 = errors;
15733
+ const _errs60 = errors;
15734
+ let valid9 = false;
15735
+ let passing1 = null;
15736
+ const _errs61 = errors;
15737
+ if (errors === _errs61) {
15738
+ if (data22 && typeof data22 == "object" && !Array.isArray(data22)) {
15739
+ let missing5;
15740
+ if (data22.kind === void 0 && (missing5 = "kind") || data22.repoSyncId === void 0 && (missing5 = "repoSyncId")) {
15741
+ const err42 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/required", keyword: "required", params: { missingProperty: missing5 }, message: "must have required property '" + missing5 + "'" };
15651
15742
  if (vErrors === null) {
15652
- vErrors = [err28];
15743
+ vErrors = [err42];
15653
15744
  } else {
15654
- vErrors.push(err28);
15745
+ vErrors.push(err42);
15655
15746
  }
15656
15747
  errors++;
15657
15748
  } else {
15658
- if (func1(data18) < 1) {
15659
- const err29 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15660
- if (vErrors === null) {
15661
- vErrors = [err29];
15662
- } else {
15663
- vErrors.push(err29);
15664
- }
15665
- errors++;
15666
- } else {
15667
- if (!pattern8.test(data18)) {
15668
- const err30 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' };
15749
+ const _errs63 = errors;
15750
+ for (const key2 in data22) {
15751
+ if (!(key2 === "kind" || key2 === "repoSyncId")) {
15752
+ const err43 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key2 }, message: "must NOT have additional properties" };
15669
15753
  if (vErrors === null) {
15670
- vErrors = [err30];
15754
+ vErrors = [err43];
15671
15755
  } else {
15672
- vErrors.push(err30);
15756
+ vErrors.push(err43);
15673
15757
  }
15674
15758
  errors++;
15759
+ break;
15760
+ }
15761
+ }
15762
+ if (_errs63 === errors) {
15763
+ if (data22.kind !== void 0) {
15764
+ let data23 = data22.kind;
15765
+ const _errs64 = errors;
15766
+ if (typeof data23 !== "string") {
15767
+ const err44 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/properties/kind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15768
+ if (vErrors === null) {
15769
+ vErrors = [err44];
15770
+ } else {
15771
+ vErrors.push(err44);
15772
+ }
15773
+ errors++;
15774
+ }
15775
+ if ("repository_bound" !== data23) {
15776
+ const err45 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/properties/kind/const", keyword: "const", params: { allowedValue: "repository_bound" }, message: "must be equal to constant" };
15777
+ if (vErrors === null) {
15778
+ vErrors = [err45];
15779
+ } else {
15780
+ vErrors.push(err45);
15781
+ }
15782
+ errors++;
15783
+ }
15784
+ var valid10 = _errs64 === errors;
15785
+ } else {
15786
+ var valid10 = true;
15787
+ }
15788
+ if (valid10) {
15789
+ if (data22.repoSyncId !== void 0) {
15790
+ let data24 = data22.repoSyncId;
15791
+ const _errs66 = errors;
15792
+ if (errors === _errs66) {
15793
+ if (typeof data24 === "string") {
15794
+ if (func1(data24) > 128) {
15795
+ const err46 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/properties/repoSyncId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15796
+ if (vErrors === null) {
15797
+ vErrors = [err46];
15798
+ } else {
15799
+ vErrors.push(err46);
15800
+ }
15801
+ errors++;
15802
+ } else {
15803
+ if (func1(data24) < 1) {
15804
+ const err47 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/properties/repoSyncId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15805
+ if (vErrors === null) {
15806
+ vErrors = [err47];
15807
+ } else {
15808
+ vErrors.push(err47);
15809
+ }
15810
+ errors++;
15811
+ }
15812
+ }
15813
+ } else {
15814
+ const err48 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/repoSyncId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/properties/repoSyncId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15815
+ if (vErrors === null) {
15816
+ vErrors = [err48];
15817
+ } else {
15818
+ vErrors.push(err48);
15819
+ }
15820
+ errors++;
15821
+ }
15822
+ }
15823
+ var valid10 = _errs66 === errors;
15824
+ } else {
15825
+ var valid10 = true;
15826
+ }
15675
15827
  }
15676
15828
  }
15677
15829
  }
15678
15830
  } else {
15679
- const err31 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15831
+ const err49 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/0/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15680
15832
  if (vErrors === null) {
15681
- vErrors = [err31];
15833
+ vErrors = [err49];
15682
15834
  } else {
15683
- vErrors.push(err31);
15835
+ vErrors.push(err49);
15684
15836
  }
15685
15837
  errors++;
15686
15838
  }
15687
15839
  }
15688
- var valid5 = _errs45 === errors;
15689
- } else {
15690
- var valid5 = true;
15691
- }
15692
- if (valid5) {
15693
- if (data1.captureAuthorityKind !== void 0) {
15694
- let data19 = data1.captureAuthorityKind;
15695
- const _errs47 = errors;
15696
- if (typeof data19 !== "string") {
15697
- const err32 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/captureAuthorityKind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15698
- if (vErrors === null) {
15699
- vErrors = [err32];
15840
+ var _valid2 = _errs61 === errors;
15841
+ if (_valid2) {
15842
+ valid9 = true;
15843
+ passing1 = 0;
15844
+ var props2 = true;
15845
+ }
15846
+ const _errs68 = errors;
15847
+ if (errors === _errs68) {
15848
+ if (data22 && typeof data22 == "object" && !Array.isArray(data22)) {
15849
+ let missing6;
15850
+ if (data22.kind === void 0 && (missing6 = "kind")) {
15851
+ const err50 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/1/required", keyword: "required", params: { missingProperty: missing6 }, message: "must have required property '" + missing6 + "'" };
15852
+ if (vErrors === null) {
15853
+ vErrors = [err50];
15854
+ } else {
15855
+ vErrors.push(err50);
15856
+ }
15857
+ errors++;
15700
15858
  } else {
15701
- vErrors.push(err32);
15859
+ const _errs70 = errors;
15860
+ for (const key3 in data22) {
15861
+ if (!(key3 === "kind")) {
15862
+ const err51 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/1/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key3 }, message: "must NOT have additional properties" };
15863
+ if (vErrors === null) {
15864
+ vErrors = [err51];
15865
+ } else {
15866
+ vErrors.push(err51);
15867
+ }
15868
+ errors++;
15869
+ break;
15870
+ }
15871
+ }
15872
+ if (_errs70 === errors) {
15873
+ if (data22.kind !== void 0) {
15874
+ let data25 = data22.kind;
15875
+ if (typeof data25 !== "string") {
15876
+ const err52 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/1/properties/kind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15877
+ if (vErrors === null) {
15878
+ vErrors = [err52];
15879
+ } else {
15880
+ vErrors.push(err52);
15881
+ }
15882
+ errors++;
15883
+ }
15884
+ if ("non_repository" !== data25) {
15885
+ const err53 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext/kind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/1/properties/kind/const", keyword: "const", params: { allowedValue: "non_repository" }, message: "must be equal to constant" };
15886
+ if (vErrors === null) {
15887
+ vErrors = [err53];
15888
+ } else {
15889
+ vErrors.push(err53);
15890
+ }
15891
+ errors++;
15892
+ }
15893
+ }
15894
+ }
15702
15895
  }
15703
- errors++;
15704
- }
15705
- if (!(data19 === "workos" || data19 === "service_token")) {
15706
- const err33 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/captureAuthorityKind/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.captureAuthorityKind.enum }, message: "must be equal to one of the allowed values" };
15896
+ } else {
15897
+ const err54 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf/1/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15707
15898
  if (vErrors === null) {
15708
- vErrors = [err33];
15899
+ vErrors = [err54];
15709
15900
  } else {
15710
- vErrors.push(err33);
15901
+ vErrors.push(err54);
15711
15902
  }
15712
15903
  errors++;
15713
15904
  }
15714
- var valid5 = _errs47 === errors;
15905
+ }
15906
+ var _valid2 = _errs68 === errors;
15907
+ if (_valid2 && valid9) {
15908
+ valid9 = false;
15909
+ passing1 = [passing1, 1];
15715
15910
  } else {
15716
- var valid5 = true;
15911
+ if (_valid2) {
15912
+ valid9 = true;
15913
+ passing1 = 1;
15914
+ if (props2 !== true) {
15915
+ props2 = true;
15916
+ }
15917
+ }
15717
15918
  }
15718
- if (valid5) {
15719
- if (data1.decisionLifecycleProtocolVersion !== void 0) {
15720
- let data20 = data1.decisionLifecycleProtocolVersion;
15721
- const _errs49 = errors;
15722
- if (!(typeof data20 == "number" && (!(data20 % 1) && !isNaN(data20)) && isFinite(data20))) {
15723
- const err34 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
15724
- if (vErrors === null) {
15725
- vErrors = [err34];
15726
- } else {
15727
- vErrors.push(err34);
15728
- }
15729
- errors++;
15919
+ if (!valid9) {
15920
+ const err55 = { instancePath: instancePath + "/batch/" + i0 + "/repositoryContext", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/repositoryContext/oneOf", keyword: "oneOf", params: { passingSchemas: passing1 }, message: "must match exactly one schema in oneOf" };
15921
+ if (vErrors === null) {
15922
+ vErrors = [err55];
15923
+ } else {
15924
+ vErrors.push(err55);
15925
+ }
15926
+ errors++;
15927
+ } else {
15928
+ errors = _errs60;
15929
+ if (vErrors !== null) {
15930
+ if (_errs60) {
15931
+ vErrors.length = _errs60;
15932
+ } else {
15933
+ vErrors = null;
15730
15934
  }
15731
- if (errors === _errs49) {
15732
- if (typeof data20 == "number" && isFinite(data20)) {
15733
- if (data20 > 9007199254740991 || isNaN(data20)) {
15734
- const err35 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
15935
+ }
15936
+ }
15937
+ var valid8 = _errs59 === errors;
15938
+ } else {
15939
+ var valid8 = true;
15940
+ }
15941
+ if (valid8) {
15942
+ if (data1.capturedOrganizationId !== void 0) {
15943
+ let data26 = data1.capturedOrganizationId;
15944
+ const _errs73 = errors;
15945
+ if (errors === _errs73) {
15946
+ if (typeof data26 === "string") {
15947
+ if (func1(data26) > 128) {
15948
+ const err56 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
15949
+ if (vErrors === null) {
15950
+ vErrors = [err56];
15951
+ } else {
15952
+ vErrors.push(err56);
15953
+ }
15954
+ errors++;
15955
+ } else {
15956
+ if (func1(data26) < 1) {
15957
+ const err57 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
15735
15958
  if (vErrors === null) {
15736
- vErrors = [err35];
15959
+ vErrors = [err57];
15737
15960
  } else {
15738
- vErrors.push(err35);
15961
+ vErrors.push(err57);
15739
15962
  }
15740
15963
  errors++;
15741
15964
  } else {
15742
- if (data20 < 1 || isNaN(data20)) {
15743
- const err36 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" };
15965
+ if (!pattern8.test(data26)) {
15966
+ const err58 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' };
15744
15967
  if (vErrors === null) {
15745
- vErrors = [err36];
15968
+ vErrors = [err58];
15746
15969
  } else {
15747
- vErrors.push(err36);
15970
+ vErrors.push(err58);
15748
15971
  }
15749
15972
  errors++;
15750
15973
  }
15751
15974
  }
15752
15975
  }
15976
+ } else {
15977
+ const err59 = { instancePath: instancePath + "/batch/" + i0 + "/capturedOrganizationId", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/capturedOrganizationId/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15978
+ if (vErrors === null) {
15979
+ vErrors = [err59];
15980
+ } else {
15981
+ vErrors.push(err59);
15982
+ }
15983
+ errors++;
15984
+ }
15985
+ }
15986
+ var valid8 = _errs73 === errors;
15987
+ } else {
15988
+ var valid8 = true;
15989
+ }
15990
+ if (valid8) {
15991
+ if (data1.captureAuthorityKind !== void 0) {
15992
+ let data27 = data1.captureAuthorityKind;
15993
+ const _errs75 = errors;
15994
+ if (typeof data27 !== "string") {
15995
+ const err60 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/captureAuthorityKind/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15996
+ if (vErrors === null) {
15997
+ vErrors = [err60];
15998
+ } else {
15999
+ vErrors.push(err60);
16000
+ }
16001
+ errors++;
16002
+ }
16003
+ if (!(data27 === "workos" || data27 === "service_token")) {
16004
+ const err61 = { instancePath: instancePath + "/batch/" + i0 + "/captureAuthorityKind", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/captureAuthorityKind/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.captureAuthorityKind.enum }, message: "must be equal to one of the allowed values" };
16005
+ if (vErrors === null) {
16006
+ vErrors = [err61];
16007
+ } else {
16008
+ vErrors.push(err61);
16009
+ }
16010
+ errors++;
15753
16011
  }
15754
- var valid5 = _errs49 === errors;
16012
+ var valid8 = _errs75 === errors;
15755
16013
  } else {
15756
- var valid5 = true;
16014
+ var valid8 = true;
15757
16015
  }
15758
- if (valid5) {
15759
- if (data1.producer !== void 0) {
15760
- let data21 = data1.producer;
15761
- const _errs51 = errors;
15762
- if (typeof data21 !== "string") {
15763
- const err37 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/producer/type", keyword: "type", params: { type: "string" }, message: "must be string" };
16016
+ if (valid8) {
16017
+ if (data1.decisionLifecycleProtocolVersion !== void 0) {
16018
+ let data28 = data1.decisionLifecycleProtocolVersion;
16019
+ const _errs77 = errors;
16020
+ if (!(typeof data28 == "number" && (!(data28 % 1) && !isNaN(data28)) && isFinite(data28))) {
16021
+ const err62 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
15764
16022
  if (vErrors === null) {
15765
- vErrors = [err37];
16023
+ vErrors = [err62];
15766
16024
  } else {
15767
- vErrors.push(err37);
16025
+ vErrors.push(err62);
15768
16026
  }
15769
16027
  errors++;
15770
16028
  }
15771
- if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
15772
- const err38 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.producer.enum }, message: "must be equal to one of the allowed values" };
15773
- if (vErrors === null) {
15774
- vErrors = [err38];
15775
- } else {
15776
- vErrors.push(err38);
16029
+ if (errors === _errs77) {
16030
+ if (typeof data28 == "number" && isFinite(data28)) {
16031
+ if (data28 > 9007199254740991 || isNaN(data28)) {
16032
+ const err63 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" };
16033
+ if (vErrors === null) {
16034
+ vErrors = [err63];
16035
+ } else {
16036
+ vErrors.push(err63);
16037
+ }
16038
+ errors++;
16039
+ } else {
16040
+ if (data28 < 1 || isNaN(data28)) {
16041
+ const err64 = { instancePath: instancePath + "/batch/" + i0 + "/decisionLifecycleProtocolVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/decisionLifecycleProtocolVersion/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" };
16042
+ if (vErrors === null) {
16043
+ vErrors = [err64];
16044
+ } else {
16045
+ vErrors.push(err64);
16046
+ }
16047
+ errors++;
16048
+ }
16049
+ }
15777
16050
  }
15778
- errors++;
15779
16051
  }
15780
- var valid5 = _errs51 === errors;
16052
+ var valid8 = _errs77 === errors;
15781
16053
  } else {
15782
- var valid5 = true;
16054
+ var valid8 = true;
15783
16055
  }
15784
- if (valid5) {
15785
- if (data1.toolOutcome !== void 0) {
15786
- let data22 = data1.toolOutcome;
15787
- const _errs53 = errors;
15788
- if (typeof data22 !== "string") {
15789
- const err39 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/toolOutcome/type", keyword: "type", params: { type: "string" }, message: "must be string" };
16056
+ if (valid8) {
16057
+ if (data1.producer !== void 0) {
16058
+ let data29 = data1.producer;
16059
+ const _errs79 = errors;
16060
+ if (typeof data29 !== "string") {
16061
+ const err65 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/producer/type", keyword: "type", params: { type: "string" }, message: "must be string" };
15790
16062
  if (vErrors === null) {
15791
- vErrors = [err39];
16063
+ vErrors = [err65];
15792
16064
  } else {
15793
- vErrors.push(err39);
16065
+ vErrors.push(err65);
15794
16066
  }
15795
16067
  errors++;
15796
16068
  }
15797
- if (!(data22 === "succeeded" || data22 === "returned" || data22 === "failed" || data22 === "interrupted" || data22 === "prevented" || data22 === "unknown")) {
15798
- const err40 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/toolOutcome/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.toolOutcome.enum }, message: "must be equal to one of the allowed values" };
16069
+ if (!(data29 === "claude_code" || data29 === "codex" || data29 === "cursor" || data29 === "hermes")) {
16070
+ const err66 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.producer.enum }, message: "must be equal to one of the allowed values" };
15799
16071
  if (vErrors === null) {
15800
- vErrors = [err40];
16072
+ vErrors = [err66];
15801
16073
  } else {
15802
- vErrors.push(err40);
16074
+ vErrors.push(err66);
15803
16075
  }
15804
16076
  errors++;
15805
16077
  }
15806
- var valid5 = _errs53 === errors;
16078
+ var valid8 = _errs79 === errors;
15807
16079
  } else {
15808
- var valid5 = true;
16080
+ var valid8 = true;
15809
16081
  }
15810
- if (valid5) {
15811
- if (data1.envelopeVersion !== void 0) {
15812
- let data23 = data1.envelopeVersion;
15813
- const _errs55 = errors;
15814
- if (errors === _errs55) {
15815
- if (typeof data23 == "number" && isFinite(data23)) {
15816
- if (data23 >= 4 || isNaN(data23)) {
15817
- const err41 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/envelopeVersion/exclusiveMaximum", keyword: "exclusiveMaximum", params: { comparison: "<", limit: 4 }, message: "must be < 4" };
16082
+ if (valid8) {
16083
+ if (data1.toolOutcome !== void 0) {
16084
+ let data30 = data1.toolOutcome;
16085
+ const _errs81 = errors;
16086
+ if (typeof data30 !== "string") {
16087
+ const err67 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/toolOutcome/type", keyword: "type", params: { type: "string" }, message: "must be string" };
16088
+ if (vErrors === null) {
16089
+ vErrors = [err67];
16090
+ } else {
16091
+ vErrors.push(err67);
16092
+ }
16093
+ errors++;
16094
+ }
16095
+ if (!(data30 === "succeeded" || data30 === "returned" || data30 === "failed" || data30 === "interrupted" || data30 === "prevented" || data30 === "unknown")) {
16096
+ const err68 = { instancePath: instancePath + "/batch/" + i0 + "/toolOutcome", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/toolOutcome/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.toolOutcome.enum }, message: "must be equal to one of the allowed values" };
16097
+ if (vErrors === null) {
16098
+ vErrors = [err68];
16099
+ } else {
16100
+ vErrors.push(err68);
16101
+ }
16102
+ errors++;
16103
+ }
16104
+ var valid8 = _errs81 === errors;
16105
+ } else {
16106
+ var valid8 = true;
16107
+ }
16108
+ if (valid8) {
16109
+ if (data1.envelopeVersion !== void 0) {
16110
+ let data31 = data1.envelopeVersion;
16111
+ const _errs83 = errors;
16112
+ if (errors === _errs83) {
16113
+ if (typeof data31 == "number" && isFinite(data31)) {
16114
+ if (data31 >= 4 || isNaN(data31)) {
16115
+ const err69 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/envelopeVersion/exclusiveMaximum", keyword: "exclusiveMaximum", params: { comparison: "<", limit: 4 }, message: "must be < 4" };
16116
+ if (vErrors === null) {
16117
+ vErrors = [err69];
16118
+ } else {
16119
+ vErrors.push(err69);
16120
+ }
16121
+ errors++;
16122
+ }
16123
+ } else {
16124
+ const err70 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/envelopeVersion/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15818
16125
  if (vErrors === null) {
15819
- vErrors = [err41];
16126
+ vErrors = [err70];
15820
16127
  } else {
15821
- vErrors.push(err41);
16128
+ vErrors.push(err70);
15822
16129
  }
15823
16130
  errors++;
15824
16131
  }
15825
- } else {
15826
- const err42 = { instancePath: instancePath + "/batch/" + i0 + "/envelopeVersion", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/envelopeVersion/type", keyword: "type", params: { type: "number" }, message: "must be number" };
15827
- if (vErrors === null) {
15828
- vErrors = [err42];
15829
- } else {
15830
- vErrors.push(err42);
15831
- }
15832
- errors++;
15833
16132
  }
16133
+ var valid8 = _errs83 === errors;
16134
+ } else {
16135
+ var valid8 = true;
15834
16136
  }
15835
- var valid5 = _errs55 === errors;
15836
- } else {
15837
- var valid5 = true;
15838
16137
  }
15839
16138
  }
15840
16139
  }
@@ -15848,28 +16147,28 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15848
16147
  }
15849
16148
  }
15850
16149
  } else {
15851
- const err43 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/type", keyword: "type", params: { type: "object" }, message: "must be object" };
16150
+ const err71 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/type", keyword: "type", params: { type: "object" }, message: "must be object" };
15852
16151
  if (vErrors === null) {
15853
- vErrors = [err43];
16152
+ vErrors = [err71];
15854
16153
  } else {
15855
- vErrors.push(err43);
16154
+ vErrors.push(err71);
15856
16155
  }
15857
16156
  errors++;
15858
16157
  }
15859
16158
  }
15860
- var _valid0 = _errs32 === errors;
16159
+ var _valid0 = _errs46 === errors;
15861
16160
  valid3 = valid3 || _valid0;
15862
16161
  if (_valid0) {
15863
- if (props0 !== true) {
15864
- props0 = true;
16162
+ if (props1 !== true) {
16163
+ props1 = true;
15865
16164
  }
15866
16165
  }
15867
16166
  if (!valid3) {
15868
- const err44 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf", keyword: "anyOf", params: {}, message: "must match a schema in anyOf" };
16167
+ const err72 = { instancePath: instancePath + "/batch/" + i0, schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf", keyword: "anyOf", params: {}, message: "must match a schema in anyOf" };
15869
16168
  if (vErrors === null) {
15870
- vErrors = [err44];
16169
+ vErrors = [err72];
15871
16170
  } else {
15872
- vErrors.push(err44);
16171
+ vErrors.push(err72);
15873
16172
  }
15874
16173
  errors++;
15875
16174
  validate51.errors = vErrors;
@@ -20292,6 +20591,53 @@ import {
20292
20591
  writeFileSync as writeFileSync4
20293
20592
  } from "fs";
20294
20593
  import { delimiter, dirname as dirname6, isAbsolute as isAbsolute4, join as join9, resolve as resolve3 } from "path";
20594
+
20595
+ // src/lib/git-hook-contract.ts
20596
+ var GIT_HOOK_ENTRYPOINT_CONTENT = `#!/bin/sh
20597
+ # prim git hook entrypoint v1 \u2014 managed by prim; do not edit.
20598
+ # Run by the "# >>> prim <hook> hook >>>" block in a Git hook file. Acts only
20599
+ # where prim is active (git config prim.active true) and never fails the hook.
20600
+ case "$0" in */*) prim_dir=\${0%/*} ;; *) exit 0 ;; esac
20601
+ prim_launcher="$prim_dir/${STABLE_HOOK_LAUNCHER_NAME}"
20602
+ [ -x "$prim_launcher" ] || exit 0
20603
+ [ "$(git config --get prim.active 2>/dev/null)" = "true" ] || exit 0
20604
+ prim_hook=\${1-}
20605
+ if [ "$#" -gt 0 ]; then shift; fi
20606
+ case "$prim_hook" in
20607
+ pre-commit)
20608
+ "$prim_launcher" prim-pre-commit "$@" || :
20609
+ ;;
20610
+ post-commit)
20611
+ prim_sha=$(git rev-parse --verify HEAD 2>/dev/null) || exit 0
20612
+ case "$prim_sha" in *[!0-9a-f]* | "") exit 0 ;; esac
20613
+ case "\${#prim_sha}" in 40 | 64) ;; *) exit 0 ;; esac
20614
+ prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
20615
+ prim_observed=$(mktemp "\${TMPDIR:-/tmp}/prim-post-commit-observed.XXXXXXXX" 2>/dev/null) || prim_observed=
20616
+ (
20617
+ trap '' HUP
20618
+ trap 'if [ -n "$prim_observed" ]; then rm -f "$prim_observed"; fi' 0
20619
+ PRIM_COMMIT_SHA=$prim_sha PRIM_COMMIT_BRANCH=$prim_branch PRIM_COMMIT_OBSERVED_FILE=$prim_observed "$prim_launcher" prim-post-commit
20620
+ ) </dev/null >/dev/null 2>&1 &
20621
+ ;;
20622
+ post-rewrite)
20623
+ case "\${1-}" in amend | rebase) prim_source=$1 ;; *) exit 0 ;; esac
20624
+ prim_pairs=$(mktemp "\${TMPDIR:-/tmp}/prim-post-rewrite-pairs.XXXXXXXX" 2>/dev/null) || exit 0
20625
+ if ! chmod 600 "$prim_pairs" 2>/dev/null || ! cat >"$prim_pairs"; then
20626
+ rm -f "$prim_pairs"
20627
+ exit 0
20628
+ fi
20629
+ prim_branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || prim_branch=
20630
+ (
20631
+ trap '' HUP
20632
+ trap 'rm -f "$prim_pairs"' 0
20633
+ PRIM_REWRITE_SOURCE=$prim_source PRIM_REWRITE_BRANCH=$prim_branch PRIM_REWRITE_PAIRS_FILE=$prim_pairs "$prim_launcher" prim-post-rewrite
20634
+ ) </dev/null >/dev/null 2>&1 &
20635
+ ;;
20636
+ esac
20637
+ exit 0
20638
+ `;
20639
+
20640
+ // src/lib/hook-runtime.ts
20295
20641
  var RELEASE_PREFIX = "release-";
20296
20642
  var MAX_MANIFEST_BYTES = 64 * 1024;
20297
20643
  var RELEASE_GRACE_MS = 10 * 60 * 1e3;
@@ -24964,7 +25310,7 @@ var COMMAND_OPTIONS = {
24964
25310
  longOptionalValues: set("--color")
24965
25311
  },
24966
25312
  grep: {
24967
- shortFlags: "EFGHIPRTUVabcdhLlnqrsuvwxyZz",
25313
+ shortFlags: "EFGHIPRTUVabcdhiLlnoqrsuvwxyZz",
24968
25314
  shortValues: "ABCDefm",
24969
25315
  longFlags: set(
24970
25316
  "--basic-regexp --binary-files-without-match --byte-offset --count --extended-regexp --files-with-matches --files-without-match --fixed-regexp --fixed-strings --help --ignore-case --initial-tab --invert-match --line-buffered --line-number --line-regexp --null --null-data --only-matching --perl-regexp --quiet --recursive --silent --unix-byte-offsets --version --with-filename --word-regexp"
@@ -24975,12 +25321,14 @@ var COMMAND_OPTIONS = {
24975
25321
  longOptionalValues: set("--color")
24976
25322
  },
24977
25323
  head: {
25324
+ numericCount: true,
24978
25325
  shortFlags: "qvz",
24979
25326
  shortValues: "cn",
24980
25327
  longFlags: set("--help --quiet --verbose --version --zero-terminated"),
24981
25328
  longValues: set("--bytes --lines")
24982
25329
  },
24983
25330
  tail: {
25331
+ numericCount: true,
24984
25332
  shortFlags: "Fqsvz",
24985
25333
  shortValues: "cn",
24986
25334
  longFlags: set("--help --quiet --retry --silent --verbose --version --zero-terminated"),
@@ -25005,6 +25353,7 @@ var COMMAND_OPTIONS = {
25005
25353
  }
25006
25354
  };
25007
25355
  var GIT_INSPECTION_OPTIONS = {
25356
+ numericCount: true,
25008
25357
  shortFlags: "abcdfhiklmnprstuvwz",
25009
25358
  shortValues: "ABCGLMSU",
25010
25359
  longFlags: set(
@@ -25147,6 +25496,7 @@ function parseOptions(args, spec) {
25147
25496
  optionsEnded = true;
25148
25497
  continue;
25149
25498
  }
25499
+ if (spec.numericCount && /^-\d+$/.test(arg)) continue;
25150
25500
  if (arg.startsWith("--")) {
25151
25501
  const separator = arg.indexOf("=");
25152
25502
  const option = separator === -1 ? arg : arg.slice(0, separator);
@@ -25703,6 +26053,15 @@ function hermesAdvisory(result, aggregate) {
25703
26053
  const message = [...new Set(parts.filter(Boolean))].join("\n");
25704
26054
  return message.startsWith("[primitive]") ? message : message ? `[primitive] ${message}` : "";
25705
26055
  }
26056
+ function preflightFailure(error) {
26057
+ if (!(error instanceof HttpError && error.status === 401)) {
26058
+ return "enforcement service unavailable; change was not verified";
26059
+ }
26060
+ if (resolveAuthCredential()?.source === "environment") {
26061
+ return "PRIM_TOKEN was rejected; change was not verified";
26062
+ }
26063
+ return "authentication required; run `prim auth login`; change was not verified";
26064
+ }
25706
26065
  async function emitUnverified(message, envelope) {
25707
26066
  const result = unverifiedResult(message);
25708
26067
  if (agent === "hermes") {
@@ -25824,8 +26183,8 @@ async function main() {
25824
26183
  return;
25825
26184
  }
25826
26185
  result = resultForPreflight(response);
25827
- } catch {
25828
- await emitUnverified("enforcement service unavailable; change was not verified", envelope);
26186
+ } catch (error) {
26187
+ await emitUnverified(preflightFailure(error), envelope);
25829
26188
  return;
25830
26189
  }
25831
26190
  const aggregate = demoteForMode(