@primitive.ai/prim 0.1.0-alpha.94 → 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 (40) hide show
  1. package/README.md +7 -4
  2. package/dist/{chunk-UKUAAAXE.js → chunk-27ADT6FQ.js} +2 -2
  3. package/dist/{chunk-OTHKG76J.js → chunk-35FMRWJH.js} +1 -1
  4. package/dist/{chunk-DXJQR4QI.js → chunk-4GHANPWQ.js} +2 -2
  5. package/dist/{chunk-WUXFLE7X.js → chunk-7KABYYWG.js} +64 -66
  6. package/dist/{chunk-LFFLHSQO.js → chunk-CU7RW7XU.js} +63 -6
  7. package/dist/{chunk-H4UNYFUC.js → chunk-DHOQGHKQ.js} +184 -1
  8. package/dist/{chunk-2GP5UFV7.js → chunk-DWRSEC34.js} +5 -3
  9. package/dist/{chunk-O7YAW7G6.js → chunk-FVDBULGZ.js} +9 -11
  10. package/dist/{chunk-G2VMA2QO.js → chunk-LY6NJ7KL.js} +6 -4
  11. package/dist/{chunk-ZB4F75SZ.js → chunk-MXVCP33E.js} +5 -1
  12. package/dist/{chunk-TYAHC25F.js → chunk-QCBB5HFX.js} +1 -1
  13. package/dist/{chunk-IMK4JKTA.js → chunk-RK4ZS3HG.js} +2 -2
  14. package/dist/{chunk-ZU563PQI.js → chunk-ROLYLXJS.js} +2 -2
  15. package/dist/{chunk-OH3EZXYX.js → chunk-UO2U6IKF.js} +1 -1
  16. package/dist/{chunk-K7D2EYBS.js → chunk-URLLSALP.js} +2 -2
  17. package/dist/{chunk-FXF4JWK2.js → chunk-XEDJ5N3M.js} +17 -2
  18. package/dist/{chunk-AXQQMX2U.js → chunk-Y5W4TZM7.js} +2 -2
  19. package/dist/{chunk-ICM2XCXS.js → chunk-YYE2NLWX.js} +2 -2
  20. package/dist/{chunk-DSWT6BCC.js → chunk-Z6NPNLOT.js} +825 -665
  21. package/dist/daemon/server.js +836 -540
  22. package/dist/hook-runtime/daemon/server.js +836 -540
  23. package/dist/hook-runtime/hooks/post-commit.js +836 -540
  24. package/dist/hook-runtime/hooks/post-rewrite.js +836 -540
  25. package/dist/hook-runtime/hooks/post-tool-use.js +1160 -791
  26. package/dist/hook-runtime/hooks/pre-tool-use.js +2060 -1751
  27. package/dist/hook-runtime/hooks/prim-hook.js +1257 -856
  28. package/dist/hook-runtime/hooks/session-end.js +179 -129
  29. package/dist/hook-runtime/hooks/session-start.js +938 -640
  30. package/dist/hook-runtime/index.js +892 -554
  31. package/dist/hooks/post-commit.js +11 -11
  32. package/dist/hooks/post-rewrite.js +10 -10
  33. package/dist/hooks/post-tool-use.js +20 -20
  34. package/dist/hooks/pre-commit.js +4 -4
  35. package/dist/hooks/pre-tool-use.js +29 -17
  36. package/dist/hooks/prim-hook.js +22 -18
  37. package/dist/hooks/session-end.js +11 -5
  38. package/dist/hooks/session-start.js +26 -22
  39. package/dist/index.js +79 -60
  40. package/package.json +1 -1
@@ -51,626 +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;
372
+ return {
373
+ version: 1,
374
+ family: "legacy_broker",
375
+ accessTokenHash: record.accessTokenHash,
376
+ refreshTokenHash: record.refreshTokenHash
377
+ };
367
378
  }
368
- function shellQuote(value) {
369
- return `'${value.replaceAll("'", `'"'"'`)}'`;
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;
385
+ }
386
+ if (Buffer.byteLength(raw, "utf8") > MAX_CREDENTIAL_METADATA_BYTES) return null;
387
+ try {
388
+ return JSON.parse(raw);
389
+ } catch {
390
+ return null;
391
+ }
370
392
  }
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
- var PRIM_CONFIG_SHELL_RESOLVER = [
374
- 'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
375
- 'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
376
- 'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
377
- '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; ',
378
- "fi; fi; "
379
- ].join("");
380
- function stableHookCommand(bin, args = "") {
381
- if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
382
- throw new Error("invalid stable hook command");
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) };
400
+ }
401
+ return {
402
+ state: "workos_connect",
403
+ metadata: parseWorkosConnectCredentialMetadata(parsed)
404
+ };
405
+ } catch {
406
+ return { state: "invalid" };
383
407
  }
384
- const resolver = [
385
- // #242 and earlier identify managed commands by this package marker. Keep
386
- // it as inert data during the rolling window so an older uninstall or
387
- // reinstall can remove the stable entry without invoking npm or PATH.
388
- `prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
389
- PRIM_CONFIG_SHELL_RESOLVER,
390
- `case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
391
- 'exec "$prim_launcher" "$@"'
392
- ].join("");
393
- const suffix = args ? ` ${args}` : "";
394
- return `/bin/sh -c ${shellQuote(resolver)} ${STABLE_HOOK_LAUNCHER_NAME} ${bin}${suffix}`;
395
408
  }
396
- function detachedHookShimCommand(bin, args = "") {
397
- return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
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;
398
414
  }
399
-
400
- // src/client.ts
401
- import { createHash as createHash3 } from "crypto";
402
- import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, rmSync as rmSync3 } from "fs";
403
- import { dirname as dirname5 } from "path";
404
-
405
- // src/lib/atomic-file.ts
406
- import { randomUUID } from "crypto";
407
- import {
408
- constants,
409
- closeSync,
410
- fchmodSync,
411
- fsyncSync,
412
- mkdirSync,
413
- openSync,
414
- renameSync,
415
- rmSync,
416
- writeFileSync
417
- } from "fs";
418
- import { dirname as dirname3 } from "path";
419
- var DEFAULT_FILE_MODE = 438;
420
- function syncDirectory(path) {
421
- const fd = openSync(path, constants.O_RDONLY);
422
- try {
423
- fsyncSync(fd);
424
- } finally {
425
- closeSync(fd);
426
- }
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";
427
419
  }
428
- function syncCreatedParentChain(firstCreatedParent, parent) {
429
- const createdDirectories = [];
430
- let current = parent;
431
- while (current !== firstCreatedParent) {
432
- createdDirectories.push(current);
433
- const next = dirname3(current);
434
- if (next === current) {
435
- throw new Error("recursive mkdir returned a path outside the target parent chain");
436
- }
437
- current = next;
438
- }
439
- createdDirectories.push(firstCreatedParent);
440
- syncDirectory(dirname3(firstCreatedParent));
441
- for (const directory of createdDirectories.reverse().slice(0, -1)) {
442
- syncDirectory(directory);
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" };
443
426
  }
444
- }
445
- function ensureDurableDirectory(path, mode) {
446
- const firstCreatedParent = mkdirSync(path, { recursive: true, mode });
447
- if (firstCreatedParent) {
448
- syncCreatedParentChain(firstCreatedParent, path);
427
+ if (parsed === null) return { state: "invalid" };
428
+ try {
429
+ return {
430
+ state: "workos_connect",
431
+ metadata: parseWorkosConnectCredentialMetadata(parsed)
432
+ };
433
+ } catch {
434
+ return { state: "invalid" };
449
435
  }
450
436
  }
451
- function atomicWriteFile(target, content, options = {}) {
452
- const parent = dirname3(target);
453
- if (options.ensureParent) {
454
- ensureDurableDirectory(parent);
455
- }
456
- const temporaryPath = `${target}.${randomUUID()}.tmp`;
457
- let temporaryCreated = false;
437
+ function decodeJwtPayload(token) {
438
+ const parts = token.split(".");
439
+ if (parts.length !== 3) return void 0;
458
440
  try {
459
- const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
460
- const fd = openSync(temporaryPath, flags, options.mode ?? DEFAULT_FILE_MODE);
461
- temporaryCreated = true;
462
- try {
463
- if (options.mode !== void 0) fchmodSync(fd, options.mode);
464
- writeFileSync(fd, content);
465
- fsyncSync(fd);
466
- } finally {
467
- closeSync(fd);
468
- }
469
- options.validate?.(temporaryPath);
470
- renameSync(temporaryPath, target);
471
- syncDirectory(parent);
472
- } catch (error) {
473
- if (temporaryCreated) {
474
- try {
475
- rmSync(temporaryPath, { force: true });
476
- } catch {
477
- }
478
- }
479
- throw error;
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;
480
446
  }
481
447
  }
448
+ function jwtExpiresAt(token) {
449
+ const exp = decodeJwtPayload(token)?.exp;
450
+ return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : void 0;
451
+ }
482
452
 
483
- // src/lib/credentials.ts
484
- import { createHash as createHash2 } from "crypto";
485
- import { readFileSync as readFileSync3 } from "fs";
486
- import { join as join4 } from "path";
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";
487
457
 
488
- // src/lib/paths.ts
489
- import { homedir as homedir2 } from "os";
490
- import { isAbsolute as isAbsolute3, join as join3, normalize } from "path";
491
- var UNSAFE_CONFIG_PATH_CHARACTERS = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
492
- function absolutePath(value, variable) {
493
- if (value !== void 0 && UNSAFE_CONFIG_PATH_CHARACTERS.test(value)) {
494
- throw new Error(`${variable} contains unsafe characters`);
495
- }
496
- if (!value || value.trim() !== value || !isAbsolute3(value)) return;
497
- const normalized = normalize(value);
498
- return normalized === value ? value : void 0;
499
- }
500
- function resolvePrimConfigDirectory(options = {}) {
501
- const env = options.env ?? process.env;
502
- const explicit = absolutePath(env.PRIM_CONFIG_DIR, "PRIM_CONFIG_DIR");
503
- if (explicit) return { path: explicit, source: "explicit" };
504
- const xdgConfigHome = absolutePath(env.XDG_CONFIG_HOME, "XDG_CONFIG_HOME");
505
- if (xdgConfigHome) return { path: join3(xdgConfigHome, "prim"), source: "xdg" };
506
- const home = absolutePath(options.homeDir ?? homedir2(), "HOME");
507
- if (!home) {
508
- throw new Error("cannot resolve Primitive config directory: HOME is not an absolute path");
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";
509
466
  }
510
- return { path: join3(home, ".config", "prim"), source: "default" };
511
- }
512
- function primConfigDirectory(options = {}) {
513
- return resolvePrimConfigDirectory(options).path;
514
467
  }
515
468
 
516
- // src/lib/workos-connect.ts
517
- var TOKEN_PATH = "/oauth2/token";
518
- var DISCOVERY_MAX_BYTES = 16 * 1024;
519
- var WORKOS_CONNECT_RESPONSE_MAX_BYTES = 64 * 1024;
520
- var MAX_DEVICE_LIFETIME_SECONDS = 60 * 60;
521
- var MAX_TOKEN_LIFETIME_SECONDS = 24 * 60 * 60;
522
- var MAX_URL_LENGTH = 2048;
523
- var MAX_CLIENT_ID_LENGTH = 256;
524
- var CONNECT_CLIENT_ID_PATTERN = /^client_[A-Za-z0-9_-]+$/u;
525
- var WorkosConnectProtocolError = class extends Error {
526
- code;
527
- constructor(code, message) {
528
- super(message);
529
- this.name = "WorkosConnectProtocolError";
530
- this.code = code;
531
- }
532
- };
533
- function recordFrom(value, label) {
534
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
535
- throw new WorkosConnectProtocolError("invalid_response", `${label} must be an object`);
536
- }
537
- return value;
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");
538
477
  }
539
- function exactString(value, field, maxLength) {
540
- const containsControl = typeof value === "string" && [...value].some((character) => {
541
- const code = character.charCodeAt(0);
542
- return code <= 31 || code === 127;
543
- });
544
- if (typeof value !== "string" || value.length === 0 || value.length > maxLength || value.trim() !== value || containsControl) {
545
- 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;
546
487
  }
547
- return value;
548
488
  }
549
- function safeInteger(value, field, minimum, maximum) {
550
- if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
551
- throw new WorkosConnectProtocolError("invalid_response", `${field} is invalid`);
552
- }
553
- return value;
489
+ function sameOwner(a, b) {
490
+ return a?.pid === b.pid && a.nonce === b.nonce && a.createdAt === b.createdAt;
554
491
  }
555
- function canonicalIssuer(value) {
556
- const issuer = exactString(value, "issuer", MAX_URL_LENGTH);
557
- let parsed;
492
+ function tryTakeLock(lockDir, now) {
558
493
  try {
559
- parsed = new URL(issuer);
560
- } catch {
561
- 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;
562
498
  }
563
- if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash || parsed.origin !== issuer) {
564
- 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;
565
515
  }
566
- return issuer;
567
516
  }
568
- function parseWorkosConnectCredentialMetadata(value) {
569
- const record = recordFrom(value, "credential metadata");
570
- if (record.version !== 1 || record.family !== "workos_connect") {
571
- throw new WorkosConnectProtocolError("invalid_metadata", "credential metadata is invalid");
572
- }
573
- const issuer = canonicalIssuer(record.issuer);
574
- const clientId = exactString(record.clientId, "clientId", MAX_CLIENT_ID_LENGTH);
575
- const accessTokenHash = exactString(record.accessTokenHash, "accessTokenHash", 64);
576
- const refreshTokenHash = exactString(record.refreshTokenHash, "refreshTokenHash", 64);
577
- if (!CONNECT_CLIENT_ID_PATTERN.test(clientId)) {
578
- 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;
579
524
  }
580
- if (!/^[a-f0-9]{64}$/u.test(accessTokenHash)) {
581
- throw new WorkosConnectProtocolError(
582
- "invalid_metadata",
583
- "credential accessTokenHash is invalid"
584
- );
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;
585
534
  }
586
- if (!/^[a-f0-9]{64}$/u.test(refreshTokenHash)) {
587
- throw new WorkosConnectProtocolError(
588
- "invalid_metadata",
589
- "credential refreshTokenHash is invalid"
590
- );
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;
591
549
  }
592
- return {
593
- version: 1,
594
- family: "workos_connect",
595
- issuer,
596
- clientId,
597
- accessTokenHash,
598
- refreshTokenHash
599
- };
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
+ });
600
562
  }
