@primitive.ai/prim 0.1.0-alpha.9 → 0.1.0-alpha.91

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 (47) hide show
  1. package/README.md +303 -37
  2. package/SKILL.md +269 -0
  3. package/dist/chunk-4GLVJLEQ.js +55 -0
  4. package/dist/chunk-5AFRMOPX.js +209 -0
  5. package/dist/chunk-5GYQ4J3D.js +126 -0
  6. package/dist/chunk-67VNLLBN.js +789 -0
  7. package/dist/chunk-BTNNEH2W.js +79 -0
  8. package/dist/chunk-EWZMDD44.js +1474 -0
  9. package/dist/chunk-EZXEWFDG.js +210 -0
  10. package/dist/chunk-FBAYCS3X.js +327 -0
  11. package/dist/chunk-FKXFUUWJ.js +36 -0
  12. package/dist/chunk-FOLKHXLJ.js +1529 -0
  13. package/dist/chunk-H4UNYFUC.js +196 -0
  14. package/dist/chunk-HU4PW6I6.js +264 -0
  15. package/dist/chunk-KFXF2V5G.js +155 -0
  16. package/dist/chunk-LFFLHSQO.js +78 -0
  17. package/dist/chunk-M6RIJVRE.js +18358 -0
  18. package/dist/chunk-NAHHFSLH.js +258 -0
  19. package/dist/chunk-OAAP2MY6.js +262 -0
  20. package/dist/chunk-PCVGBE5B.js +659 -0
  21. package/dist/chunk-VW3FDYRT.js +517 -0
  22. package/dist/chunk-WX52U7Z2.js +112 -0
  23. package/dist/chunk-ZB4F75SZ.js +843 -0
  24. package/dist/daemon/server.js +21633 -0
  25. package/dist/hook-runtime/daemon/server.js +21633 -0
  26. package/dist/hook-runtime/hooks/post-commit.js +19258 -0
  27. package/dist/hook-runtime/hooks/post-rewrite.js +19273 -0
  28. package/dist/hook-runtime/hooks/post-tool-use.js +26365 -0
  29. package/dist/hook-runtime/hooks/pre-commit.js +1314 -0
  30. package/dist/hook-runtime/hooks/pre-tool-use.js +25832 -0
  31. package/dist/hook-runtime/hooks/prim-hook.js +26386 -0
  32. package/dist/hook-runtime/hooks/session-end.js +1078 -0
  33. package/dist/hook-runtime/hooks/session-start.js +28779 -0
  34. package/dist/hook-runtime/index.js +50987 -0
  35. package/dist/hook-runtime/statusline-main.js +809 -0
  36. package/dist/hooks/post-commit.js +190 -0
  37. package/dist/hooks/post-rewrite.js +203 -0
  38. package/dist/hooks/post-tool-use.js +288 -0
  39. package/dist/hooks/pre-commit.js +16 -101
  40. package/dist/hooks/pre-tool-use.js +369 -0
  41. package/dist/hooks/prim-hook.js +229 -0
  42. package/dist/hooks/session-end.js +59 -0
  43. package/dist/hooks/session-start.js +316 -0
  44. package/dist/index.js +8875 -429
  45. package/dist/statusline-main.js +809 -0
  46. package/package.json +35 -13
  47. package/dist/chunk-3APLWTLB.js +0 -165