601
- async function readBoundedJson(response, maxBytes) {
602
- const contentLength = response.headers.get("content-length");
603
- if (contentLength !== null) {
604
- if (!/^\d+$/u.test(contentLength) || Number(contentLength) > maxBytes) {
605
- 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);
606
584
  }
607
585
  }
608
- if (!response.body) {
609
- throw new WorkosConnectProtocolError("invalid_response", "response body is missing");
610
- }
611
- const reader = response.body.getReader();
612
- const chunks = [];
613
- let total = 0;
614
586
  try {
615
- while (true) {
616
- const result = await reader.read();
617
- if (result.done) break;
618
- total += result.value.byteLength;
619
- if (total > maxBytes) {
620
- await reader.cancel();
621
- throw new WorkosConnectProtocolError("invalid_response", "response body is too large");
622
- }
623
- chunks.push(result.value);
624
- }
587
+ throwIfAborted(options.signal);
588
+ return await operation();
625
589
  } finally {
626
- reader.releaseLock();
627
- }
628
- const bytes = new Uint8Array(total);
629
- let offset = 0;
630
- for (const chunk of chunks) {
631
- bytes.set(chunk, offset);
632
- offset += chunk.byteLength;
590
+ if (sameOwner(readOwner(lockDir), owner)) {
591
+ rmSync2(lockDir, { recursive: true, force: true });
592
+ }
633
593
  }
634
- let text;
635
- try {
636
- text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
637
- return JSON.parse(text);
638
- } catch {
639
- 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
+ }
640
614
  }
615
+ return out;
641
616
  }
642
- function workosConnectTokenEndpoint(issuer) {
643
- 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;
644
629
  }
645
- function parseWorkosConnectTokens(value, options = {}) {
646
- const record = recordFrom(value, "token response");
647
- const accessToken = exactString(
648
- record.access_token,
649
- "access_token",
650
- WORKOS_CONNECT_RESPONSE_MAX_BYTES
651
- );
652
- const refreshToken2 = record.refresh_token === void 0 && options.fallbackRefreshToken !== void 0 ? options.fallbackRefreshToken : exactString(record.refresh_token, "refresh_token", WORKOS_CONNECT_RESPONSE_MAX_BYTES);
653
- return {
654
- accessToken,
655
- refreshToken: refreshToken2,
656
- expiresIn: record.expires_in === void 0 ? void 0 : safeInteger(record.expires_in, "expires_in", 1, MAX_TOKEN_LIFETIME_SECONDS)
657
- };
630
+ function terminalSafeText(value) {
631
+ return Array.from(replaceIsolatedSurrogates(value)).filter((character) => !isUnsafeTerminalCodePoint(character.codePointAt(0) ?? 0)).join("");
658
632
  }
633
+ function terminalSafeLine(value) {
634
+ return terminalSafeText(value.replace(/\s+/gu, " ")).replace(/\s+/gu, " ").trim();
635
+ }
636
+ var stripControlChars = terminalSafeText;
659
637
 
660
- // src/lib/credentials.ts
661
- var CONFIG_DIRECTORY = primConfigDirectory();
662
- var TOKEN_FILE_PATH = join4(CONFIG_DIRECTORY, "token");
663
- var REFRESH_TOKEN_PATH = join4(CONFIG_DIRECTORY, "refresh_token");
664
- var TOKEN_EXPIRES_PATH = join4(CONFIG_DIRECTORY, "token_expires_at");
665
- var TERMINAL_REFRESH_PATH = join4(CONFIG_DIRECTORY, "refresh_terminal");
666
- var CREDENTIAL_METADATA_PATH = join4(CONFIG_DIRECTORY, "credential_metadata.json");
667
- var CREDENTIAL_FAMILY_PATH = join4(CONFIG_DIRECTORY, "credential_family.json");
668
- var CREDENTIAL_MIGRATION_PATH = join4(CONFIG_DIRECTORY, "credential_migration.json");
669
- var CREDENTIAL_LOCK_PATH = join4(CONFIG_DIRECTORY, "credentials.lock");
670
- var MAX_CREDENTIAL_METADATA_BYTES = 4096;
671
- var CREDENTIAL_MIGRATION_VERSION = 1;
672
- var CREDENTIAL_MIGRATION_STATE = "family_bound";
673
- 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) {
674
645
  try {
675
646
  const value = readFileSync3(path, "utf8").trim();
676
647
  return value || void 0;
@@ -678,757 +649,786 @@ function readTrimmed(path) {
678
649
  return void 0;
679
650
  }
680
651
  }
681
- function resolveAuthCredential(options = {}) {
682
- const envToken = (options.env ?? process.env).PRIM_TOKEN?.trim();
683
- if (envToken) return { token: envToken, source: "environment" };
684
- const stored = readTrimmed(options.tokenFilePath ?? TOKEN_FILE_PATH);
685
- if (!stored) return void 0;
686
- const metadata = readStoredCredentialMetadata(
687
- options.metadataPath ?? CREDENTIAL_METADATA_PATH,
688
- options.familyPath ?? CREDENTIAL_FAMILY_PATH,
689
- options.migrationPath ?? CREDENTIAL_MIGRATION_PATH
690
- );
691
- if (metadata.state === "legacy_broker") {
692
- if (metadata.metadata) {
693
- const refreshToken3 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
694
- if (!refreshToken3 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken3)) {
695
- return void 0;
696
- }
697
- }
698
- return { token: stored, source: "token_file" };
699
- }
700
- if (metadata.state === "invalid") return void 0;
701
- const refreshToken2 = readTrimmed(options.refreshTokenPath ?? REFRESH_TOKEN_PATH);
702
- if (!refreshToken2 || metadata.metadata.accessTokenHash !== credentialFingerprint(stored) || metadata.metadata.refreshTokenHash !== credentialFingerprint(refreshToken2)) {
703
- return void 0;
704
- }
705
- return { token: stored, source: "token_file" };
706
- }
707
- function credentialFingerprint(value) {
708
- return createHash2("sha256").update(value).digest("hex");
652
+ function getSiteUrl() {
653
+ return getSiteUrlForEnvironment(process.env.PRIM_API_URL);
709
654
  }
710
- function parseLegacyBrokerCredentialMetadata(value) {
711
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
712
- throw new Error("credential family is invalid");
713
- }
714
- const record = value;
715
- 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)) {
716
- throw new Error("credential family is invalid");
717
- }
718
- return {
719
- version: 1,
720
- family: "legacy_broker",
721
- accessTokenHash: record.accessTokenHash,
722
- refreshTokenHash: record.refreshTokenHash
723
- };
655
+ function getSiteUrlForEnvironment(primApiUrl) {
656
+ return primApiUrl?.trim() || DEFAULT_API_URL;
724
657
  }
725
- function readBoundedCredentialJson(path) {
726
- let raw;
727
- try {
728
- raw = readFileSync3(path, "utf8");
729
- } catch (error) {
730
- return error.code === "ENOENT" ? void 0 : null;
731
- }
732
- if (Buffer.byteLength(raw, "utf8") > MAX_CREDENTIAL_METADATA_BYTES) return null;
733
- try {
734
- return JSON.parse(raw);
735
- } catch {
736
- return null;
737
- }
658
+ function expiresAtFor(token, expiresIn) {
659
+ return expiresIn === void 0 ? jwtExpiresAt(token) : Date.now() + expiresIn * 1e3;
738
660
  }
739
- function readCredentialFamily(path) {
740
- const parsed = readBoundedCredentialJson(path);
741
- if (parsed === void 0) return void 0;
742
- if (parsed === null) return { state: "invalid" };
743
- try {
744
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.family === "legacy_broker") {
745
- return { state: "legacy_broker", metadata: parseLegacyBrokerCredentialMetadata(parsed) };
746
- }
747
- return {
748
- state: "workos_connect",
749
- metadata: parseWorkosConnectCredentialMetadata(parsed)
750
- };
751
- } catch {
752
- return { state: "invalid" };
753
- }
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);
754
665
  }
755
- function isCredentialMigrationSentinel(value) {
756
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
757
- const record = value;
758
- const keys = Object.keys(record).sort();
759
- return keys.length === 2 && keys[0] === "state" && keys[1] === "version" && record.version === CREDENTIAL_MIGRATION_VERSION && record.state === CREDENTIAL_MIGRATION_STATE;
666
+ function atomicWrite(path, content) {
667
+ ensureConfigDirectory();
668
+ atomicWriteFile(path, content, { mode: CREDENTIAL_FILE_MODE });
760
669
  }
761
- function readCredentialMigrationState(path = CREDENTIAL_MIGRATION_PATH) {
762
- const parsed = readBoundedCredentialJson(path);
763
- if (parsed === void 0) return "absent";
764
- return parsed !== null && isCredentialMigrationSentinel(parsed) ? "valid" : "invalid";
670
+ function removeCredentialFile(path) {
671
+ if (!existsSync2(path)) return false;
672
+ rmSync3(path, { force: true });
673
+ return true;
765
674
  }
766
- function readStoredCredentialMetadata(metadataPath = CREDENTIAL_METADATA_PATH, familyPath = CREDENTIAL_FAMILY_PATH, migrationPath = CREDENTIAL_MIGRATION_PATH) {
767
- const family = readCredentialFamily(familyPath);
768
- if (family) return family;
769
- const parsed = readBoundedCredentialJson(metadataPath);
770
- if (parsed === void 0) {
771
- return readCredentialMigrationState(migrationPath) === "absent" ? { state: "legacy_broker" } : { state: "invalid" };
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) {
690
+ return {
691
+ version: 1,
692
+ family: "legacy_broker",
693
+ accessTokenHash: refreshFingerprint(accessToken),
694
+ refreshTokenHash: refreshFingerprint(refreshToken2)
695
+ };
696
+ }
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 };
703
+ }
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
+ );
713
+ }
714
+ function bindLegacyBrokerGeneration(accessToken, refreshToken2, metadata) {
715
+ if (metadata.state !== "legacy_broker" || !accessToken || !refreshToken2) {
716
+ return { state: "invalid" };
772
717
  }
773
- if (parsed === null) return { state: "invalid" };
774
- try {
775
- return {
776
- state: "workos_connect",
777
- metadata: parseWorkosConnectCredentialMetadata(parsed)
778
- };
779
- } catch {
718
+ const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
719
+ if (metadata.metadata !== void 0 && (metadata.metadata.accessTokenHash !== familyMetadata.accessTokenHash || metadata.metadata.refreshTokenHash !== familyMetadata.refreshTokenHash)) {
780
720
  return { state: "invalid" };
781
721
  }
782
- }
783
- function decodeJwtPayload(token) {
784
- const parts = token.split(".");
785
- if (parts.length !== 3) return void 0;
786
- try {
787
- const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
788
- if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return void 0;
789
- return payload;
790
- } catch {
791
- return void 0;
722
+ if (metadata.metadata === void 0) {
723
+ atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
724
+ `);
792
725
  }
726
+ const migrationState = readCredentialMigrationState();
727
+ if (migrationState === "invalid") return { state: "invalid" };
728
+ if (migrationState === "absent") writeCredentialMigrationSentinel();
729
+ return { state: "legacy_broker", metadata: familyMetadata };
793
730
  }
794
- function jwtExpiresAt(token) {
795
- const exp = decodeJwtPayload(token)?.exp;
796
- 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
+ `);
797
740
  }
798
-
799
- // src/lib/file-lock.ts
800
- import { randomBytes } from "crypto";
801
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync as rmSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
802
- import { dirname as dirname4, join as join5 } from "path";
803
-
804
- // src/lib/process-liveness.ts
805
- function processIsAlive(pid, probe = process.kill) {
806
- if (!Number.isSafeInteger(pid) || pid <= 0) return false;
807
- try {
808
- probe(pid, 0);
809
- return true;
810
- } catch (error) {
811
- return error.code === "EPERM";
812
- }
741
+ function terminalFingerprint() {
742
+ return readTrimmed2(TERMINAL_REFRESH_PATH);
813
743
  }
814
-
815
- // src/lib/file-lock.ts
816
- var DEFAULT_TIMEOUT_MS = 3e4;
817
- var DEFAULT_POLL_MS = 50;
818
- var DEFAULT_INIT_GRACE_MS = 2e3;
819
- var DIRECTORY_MODE = 448;
820
- var FILE_MODE = 384;
821
- function ownerPath(lockDir) {
822
- return join5(lockDir, "owner.json");
744
+ function writeTerminalFingerprint(refreshToken2) {
745
+ atomicWrite(TERMINAL_REFRESH_PATH, `${refreshFingerprint(refreshToken2)}
746
+ `);
823
747
  }
824
- function readOwner(lockDir) {
825
- try {
826
- const owner = JSON.parse(readFileSync4(ownerPath(lockDir), "utf8"));
827
- if (!Number.isInteger(owner.pid) || owner.pid <= 0 || typeof owner.nonce !== "string" || typeof owner.createdAt !== "number") {
828
- return null;
829
- }
830
- return owner;
831
- } catch {
832
- return null;
833
- }
748
+ function clearTerminalFingerprint() {
749
+ removeCredentialFile(TERMINAL_REFRESH_PATH);
834
750
  }
835
- function sameOwner(a, b) {
836
- 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);
837
756
  }
838
- function tryTakeLock(lockDir, now) {
839
- try {
840
- mkdirSync2(lockDir, { mode: DIRECTORY_MODE });
841
- } catch (error) {
842
- if (error.code === "EEXIST") return null;
843
- 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");
844
765
  }
845
- const owner = {
846
- pid: process.pid,
847
- nonce: randomBytes(16).toString("hex"),
848
- createdAt: now
849
- };
850
- try {
851
- writeFileSync2(ownerPath(lockDir), `${JSON.stringify(owner)}
852
- `, {
853
- encoding: "utf8",
854
- mode: FILE_MODE,
855
- flag: "wx"
856
- });
857
- return owner;
858
- } catch (error) {
859
- rmSync2(lockDir, { recursive: true, force: true });
860
- 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);
861
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" };
862
791
  }
863
- function recoverStaleLock(lockDir, now, alive, initGraceMs) {
864
- const owner = readOwner(lockDir);
865
- if (owner) {
866
- if (alive(owner.pid)) return false;
867
- if (!sameOwner(readOwner(lockDir), owner)) return false;
868
- rmSync2(lockDir, { recursive: true, force: true });
869
- return true;
870
- }
792
+ function isTerminalRefreshResponse(response, detail) {
793
+ if (detail.includes("invalid_grant") || detail.includes("Session has already ended")) return true;
871
794
  try {
872
- const before = statSync(lockDir).mtimeMs;
873
- if (now - before < initGraceMs) return false;
874
- if (readOwner(lockDir)) return false;
875
- if (statSync(lockDir).mtimeMs !== before) return false;
876
- rmSync2(lockDir, { recursive: true, force: true });
877
- return true;
795
+ const error = JSON.parse(detail).error;
796
+ return error === "invalid_grant" || response.status === 401 && error === "Invalid or expired refresh token";
878
797
  } catch {
879
- return true;
798
+ return response.status === 401 && detail.includes("Invalid or expired refresh token");
880
799
  }
881
800
  }
882
- function abortError(signal) {
883
- if (signal.reason instanceof Error) return signal.reason;
884
- const error = new Error("The operation was aborted");
885
- error.name = "AbortError";
886
- 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" : "";
887
804
  }
888
- function throwIfAborted(signal) {
889
- 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
+ );
890
813
  }
891
- async function defaultSleep(ms, signal) {
892
- if (!signal) {
893
- await new Promise((resolve5) => setTimeout(resolve5, ms));
894
- 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;
895
820
  }
896
- throwIfAborted(signal);
897
- await new Promise((resolve5, reject) => {
898
- const timer = setTimeout(() => {
899
- signal.removeEventListener("abort", onAbort);
900
- resolve5();
901
- }, ms);
902
- const onAbort = () => {
903
- clearTimeout(timer);
904
- reject(abortError(signal));
905
- };
906
- signal.addEventListener("abort", onAbort, { once: true });
907
- });
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;
908
823
  }
909
- var syncSleeper = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
910
- async function withFileLock(lockDir, operation, options = {}) {
911
- mkdirSync2(dirname4(lockDir), { recursive: true, mode: DIRECTORY_MODE });
912
- const nowMs = options.nowMs ?? Date.now;
913
- const alive = options.processAlive ?? processIsAlive;
914
- const deadline = nowMs() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
915
- let owner = null;
916
- while (!owner) {
917
- throwIfAborted(options.signal);
918
- const now = nowMs();
919
- owner = tryTakeLock(lockDir, now);
920
- if (owner) break;
921
- recoverStaleLock(lockDir, now, alive, options.initGraceMs ?? DEFAULT_INIT_GRACE_MS);
922
- if (now >= deadline) {
923
- throw new Error(`timed out waiting for file lock ${lockDir}`);
924
- }
925
- if (options.sleep) {
926
- await options.sleep(options.pollMs ?? DEFAULT_POLL_MS);
927
- throwIfAborted(options.signal);
928
- } else {
929
- await defaultSleep(options.pollMs ?? DEFAULT_POLL_MS, options.signal);
930
- }
931
- }
932
- try {
933
- throwIfAborted(options.signal);
934
- return await operation();
935
- } finally {
936
- if (sameOwner(readOwner(lockDir), owner)) {
937
- rmSync2(lockDir, { recursive: true, force: true });
938
- }
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;
939
829
  }
830
+ const replacementRefreshToken = readTrimmed2(REFRESH_TOKEN_PATH);
831
+ if (!replacementRefreshToken || replacementRefreshToken === currentGeneration) return void 0;
832
+ return readTrimmed2(TOKEN_FILE_PATH);
940
833
  }
941
-
942
- // src/lib/terminal-safe.ts
943
- function replaceIsolatedSurrogates(value) {
944
- let out = "";
945
- for (let index = 0; index < value.length; index += 1) {
946
- const unit = value.charCodeAt(index);
947
- if (unit >= 55296 && unit <= 56319) {
948
- const next = value.charCodeAt(index + 1);
949
- if (next >= 56320 && next <= 57343) {
950
- out += value[index] + value[index + 1];
951
- 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
+ }
952
954
  } else {
953
- 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
+ }
954
974
  }
955
- } else if (unit >= 56320 && unit <= 57343) {
956
- out += "\uFFFD";
957
- } else {
958
- out += value[index];
959
- }
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;
960
1010
  }
961
- 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;
962
1020
  }
963
- function isUnsafeTerminalCodePoint(point) {
964
- const c0OrC1 = point <= 31 || point >= 127 && point <= 159;
965
- const bidiOrZeroWidth = point === 173 || // soft hyphen
966
- point === 1564 || // Arabic letter mark
967
- point === 6158 || // Mongolian vowel separator
968
- point >= 8203 && point <= 8207 || // zero-width + directional marks
969
- point >= 8234 && point <= 8238 || // bidi embeddings/overrides
970
- point >= 8288 && point <= 8303 || // word joiner + bidi isolates/controls
971
- point >= 65529 && point <= 65531 || // interlinear annotation controls
972
- point === 65279 || // zero-width no-break space / BOM
973
- point >= 917504 && point <= 917631;
974
- 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
+ });
975
1031
  }
976
- function terminalSafeText(value) {
977
- 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();
978
1043
  }
979
- function terminalSafeLine(value) {
980
- 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);
981
1080
  }
982
- var stripControlChars = terminalSafeText;
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
+ };
1086
+ }
1087
+
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";
983
1093
 
984
- // src/client.ts
985
- var CONFIG_DIR_MODE = 448;
986
- var CREDENTIAL_FILE_MODE = 384;
987
- var REFRESH_THRESHOLD_MS = 6e4;
988
- var DEFAULT_API_URL = "https://api.getprimitive.ai";
989
- var AUTH_EXPIRED_MESSAGE = "Authentication expired. Run `prim auth login` to re-authenticate.";
990
- function readTrimmed2(path) {
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) {
991
1115
  try {
992
- 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();
993
1122
  return value || void 0;
994
1123
  } catch {
995
1124
  return void 0;
996
1125
  }
997
1126
  }
998
- function getSiteUrl() {
999
- return getSiteUrlForEnvironment(process.env.PRIM_API_URL);
1000
- }
1001
- function getSiteUrlForEnvironment(primApiUrl) {
1002
- return primApiUrl?.trim() || DEFAULT_API_URL;
1003
- }
1004
- function expiresAtFor(token, expiresIn) {
1005
- return expiresIn === void 0 ? jwtExpiresAt(token) : Date.now() + expiresIn * 1e3;
1006
- }
1007
- function ensureConfigDirectory() {
1008
- const directory = dirname5(TOKEN_FILE_PATH);
1009
- mkdirSync3(directory, { recursive: true, mode: CONFIG_DIR_MODE });
1010
- chmodSync(directory, CONFIG_DIR_MODE);
1011
- }
1012
- function atomicWrite(path, content) {
1013
- ensureConfigDirectory();
1014
- atomicWriteFile(path, content, { mode: CREDENTIAL_FILE_MODE });
1015
- }
1016
- function removeCredentialFile(path) {
1017
- if (!existsSync4(path)) return false;
1018
- rmSync3(path, { force: true });
1019
- return true;
1020
- }
1021
- function getTokenExpiresAt() {
1022
- const stored = readTrimmed2(TOKEN_EXPIRES_PATH);
1023
- if (stored === void 0) return void 0;
1024
- const value = Number(stored);
1025
- return Number.isNaN(value) ? void 0 : value;
1026
- }
1027
- function isTokenExpiringSoon(credential) {
1028
- if (credential.source !== "token_file") return false;
1029
- const expiresAt = getTokenExpiresAt();
1030
- return expiresAt !== void 0 && Date.now() >= expiresAt - REFRESH_THRESHOLD_MS;
1031
- }
1032
- function refreshFingerprint(refreshToken2) {
1033
- return createHash3("sha256").update(refreshToken2).digest("hex");
1034
- }
1035
- function legacyBrokerCredentialMetadata(accessToken, refreshToken2) {
1036
- return {
1037
- version: 1,
1038
- family: "legacy_broker",
1039
- accessTokenHash: refreshFingerprint(accessToken),
1040
- refreshTokenHash: refreshFingerprint(refreshToken2)
1041
- };
1042
- }
1043
- function credentialFamilyMetadata(accessToken, refreshToken2, metadata) {
1044
- const hashes = {
1045
- accessTokenHash: refreshFingerprint(accessToken),
1046
- refreshTokenHash: refreshFingerprint(refreshToken2)
1047
- };
1048
- return metadata === void 0 ? legacyBrokerCredentialMetadata(accessToken, refreshToken2) : { ...metadata, ...hashes };
1127
+ function currentBranch(cwd) {
1128
+ return gitValue(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
1049
1129
  }
1050
- function writeCredentialMigrationSentinel() {
1051
- atomicWrite(
1052
- CREDENTIAL_MIGRATION_PATH,
1053
- `${JSON.stringify({
1054
- version: CREDENTIAL_MIGRATION_VERSION,
1055
- state: CREDENTIAL_MIGRATION_STATE
1056
- })}
1057
- `
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
1058
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]}`;
1059
1143
  }
1060
- function bindLegacyBrokerGeneration(accessToken, refreshToken2, metadata) {
1061
- if (metadata.state !== "legacy_broker" || !accessToken || !refreshToken2) {
1062
- 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;
1063
1150
  }
1064
- const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
1065
- if (metadata.metadata !== void 0 && (metadata.metadata.accessTokenHash !== familyMetadata.accessTokenHash || metadata.metadata.refreshTokenHash !== familyMetadata.refreshTokenHash)) {
1066
- 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;
1067
1159
  }
1068
- if (metadata.metadata === void 0) {
1069
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1070
- `);
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;
1071
1171
  }