@@ -0,0 +1,210 @@
1
+ // src/lib/workspace-id.ts
2
+ import { execFileSync } from "child_process";
3
+ import { randomUUID } from "crypto";
4
+ import {
5
+ constants,
6
+ chmodSync,
7
+ closeSync,
8
+ fchmodSync,
9
+ fsyncSync,
10
+ linkSync,
11
+ lstatSync,
12
+ mkdirSync,
13
+ openSync,
14
+ readFileSync,
15
+ statSync,
16
+ unlinkSync,
17
+ writeFileSync
18
+ } from "fs";
19
+ import { dirname, isAbsolute, join, resolve } from "path";
20
+ var WORKSPACE_ID_RELATIVE_PATH = join("prim", "workspace-id");
21
+ var MAX_ANCESTORS = 64;
22
+ var MAX_GIT_FILE_BYTES = 4096;
23
+ var MAX_ID_FILE_BYTES = 128;
24
+ var GIT_FALLBACK_TIMEOUT_MS = 250;
25
+ var RACE_READ_ATTEMPTS = 5;
26
+ var RACE_READ_DELAY_MS = 5;
27
+ var CANONICAL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
28
+ var raceDelay = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
29
+ function isCanonicalWorkspaceId(value) {
30
+ return CANONICAL_UUID.test(value);
31
+ }
32
+ function inspectWorkspaceId(cwd = process.cwd()) {
33
+ const resolved = resolveWorkspaceIdPath(cwd);
34
+ if (resolved.status !== "resolved") return resolved;
35
+ return inspectPath(resolved.path);
36
+ }
37
+ function getOrCreateWorkspaceId(cwd = process.cwd()) {
38
+ const inspection = inspectWorkspaceId(cwd);
39
+ if (inspection.status !== "missing") return inspection;
40
+ return createWorkspaceId(inspection.path);
41
+ }
42
+ function resolveWorkspaceIdPath(cwd) {
43
+ if (!process.env.GIT_DIR && !process.env.GIT_WORK_TREE) {
44
+ const fromFilesystem = resolveFromFilesystem(cwd);
45
+ if (fromFilesystem) return { status: "resolved", path: fromFilesystem };
46
+ }
47
+ try {
48
+ const output = execFileSync(
49
+ "git",
50
+ ["rev-parse", "--is-inside-work-tree", "--git-path", WORKSPACE_ID_RELATIVE_PATH],
51
+ {
52
+ cwd,
53
+ encoding: "utf8",
54
+ maxBuffer: 4096,
55
+ stdio: ["ignore", "pipe", "ignore"],
56
+ timeout: GIT_FALLBACK_TIMEOUT_MS,
57
+ windowsHide: true
58
+ }
59
+ );
60
+ const [insideWorktree, gitPath, ...extra] = output.trim().split(/\r?\n/);
61
+ if (insideWorktree !== "true" || !gitPath || extra.length > 0 || gitPath.includes("\0")) {
62
+ return { status: "not_git" };
63
+ }
64
+ return {
65
+ status: "resolved",
66
+ path: isAbsolute(gitPath) ? resolve(gitPath) : resolve(cwd, gitPath)
67
+ };
68
+ } catch (error) {
69
+ const code = errorCode(error);
70
+ if (code === "ETIMEDOUT" || code === "EACCES" || code === "EPERM") {
71
+ return { status: "unavailable", operation: "resolve", errorCode: code };
72
+ }
73
+ return { status: "not_git" };
74
+ }
75
+ }
76
+ function resolveFromFilesystem(cwd) {
77
+ let current = resolve(cwd);
78
+ for (let depth = 0; depth < MAX_ANCESTORS; depth += 1) {
79
+ const dotGit = join(current, ".git");
80
+ try {
81
+ const stat = lstatSync(dotGit);
82
+ if (stat.isDirectory() && isGitDirectory(dotGit)) {
83
+ return join(dotGit, WORKSPACE_ID_RELATIVE_PATH);
84
+ }
85
+ if (stat.isFile() && stat.size <= MAX_GIT_FILE_BYTES) {
86
+ const contents = readFileSync(dotGit, "utf8");
87
+ const match = /^gitdir: (.+?)(?:\r?\n)?$/.exec(contents);
88
+ if (match?.[1]) {
89
+ const gitDirectory = isAbsolute(match[1]) ? resolve(match[1]) : resolve(current, match[1]);
90
+ if (isGitDirectory(gitDirectory)) {
91
+ return join(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
92
+ }
93
+ }
94
+ }
95
+ return null;
96
+ } catch (error) {
97
+ const code = errorCode(error);
98
+ if (code !== "ENOENT" && code !== "ENOTDIR") {
99
+ return null;
100
+ }
101
+ }
102
+ const parent = dirname(current);
103
+ if (parent === current) break;
104
+ current = parent;
105
+ }
106
+ return null;
107
+ }
108
+ function isGitDirectory(path) {
109
+ try {
110
+ return statSync(join(path, "HEAD")).isFile();
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+ function inspectPath(path) {
116
+ let stat;
117
+ try {
118
+ stat = lstatSync(path);
119
+ } catch (error) {
120
+ const code = errorCode(error);
121
+ if (code === "ENOENT" || code === "ENOTDIR") return { status: "missing", path };
122
+ return { status: "unavailable", path, operation: "read", errorCode: code };
123
+ }
124
+ if (!stat.isFile()) return { status: "corrupt", path, reason: "not_file" };
125
+ if (stat.size > MAX_ID_FILE_BYTES) {
126
+ return { status: "corrupt", path, reason: "invalid_content" };
127
+ }
128
+ try {
129
+ const contents = readFileSync(path, "utf8");
130
+ const workspaceId = contents.endsWith("\n") ? contents.slice(0, -1) : contents;
131
+ if ((contents === workspaceId || contents === `${workspaceId}
132
+ `) && isCanonicalWorkspaceId(workspaceId)) {
133
+ return { status: "ready", workspaceId, path, created: false };
134
+ }
135
+ return { status: "corrupt", path, reason: "invalid_content" };
136
+ } catch (error) {
137
+ return {
138
+ status: "unavailable",
139
+ path,
140
+ operation: "read",
141
+ errorCode: errorCode(error)
142
+ };
143
+ }
144
+ }
145
+ function createWorkspaceId(path) {
146
+ const parent = dirname(path);
147
+ const workspaceId = randomUUID();
148
+ const temporaryPath = join(parent, `.workspace-id-${process.pid}-${randomUUID()}.tmp`);
149
+ let temporaryCreated = false;
150
+ let publishing = false;
151
+ try {
152
+ mkdirSync(parent, { recursive: true, mode: 448 });
153
+ chmodSync(parent, 448);
154
+ const fd = openSync(
155
+ temporaryPath,
156
+ constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY,
157
+ 384
158
+ );
159
+ temporaryCreated = true;
160
+ try {
161
+ writeFileSync(fd, `${workspaceId}
162
+ `, "utf8");
163
+ fchmodSync(fd, 384);
164
+ fsyncSync(fd);
165
+ } finally {
166
+ closeSync(fd);
167
+ }
168
+ publishing = true;
169
+ linkSync(temporaryPath, path);
170
+ return { status: "ready", workspaceId, path, created: true };
171
+ } catch (error) {
172
+ if (publishing && errorCode(error) === "EEXIST") return inspectAfterRace(path);
173
+ return {
174
+ status: "unavailable",
175
+ path,
176
+ operation: "create",
177
+ errorCode: errorCode(error)
178
+ };
179
+ } finally {
180
+ if (temporaryCreated) {
181
+ try {
182
+ unlinkSync(temporaryPath);
183
+ } catch {
184
+ }
185
+ }
186
+ }
187
+ }
188
+ function inspectAfterRace(path) {
189
+ let result = { status: "missing", path };
190
+ for (let attempt = 0; attempt < RACE_READ_ATTEMPTS; attempt += 1) {
191
+ result = inspectPath(path);
192
+ if (result.status === "ready") return result;
193
+ if (attempt + 1 < RACE_READ_ATTEMPTS) {
194
+ Atomics.wait(raceDelay, 0, 0, RACE_READ_DELAY_MS);
195
+ }
196
+ }
197
+ if (result.status === "missing") {
198
+ return { status: "unavailable", path, operation: "create", errorCode: "EEXIST" };
199
+ }
200
+ return result;
201
+ }
202
+ function errorCode(error) {
203
+ if (typeof error !== "object" || error === null || !("code" in error)) return void 0;
204
+ return typeof error.code === "string" ? error.code : void 0;
205
+ }
206
+
207
+ export {
208
+ isCanonicalWorkspaceId,
209
+ getOrCreateWorkspaceId
210
+ };
@@ -0,0 +1,327 @@
1
+ import {
2
+ getSiteUrl
3
+ } from "./chunk-PCVGBE5B.js";
4
+ import {
5
+ jwtOrganizationId,
6
+ primConfigDirectory,
7
+ resolveAuthCredential
8
+ } from "./chunk-67VNLLBN.js";
9
+
10
+ // src/journal.ts
11
+ import {
12
+ appendFileSync,
13
+ closeSync,
14
+ existsSync,
15
+ fstatSync,
16
+ mkdirSync,
17
+ openSync,
18
+ opendirSync,
19
+ readFileSync,
20
+ readSync,
21
+ readdirSync
22
+ } from "fs";
23
+ import { dirname, join } from "path";
24
+ var JOURNAL_DIR = join(primConfigDirectory(), "moves");
25
+ var UNBOUND_BUCKET = "_unbound";
26
+ var JOURNAL_BASENAME = "journal.ndjson";
27
+ var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
28
+ var PENDING_STATS_MAX_FILES = 128;
29
+ function envSlug(apiUrl) {
30
+ const slug = apiUrl.replace(/^https?:\/\//, "").replace(/[^a-zA-Z0-9._-]/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
31
+ if (slug.length === 0 || slug === "." || slug === "..") {
32
+ return "default";
33
+ }
34
+ return slug;
35
+ }
36
+ function currentEnvDir() {
37
+ return join(JOURNAL_DIR, envSlug(getSiteUrl()));
38
+ }
39
+ var DIR_MODE = 448;
40
+ var FILE_MODE = 384;
41
+ var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
42
+ var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
43
+ function appendMoveToPath(path, move) {
44
+ const dir = dirname(path);
45
+ if (!existsSync(dir)) {
46
+ mkdirSync(dir, { recursive: true, mode: DIR_MODE });
47
+ }
48
+ appendFileSync(path, `${JSON.stringify(move)}
49
+ `, { mode: FILE_MODE });
50
+ }
51
+ function bucketDir(orgId) {
52
+ const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
53
+ return join(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
54
+ }
55
+ function journalPath(orgId) {
56
+ return join(bucketDir(orgId), JOURNAL_BASENAME);
57
+ }
58
+ function appendMove(move, orgId) {
59
+ appendMoveToPath(journalPath(orgId), move);
60
+ }
61
+ function parseMoves(content) {
62
+ const moves = [];
63
+ for (const line of content.split("\n")) {
64
+ if (line.length === 0) {
65
+ continue;
66
+ }
67
+ try {
68
+ moves.push(JSON.parse(line));
69
+ } catch {
70
+ }
71
+ }
72
+ return moves;
73
+ }
74
+ function readMovesFromPath(path) {
75
+ if (!existsSync(path)) {
76
+ return [];
77
+ }
78
+ return parseMoves(readFileSync(path, "utf-8"));
79
+ }
80
+ function listBuckets() {
81
+ const out = [];
82
+ const envDir = currentEnvDir();
83
+ if (!existsSync(envDir)) {
84
+ return out;
85
+ }
86
+ for (const entry of readdirSync(envDir, { withFileTypes: true })) {
87
+ if (!entry.isDirectory()) {
88
+ continue;
89
+ }
90
+ const path = join(envDir, entry.name, JOURNAL_BASENAME);
91
+ if (existsSync(path)) {
92
+ out.push({ bucket: entry.name, path });
93
+ }
94
+ }
95
+ return out;
96
+ }
97
+ var FLUSHING_PREFIX = `${JOURNAL_BASENAME}.flushing.`;
98
+ function oldestCapturedAt(moves) {
99
+ let oldest;
100
+ for (const move of moves) {
101
+ if (!Number.isFinite(move.capturedAt)) {
102
+ continue;
103
+ }
104
+ oldest = oldest === void 0 ? move.capturedAt : Math.min(oldest, move.capturedAt);
105
+ }
106
+ return oldest;
107
+ }
108
+ function sampleJournalFile(path, maxBytes = JOURNAL_STATS_SAMPLE_BYTES) {
109
+ const fd = openSync(path, "r");
110
+ try {
111
+ const initial = fstatSync(fd);
112
+ const target = Math.min(initial.size, Math.max(0, maxBytes));
113
+ const buffer = Buffer.allocUnsafe(target);
114
+ let sampledBytes = 0;
115
+ while (sampledBytes < target) {
116
+ const count = readSync(fd, buffer, sampledBytes, target - sampledBytes, sampledBytes);
117
+ if (count === 0) {
118
+ break;
119
+ }
120
+ sampledBytes += count;
121
+ }
122
+ const stat = fstatSync(fd);
123
+ const sampled = stat.size > sampledBytes;
124
+ let content = buffer.subarray(0, sampledBytes).toString("utf-8");
125
+ if (sampled) {
126
+ const lastNewline = content.lastIndexOf("\n");
127
+ content = lastNewline === -1 ? "" : content.slice(0, lastNewline + 1);
128
+ }
129
+ const lines = content.split("\n").filter((line) => line.length > 0);
130
+ const moves = parseMoves(content);
131
+ return {
132
+ sizeBytes: stat.size,
133
+ mtimeMs: stat.mtimeMs,
134
+ lineCount: sampled && stat.size > 0 ? Math.max(1, lines.length) : lines.length,
135
+ oldestCapturedAt: oldestCapturedAt(moves),
136
+ sampled,
137
+ sampledBytes
138
+ };
139
+ } finally {
140
+ closeSync(fd);
141
+ }
142
+ }
143
+ function parseFlushingPid(name) {
144
+ const segments = name.slice(FLUSHING_PREFIX.length).split(".");
145
+ const last = segments.length >= 2 ? segments[segments.length - 1] : void 0;
146
+ if (last === void 0 || !/^[0-9]+$/.test(last)) return void 0;
147
+ const pid = Number(last);
148
+ return Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
149
+ }
150
+ function listFlushingInDir(dir, bucket, options = {}) {
151
+ if (!existsSync(dir)) {
152
+ return [];
153
+ }
154
+ const out = [];
155
+ let remainingBytes = options.sampleBytes ?? JOURNAL_STATS_SAMPLE_BYTES;
156
+ const maxFiles = options.maxFiles ?? Number.POSITIVE_INFINITY;
157
+ const entries = opendirSync(dir);
158
+ try {
159
+ let entry = entries.readSync();
160
+ while (entry && out.length < maxFiles) {
161
+ if (!entry.isFile() || !entry.name.startsWith(FLUSHING_PREFIX)) {
162
+ entry = entries.readSync();
163
+ continue;
164
+ }
165
+ const path = join(dir, entry.name);
166
+ let sample;
167
+ try {
168
+ sample = sampleJournalFile(path, remainingBytes);
169
+ } catch (err) {
170
+ if (err.code === "ENOENT") {
171
+ entry = entries.readSync();
172
+ continue;
173
+ }
174
+ throw err;
175
+ }
176
+ remainingBytes = Math.max(0, remainingBytes - sample.sampledBytes);
177
+ out.push({
178
+ bucket,
179
+ path,
180
+ pid: parseFlushingPid(entry.name),
181
+ ...sample
182
+ });
183
+ entry = entries.readSync();
184
+ }
185
+ } finally {
186
+ entries.closeSync();
187
+ }
188
+ return out;
189
+ }
190
+ function listFlushing(options = {}) {
191
+ const envDir = currentEnvDir();
192
+ if (!existsSync(envDir)) {
193
+ return [];
194
+ }
195
+ const out = [];
196
+ let remainingBytes = options.sampleBytes ?? JOURNAL_STATS_SAMPLE_BYTES;
197
+ const maxFiles = options.maxFiles ?? Number.POSITIVE_INFINITY;
198
+ for (const entry of readdirSync(envDir, { withFileTypes: true })) {
199
+ if (out.length >= maxFiles) {
200
+ break;
201
+ }
202
+ if (entry.isDirectory()) {
203
+ const found = listFlushingInDir(join(envDir, entry.name), entry.name, {
204
+ sampleBytes: remainingBytes,
205
+ maxFiles: maxFiles - out.length
206
+ });
207
+ out.push(...found);
208
+ remainingBytes = Math.max(
209
+ 0,
210
+ remainingBytes - found.reduce((count, file) => count + file.sampledBytes, 0)
211
+ );
212
+ }
213
+ }
214
+ return out;
215
+ }
216
+ function bucketStats(options = {}) {
217
+ const out = [];
218
+ let remainingBytes = options.sampleBytes ?? JOURNAL_STATS_SAMPLE_BYTES;
219
+ const maxFiles = options.maxFiles ?? Number.POSITIVE_INFINITY;
220
+ for (const { bucket, path } of listBuckets()) {
221
+ if (out.length >= maxFiles) {
222
+ break;
223
+ }
224
+ let sample;
225
+ try {
226
+ sample = sampleJournalFile(path, remainingBytes);
227
+ } catch (err) {
228
+ if (err.code === "ENOENT") {
229
+ continue;
230
+ }
231
+ throw err;
232
+ }
233
+ remainingBytes = Math.max(0, remainingBytes - sample.sampledBytes);
234
+ out.push({
235
+ bucket,
236
+ path,
237
+ ...sample
238
+ });
239
+ }
240
+ return out;
241
+ }
242
+ function pendingJournalStats() {
243
+ const perKindBytes = Math.floor(JOURNAL_STATS_SAMPLE_BYTES / 2);
244
+ const perKindFiles = Math.floor(PENDING_STATS_MAX_FILES / 2);
245
+ const live = bucketStats({ sampleBytes: perKindBytes, maxFiles: perKindFiles });
246
+ const stranded = listFlushing({ sampleBytes: perKindBytes, maxFiles: perKindFiles });
247
+ const timestamps = [...live, ...stranded].map((entry) => entry.oldestCapturedAt).filter((value) => value !== void 0);
248
+ const liveSampled = live.some((entry) => entry.sampled) || live.length >= perKindFiles;
249
+ const strandedSampled = stranded.some((entry) => entry.sampled) || stranded.length >= perKindFiles;
250
+ return {
251
+ pendingCount: live.reduce((count, entry) => count + entry.lineCount, 0) + stranded.reduce((count, entry) => count + entry.lineCount, 0),
252
+ oldestPendingAt: timestamps.length > 0 ? Math.min(...timestamps) : void 0,
253
+ strandedCount: stranded.reduce((count, entry) => count + entry.lineCount, 0),
254
+ strandedFileCount: stranded.length,
255
+ sampled: liveSampled || strandedSampled,
256
+ strandedSampled
257
+ };
258
+ }
259
+
260
+ // src/binding.ts
261
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
262
+ import { dirname as dirname2, join as join2 } from "path";
263
+ var PRIM_CONFIG_DIR = primConfigDirectory();
264
+ var SESSIONS_DIR = join2(PRIM_CONFIG_DIR, "sessions");
265
+ var WORKSPACE_FILE = ".prim/workspace.json";
266
+ function readJsonSafe(path) {
267
+ if (!existsSync2(path)) {
268
+ return;
269
+ }
270
+ try {
271
+ return JSON.parse(readFileSync2(path, "utf-8"));
272
+ } catch {
273
+ return;
274
+ }
275
+ }
276
+ function fromSessionMarker(sessionId) {
277
+ if (!sessionId) {
278
+ return;
279
+ }
280
+ const marker = readJsonSafe(join2(SESSIONS_DIR, `${sessionId}.json`));
281
+ return marker?.orgId;
282
+ }
283
+ function fromWorkspaceFile(startDir) {
284
+ let dir = startDir;
285
+ while (true) {
286
+ const config = readJsonSafe(join2(dir, WORKSPACE_FILE));
287
+ if (config?.orgId) {
288
+ return config.orgId;
289
+ }
290
+ const parent = dirname2(dir);
291
+ if (parent === dir) {
292
+ return;
293
+ }
294
+ dir = parent;
295
+ }
296
+ }
297
+ function fromDefaultOrg(_cwd) {
298
+ const credential = resolveAuthCredential();
299
+ return credential ? jwtOrganizationId(credential.token) : void 0;
300
+ }
301
+ function resolveOrg(args) {
302
+ const fromSession = fromSessionMarker(args.sessionId);
303
+ if (fromSession) {
304
+ return { orgId: fromSession, source: "session" };
305
+ }
306
+ const fromWorkspace = fromWorkspaceFile(args.cwd);
307
+ if (fromWorkspace) {
308
+ return { orgId: fromWorkspace, source: "workspace" };
309
+ }
310
+ const fromDefault = fromDefaultOrg(args.cwd);
311
+ if (fromDefault) {
312
+ return { orgId: fromDefault, source: "defaultOrg" };
313
+ }
314
+ return { orgId: void 0, source: "unbound" };
315
+ }
316
+
317
+ export {
318
+ JOURNAL_DIR,
319
+ appendMove,
320
+ readMovesFromPath,
321
+ listBuckets,
322
+ listFlushing,
323
+ bucketStats,
324
+ pendingJournalStats,
325
+ SESSIONS_DIR,
326
+ resolveOrg
327
+ };
@@ -0,0 +1,36 @@
1
+ import {
2
+ scheduleCollectScopeRefresh
3
+ } from "./chunk-M6RIJVRE.js";
4
+
5
+ // src/ingest-response.ts
6
+ var IngestAcknowledgementError = class extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "IngestAcknowledgementError";
10
+ }
11
+ };
12
+ function requireDurableIngestAcknowledgement(value, expected, cwd = process.cwd()) {
13
+ if (typeof value !== "object" || value === null) {
14
+ throw new IngestAcknowledgementError("ingest response was not an object");
15
+ }
16
+ const response = value;
17
+ if (response.disposition !== "persisted") {
18
+ throw new IngestAcknowledgementError("ingest response did not confirm persistence");
19
+ }
20
+ if (response.acknowledged !== expected) {
21
+ throw new IngestAcknowledgementError(
22
+ `ingest acknowledged ${String(response.acknowledged)} of ${String(expected)} moves`
23
+ );
24
+ }
25
+ if (typeof response.collectScopeVersion === "number" && Number.isSafeInteger(response.collectScopeVersion) && response.collectScopeVersion >= 0) {
26
+ const roots = typeof cwd === "string" ? [cwd] : cwd;
27
+ for (const root of new Set(roots)) {
28
+ scheduleCollectScopeRefresh(root, response.collectScopeVersion);
29
+ }
30
+ }
31
+ return value;
32
+ }
33
+
34
+ export {
35
+ requireDurableIngestAcknowledgement
36
+ };