1072
- const migrationState = readCredentialMigrationState();
1073
- if (migrationState === "invalid") return { state: "invalid" };
1074
- if (migrationState === "absent") writeCredentialMigrationSentinel();
1075
- return { state: "legacy_broker", metadata: familyMetadata };
1076
- }
1077
- function preserveMarkerlessLegacyGeneration() {
1078
- const metadata = readStoredCredentialMetadata();
1079
- if (metadata.state !== "legacy_broker" || metadata.metadata !== void 0) return;
1080
- const accessToken = readTrimmed2(TOKEN_FILE_PATH);
1081
- const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
1082
- if (!(accessToken && refreshToken2)) return;
1083
- const familyMetadata = legacyBrokerCredentialMetadata(accessToken, refreshToken2);
1084
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1085
- `);
1086
- }
1087
- function terminalFingerprint() {
1088
- return readTrimmed2(TERMINAL_REFRESH_PATH);
1089
- }
1090
- function writeTerminalFingerprint(refreshToken2) {
1091
- atomicWrite(TERMINAL_REFRESH_PATH, `${refreshFingerprint(refreshToken2)}
1092
- `);
1093
1172
  }
1094
- function clearTerminalFingerprint() {
1095
- removeCredentialFile(TERMINAL_REFRESH_PATH);
1096
- }
1097
- function isSessionEnded() {
1098
- if (resolveAuthCredential()?.source !== "token_file") return false;
1099
- const refreshToken2 = readTrimmed2(REFRESH_TOKEN_PATH);
1100
- const ended = terminalFingerprint();
1101
- return Boolean(refreshToken2 && ended && refreshFingerprint(refreshToken2) === ended);
1173
+ function opaqueRepoKey(source, value) {
1174
+ return `repo_v1_${createHash3("sha256").update(`${source}\0${value}`).digest("hex")}`;
1102
1175
  }
1103
- function withCredentialLock(operation, options = {}) {
1104
- return withFileLock(CREDENTIAL_LOCK_PATH, operation, options);
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);
1184
+ }
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
+ };
1195
+ }
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 };
1105
1206
  }
1106
- function commitCredentialsUnlocked(credentials) {
1107
- const accessToken = credentials.accessToken.trim();
1108
- const refreshToken2 = credentials.refreshToken.trim();
1109
- if (!accessToken || !refreshToken2) {
1110
- throw new Error("OAuth credentials require both access and refresh tokens");
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
+ }
1111
1222
  }
1112
- const familyMetadata = credentialFamilyMetadata(accessToken, refreshToken2, credentials.metadata);
1113
- if (credentials.metadata !== void 0) {
1114
- preserveMarkerlessLegacyGeneration();
1115
- writeCredentialMigrationSentinel();
1116
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1117
- `);
1118
- atomicWrite(CREDENTIAL_METADATA_PATH, `${JSON.stringify(familyMetadata)}
1119
- `);
1120
- atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
1121
- `);
1122
- } else {
1123
- atomicWrite(REFRESH_TOKEN_PATH, `${refreshToken2}
1124
- `);
1125
- atomicWrite(CREDENTIAL_FAMILY_PATH, `${JSON.stringify(familyMetadata)}
1126
- `);
1127
- removeCredentialFile(CREDENTIAL_METADATA_PATH);
1223
+ try {
1224
+ return { real: realpathSync.native(cursor), suffix };
1225
+ } catch {
1226
+ return null;
1128
1227
  }
1129
- const expiresAt = expiresAtFor(accessToken, credentials.expiresIn);
1130
- if (expiresAt === void 0) removeCredentialFile(TOKEN_EXPIRES_PATH);
1131
- else atomicWrite(TOKEN_EXPIRES_PATH, `${expiresAt}
1132
- `);
1133
- atomicWrite(TOKEN_FILE_PATH, `${accessToken}
1134
- `);
1135
- clearTerminalFingerprint();
1136
- _cachedCredential = { token: accessToken, source: "token_file" };
1137
1228
  }
1138
- function isTerminalRefreshResponse(response, detail) {
1139
- if (detail.includes("invalid_grant") || detail.includes("Session has already ended")) return true;
1229
+ function canonicalRepositoryPathScoped(filePath, context, baseDir) {
1230
+ if (!filePath || filePath !== filePath.trim() || filePath.includes("\0")) {
1231
+ return { ok: false, reason: "invalid_path" };
1232
+ }
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" };
1241
+ }
1242
+ return { ok: true, file: sep === "/" ? rel : rel.split(sep).join("/") };
1243
+ }
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;
1140
1249
  try {
1141
- const error = JSON.parse(detail).error;
1142
- return error === "invalid_grant" || response.status === 401 && error === "Invalid or expired refresh token";
1143
- } catch {
1144
- return response.status === 401 && detail.includes("Invalid or expired refresh token");
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
+ }
1145
1264
  }
1146
- }
1147
- function workosConnectRefreshErrorCode(value) {
1148
- if (value === null || typeof value !== "object" || Array.isArray(value)) return "";
1149
- return value.error === "invalid_grant" ? "invalid_grant" : "";
1150
- }
1151
- function refreshDiagnostic(response, detail, quiet, provider) {
1152
- if (quiet) return;
1153
- const statusText = terminalSafeLine(response.statusText).slice(0, 120);
1154
- const safeDetail = terminalSafeLine(detail).slice(0, 200);
1155
- process.stderr.write(
1156
- `[prim] token refresh rejected by ${provider}: ${response.status}${statusText ? ` ${statusText}` : ""}${safeDetail ? ` \u2014 ${safeDetail}` : ""}
1157
- `
1158
- );
1159
- }
1160
- function metadataMatchesCredentialGeneration(expected, accessToken, refreshToken2) {
1161
- const current = readStoredCredentialMetadata();
1162
- if (expected.state === "legacy_broker") {
1163
- if (current.state !== "legacy_broker") return false;
1164
- if (!expected.metadata) return current.metadata === void 0;
1165
- 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;
1265
+ const rel = relative(repositoryRoot, target);
1266
+ if (!rel || isAbsolute2(rel) || rel === ".." || rel.startsWith(`..${sep}`)) {
1267
+ return null;
1166
1268
  }
1167
- if (expected.state !== "workos_connect" || current.state !== "workos_connect") return false;
1168
- 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;
1269
+ return sep === "/" ? rel : rel.split(sep).join("/");
1169
1270
  }
1170
- function uncoordinatedLegacyWinnerAccessToken(expected, currentGeneration) {
1171
- if (!expected || readCredentialMigrationState() !== "valid") return void 0;
1172
- const stored = readStoredCredentialMetadata();
1173
- if (stored.state !== "legacy_broker" || stored.metadata === void 0 || stored.metadata.accessTokenHash !== expected.accessTokenHash || stored.metadata.refreshTokenHash !== expected.refreshTokenHash) {
1174
- return void 0;
1271
+ function canonicalRepositoryPath(filePath, contextOrCwd, baseDirOrRoot) {
1272
+ if (typeof contextOrCwd === "string") {
1273
+ return canonicalRepositoryPathLegacy(filePath, contextOrCwd, baseDirOrRoot);
1175
1274
  }
1176
- const replacementRefreshToken = readTrimmed2(REFRESH_TOKEN_PATH);
1177
- if (!replacementRefreshToken || replacementRefreshToken === currentGeneration) return void 0;
1178
- return readTrimmed2(TOKEN_FILE_PATH);
1179
- }
1180
- function winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration) {
1181
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) return void 0;
1182
- const winner = resolveAuthCredential();
1183
- return (winner?.source === "token_file" ? winner.token : void 0) ?? uncoordinatedLegacyWinnerAccessToken(expectedLegacyGeneration, currentGeneration);
1184
- }
1185
- async function performTokenRefresh(options = {}) {
1186
- const selected = resolveAuthCredential();
1187
- if (selected?.source !== "token_file") return void 0;
1188
- const startingGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
1189
- if (!startingGeneration || isSessionEnded()) return void 0;
1190
- const startingAccessToken = selected.token;
1191
- return withCredentialLock(
1192
- async () => {
1193
- const currentCredential = resolveAuthCredential();
1194
- if (currentCredential?.source !== "token_file") return void 0;
1195
- const currentGeneration = readTrimmed2(REFRESH_TOKEN_PATH);
1196
- if (!currentGeneration) return void 0;
1197
- if (currentGeneration !== startingGeneration) {
1198
- return currentCredential.token;
1199
- }
1200
- if (currentCredential.token !== startingAccessToken) {
1201
- return currentCredential.token;
1202
- }
1203
- if (isSessionEnded()) return void 0;
1204
- let metadata = readStoredCredentialMetadata();
1205
- const markerlessLegacyAtStart = metadata.state === "legacy_broker" && metadata.metadata === void 0;
1206
- if (metadata.state === "invalid" || metadata.state === "workos_connect" && (metadata.metadata.accessTokenHash !== refreshFingerprint(currentCredential.token) || metadata.metadata.refreshTokenHash !== refreshFingerprint(currentGeneration))) {
1207
- return void 0;
1208
- }
1209
- if (metadata.state === "legacy_broker") {
1210
- try {
1211
- metadata = bindLegacyBrokerGeneration(
1212
- currentCredential.token,
1213
- currentGeneration,
1214
- metadata
1215
- );
1216
- } catch {
1217
- return void 0;
1218
- }
1219
- if (metadata.state !== "legacy_broker") return void 0;
1220
- }
1221
- const expectedLegacyGeneration = markerlessLegacyAtStart && metadata.state === "legacy_broker" ? metadata.metadata : void 0;
1222
- const connectContext = metadata.state === "workos_connect" ? {
1223
- version: 1,
1224
- family: "workos_connect",
1225
- issuer: metadata.metadata.issuer,
1226
- clientId: metadata.metadata.clientId
1227
- } : void 0;
1228
- const response = await fetch(
1229
- connectContext ? workosConnectTokenEndpoint(connectContext.issuer) : `${getSiteUrl()}/mcp/broker/refresh`,
1230
- connectContext ? {
1231
- method: "POST",
1232
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1233
- body: new URLSearchParams({
1234
- grant_type: "refresh_token",
1235
- refresh_token: currentGeneration,
1236
- client_id: connectContext.clientId
1237
- }),
1238
- signal: options.signal
1239
- } : {
1240
- method: "POST",
1241
- headers: { "Content-Type": "application/json" },
1242
- body: JSON.stringify({ refresh_token: currentGeneration }),
1243
- signal: options.signal
1244
- }
1245
- );
1246
- let directResponse;
1247
- if (connectContext) {
1248
- try {
1249
- directResponse = await readBoundedJson(response, WORKOS_CONNECT_RESPONSE_MAX_BYTES);
1250
- } catch {
1251
- if (response.ok && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
1252
- metadata,
1253
- currentCredential.token,
1254
- currentGeneration
1255
- )) {
1256
- writeTerminalFingerprint(currentGeneration);
1257
- }
1258
- return void 0;
1259
- }
1260
- }
1261
- if (!response.ok) {
1262
- let detail = "";
1263
- if (connectContext) {
1264
- detail = workosConnectRefreshErrorCode(directResponse);
1265
- } else {
1266
- detail = (await response.text().catch(() => "")).slice(0, 200);
1267
- }
1268
- if (isTerminalRefreshResponse(response, detail) && readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
1269
- writeTerminalFingerprint(currentGeneration);
1270
- }
1271
- refreshDiagnostic(
1272
- response,
1273
- detail,
1274
- options.quiet,
1275
- connectContext ? "WorkOS Connect" : "broker"
1276
- );
1277
- return winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
1278
- }
1279
- let accessToken;
1280
- let replacementRefreshToken;
1281
- let expiresIn;
1282
- if (connectContext) {
1283
- try {
1284
- const tokens = parseWorkosConnectTokens(directResponse, {
1285
- fallbackRefreshToken: currentGeneration
1286
- });
1287
- accessToken = tokens.accessToken;
1288
- replacementRefreshToken = tokens.refreshToken;
1289
- expiresIn = tokens.expiresIn;
1290
- } catch {
1291
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration && metadataMatchesCredentialGeneration(
1292
- metadata,
1293
- currentCredential.token,
1294
- currentGeneration
1295
- )) {
1296
- writeTerminalFingerprint(currentGeneration);
1297
- }
1298
- return void 0;
1299
- }
1300
- } else {
1301
- let data;
1302
- try {
1303
- data = await response.json();
1304
- } catch {
1305
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
1306
- writeTerminalFingerprint(currentGeneration);
1307
- }
1308
- return void 0;
1309
- }
1310
- const record = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
1311
- accessToken = typeof record?.access_token === "string" ? record.access_token.trim() : "";
1312
- replacementRefreshToken = typeof record?.refresh_token === "string" ? record.refresh_token.trim() : "";
1313
- expiresIn = typeof record?.expires_in === "number" && Number.isFinite(record.expires_in) ? record.expires_in : void 0;
1314
- if (!(accessToken && replacementRefreshToken)) {
1315
- if (readTrimmed2(REFRESH_TOKEN_PATH) === currentGeneration) {
1316
- writeTerminalFingerprint(currentGeneration);
1317
- }
1318
- return void 0;
1319
- }
1320
- }
1321
- const latestCredential = resolveAuthCredential();
1322
- if (readTrimmed2(REFRESH_TOKEN_PATH) !== currentGeneration || latestCredential?.source !== "token_file" || latestCredential.token !== currentCredential.token || !metadataMatchesCredentialGeneration(metadata, currentCredential.token, currentGeneration)) {
1323
- return latestCredential?.source === "token_file" ? latestCredential.token : winnerAfterRefreshRace(currentGeneration, expectedLegacyGeneration);
1324
- }
1325
- commitCredentialsUnlocked({
1326
- accessToken,
1327
- refreshToken: replacementRefreshToken,
1328
- expiresIn,
1329
- metadata: connectContext
1330
- });
1331
- return accessToken;
1332
- },
1333
- { signal: options.signal }
1275
+ return canonicalRepositoryPathScoped(
1276
+ filePath,
1277
+ contextOrCwd,
1278
+ baseDirOrRoot ?? contextOrCwd.repoRoot
1334
1279
  );
1335
1280
  }
1336
- var _refreshInFlight;
1337
- function refreshToken(options = {}) {
1338
- if (_refreshInFlight) return _refreshInFlight;
1339
- const attempt = performTokenRefresh(options).then((token) => {
1340
- if (token) _cachedCredential = { token, source: "token_file" };
1341
- return token;
1342
- }).finally(() => {
1343
- if (_refreshInFlight === attempt) _refreshInFlight = void 0;
1344
- });
1345
- _refreshInFlight = attempt;
1346
- return attempt;
1347
- }
1348
- var HttpError = class extends Error {
1349
- status;
1350
- body;
1351
- constructor(status, message, body) {
1352
- super(message);
1353
- this.name = "HttpError";
1354
- this.status = status;
1355
- 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;
1356
1304
  }
1357
- };
1358
- var CLI_MANAGEMENT_RESPONSE_MAX_BYTES = 2 * 1024 * 1024;
1359
- var _cachedCredential;
1360
- function selectedCredential() {
1361
- const resolved = resolveAuthCredential();
1362
- if (!_cachedCredential || resolved?.token !== _cachedCredential.token || resolved?.source !== _cachedCredential.source) {
1363
- _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;
1364
1323
  }
1365
- return _cachedCredential;
1366
1324
  }
1367
- function fetchWithToken(method, path, body, options, token, siteUrl) {
1368
- return fetch(`${siteUrl}${path}`, {
1369
- method,
1370
- headers: {
1371
- Authorization: `Bearer ${token}`,
1372
- "Content-Type": "application/json"
1373
- },
1374
- body: body === void 0 ? void 0 : JSON.stringify(body),
1375
- signal: options?.signal
1376
- });
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;
1377
1330
  }
1378
- async function responseValue(response) {
1379
- if (!response.ok) {
1380
- if (response.status === 401) {
1381
- 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
+ }
1382
1351
  }
1383
- const errorBody = await response.json().catch(() => null);
1384
- const errorRecord = typeof errorBody === "object" && errorBody !== null && !Array.isArray(errorBody) ? errorBody : void 0;
1385
- const message = typeof errorRecord?.error === "string" ? errorRecord.error : `HTTP ${response.status}`;
1386
- throw new HttpError(response.status, message, errorBody);
1387
1352
  }
1388
- return response.json();
1353
+ return false;
1389
1354
  }
1390
- async function request(method, path, body, options) {
1391
- const siteUrl = getSiteUrl();
1392
- let credential = selectedCredential();
1393
- let refreshAttempted = false;
1394
- if (credential && isTokenExpiringSoon(credential)) {
1395
- refreshAttempted = true;
1396
- const token = await refreshToken({
1397
- signal: options?.signal,
1398
- quiet: options?.quietRefresh
1399
- });
1400
- if (token) credential = { token, source: "token_file" };
1401
- }
1402
- if (!credential) {
1403
- throw new HttpError(401, AUTH_EXPIRED_MESSAGE);
1404
- }
1405
- if (isTokenExpiringSoon(credential) && isSessionEnded()) {
1406
- 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;
1407
1376
  }
1408
- const tokenUsed = credential.token;
1409
- let response = await fetchWithToken(method, path, body, options, tokenUsed, siteUrl);
1410
- if (response.status === 401) {
1411
- const latest = resolveAuthCredential();
1412
- let retryToken = latest?.token !== tokenUsed ? latest?.token : void 0;
1413
- if (!retryToken && latest?.source === "token_file" && !refreshAttempted) {
1414
- refreshAttempted = true;
1415
- 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
+ }
1416
1389
  }
1417
- if (retryToken) {
1418
- _cachedCredential = {
1419
- token: retryToken,
1420
- source: latest?.source === "token_file" ? "token_file" : latest?.source ?? "token_file"
1421
- };
1422
- response = await fetchWithToken(method, path, body, options, retryToken, siteUrl);
1390
+ const parent = dirname5(dir);
1391
+ if (parent === dir) {
1392
+ break;
1423
1393
  }
1394
+ dir = parent;
1424
1395
  }
1425
- return responseValue(response);
1396
+ resolvedRoot = null;
1397
+ return resolvedRoot;
1426
1398
  }
1427
- function getClient() {
1428
- return {
1429
- get: (path, options) => request("GET", path, void 0, options),
1430
- post: (path, body, options) => request("POST", path, body, options)
1431
- };
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 &`;
1432
1432
  }
1433
1433
 
1434
1434
  // src/generated/cli-http-v1.validators.js
@@ -12510,7 +12510,6 @@ function validate45(data, { instancePath = "", parentData, parentDataProperty, r
12510
12510
  return errors === 0;
12511
12511
  }
12512
12512
  validate45.evaluated = { "dynamicProps": true, "dynamicItems": false };
12513
- 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 }] };
12514
12513
  function validate46(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
12515
12514
  ;
12516
12515
  let vErrors = null;
@@ -12660,7 +12659,7 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12660
12659
  if (errors === _errs12) {
12661
12660
  if (data && typeof data == "object" && !Array.isArray(data)) {
12662
12661
  let missing2;
12663
- if (data.error === void 0 && (missing2 = "error") || data.feature === void 0 && (missing2 = "feature")) {
12662
+ if (data.error === void 0 && (missing2 = "error")) {
12664
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 + "'" };
12665
12664
  if (vErrors === null) {
12666
12665
  vErrors = [err10];
@@ -12671,231 +12670,102 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12671
12670
  } else {
12672
12671
  const _errs14 = errors;
12673
12672
  for (const key2 in data) {
12674
- if (!(key2 === "error" || key2 === "feature")) {
12673
+ if (!(key2 === "error")) {
12675
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" };
12676
12675
  if (vErrors === null) {
12677
12676
  vErrors = [err11];
12678
12677
  } else {
12679
- vErrors.push(err11);
12680
- }
12681
- errors++;
12682
- break;
12683
- }
12684
- }
12685
- if (_errs14 === errors) {
12686
- if (data.error !== void 0) {
12687
- let data2 = data.error;
12688
- const _errs15 = errors;
12689
- if (typeof data2 !== "string") {
12690
- 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" };
12691
- if (vErrors === null) {
12692
- vErrors = [err12];
12693
- } else {
12694
- vErrors.push(err12);
12695
- }
12696
- errors++;
12697
- }
12698
- if ("feature_disabled" !== data2) {
12699
- 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" };
12700
- if (vErrors === null) {
12701
- vErrors = [err13];
12702
- } else {
12703
- vErrors.push(err13);
12704
- }
12705
- errors++;
12706
- }
12707
- var valid4 = _errs15 === errors;
12708
- } else {
12709
- var valid4 = true;
12710
- }
12711
- if (valid4) {
12712
- if (data.feature !== void 0) {
12713
- let data3 = data.feature;
12714
- const _errs17 = errors;
12715
- if (typeof data3 !== "string") {
12716
- 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" };
12717
- if (vErrors === null) {
12718
- vErrors = [err14];
12719
- } else {
12720
- vErrors.push(err14);
12721
- }
12722
- errors++;
12723
- }
12724
- if ("github-connect" !== data3) {
12725
- 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" };
12726
- if (vErrors === null) {
12727
- vErrors = [err15];
12728
- } else {
12729
- vErrors.push(err15);
12730
- }
12731
- errors++;
12732
- }
12733
- var valid4 = _errs17 === errors;
12734
- } else {
12735
- var valid4 = true;
12736
- }
12737
- }
12738
- }
12739
- }
12740
- } else {
12741
- 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" };
12742
- if (vErrors === null) {
12743
- vErrors = [err16];
12744
- } else {
12745
- vErrors.push(err16);
12746
- }
12747
- errors++;
12748
- }
12749
- }
12750
- var _valid0 = _errs12 === errors;
12751
- valid1 = valid1 || _valid0;
12752
- if (_valid0) {
12753
- if (props0 !== true) {
12754
- props0 = true;
12755
- }
12756
- }
12757
- const _errs19 = errors;
12758
- if (errors === _errs19) {
12759
- if (data && typeof data == "object" && !Array.isArray(data)) {
12760
- let missing3;
12761
- if (data.error === void 0 && (missing3 = "error") || data.feature === void 0 && (missing3 = "feature")) {
12762
- 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 + "'" };
12763
- if (vErrors === null) {
12764
- vErrors = [err17];
12765
- } else {
12766
- vErrors.push(err17);
12767
- }
12768
- errors++;
12769
- } else {
12770
- const _errs21 = errors;
12771
- for (const key3 in data) {
12772
- if (!(key3 === "error" || key3 === "feature")) {
12773
- 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" };
12774
- if (vErrors === null) {
12775
- vErrors = [err18];
12776
- } else {
12777
- vErrors.push(err18);
12678
+ vErrors.push(err11);
12778
12679
  }
12779
12680
  errors++;
12780
12681
  break;
12781
12682
  }
12782
12683
  }
12783
- if (_errs21 === errors) {
12684
+ if (_errs14 === errors) {
12784
12685
  if (data.error !== void 0) {
12785
- let data4 = data.error;
12786
- const _errs22 = errors;
12787
- if (typeof data4 !== "string") {
12788
- 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" };
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" };
12789
12689
  if (vErrors === null) {
12790
- vErrors = [err19];
12690
+ vErrors = [err12];
12791
12691
  } else {
12792
- vErrors.push(err19);
12692
+ vErrors.push(err12);
12793
12693
  }
12794
12694
  errors++;
12795
12695
  }
12796
- if (!(data4 === "github_connect_unavailable" || data4 === "feature_check_unavailable")) {
12797
- 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" };
12798
12698
  if (vErrors === null) {
12799
- vErrors = [err20];
12699
+ vErrors = [err13];
12800
12700
  } else {
12801
- vErrors.push(err20);
12701
+ vErrors.push(err13);
12802
12702
  }
12803
12703
  errors++;
12804
12704
  }
12805
- var valid5 = _errs22 === errors;
12806
- } else {
12807
- var valid5 = true;
12808
- }
12809
- if (valid5) {
12810
- if (data.feature !== void 0) {
12811
- let data5 = data.feature;
12812
- const _errs24 = errors;
12813
- if (typeof data5 !== "string") {
12814
- 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" };
12815
- if (vErrors === null) {
12816
- vErrors = [err21];
12817
- } else {
12818
- vErrors.push(err21);
12819
- }
12820
- errors++;
12821
- }
12822
- if ("github-connect" !== data5) {
12823
- 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" };
12824
- if (vErrors === null) {
12825
- vErrors = [err22];
12826
- } else {
12827
- vErrors.push(err22);
12828
- }
12829
- errors++;
12830
- }
12831
- var valid5 = _errs24 === errors;
12832
- } else {
12833
- var valid5 = true;
12834
- }
12835
12705
  }
12836
12706
  }
12837
12707
  }
12838
12708
  } else {
12839
- 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" };
12840
12710
  if (vErrors === null) {
12841
- vErrors = [err23];
12711
+ vErrors = [err14];
12842
12712
  } else {
12843
- vErrors.push(err23);
12713
+ vErrors.push(err14);
12844
12714
  }
12845
12715
  errors++;
12846
12716
  }
12847
12717
  }
12848
- var _valid0 = _errs19 === errors;
12718
+ var _valid0 = _errs12 === errors;
12849
12719
  valid1 = valid1 || _valid0;
12850
12720
  if (_valid0) {
12851
12721
  if (props0 !== true) {
12852
12722
  props0 = true;
12853
12723
  }
12854
12724
  }
12855
- const _errs26 = errors;
12856
- if (errors === _errs26) {
12725
+ const _errs17 = errors;
12726
+ if (errors === _errs17) {
12857
12727
  if (data && typeof data == "object" && !Array.isArray(data)) {
12858
- let missing4;
12859
- if (data.error === void 0 && (missing4 = "error")) {
12860
- 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 + "'" };
12861
12731
  if (vErrors === null) {
12862
- vErrors = [err24];
12732
+ vErrors = [err15];
12863
12733
  } else {
12864
- vErrors.push(err24);
12734
+ vErrors.push(err15);
12865
12735
  }
12866
12736
  errors++;
12867
12737
  } else {
12868
- const _errs28 = errors;
12869
- for (const key4 in data) {
12870
- if (!(key4 === "error")) {
12871
- 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" };
12872
12742
  if (vErrors === null) {
12873
- vErrors = [err25];
12743
+ vErrors = [err16];
12874
12744
  } else {
12875
- vErrors.push(err25);
12745
+ vErrors.push(err16);
12876
12746
  }
12877
12747
  errors++;
12878
12748
  break;
12879
12749
  }
12880
12750
  }
12881
- if (_errs28 === errors) {
12751
+ if (_errs19 === errors) {
12882
12752
  if (data.error !== void 0) {
12883
- let data6 = data.error;
12884
- if (typeof data6 !== "string") {
12885
- 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" };
12886
12756
  if (vErrors === null) {
12887
- vErrors = [err26];
12757
+ vErrors = [err17];
12888
12758
  } else {
12889
- vErrors.push(err26);
12759
+ vErrors.push(err17);
12890
12760
  }
12891
12761
  errors++;
12892
12762
  }
12893
- if ("WorkOS identity authority is temporarily unavailable" !== data6) {
12894
- 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" };
12895
12765
  if (vErrors === null) {
12896
- vErrors = [err27];
12766
+ vErrors = [err18];
12897
12767
  } else {
12898
- vErrors.push(err27);
12768
+ vErrors.push(err18);
12899
12769
  }
12900
12770
  errors++;
12901
12771
  }
@@ -12903,66 +12773,66 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12903
12773
  }
12904
12774
  }
12905
12775
  } else {
12906
- 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" };
12907
12777
  if (vErrors === null) {
12908
- vErrors = [err28];
12778
+ vErrors = [err19];
12909
12779
  } else {
12910
- vErrors.push(err28);
12780
+ vErrors.push(err19);
12911
12781
  }
12912
12782
  errors++;
12913
12783
  }
12914
12784
  }
12915
- var _valid0 = _errs26 === errors;
12785
+ var _valid0 = _errs17 === errors;
12916
12786
  valid1 = valid1 || _valid0;
12917
12787
  if (_valid0) {
12918
12788
  if (props0 !== true) {
12919
12789
  props0 = true;
12920
12790
  }
12921
12791
  }
12922
- const _errs31 = errors;
12923
- if (errors === _errs31) {
12792
+ const _errs22 = errors;
12793
+ if (errors === _errs22) {
12924
12794
  if (data && typeof data == "object" && !Array.isArray(data)) {
12925
- let missing5;
12926
- if (data.error === void 0 && (missing5 = "error")) {
12927
- 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 + "'" };
12928
12798
  if (vErrors === null) {
12929
- vErrors = [err29];
12799
+ vErrors = [err20];
12930
12800
  } else {
12931
- vErrors.push(err29);
12801
+ vErrors.push(err20);
12932
12802
  }
12933
12803
  errors++;
12934
12804
  } else {
12935
- const _errs33 = errors;
12936
- for (const key5 in data) {
12937
- if (!(key5 === "error")) {
12938
- 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" };
12939
12809
  if (vErrors === null) {
12940
- vErrors = [err30];
12810
+ vErrors = [err21];
12941
12811
  } else {
12942
- vErrors.push(err30);
12812
+ vErrors.push(err21);
12943
12813
  }
12944
12814
  errors++;
12945
12815
  break;
12946
12816
  }
12947
12817
  }
12948
- if (_errs33 === errors) {
12818
+ if (_errs24 === errors) {
12949
12819
  if (data.error !== void 0) {
12950
- let data7 = data.error;
12951
- if (typeof data7 !== "string") {
12952
- 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" };
12953
12823
  if (vErrors === null) {
12954
- vErrors = [err31];
12824
+ vErrors = [err22];
12955
12825
  } else {
12956
- vErrors.push(err31);
12826
+ vErrors.push(err22);
12957
12827
  }
12958
12828
  errors++;
12959
12829
  }
12960
- if ("github_install_intent_conflict" !== data7) {
12961
- 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" };
12962
12832
  if (vErrors === null) {
12963
- vErrors = [err32];
12833
+ vErrors = [err23];
12964
12834
  } else {
12965
- vErrors.push(err32);
12835
+ vErrors.push(err23);
12966
12836
  }
12967
12837
  errors++;
12968
12838
  }
@@ -12970,128 +12840,128 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
12970
12840
  }
12971
12841
  }
12972
12842
  } else {
12973
- 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" };
12974
12844
  if (vErrors === null) {
12975
- vErrors = [err33];
12845
+ vErrors = [err24];
12976
12846
  } else {
12977
- vErrors.push(err33);
12847
+ vErrors.push(err24);
12978
12848
  }
12979
12849
  errors++;
12980
12850
  }
12981
12851
  }
12982
- var _valid0 = _errs31 === errors;
12852
+ var _valid0 = _errs22 === errors;
12983
12853
  valid1 = valid1 || _valid0;
12984
12854
  if (_valid0) {
12985
12855
  if (props0 !== true) {
12986
12856
  props0 = true;
12987
12857
  }
12988
12858
  }
12989
- const _errs36 = errors;
12990
- if (errors === _errs36) {
12859
+ const _errs27 = errors;
12860
+ if (errors === _errs27) {
12991
12861
  if (data && typeof data == "object" && !Array.isArray(data)) {
12992
- let missing6;
12993
- if (data.error === void 0 && (missing6 = "error") || data.retryAt === void 0 && (missing6 = "retryAt")) {
12994
- 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 + "'" };
12995
12865
  if (vErrors === null) {
12996
- vErrors = [err34];
12866
+ vErrors = [err25];
12997
12867
  } else {
12998
- vErrors.push(err34);
12868
+ vErrors.push(err25);
12999
12869
  }
13000
12870
  errors++;
13001
12871
  } else {
13002
- const _errs38 = errors;
13003
- for (const key6 in data) {
13004
- if (!(key6 === "error" || key6 === "retryAt")) {
13005
- 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" };
13006
12876
  if (vErrors === null) {
13007
- vErrors = [err35];
12877
+ vErrors = [err26];
13008
12878
  } else {
13009
- vErrors.push(err35);
12879
+ vErrors.push(err26);
13010
12880
  }
13011
12881
  errors++;
13012
12882
  break;
13013
12883
  }
13014
12884
  }
13015
- if (_errs38 === errors) {
12885
+ if (_errs29 === errors) {
13016
12886
  if (data.error !== void 0) {
13017
- let data8 = data.error;
13018
- const _errs39 = errors;
13019
- if (typeof data8 !== "string") {
13020
- 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" };
13021
12891
  if (vErrors === null) {
13022
- vErrors = [err36];
12892
+ vErrors = [err27];
13023
12893
  } else {
13024
- vErrors.push(err36);
12894
+ vErrors.push(err27);
13025
12895
  }
13026
12896
  errors++;
13027
12897
  }
13028
- if ("github_install_intent_rate_limited" !== data8) {
13029
- 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" };
13030
12900
  if (vErrors === null) {
13031
- vErrors = [err37];
12901
+ vErrors = [err28];
13032
12902
  } else {
13033
- vErrors.push(err37);
12903
+ vErrors.push(err28);
13034
12904
  }
13035
12905
  errors++;
13036
12906
  }
13037
- var valid8 = _errs39 === errors;
12907
+ var valid7 = _errs30 === errors;
13038
12908
  } else {
13039
- var valid8 = true;
12909
+ var valid7 = true;
13040
12910
  }
13041
- if (valid8) {
12911
+ if (valid7) {
13042
12912
  if (data.retryAt !== void 0) {
13043
- let data9 = data.retryAt;
13044
- const _errs41 = errors;
13045
- if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9))) {
13046
- 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" };
13047
12917
  if (vErrors === null) {
13048
- vErrors = [err38];
12918
+ vErrors = [err29];
13049
12919
  } else {
13050
- vErrors.push(err38);
12920
+ vErrors.push(err29);
13051
12921
  }
13052
12922
  errors++;
13053
12923
  }
13054
- if (errors === _errs41) {
13055
- if (typeof data9 == "number" && isFinite(data9)) {
13056
- if (data9 > 9007199254740991 || isNaN(data9)) {
13057
- 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" };
13058
12928
  if (vErrors === null) {
13059
- vErrors = [err39];
12929
+ vErrors = [err30];
13060
12930
  } else {
13061
- vErrors.push(err39);
12931
+ vErrors.push(err30);
13062
12932
  }
13063
12933
  errors++;
13064
12934
  } else {
13065
- if (data9 < 0 || isNaN(data9)) {
13066
- 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" };
13067
12937
  if (vErrors === null) {
13068
- vErrors = [err40];
12938
+ vErrors = [err31];
13069
12939
  } else {
13070
- vErrors.push(err40);
12940
+ vErrors.push(err31);
13071
12941
  }
13072
12942
  errors++;
13073
12943
  }
13074
12944
  }
13075
12945
  }
13076
12946
  }
13077
- var valid8 = _errs41 === errors;
12947
+ var valid7 = _errs32 === errors;
13078
12948
  } else {
13079
- var valid8 = true;
12949
+ var valid7 = true;
13080
12950
  }
13081
12951
  }
13082
12952
  }
13083
12953
  }
13084
12954
  } else {
13085
- 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" };
13086
12956
  if (vErrors === null) {
13087
- vErrors = [err41];
12957
+ vErrors = [err32];
13088
12958
  } else {
13089
- vErrors.push(err41);
12959
+ vErrors.push(err32);
13090
12960
  }
13091
12961
  errors++;
13092
12962
  }
13093
12963
  }
13094
- var _valid0 = _errs36 === errors;
12964
+ var _valid0 = _errs27 === errors;
13095
12965
  valid1 = valid1 || _valid0;
13096
12966
  if (_valid0) {
13097
12967
  if (props0 !== true) {
@@ -13099,11 +12969,11 @@ function validate46(data, { instancePath = "", parentData, parentDataProperty, r
13099
12969
  }
13100
12970
  }
13101
12971
  if (!valid1) {
13102
- 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" };
13103
12973
  if (vErrors === null) {
13104
- vErrors = [err42];
12974
+ vErrors = [err33];
13105
12975
  } else {
13106
- vErrors.push(err42);
12976
+ vErrors.push(err33);
13107
12977
  }
13108
12978
  errors++;
13109
12979
  validate46.errors = vErrors;
@@ -15205,7 +15075,7 @@ function validate50(data, { instancePath = "", parentData, parentDataProperty, r
15205
15075
  return errors === 0;
15206
15076
  }
15207
15077
  validate50.evaluated = { "dynamicProps": true, "dynamicItems": false };
15208
- 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": {} };
15209
15079
  var pattern8 = new RegExp("^[A-Za-z0-9_-]+$", "u");
15210
15080
  function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
15211
15081
  ;
@@ -15332,13 +15202,18 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15332
15202
  var valid4 = true;
15333
15203
  }
15334
15204
  if (valid4) {
15335
- if (data1.capturedOrganizationId !== void 0) {
15336
- let data7 = data1.capturedOrganizationId;
15205
+ if (data1.repositoryContext !== void 0) {
15206
+ let data7 = data1.repositoryContext;
15337
15207
  const _errs20 = errors;
15338
- if (errors === _errs20) {
15339
- if (typeof data7 === "string") {
15340
- if (func1(data7) > 128) {
15341
- 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 + "'" };
15342
15217
  if (vErrors === null) {
15343
15218
  vErrors = [err6];
15344
15219
  } else {
@@ -15346,184 +15221,392 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15346
15221
  }
15347
15222
  errors++;
15348
15223
  } else {
15349
- if (func1(data7) < 1) {
15350
- 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" };
15351
- if (vErrors === null) {
15352
- vErrors = [err7];
15353
- } else {
15354
- vErrors.push(err7);
15355
- }
15356
- errors++;
15357
- } else {
15358
- if (!pattern8.test(data7)) {
15359
- 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" };
15360
15228
  if (vErrors === null) {
15361
- vErrors = [err8];
15229
+ vErrors = [err7];
15362
15230
  } else {
15363
- vErrors.push(err8);
15231
+ vErrors.push(err7);
15364
15232
  }
15365
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
+ }
15366
15302
  }
15367
15303
  }
15368
15304
  }
15369
15305
  } else {
15370
- 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" };
15371
15307
  if (vErrors === null) {
15372
- vErrors = [err9];
15308
+ vErrors = [err13];
15373
15309
  } else {
15374
- vErrors.push(err9);
15310
+ vErrors.push(err13);
15375
15311
  }
15376
15312
  errors++;
15377
15313
  }
15378
15314
  }
15379
- var valid4 = _errs20 === errors;
15380
- } else {
15381
- var valid4 = true;
15382
- }
15383
- if (valid4) {
15384
- if (data1.captureAuthorityKind !== void 0) {
15385
- let data8 = data1.captureAuthorityKind;
15386
- const _errs22 = errors;
15387
- if (typeof data8 !== "string") {
15388
- 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" };
15389
- if (vErrors === null) {
15390
- 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++;
15391
15333
  } else {
15392
- 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
+ }
15393
15370
  }
15394
- errors++;
15395
- }
15396
- if (!(data8 === "workos" || data8 === "service_token")) {
15397
- 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" };
15398
15373
  if (vErrors === null) {
15399
- vErrors = [err11];
15374
+ vErrors = [err18];
15400
15375
  } else {
15401
- vErrors.push(err11);
15376
+ vErrors.push(err18);
15402
15377
  }
15403
15378
  errors++;
15404
15379
  }
15405
- var valid4 = _errs22 === errors;
15380
+ }
15381
+ var _valid1 = _errs29 === errors;
15382
+ if (_valid1 && valid5) {
15383
+ valid5 = false;
15384
+ passing0 = [passing0, 1];
15406
15385
  } else {
15407
- var valid4 = true;
15386
+ if (_valid1) {
15387
+ valid5 = true;
15388
+ passing0 = 1;
15389
+ if (props0 !== true) {
15390
+ props0 = true;
15391
+ }
15392
+ }
15408
15393
  }
15409
- if (valid4) {
15410
- if (data1.decisionLifecycleProtocolVersion !== void 0) {
15411
- let data9 = data1.decisionLifecycleProtocolVersion;
15412
- const _errs24 = errors;
15413
- if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9))) {
15414
- 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" };
15415
- if (vErrors === null) {
15416
- vErrors = [err12];
15417
- } else {
15418
- vErrors.push(err12);
15419
- }
15420
- 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;
15421
15409
  }
15422
- if (errors === _errs24) {
15423
- if (typeof data9 == "number" && isFinite(data9)) {
15424
- if (data9 > 9007199254740991 || isNaN(data9)) {
15425
- 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" };
15426
15433
  if (vErrors === null) {
15427
- vErrors = [err13];
15434
+ vErrors = [err21];
15428
15435
  } else {
15429
- vErrors.push(err13);
15436
+ vErrors.push(err21);
15430
15437
  }
15431
15438
  errors++;
15432
15439
  } else {
15433
- if (data9 < 1 || isNaN(data9)) {
15434
- 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_-]+$"' };
15435
15442
  if (vErrors === null) {
15436
- vErrors = [err14];
15443
+ vErrors = [err22];
15437
15444
  } else {
15438
- vErrors.push(err14);
15445
+ vErrors.push(err22);
15439
15446
  }
15440
15447
  errors++;
15441
15448
  }
15442
15449
  }
15443
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++;
15444
15486
  }
15445
- var valid4 = _errs24 === errors;
15487
+ var valid4 = _errs36 === errors;
15446
15488
  } else {
15447
15489
  var valid4 = true;
15448
15490
  }
15449
15491
  if (valid4) {
15450
- if (data1.producer !== void 0) {
15451
- let data10 = data1.producer;
15452
- const _errs26 = errors;
15453
- if (typeof data10 !== "string") {
15454
- 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" };
15455
15497
  if (vErrors === null) {
15456
- vErrors = [err15];
15498
+ vErrors = [err26];
15457
15499
  } else {
15458
- vErrors.push(err15);
15500
+ vErrors.push(err26);
15459
15501
  }
15460
15502
  errors++;
15461
15503
  }
15462
- if (!(data10 === "claude_code" || data10 === "codex" || data10 === "cursor" || data10 === "hermes")) {
15463
- 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" };
15464
- if (vErrors === null) {
15465
- vErrors = [err16];
15466
- } else {
15467
- 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
+ }
15468
15525
  }
15469
- errors++;
15470
15526
  }
15471
- var valid4 = _errs26 === errors;
15527
+ var valid4 = _errs38 === errors;
15472
15528
  } else {
15473
15529
  var valid4 = true;
15474
15530
  }
15475
15531
  if (valid4) {
15476
- if (data1.toolOutcome !== void 0) {
15477
- let data11 = data1.toolOutcome;
15478
- const _errs28 = errors;
15479
- if (typeof data11 !== "string") {
15480
- 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" };
15481
15537
  if (vErrors === null) {
15482
- vErrors = [err17];
15538
+ vErrors = [err29];
15483
15539
  } else {
15484
- vErrors.push(err17);
15540
+ vErrors.push(err29);
15485
15541
  }
15486
15542
  errors++;
15487
15543
  }
15488
- if (!(data11 === "succeeded" || data11 === "returned" || data11 === "failed" || data11 === "interrupted" || data11 === "prevented" || data11 === "unknown")) {
15489
- 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" };
15490
15546
  if (vErrors === null) {
15491
- vErrors = [err18];
15547
+ vErrors = [err30];
15492
15548
  } else {
15493
- vErrors.push(err18);
15549
+ vErrors.push(err30);
15494
15550
  }
15495
15551
  errors++;
15496
15552
  }
15497
- var valid4 = _errs28 === errors;
15553
+ var valid4 = _errs40 === errors;
15498
15554
  } else {
15499
15555
  var valid4 = true;
15500
15556
  }
15501
15557
  if (valid4) {
15502
- if (data1.envelopeVersion !== void 0) {
15503
- let data12 = data1.envelopeVersion;
15504
- const _errs30 = errors;
15505
- if (!(typeof data12 == "number" && isFinite(data12))) {
15506
- 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" };
15507
15563
  if (vErrors === null) {
15508
- vErrors = [err19];
15564
+ vErrors = [err31];
15509
15565
  } else {
15510
- vErrors.push(err19);
15566
+ vErrors.push(err31);
15511
15567
  }
15512
15568
  errors++;
15513
15569
  }
15514
- if (4 !== data12) {
15515
- 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" };
15516
15572
  if (vErrors === null) {
15517
- vErrors = [err20];
15573
+ vErrors = [err32];
15518
15574
  } else {
15519
- vErrors.push(err20);
15575
+ vErrors.push(err32);
15520
15576
  }
15521
15577
  errors++;
15522
15578
  }
15523
- var valid4 = _errs30 === errors;
15579
+ var valid4 = _errs42 === errors;
15524
15580
  } else {
15525
15581
  var valid4 = true;
15526
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
+ }
15527
15610
  }
15528
15611
  }
15529
15612
  }
@@ -15536,11 +15619,11 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15536
15619
  }
15537
15620
  }
15538
15621
  } else {
15539
- 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" };
15540
15623
  if (vErrors === null) {
15541
- vErrors = [err21];
15624
+ vErrors = [err35];
15542
15625
  } else {
15543
- vErrors.push(err21);
15626
+ vErrors.push(err35);
15544
15627
  }
15545
15628
  errors++;
15546
15629
  }
@@ -15548,296 +15631,509 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15548
15631
  var _valid0 = _errs7 === errors;
15549
15632
  valid3 = valid3 || _valid0;
15550
15633
  if (_valid0) {
15551
- var props0 = true;
15634
+ var props1 = true;
15552
15635
  }
15553
- const _errs32 = errors;
15554
- if (errors === _errs32) {
15636
+ const _errs46 = errors;
15637
+ if (errors === _errs46) {
15555
15638
  if (data1 && typeof data1 == "object" && !Array.isArray(data1)) {
15556
- let missing2;
15557
- 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")) {
15558
- 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 + "'" };
15559
15642
  if (vErrors === null) {
15560
- vErrors = [err22];
15643
+ vErrors = [err36];
15561
15644
  } else {
15562
- vErrors.push(err22);
15645
+ vErrors.push(err36);
15563
15646
  }
15564
15647
  errors++;
15565
15648
  } else {
15566
15649
  if (data1.moveId !== void 0) {
15567
- const _errs35 = errors;
15650
+ const _errs49 = errors;
15568
15651
  if (typeof data1.moveId !== "string") {
15569
- 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" };
15570
15653
  if (vErrors === null) {
15571
- vErrors = [err23];
15654
+ vErrors = [err37];
15572
15655
  } else {
15573
- vErrors.push(err23);
15656
+ vErrors.push(err37);
15574
15657
  }
15575
15658
  errors++;
15576
15659
  }
15577
- var valid5 = _errs35 === errors;
15660
+ var valid8 = _errs49 === errors;
15578
15661
  } else {
15579
- var valid5 = true;
15662
+ var valid8 = true;
15580
15663
  }
15581
- if (valid5) {
15664
+ if (valid8) {
15582
15665
  if (data1.capturedAt !== void 0) {
15583
- let data14 = data1.capturedAt;
15584
- const _errs37 = errors;
15585
- if (!(typeof data14 == "number" && isFinite(data14))) {
15586
- 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" };
15587
15670
  if (vErrors === null) {
15588
- vErrors = [err24];
15671
+ vErrors = [err38];
15589
15672
  } else {
15590
- vErrors.push(err24);
15673
+ vErrors.push(err38);
15591
15674
  }
15592
15675
  errors++;
15593
15676
  }
15594
- var valid5 = _errs37 === errors;
15677
+ var valid8 = _errs51 === errors;
15595
15678
  } else {
15596
- var valid5 = true;
15679
+ var valid8 = true;
15597
15680
  }
15598
- if (valid5) {
15681
+ if (valid8) {
15599
15682
  if (data1.sessionId !== void 0) {
15600
- const _errs39 = errors;
15683
+ const _errs53 = errors;
15601
15684
  if (typeof data1.sessionId !== "string") {
15602
- 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" };
15603
15686
  if (vErrors === null) {
15604
- vErrors = [err25];
15687
+ vErrors = [err39];
15605
15688
  } else {
15606
- vErrors.push(err25);
15689
+ vErrors.push(err39);
15607
15690
  }
15608
15691
  errors++;
15609
15692
  }
15610
- var valid5 = _errs39 === errors;
15693
+ var valid8 = _errs53 === errors;
15611
15694
  } else {
15612
- var valid5 = true;
15695
+ var valid8 = true;
15613
15696
  }
15614
- if (valid5) {
15697
+ if (valid8) {
15615
15698
  if (data1.invocationId !== void 0) {
15616
- const _errs41 = errors;
15699
+ const _errs55 = errors;
15617
15700
  if (typeof data1.invocationId !== "string") {
15618
- 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" };
15619
15702
  if (vErrors === null) {
15620
- vErrors = [err26];
15703
+ vErrors = [err40];
15621
15704
  } else {
15622
- vErrors.push(err26);
15705
+ vErrors.push(err40);
15623
15706
  }
15624
15707
  errors++;
15625
15708
  }
15626
- var valid5 = _errs41 === errors;
15709
+ var valid8 = _errs55 === errors;
15627
15710
  } else {
15628
- var valid5 = true;
15711
+ var valid8 = true;
15629
15712
  }
15630
- if (valid5) {
15713
+ if (valid8) {
15631
15714
  if (data1.eventType !== void 0) {
15632
- const _errs43 = errors;
15715
+ const _errs57 = errors;
15633
15716
  if (typeof data1.eventType !== "string") {
15634
- 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" };
15635
15718
  if (vErrors === null) {
15636
- vErrors = [err27];
15719
+ vErrors = [err41];
15637
15720
  } else {
15638
- vErrors.push(err27);
15721
+ vErrors.push(err41);
15639
15722
  }
15640
15723
  errors++;
15641
15724
  }
15642
- var valid5 = _errs43 === errors;
15725
+ var valid8 = _errs57 === errors;
15643
15726
  } else {
15644
- var valid5 = true;
15727
+ var valid8 = true;
15645
15728
  }
15646
- if (valid5) {
15647
- if (data1.capturedOrganizationId !== void 0) {
15648
- let data18 = data1.capturedOrganizationId;
15649
- const _errs45 = errors;
15650
- if (errors === _errs45) {
15651
- if (typeof data18 === "string") {
15652
- if (func1(data18) > 128) {
15653
- 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 + "'" };
15654
15742
  if (vErrors === null) {
15655
- vErrors = [err28];
15743
+ vErrors = [err42];
15656
15744
  } else {
15657
- vErrors.push(err28);
15745
+ vErrors.push(err42);
15658
15746
  }
15659
15747
  errors++;
15660
15748
  } else {
15661
- if (func1(data18) < 1) {
15662
- 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" };
15663
- if (vErrors === null) {
15664
- vErrors = [err29];
15665
- } else {
15666
- vErrors.push(err29);
15667
- }
15668
- errors++;
15669
- } else {
15670
- if (!pattern8.test(data18)) {
15671
- 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" };
15672
15753
  if (vErrors === null) {
15673
- vErrors = [err30];
15754
+ vErrors = [err43];
15674
15755
  } else {
15675
- vErrors.push(err30);
15756
+ vErrors.push(err43);
15676
15757
  }
15677
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
+ }
15678
15827
  }
15679
15828
  }
15680
15829
  }
15681
15830
  } else {
15682
- 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" };
15683
15832
  if (vErrors === null) {
15684
- vErrors = [err31];
15833
+ vErrors = [err49];
15685
15834
  } else {
15686
- vErrors.push(err31);
15835
+ vErrors.push(err49);
15687
15836
  }
15688
15837
  errors++;
15689
15838
  }
15690
15839
  }
15691
- var valid5 = _errs45 === errors;
15692
- } else {
15693
- var valid5 = true;
15694
- }
15695
- if (valid5) {
15696
- if (data1.captureAuthorityKind !== void 0) {
15697
- let data19 = data1.captureAuthorityKind;
15698
- const _errs47 = errors;
15699
- if (typeof data19 !== "string") {
15700
- 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" };
15701
- if (vErrors === null) {
15702
- 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++;
15703
15858
  } else {
15704
- 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
+ }
15705
15895
  }
15706
- errors++;
15707
- }
15708
- if (!(data19 === "workos" || data19 === "service_token")) {
15709
- 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" };
15710
15898
  if (vErrors === null) {
15711
- vErrors = [err33];
15899
+ vErrors = [err54];
15712
15900
  } else {
15713
- vErrors.push(err33);
15901
+ vErrors.push(err54);
15714
15902
  }
15715
15903
  errors++;
15716
15904
  }
15717
- var valid5 = _errs47 === errors;
15905
+ }
15906
+ var _valid2 = _errs68 === errors;
15907
+ if (_valid2 && valid9) {
15908
+ valid9 = false;
15909
+ passing1 = [passing1, 1];
15718
15910
  } else {
15719
- var valid5 = true;
15911
+ if (_valid2) {
15912
+ valid9 = true;
15913
+ passing1 = 1;
15914
+ if (props2 !== true) {
15915
+ props2 = true;
15916
+ }
15917
+ }
15720
15918
  }
15721
- if (valid5) {
15722
- if (data1.decisionLifecycleProtocolVersion !== void 0) {
15723
- let data20 = data1.decisionLifecycleProtocolVersion;
15724
- const _errs49 = errors;
15725
- if (!(typeof data20 == "number" && (!(data20 % 1) && !isNaN(data20)) && isFinite(data20))) {
15726
- 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" };
15727
- if (vErrors === null) {
15728
- vErrors = [err34];
15729
- } else {
15730
- vErrors.push(err34);
15731
- }
15732
- 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;
15733
15934
  }
15734
- if (errors === _errs49) {
15735
- if (typeof data20 == "number" && isFinite(data20)) {
15736
- if (data20 > 9007199254740991 || isNaN(data20)) {
15737
- 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" };
15738
15958
  if (vErrors === null) {
15739
- vErrors = [err35];
15959
+ vErrors = [err57];
15740
15960
  } else {
15741
- vErrors.push(err35);
15961
+ vErrors.push(err57);
15742
15962
  }
15743
15963
  errors++;
15744
15964
  } else {
15745
- if (data20 < 1 || isNaN(data20)) {
15746
- 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_-]+$"' };
15747
15967
  if (vErrors === null) {
15748
- vErrors = [err36];
15968
+ vErrors = [err58];
15749
15969
  } else {
15750
- vErrors.push(err36);
15970
+ vErrors.push(err58);
15751
15971
  }
15752
15972
  errors++;
15753
15973
  }
15754
15974
  }
15755
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++;
15756
16011
  }
15757
- var valid5 = _errs49 === errors;
16012
+ var valid8 = _errs75 === errors;
15758
16013
  } else {
15759
- var valid5 = true;
16014
+ var valid8 = true;
15760
16015
  }
15761
- if (valid5) {
15762
- if (data1.producer !== void 0) {
15763
- let data21 = data1.producer;
15764
- const _errs51 = errors;
15765
- if (typeof data21 !== "string") {
15766
- 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" };
15767
16022
  if (vErrors === null) {
15768
- vErrors = [err37];
16023
+ vErrors = [err62];
15769
16024
  } else {
15770
- vErrors.push(err37);
16025
+ vErrors.push(err62);
15771
16026
  }
15772
16027
  errors++;
15773
16028
  }
15774
- if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
15775
- 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" };
15776
- if (vErrors === null) {
15777
- vErrors = [err38];
15778
- } else {
15779
- 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
+ }
15780
16050
  }
15781
- errors++;
15782
16051
  }
15783
- var valid5 = _errs51 === errors;
16052
+ var valid8 = _errs77 === errors;
15784
16053
  } else {
15785
- var valid5 = true;
16054
+ var valid8 = true;
15786
16055
  }
15787
- if (valid5) {
15788
- if (data1.toolOutcome !== void 0) {
15789
- let data22 = data1.toolOutcome;
15790
- const _errs53 = errors;
15791
- if (typeof data22 !== "string") {
15792
- 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" };
15793
16062
  if (vErrors === null) {
15794
- vErrors = [err39];
16063
+ vErrors = [err65];
15795
16064
  } else {
15796
- vErrors.push(err39);
16065
+ vErrors.push(err65);
15797
16066
  }
15798
16067
  errors++;
15799
16068
  }
15800
- if (!(data22 === "succeeded" || data22 === "returned" || data22 === "failed" || data22 === "interrupted" || data22 === "prevented" || data22 === "unknown")) {
15801
- 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" };
15802
16071
  if (vErrors === null) {
15803
- vErrors = [err40];
16072
+ vErrors = [err66];
15804
16073
  } else {
15805
- vErrors.push(err40);
16074
+ vErrors.push(err66);
15806
16075
  }
15807
16076
  errors++;
15808
16077
  }
15809
- var valid5 = _errs53 === errors;
16078
+ var valid8 = _errs79 === errors;
15810
16079
  } else {
15811
- var valid5 = true;
16080
+ var valid8 = true;
15812
16081
  }
15813
- if (valid5) {
15814
- if (data1.envelopeVersion !== void 0) {
15815
- let data23 = data1.envelopeVersion;
15816
- const _errs55 = errors;
15817
- if (errors === _errs55) {
15818
- if (typeof data23 == "number" && isFinite(data23)) {
15819
- if (data23 >= 4 || isNaN(data23)) {
15820
- 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" };
15821
16125
  if (vErrors === null) {
15822
- vErrors = [err41];
16126
+ vErrors = [err70];
15823
16127
  } else {
15824
- vErrors.push(err41);
16128
+ vErrors.push(err70);
15825
16129
  }
15826
16130
  errors++;
15827
16131
  }
15828
- } else {
15829
- 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" };
15830
- if (vErrors === null) {
15831
- vErrors = [err42];
15832
- } else {
15833
- vErrors.push(err42);
15834
- }
15835
- errors++;
15836
16132
  }
16133
+ var valid8 = _errs83 === errors;
16134
+ } else {
16135
+ var valid8 = true;
15837
16136
  }
15838
- var valid5 = _errs55 === errors;
15839
- } else {
15840
- var valid5 = true;
15841
16137
  }
15842
16138
  }
15843
16139
  }
@@ -15851,28 +16147,28 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
15851
16147
  }
15852
16148
  }
15853
16149
  } else {
15854
- 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" };
15855
16151
  if (vErrors === null) {
15856
- vErrors = [err43];
16152
+ vErrors = [err71];
15857
16153
  } else {
15858
- vErrors.push(err43);
16154
+ vErrors.push(err71);
15859
16155
  }
15860
16156
  errors++;
15861
16157
  }
15862
16158
  }
15863
- var _valid0 = _errs32 === errors;
16159
+ var _valid0 = _errs46 === errors;
15864
16160
  valid3 = valid3 || _valid0;
15865
16161
  if (_valid0) {
15866
- if (props0 !== true) {
15867
- props0 = true;
16162
+ if (props1 !== true) {
16163
+ props1 = true;
15868
16164
  }
15869
16165
  }
15870
16166
  if (!valid3) {
15871
- 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" };
15872
16168
  if (vErrors === null) {
15873
- vErrors = [err44];
16169
+ vErrors = [err72];
15874
16170
  } else {
15875
- vErrors.push(err44);
16171
+ vErrors.push(err72);
15876
16172
  }
15877
16173
  errors++;
15878
16174
  validate51.errors = vErrors;
@@ -25014,7 +25310,7 @@ var COMMAND_OPTIONS = {
25014
25310
  longOptionalValues: set("--color")
25015
25311
  },
25016
25312
  grep: {
25017
- shortFlags: "EFGHIPRTUVabcdhLlnqrsuvwxyZz",
25313
+ shortFlags: "EFGHIPRTUVabcdhiLlnoqrsuvwxyZz",
25018
25314
  shortValues: "ABCDefm",
25019
25315
  longFlags: set(
25020
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"
@@ -25025,12 +25321,14 @@ var COMMAND_OPTIONS = {
25025
25321
  longOptionalValues: set("--color")
25026
25322
  },
25027
25323
  head: {
25324
+ numericCount: true,
25028
25325
  shortFlags: "qvz",
25029
25326
  shortValues: "cn",
25030
25327
  longFlags: set("--help --quiet --verbose --version --zero-terminated"),
25031
25328
  longValues: set("--bytes --lines")
25032
25329
  },
25033
25330
  tail: {
25331
+ numericCount: true,
25034
25332
  shortFlags: "Fqsvz",
25035
25333
  shortValues: "cn",
25036
25334
  longFlags: set("--help --quiet --retry --silent --verbose --version --zero-terminated"),
@@ -25055,6 +25353,7 @@ var COMMAND_OPTIONS = {
25055
25353
  }
25056
25354
  };
25057
25355
  var GIT_INSPECTION_OPTIONS = {
25356
+ numericCount: true,
25058
25357
  shortFlags: "abcdfhiklmnprstuvwz",
25059
25358
  shortValues: "ABCGLMSU",
25060
25359
  longFlags: set(
@@ -25197,6 +25496,7 @@ function parseOptions(args, spec) {
25197
25496
  optionsEnded = true;
25198
25497
  continue;
25199
25498
  }
25499
+ if (spec.numericCount && /^-\d+$/.test(arg)) continue;
25200
25500
  if (arg.startsWith("--")) {
25201
25501
  const separator = arg.indexOf("=");
25202
25502
  const option = separator === -1 ? arg : arg.slice(0, separator);
@@ -25753,6 +26053,15 @@ function hermesAdvisory(result, aggregate) {
25753
26053
  const message = [...new Set(parts.filter(Boolean))].join("\n");
25754
26054
  return message.startsWith("[primitive]") ? message : message ? `[primitive] ${message}` : "";
25755
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
+ }
25756
26065
  async function emitUnverified(message, envelope) {
25757
26066
  const result = unverifiedResult(message);
25758
26067
  if (agent === "hermes") {
@@ -25874,8 +26183,8 @@ async function main() {
25874
26183
  return;
25875
26184
  }
25876
26185
  result = resultForPreflight(response);
25877
- } catch {
25878
- await emitUnverified("enforcement service unavailable; change was not verified", envelope);
26186
+ } catch (error) {
26187
+ await emitUnverified(preflightFailure(error), envelope);
25879
26188
  return;
25880
26189
  }
25881
26190
  const aggregate = demoteForMode(