@oxagen/cli 2.1.4-671 → 2.1.4-679
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -26
- package/oxagen.mjs +743 -1146
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -149,359 +149,6 @@ var init_fs = __esm({
|
|
|
149
149
|
}
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
-
// ../../packages/tacho/src/host/harness-file.ts
|
|
153
|
-
import {
|
|
154
|
-
chmodSync as chmodSync2,
|
|
155
|
-
existsSync,
|
|
156
|
-
lstatSync,
|
|
157
|
-
mkdirSync as mkdirSync2,
|
|
158
|
-
readdirSync,
|
|
159
|
-
readFileSync as readFileSync2,
|
|
160
|
-
readlinkSync,
|
|
161
|
-
rmdirSync,
|
|
162
|
-
statSync,
|
|
163
|
-
unlinkSync as unlinkSync2
|
|
164
|
-
} from "node:fs";
|
|
165
|
-
import { createHash } from "node:crypto";
|
|
166
|
-
import { basename as basename2, dirname as dirname2, join as join2, resolve } from "node:path";
|
|
167
|
-
import { isDeepStrictEqual } from "node:util";
|
|
168
|
-
function enrollmentIdsIn(text5) {
|
|
169
|
-
const ids = /* @__PURE__ */ new Set();
|
|
170
|
-
for (const match of text5.matchAll(ENROLLMENT_MARKER)) {
|
|
171
|
-
const id2 = match[1] ?? match[2];
|
|
172
|
-
if (id2 !== void 0) ids.add(id2);
|
|
173
|
-
}
|
|
174
|
-
return ids;
|
|
175
|
-
}
|
|
176
|
-
function withoutBom(text5) {
|
|
177
|
-
return text5.startsWith(BOM) ? text5.slice(BOM.length) : text5;
|
|
178
|
-
}
|
|
179
|
-
function realTarget(path2) {
|
|
180
|
-
let current = path2;
|
|
181
|
-
for (let hops = 0; hops < 16; hops += 1) {
|
|
182
|
-
let stat6;
|
|
183
|
-
try {
|
|
184
|
-
stat6 = lstatSync(current);
|
|
185
|
-
} catch {
|
|
186
|
-
return current;
|
|
187
|
-
}
|
|
188
|
-
if (!stat6.isSymbolicLink()) return current;
|
|
189
|
-
current = resolve(dirname2(current), readlinkSync(current));
|
|
190
|
-
}
|
|
191
|
-
throw new HarnessFileError(path2, "too many levels of symbolic links");
|
|
192
|
-
}
|
|
193
|
-
function writeAtomic(path2, data, mode) {
|
|
194
|
-
writeFileAtomic(path2, data, { mode });
|
|
195
|
-
}
|
|
196
|
-
function digestOf(text5) {
|
|
197
|
-
return createHash("sha256").update(text5).digest("hex");
|
|
198
|
-
}
|
|
199
|
-
function isBlank(text5) {
|
|
200
|
-
if (text5.trim() === "") return true;
|
|
201
|
-
try {
|
|
202
|
-
return isDeepStrictEqual(JSON.parse(withoutBom(text5)), {});
|
|
203
|
-
} catch {
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
function sameDocument(a, b5) {
|
|
208
|
-
if (a === b5) return true;
|
|
209
|
-
try {
|
|
210
|
-
return isDeepStrictEqual(
|
|
211
|
-
sortKeys(withoutStrippedEmpties(JSON.parse(withoutBom(a)))),
|
|
212
|
-
sortKeys(withoutStrippedEmpties(JSON.parse(withoutBom(b5))))
|
|
213
|
-
);
|
|
214
|
-
} catch {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
function isEmptyContainer(value) {
|
|
219
|
-
if (Array.isArray(value)) return value.length === 0;
|
|
220
|
-
return typeof value === "object" && value !== null && Object.keys(value).length === 0;
|
|
221
|
-
}
|
|
222
|
-
function withoutStrippedEmpties(value) {
|
|
223
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
224
|
-
return value;
|
|
225
|
-
const document = { ...value };
|
|
226
|
-
const hooks = document["hooks"];
|
|
227
|
-
if (typeof hooks === "object" && hooks !== null && !Array.isArray(hooks))
|
|
228
|
-
document["hooks"] = Object.fromEntries(
|
|
229
|
-
Object.entries(hooks).filter(([, list]) => !isEmptyContainer(list))
|
|
230
|
-
);
|
|
231
|
-
for (const key of ["env", "hooks", "mcpServers"])
|
|
232
|
-
if (isEmptyContainer(document[key])) delete document[key];
|
|
233
|
-
return document;
|
|
234
|
-
}
|
|
235
|
-
function sortKeys(value) {
|
|
236
|
-
if (Array.isArray(value)) return value.map(sortKeys);
|
|
237
|
-
if (typeof value !== "object" || value === null) return value;
|
|
238
|
-
return Object.fromEntries(
|
|
239
|
-
Object.entries(value).sort(([a], [b5]) => a < b5 ? -1 : a > b5 ? 1 : 0).map(([key, child]) => [key, sortKeys(child)])
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
var HarnessFileError, ENROLLMENT_MARKER, BOM, HARNESS_RECEIPTS, HARNESS_BACKUPS, HarnessFiles;
|
|
243
|
-
var init_harness_file = __esm({
|
|
244
|
-
"../../packages/tacho/src/host/harness-file.ts"() {
|
|
245
|
-
"use strict";
|
|
246
|
-
init_fs();
|
|
247
|
-
HarnessFileError = class extends Error {
|
|
248
|
-
constructor(path2, reason3) {
|
|
249
|
-
super(`${path2}: ${reason3}`);
|
|
250
|
-
this.path = path2;
|
|
251
|
-
this.reason = reason3;
|
|
252
|
-
this.name = "HarnessFileError";
|
|
253
|
-
}
|
|
254
|
-
path;
|
|
255
|
-
reason;
|
|
256
|
-
};
|
|
257
|
-
ENROLLMENT_MARKER = /--enrollment(?:\s+|"\s*,\s*")(tch_[a-z0-9]{22})|\/hook\/(tch_[a-z0-9]{22})/g;
|
|
258
|
-
BOM = "\uFEFF";
|
|
259
|
-
HARNESS_RECEIPTS = "install-receipts.json";
|
|
260
|
-
HARNESS_BACKUPS = "backups";
|
|
261
|
-
HarnessFiles = class {
|
|
262
|
-
/**
|
|
263
|
-
* `root` is the agent's directory (`TachoPaths.dir`). Each agent keeps the
|
|
264
|
-
* receipts for the files its own enroll touched, so its unenroll settles
|
|
265
|
-
* those and no other agent's.
|
|
266
|
-
*/
|
|
267
|
-
constructor(root) {
|
|
268
|
-
this.root = root;
|
|
269
|
-
this.receiptsPath = join2(root, HARNESS_RECEIPTS);
|
|
270
|
-
this.backupsDir = join2(root, HARNESS_BACKUPS);
|
|
271
|
-
}
|
|
272
|
-
root;
|
|
273
|
-
receiptsPath;
|
|
274
|
-
backupsDir;
|
|
275
|
-
/** The file's text, or undefined when it does not exist. */
|
|
276
|
-
readText(path2) {
|
|
277
|
-
try {
|
|
278
|
-
return readFileSync2(path2, "utf8");
|
|
279
|
-
} catch (error) {
|
|
280
|
-
if (error.code === "ENOENT") return void 0;
|
|
281
|
-
throw new HarnessFileError(
|
|
282
|
-
path2,
|
|
283
|
-
`cannot be read (${error.code ?? "error"})`
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
/** The file parsed as JSON; undefined when absent; a named error when malformed. */
|
|
288
|
-
readJson(path2) {
|
|
289
|
-
const text5 = this.readText(path2);
|
|
290
|
-
if (text5 === void 0) return void 0;
|
|
291
|
-
if (text5.trim() === "") return void 0;
|
|
292
|
-
try {
|
|
293
|
-
return JSON.parse(withoutBom(text5));
|
|
294
|
-
} catch (error) {
|
|
295
|
-
throw new HarnessFileError(
|
|
296
|
-
path2,
|
|
297
|
-
`is not valid JSON (${error instanceof Error ? error.message : String(error)}); fix or remove it and run this again`
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Whether `write` would be refused, without writing: the file, or the
|
|
303
|
-
* nearest existing directory above it, is not writable by this user.
|
|
304
|
-
*/
|
|
305
|
-
writeProblem(path2) {
|
|
306
|
-
const target2 = realTarget(path2);
|
|
307
|
-
if (existsSync(target2)) {
|
|
308
|
-
if ((statSync(target2).mode & 128) === 0)
|
|
309
|
-
return "is read-only; Oxagen does not replace a file you have locked (chmod u+w it to allow the hooks)";
|
|
310
|
-
return void 0;
|
|
311
|
-
}
|
|
312
|
-
let dir = dirname2(target2);
|
|
313
|
-
while (!existsSync(dir) && dirname2(dir) !== dir) dir = dirname2(dir);
|
|
314
|
-
if ((statSync(dir).mode & 128) === 0)
|
|
315
|
-
return `cannot be created: ${dir} is read-only`;
|
|
316
|
-
return void 0;
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Write `text`, taking a receipt the first time this path is touched.
|
|
320
|
-
*
|
|
321
|
-
* `vestigial` is the writer saying that what it is about to write holds
|
|
322
|
-
* nothing but the scaffolding it had to add itself (Cursor's `version`
|
|
323
|
-
* is the one instance), so `settle` may take the whole file back. It
|
|
324
|
-
* defaults to false, and every ordinary write leaves it false, because a
|
|
325
|
-
* teardown writes through here too: the stripped document is the bytes
|
|
326
|
-
* Tacho last wrote, and a hook the user added while enrolled survives
|
|
327
|
-
* inside it. Deleting on the digest alone would take that hook with the
|
|
328
|
-
* file.
|
|
329
|
-
*/
|
|
330
|
-
write(path2, text5, vestigial = false) {
|
|
331
|
-
const problem = this.writeProblem(path2);
|
|
332
|
-
if (problem !== void 0) throw new HarnessFileError(path2, problem);
|
|
333
|
-
const target2 = realTarget(path2);
|
|
334
|
-
const receipts = this.load();
|
|
335
|
-
if (receipts.files[path2] === void 0) {
|
|
336
|
-
receipts.files[path2] = this.takeReceipt(path2, target2);
|
|
337
|
-
this.save(receipts);
|
|
338
|
-
}
|
|
339
|
-
for (const dir of receipts.files[path2]?.created_dirs ?? []) {
|
|
340
|
-
if (!existsSync(dir)) mkdirSync2(dir, { mode: 448 });
|
|
341
|
-
}
|
|
342
|
-
mkdirSync2(dirname2(target2), { recursive: true, mode: 448 });
|
|
343
|
-
const before = this.readText(target2);
|
|
344
|
-
const bom = !text5.startsWith(BOM) && before?.startsWith(BOM) === true ? BOM : "";
|
|
345
|
-
writeAtomic(target2, `${bom}${text5}`, 384);
|
|
346
|
-
const receipt = receipts.files[path2];
|
|
347
|
-
if (receipt !== void 0) {
|
|
348
|
-
receipt.last_written = digestOf(`${bom}${text5}`);
|
|
349
|
-
receipt.vestigial = vestigial;
|
|
350
|
-
receipt.enrollments = [
|
|
351
|
-
.../* @__PURE__ */ new Set([
|
|
352
|
-
...receipt.enrollments ?? enrollmentIdsIn(before ?? ""),
|
|
353
|
-
...enrollmentIdsIn(text5)
|
|
354
|
-
])
|
|
355
|
-
].sort();
|
|
356
|
-
this.save(receipts);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Give every file back (see the module comment). Safe to call with no
|
|
361
|
-
* receipts, twice, or after a run that died half way.
|
|
362
|
-
*/
|
|
363
|
-
settle() {
|
|
364
|
-
const receipts = this.load();
|
|
365
|
-
const outcomes = [];
|
|
366
|
-
for (const [path2, receipt] of Object.entries(receipts.files)) {
|
|
367
|
-
const outcome = this.settleOne(path2, receipt);
|
|
368
|
-
outcomes.push(outcome);
|
|
369
|
-
if (outcome.result === "failed") continue;
|
|
370
|
-
delete receipts.files[path2];
|
|
371
|
-
this.save(receipts);
|
|
372
|
-
}
|
|
373
|
-
this.save(receipts);
|
|
374
|
-
return outcomes;
|
|
375
|
-
}
|
|
376
|
-
settleOne(path2, receipt) {
|
|
377
|
-
const target2 = realTarget(path2);
|
|
378
|
-
const backupPath = this.backupOf(receipt);
|
|
379
|
-
const backup = backupPath !== void 0 ? readFileSync2(backupPath) : void 0;
|
|
380
|
-
let result2;
|
|
381
|
-
let current;
|
|
382
|
-
try {
|
|
383
|
-
current = readFileSync2(target2, "utf8");
|
|
384
|
-
} catch (error) {
|
|
385
|
-
if (error.code !== "ENOENT") throw error;
|
|
386
|
-
current = void 0;
|
|
387
|
-
}
|
|
388
|
-
const original = enrollmentIdsIn(backup?.toString("utf8") ?? "");
|
|
389
|
-
const added = [...enrollmentIdsIn(current ?? "")].filter(
|
|
390
|
-
(id2) => !original.has(id2)
|
|
391
|
-
);
|
|
392
|
-
const ours = added.filter(
|
|
393
|
-
(id2) => receipt.enrollments?.includes(id2) ?? true
|
|
394
|
-
);
|
|
395
|
-
if (ours.length > 0) {
|
|
396
|
-
return {
|
|
397
|
-
path: path2,
|
|
398
|
-
result: "failed",
|
|
399
|
-
reason: `still carries Tacho's hooks, so it was not given back; run \`oxagen agent unenroll\` again from the environment that enrolled, or remove the entries that name ${ours.map((id2) => `\`${id2}\``).join(" or ")}`
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
if (added.length > 0) {
|
|
403
|
-
if (backupPath !== void 0 && existsSync(backupPath))
|
|
404
|
-
unlinkSync2(backupPath);
|
|
405
|
-
return { path: path2, result: "left-to-another-enrollment" };
|
|
406
|
-
}
|
|
407
|
-
if (current === void 0) {
|
|
408
|
-
result2 = "missing";
|
|
409
|
-
} else if (!receipt.existed) {
|
|
410
|
-
const oursAlone = receipt.vestigial === true && digestOf(current) === receipt.last_written;
|
|
411
|
-
if (isBlank(current) || oursAlone) {
|
|
412
|
-
unlinkSync2(target2);
|
|
413
|
-
result2 = "deleted";
|
|
414
|
-
} else {
|
|
415
|
-
result2 = "kept-user-edit";
|
|
416
|
-
}
|
|
417
|
-
} else if (backup !== void 0 && sameDocument(current, backup.toString("utf8"))) {
|
|
418
|
-
writeAtomic(target2, backup, receipt.mode ?? 420);
|
|
419
|
-
result2 = "restored";
|
|
420
|
-
} else {
|
|
421
|
-
if (receipt.mode !== void 0) chmodSync2(target2, receipt.mode);
|
|
422
|
-
result2 = "kept-user-edit";
|
|
423
|
-
}
|
|
424
|
-
if (backupPath !== void 0 && existsSync(backupPath))
|
|
425
|
-
unlinkSync2(backupPath);
|
|
426
|
-
for (const dir of [...receipt.created_dirs].reverse()) {
|
|
427
|
-
try {
|
|
428
|
-
if (readdirSync(dir).length === 0) rmdirSync(dir);
|
|
429
|
-
} catch {
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
return { path: path2, result: result2 };
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Where the receipt's byte copy is now, or undefined when it is gone. The
|
|
436
|
-
* receipt records an absolute path, and the move of a pre-ADR-203
|
|
437
|
-
* enrollment into `agents/<id>/` (`migrateLegacyLayout`) carries
|
|
438
|
-
* `backups/` along without rewriting it, so a copy missing from the
|
|
439
|
-
* recorded path is looked for under its own name in this `backups/`.
|
|
440
|
-
*/
|
|
441
|
-
backupOf(receipt) {
|
|
442
|
-
if (receipt.backup === void 0) return void 0;
|
|
443
|
-
if (existsSync(receipt.backup)) return receipt.backup;
|
|
444
|
-
const moved = join2(this.backupsDir, basename2(receipt.backup));
|
|
445
|
-
return existsSync(moved) ? moved : void 0;
|
|
446
|
-
}
|
|
447
|
-
takeReceipt(path2, target2) {
|
|
448
|
-
const created = [];
|
|
449
|
-
let dir = dirname2(target2);
|
|
450
|
-
while (!existsSync(dir) && dirname2(dir) !== dir) {
|
|
451
|
-
created.unshift(dir);
|
|
452
|
-
dir = dirname2(dir);
|
|
453
|
-
}
|
|
454
|
-
if (!existsSync(target2))
|
|
455
|
-
return { existed: false, created_dirs: created, enrollments: [] };
|
|
456
|
-
mkdirSync2(this.backupsDir, { recursive: true, mode: 448 });
|
|
457
|
-
const backup = join2(
|
|
458
|
-
this.backupsDir,
|
|
459
|
-
`${createHash("sha256").update(path2).digest("hex").slice(0, 24)}.orig`
|
|
460
|
-
);
|
|
461
|
-
writeAtomic(backup, readFileSync2(target2), 384);
|
|
462
|
-
return {
|
|
463
|
-
existed: true,
|
|
464
|
-
mode: statSync(target2).mode & 511,
|
|
465
|
-
backup,
|
|
466
|
-
created_dirs: created,
|
|
467
|
-
enrollments: []
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
load() {
|
|
471
|
-
try {
|
|
472
|
-
const parsed2 = JSON.parse(
|
|
473
|
-
readFileSync2(this.receiptsPath, "utf8")
|
|
474
|
-
);
|
|
475
|
-
if (typeof parsed2.files === "object" && parsed2.files !== null)
|
|
476
|
-
return { schema: "tacho.install-receipts.v1", files: parsed2.files };
|
|
477
|
-
} catch {
|
|
478
|
-
}
|
|
479
|
-
return { schema: "tacho.install-receipts.v1", files: {} };
|
|
480
|
-
}
|
|
481
|
-
save(receipts) {
|
|
482
|
-
if (Object.keys(receipts.files).length === 0) {
|
|
483
|
-
for (const path2 of [this.receiptsPath]) {
|
|
484
|
-
if (existsSync(path2)) unlinkSync2(path2);
|
|
485
|
-
}
|
|
486
|
-
try {
|
|
487
|
-
if (readdirSync(this.backupsDir).length === 0)
|
|
488
|
-
rmdirSync(this.backupsDir);
|
|
489
|
-
} catch {
|
|
490
|
-
}
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
mkdirSync2(this.root, { recursive: true, mode: 448 });
|
|
494
|
-
writeAtomic(
|
|
495
|
-
this.receiptsPath,
|
|
496
|
-
`${JSON.stringify(receipts, null, 2)}
|
|
497
|
-
`,
|
|
498
|
-
384
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
|
|
505
152
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
506
153
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
507
154
|
var init_util = __esm({
|
|
@@ -4609,7 +4256,7 @@ var init_zod = __esm({
|
|
|
4609
4256
|
});
|
|
4610
4257
|
|
|
4611
4258
|
// ../../packages/tacho/src/digest.ts
|
|
4612
|
-
import { createHash
|
|
4259
|
+
import { createHash } from "node:crypto";
|
|
4613
4260
|
function jcs(value) {
|
|
4614
4261
|
const text5 = serialize(value, false);
|
|
4615
4262
|
if (text5 === void 0) {
|
|
@@ -4654,7 +4301,7 @@ function serialize(value, legacy) {
|
|
|
4654
4301
|
return `{${out}}`;
|
|
4655
4302
|
}
|
|
4656
4303
|
function sha256Hex(input) {
|
|
4657
|
-
return
|
|
4304
|
+
return createHash("sha256").update(input).digest("hex");
|
|
4658
4305
|
}
|
|
4659
4306
|
function digestBytes(input) {
|
|
4660
4307
|
return `sha256:${sha256Hex(input)}`;
|
|
@@ -8155,7 +7802,7 @@ var init_bundle = __esm({
|
|
|
8155
7802
|
});
|
|
8156
7803
|
|
|
8157
7804
|
// ../../packages/tacho/src/host/host-file.ts
|
|
8158
|
-
import { dirname as
|
|
7805
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
8159
7806
|
function enrolledWithToken(host) {
|
|
8160
7807
|
return host.agent_id !== void 0 || host.enrollment_source === "token";
|
|
8161
7808
|
}
|
|
@@ -8192,7 +7839,7 @@ function withRecordedHarnessFiles(paths, host) {
|
|
|
8192
7839
|
// A record from before #5287 has no entry, and the host it describes
|
|
8193
7840
|
// never had the Oxagen MCP server written, so this process's path stands.
|
|
8194
7841
|
claudeUserConfig: record.claude_user_config ?? paths.claudeUserConfig,
|
|
8195
|
-
claudeProjects: record.claude_settings !== void 0 ?
|
|
7842
|
+
claudeProjects: record.claude_settings !== void 0 ? join2(dirname2(claudeSettings), "projects") : paths.claudeProjects,
|
|
8196
7843
|
codexHooks: record.codex_hooks ?? paths.codexHooks,
|
|
8197
7844
|
cursorHooks: record.cursor_hooks ?? paths.cursorHooks,
|
|
8198
7845
|
stellaToml: record.stella_toml ?? paths.stellaToml,
|
|
@@ -9035,10 +8682,10 @@ var init_mcp_config_writer = __esm({
|
|
|
9035
8682
|
});
|
|
9036
8683
|
|
|
9037
8684
|
// ../../packages/tacho/src/host/claude-desktop-writer.ts
|
|
9038
|
-
import { join as
|
|
8685
|
+
import { join as join3 } from "node:path";
|
|
9039
8686
|
function claudeDesktopConfigPath(platform, home, env = {}) {
|
|
9040
8687
|
if (platform === "darwin") {
|
|
9041
|
-
return
|
|
8688
|
+
return join3(
|
|
9042
8689
|
home,
|
|
9043
8690
|
"Library",
|
|
9044
8691
|
"Application Support",
|
|
@@ -9047,8 +8694,8 @@ function claudeDesktopConfigPath(platform, home, env = {}) {
|
|
|
9047
8694
|
);
|
|
9048
8695
|
}
|
|
9049
8696
|
if (platform === "win32") {
|
|
9050
|
-
const appData = env["APPDATA"] ??
|
|
9051
|
-
return
|
|
8697
|
+
const appData = env["APPDATA"] ?? join3(home, "AppData", "Roaming");
|
|
8698
|
+
return join3(appData, "Claude", "claude_desktop_config.json");
|
|
9052
8699
|
}
|
|
9053
8700
|
return void 0;
|
|
9054
8701
|
}
|
|
@@ -9071,9 +8718,9 @@ var init_claude_desktop_writer = __esm({
|
|
|
9071
8718
|
});
|
|
9072
8719
|
|
|
9073
8720
|
// ../../packages/tacho/src/claude-code/context.ts
|
|
9074
|
-
import { createHash as
|
|
8721
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
9075
8722
|
function digestText(value) {
|
|
9076
|
-
return `sha256:${
|
|
8723
|
+
return `sha256:${createHash2("sha256").update(value, "utf8").digest("hex")}`;
|
|
9077
8724
|
}
|
|
9078
8725
|
function deliveredContext(text5, bundleEtag) {
|
|
9079
8726
|
return text5 === null ? { chars: 0, bundle_etag: bundleEtag } : { digest: digestText(text5), chars: text5.length, bundle_etag: bundleEtag };
|
|
@@ -9355,18 +9002,18 @@ var init_cursor_adapter = __esm({
|
|
|
9355
9002
|
});
|
|
9356
9003
|
|
|
9357
9004
|
// ../../packages/tacho/src/host/cursor-writer.ts
|
|
9358
|
-
import { join as
|
|
9005
|
+
import { join as join4 } from "node:path";
|
|
9359
9006
|
function cursorConfigDir(home, platform, env = {}) {
|
|
9360
9007
|
const explicit = env["CURSOR_CONFIG_DIR"];
|
|
9361
9008
|
if (explicit !== void 0 && explicit.length > 0) return explicit;
|
|
9362
9009
|
const xdg = env["XDG_CONFIG_HOME"];
|
|
9363
9010
|
if (platform !== "darwin" && platform !== "win32" && xdg !== void 0 && xdg.length > 0)
|
|
9364
|
-
return
|
|
9365
|
-
return
|
|
9011
|
+
return join4(xdg, "cursor");
|
|
9012
|
+
return join4(home, ".cursor");
|
|
9366
9013
|
}
|
|
9367
9014
|
function cursorHooksPaths(home, platform, env = {}) {
|
|
9368
|
-
const resolved =
|
|
9369
|
-
const fallback =
|
|
9015
|
+
const resolved = join4(cursorConfigDir(home, platform, env), "hooks.json");
|
|
9016
|
+
const fallback = join4(home, ".cursor", "hooks.json");
|
|
9370
9017
|
return resolved === fallback ? [resolved] : [resolved, fallback];
|
|
9371
9018
|
}
|
|
9372
9019
|
function cursorHooksShapeProblem(document) {
|
|
@@ -9489,16 +9136,16 @@ var init_cursor_writer = __esm({
|
|
|
9489
9136
|
|
|
9490
9137
|
// ../../packages/tacho/src/host/paths.ts
|
|
9491
9138
|
import { homedir } from "node:os";
|
|
9492
|
-
import { join as
|
|
9139
|
+
import { join as join5 } from "node:path";
|
|
9493
9140
|
function claudeConfigDirFor(env, home) {
|
|
9494
|
-
return env["CLAUDE_CONFIG_DIR"] ??
|
|
9141
|
+
return env["CLAUDE_CONFIG_DIR"] ?? join5(home, ".claude");
|
|
9495
9142
|
}
|
|
9496
9143
|
function claudeUserConfigFor(env, home) {
|
|
9497
9144
|
const dir = env["CLAUDE_CONFIG_DIR"];
|
|
9498
|
-
return
|
|
9145
|
+
return join5(dir === void 0 || dir === "" ? home : dir, ".claude.json");
|
|
9499
9146
|
}
|
|
9500
9147
|
function codexHomeFor(env, home) {
|
|
9501
|
-
return env["CODEX_HOME"] ??
|
|
9148
|
+
return env["CODEX_HOME"] ?? join5(home, ".codex");
|
|
9502
9149
|
}
|
|
9503
9150
|
function harnessConfigDirs(home, env = process.env, ownHome = homedir()) {
|
|
9504
9151
|
const own = home === ownHome ? env : {};
|
|
@@ -9508,23 +9155,23 @@ function harnessConfigDirs(home, env = process.env, ownHome = homedir()) {
|
|
|
9508
9155
|
};
|
|
9509
9156
|
}
|
|
9510
9157
|
function tachoHome(env = process.env, home = homedir(), platform = process.platform) {
|
|
9511
|
-
const tachoDir = env["TACHO_HOME"] ??
|
|
9158
|
+
const tachoDir = env["TACHO_HOME"] ?? join5(home, ".config", "oxagen", "tacho");
|
|
9512
9159
|
const claudeConfigDir = claudeConfigDirFor(env, home);
|
|
9513
9160
|
const codexHome = codexHomeFor(env, home);
|
|
9514
|
-
const stellaHome = env["STELLA_HOME"] ??
|
|
9161
|
+
const stellaHome = env["STELLA_HOME"] ?? join5(home, ".stella");
|
|
9515
9162
|
return {
|
|
9516
9163
|
tachoDir,
|
|
9517
|
-
agents:
|
|
9518
|
-
pid:
|
|
9519
|
-
log:
|
|
9520
|
-
daemonLauncher:
|
|
9521
|
-
claudeSettings:
|
|
9164
|
+
agents: join5(tachoDir, "agents"),
|
|
9165
|
+
pid: join5(tachoDir, "tachod.pid"),
|
|
9166
|
+
log: join5(tachoDir, "tachod.log"),
|
|
9167
|
+
daemonLauncher: join5(tachoDir, "tachod.cmd"),
|
|
9168
|
+
claudeSettings: join5(claudeConfigDir, "settings.json"),
|
|
9522
9169
|
claudeUserConfig: claudeUserConfigFor(env, home),
|
|
9523
|
-
claudeProjects:
|
|
9524
|
-
codexHooks:
|
|
9170
|
+
claudeProjects: join5(claudeConfigDir, "projects"),
|
|
9171
|
+
codexHooks: join5(codexHome, "hooks.json"),
|
|
9525
9172
|
cursorHooks: cursorHooksPaths(home, platform, env),
|
|
9526
|
-
stellaToml:
|
|
9527
|
-
stellaSettingsJson:
|
|
9173
|
+
stellaToml: join5(stellaHome, "stella.toml"),
|
|
9174
|
+
stellaSettingsJson: join5(stellaHome, "settings.json"),
|
|
9528
9175
|
claudeDesktopConfig: claudeDesktopConfigPath(platform, home, env)
|
|
9529
9176
|
};
|
|
9530
9177
|
}
|
|
@@ -9546,16 +9193,16 @@ function homeOf(paths) {
|
|
|
9546
9193
|
};
|
|
9547
9194
|
}
|
|
9548
9195
|
function agentPaths(home, id2) {
|
|
9549
|
-
return pathsInDir(home,
|
|
9196
|
+
return pathsInDir(home, join5(home.agents, id2));
|
|
9550
9197
|
}
|
|
9551
9198
|
function pathsInDir(home, dir) {
|
|
9552
9199
|
const files3 = {};
|
|
9553
9200
|
for (const key of Object.keys(AGENT_FILES))
|
|
9554
|
-
files3[key] =
|
|
9201
|
+
files3[key] = join5(dir, AGENT_FILES[key]);
|
|
9555
9202
|
return { ...homeOf(home), dir, ...files3 };
|
|
9556
9203
|
}
|
|
9557
9204
|
function oxagenConfigPath(home = homedir()) {
|
|
9558
|
-
return
|
|
9205
|
+
return join5(home, ".config", "oxagen", "config.json");
|
|
9559
9206
|
}
|
|
9560
9207
|
var AGENT_FILES;
|
|
9561
9208
|
var init_paths = __esm({
|
|
@@ -9590,34 +9237,21 @@ var init_paths = __esm({
|
|
|
9590
9237
|
|
|
9591
9238
|
// ../../packages/tacho/src/host/agents.ts
|
|
9592
9239
|
import { randomBytes } from "node:crypto";
|
|
9593
|
-
import {
|
|
9594
|
-
existsSync as existsSync2,
|
|
9595
|
-
mkdirSync as mkdirSync3,
|
|
9596
|
-
readdirSync as readdirSync2,
|
|
9597
|
-
renameSync as renameSync2,
|
|
9598
|
-
rmdirSync as rmdirSync2,
|
|
9599
|
-
statSync as statSync2
|
|
9600
|
-
} from "node:fs";
|
|
9601
|
-
import { join as join7 } from "node:path";
|
|
9240
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
9602
9241
|
function agentDirs(home) {
|
|
9603
9242
|
let names2;
|
|
9604
9243
|
try {
|
|
9605
|
-
names2 =
|
|
9244
|
+
names2 = readdirSync(home.agents);
|
|
9606
9245
|
} catch {
|
|
9607
9246
|
names2 = [];
|
|
9608
9247
|
}
|
|
9609
|
-
|
|
9610
|
-
const legacy = pathsInDir(home, home.tachoDir);
|
|
9611
|
-
if (existsSync2(legacy.hostFile))
|
|
9612
|
-
dirs.push({ id: LEGACY_AGENT_ID, paths: legacy });
|
|
9613
|
-
return dirs;
|
|
9248
|
+
return names2.sort().map((id2) => ({ id: id2, paths: agentPaths(home, id2) })).filter(({ paths }) => existsSync(paths.hostFile));
|
|
9614
9249
|
}
|
|
9615
9250
|
function listAgents(home) {
|
|
9616
9251
|
return agentDirs(home).map(({ id: id2, paths }) => ({
|
|
9617
9252
|
id: id2,
|
|
9618
9253
|
paths,
|
|
9619
|
-
host: readHostFileLenient(paths.hostFile).host
|
|
9620
|
-
legacy: id2 === LEGACY_AGENT_ID
|
|
9254
|
+
host: readHostFileLenient(paths.hostFile).host
|
|
9621
9255
|
})).sort((a, b5) => {
|
|
9622
9256
|
if (a.host !== void 0 && b5.host !== void 0)
|
|
9623
9257
|
return a.host.enrolled_at.localeCompare(b5.host.enrolled_at) || a.id.localeCompare(b5.id);
|
|
@@ -9686,8 +9320,7 @@ function freshAgentPaths(home, mint = newAgentId) {
|
|
|
9686
9320
|
for (; ; ) {
|
|
9687
9321
|
const id2 = mint();
|
|
9688
9322
|
const paths = agentPaths(home, id2);
|
|
9689
|
-
if (!
|
|
9690
|
-
return paths;
|
|
9323
|
+
if (!existsSync(paths.dir)) return paths;
|
|
9691
9324
|
}
|
|
9692
9325
|
}
|
|
9693
9326
|
function agentPathsForEnrollment(home, enrollmentId, harness) {
|
|
@@ -9720,75 +9353,17 @@ function harnessesIn(hostFile) {
|
|
|
9720
9353
|
const value = hostField(hostFile, "harnesses");
|
|
9721
9354
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
9722
9355
|
}
|
|
9723
|
-
function migratingDir(home, id2) {
|
|
9724
|
-
return join7(home.agents, `${MIGRATING_PREFIX}${id2}`);
|
|
9725
|
-
}
|
|
9726
|
-
function legacyNames() {
|
|
9727
|
-
return [
|
|
9728
|
-
...Object.values(AGENT_FILES).filter(
|
|
9729
|
-
(name) => name !== AGENT_FILES.hostFile
|
|
9730
|
-
),
|
|
9731
|
-
HARNESS_RECEIPTS,
|
|
9732
|
-
HARNESS_BACKUPS
|
|
9733
|
-
];
|
|
9734
|
-
}
|
|
9735
|
-
function moveInto(from, to) {
|
|
9736
|
-
if (!existsSync2(from)) return;
|
|
9737
|
-
if (!existsSync2(to)) {
|
|
9738
|
-
renameSync2(from, to);
|
|
9739
|
-
return;
|
|
9740
|
-
}
|
|
9741
|
-
if (!statSync2(from).isDirectory() || !statSync2(to).isDirectory()) return;
|
|
9742
|
-
for (const name of readdirSync2(from))
|
|
9743
|
-
moveInto(join7(from, name), join7(to, name));
|
|
9744
|
-
try {
|
|
9745
|
-
rmdirSync2(from);
|
|
9746
|
-
} catch {
|
|
9747
|
-
}
|
|
9748
|
-
}
|
|
9749
|
-
function migrateLegacyLayout(home, mint = newAgentId) {
|
|
9750
|
-
const legacy = pathsInDir(home, home.tachoDir);
|
|
9751
|
-
let pending;
|
|
9752
|
-
try {
|
|
9753
|
-
pending = readdirSync2(home.agents).find(
|
|
9754
|
-
(name) => name.startsWith(MIGRATING_PREFIX)
|
|
9755
|
-
);
|
|
9756
|
-
} catch {
|
|
9757
|
-
pending = void 0;
|
|
9758
|
-
}
|
|
9759
|
-
if (pending === void 0 && !existsSync2(legacy.hostFile)) return void 0;
|
|
9760
|
-
let id2;
|
|
9761
|
-
if (pending === void 0) {
|
|
9762
|
-
id2 = freshAgentPaths(home, mint).dir.slice(home.agents.length + 1);
|
|
9763
|
-
mkdirSync3(migratingDir(home, id2), { recursive: true, mode: 448 });
|
|
9764
|
-
} else {
|
|
9765
|
-
id2 = pending.slice(MIGRATING_PREFIX.length);
|
|
9766
|
-
}
|
|
9767
|
-
const staging = migratingDir(home, id2);
|
|
9768
|
-
for (const name of legacyNames())
|
|
9769
|
-
moveInto(join7(home.tachoDir, name), join7(staging, name));
|
|
9770
|
-
moveInto(legacy.hostFile, join7(staging, AGENT_FILES.hostFile));
|
|
9771
|
-
const target2 = agentPaths(home, id2).dir;
|
|
9772
|
-
renameSync2(staging, target2);
|
|
9773
|
-
for (const name of legacyNames())
|
|
9774
|
-
moveInto(join7(home.tachoDir, name), join7(target2, name));
|
|
9775
|
-
return id2;
|
|
9776
|
-
}
|
|
9777
|
-
var LEGACY_AGENT_ID, MIGRATING_PREFIX;
|
|
9778
9356
|
var init_agents = __esm({
|
|
9779
9357
|
"../../packages/tacho/src/host/agents.ts"() {
|
|
9780
9358
|
"use strict";
|
|
9781
9359
|
init_fs();
|
|
9782
|
-
init_harness_file();
|
|
9783
9360
|
init_host_file();
|
|
9784
9361
|
init_paths();
|
|
9785
|
-
LEGACY_AGENT_ID = "legacy";
|
|
9786
|
-
MIGRATING_PREFIX = ".migrating-";
|
|
9787
9362
|
}
|
|
9788
9363
|
});
|
|
9789
9364
|
|
|
9790
9365
|
// ../../packages/tacho/src/ids.ts
|
|
9791
|
-
import { createHash as
|
|
9366
|
+
import { createHash as createHash3, randomBytes as randomBytes2 } from "node:crypto";
|
|
9792
9367
|
function uuidBytes(uuid) {
|
|
9793
9368
|
const hex = uuid.replace(/-/g, "");
|
|
9794
9369
|
if (!/^[0-9a-f]{32}$/i.test(hex)) {
|
|
@@ -9801,7 +9376,7 @@ function formatUuid(bytes) {
|
|
|
9801
9376
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
9802
9377
|
}
|
|
9803
9378
|
function uuidv5(namespace, name) {
|
|
9804
|
-
const hash3 =
|
|
9379
|
+
const hash3 = createHash3("sha1").update(uuidBytes(namespace)).update(Buffer.from(name, "utf8")).digest();
|
|
9805
9380
|
const bytes = Buffer.from(hash3.subarray(0, 16));
|
|
9806
9381
|
bytes[6] = (bytes[6] ?? 0) & 15 | 80;
|
|
9807
9382
|
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
@@ -9814,11 +9389,11 @@ function eventIdIdem(sessionUuidValue, seq) {
|
|
|
9814
9389
|
if (!Number.isInteger(seq) || seq < 0) {
|
|
9815
9390
|
throw new TypeError(`seq must be a non-negative integer, got ${seq}`);
|
|
9816
9391
|
}
|
|
9817
|
-
const hash3 =
|
|
9392
|
+
const hash3 = createHash3("sha256").update(sessionUuidValue).update(" ").update(String(seq)).digest("hex");
|
|
9818
9393
|
return `evt_${hash3}`;
|
|
9819
9394
|
}
|
|
9820
9395
|
function effectId(sessionUuidValue, toolUseId, target2) {
|
|
9821
|
-
return `eff_${
|
|
9396
|
+
return `eff_${createHash3("sha256").update(sessionUuidValue).update(" ").update(toolUseId).update(" ").update(target2).digest("hex")}`;
|
|
9822
9397
|
}
|
|
9823
9398
|
function ulid(now = Date.now()) {
|
|
9824
9399
|
let time = now;
|
|
@@ -9844,7 +9419,7 @@ function backfillEventId(sessionUuidValue, seq, rawSourceDigest, tsMs) {
|
|
|
9844
9419
|
timePart = CROCKFORD[time % 32] + timePart;
|
|
9845
9420
|
time = Math.floor(time / 32);
|
|
9846
9421
|
}
|
|
9847
|
-
const hash3 =
|
|
9422
|
+
const hash3 = createHash3("sha256").update(sessionUuidValue).update(" ").update(String(seq)).update(" ").update(rawSourceDigest).digest();
|
|
9848
9423
|
let bits2 = 0n;
|
|
9849
9424
|
for (let index = 0; index < 10; index += 1)
|
|
9850
9425
|
bits2 = bits2 << 8n | BigInt(hash3[index] ?? 0);
|
|
@@ -10075,7 +9650,7 @@ var init_codex_prompt_source = __esm({
|
|
|
10075
9650
|
});
|
|
10076
9651
|
|
|
10077
9652
|
// ../../packages/tacho/src/host/stella-writer.ts
|
|
10078
|
-
import { existsSync as
|
|
9653
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
10079
9654
|
function stellaHookTimeoutMs(event) {
|
|
10080
9655
|
switch (event) {
|
|
10081
9656
|
case "SessionStart":
|
|
@@ -10101,7 +9676,7 @@ function stellaHookEntries(config) {
|
|
|
10101
9676
|
}
|
|
10102
9677
|
return out;
|
|
10103
9678
|
}
|
|
10104
|
-
function readStellaHooksFile(paths, format, exists =
|
|
9679
|
+
function readStellaHooksFile(paths, format, exists = existsSync2, read2 = (path2) => readFileSync2(path2, "utf8")) {
|
|
10105
9680
|
const chosen = format ?? (exists(paths.stellaToml) ? "toml" : exists(paths.stellaSettingsJson) ? "json" : "toml");
|
|
10106
9681
|
const path2 = chosen === "toml" ? paths.stellaToml : paths.stellaSettingsJson;
|
|
10107
9682
|
return { path: path2, format: chosen, text: exists(path2) ? read2(path2) : void 0 };
|
|
@@ -10324,7 +9899,7 @@ var init_stella_writer = __esm({
|
|
|
10324
9899
|
|
|
10325
9900
|
// ../../packages/tacho/src/host/process-scan.ts
|
|
10326
9901
|
import { execFile, spawnSync } from "node:child_process";
|
|
10327
|
-
import { readFileSync as
|
|
9902
|
+
import { readFileSync as readFileSync3, readlinkSync } from "node:fs";
|
|
10328
9903
|
import { win32 as win322 } from "node:path";
|
|
10329
9904
|
function parsePsListing(listing) {
|
|
10330
9905
|
const out = [];
|
|
@@ -10380,7 +9955,7 @@ function psExecAsync(command2, args) {
|
|
|
10380
9955
|
}
|
|
10381
9956
|
function readText(path2) {
|
|
10382
9957
|
try {
|
|
10383
|
-
return
|
|
9958
|
+
return readFileSync3(path2, "utf8");
|
|
10384
9959
|
} catch {
|
|
10385
9960
|
return void 0;
|
|
10386
9961
|
}
|
|
@@ -10502,7 +10077,7 @@ function createdAfterRecord(record, createdMs) {
|
|
|
10502
10077
|
}
|
|
10503
10078
|
function processExecutable(pid) {
|
|
10504
10079
|
try {
|
|
10505
|
-
return
|
|
10080
|
+
return readlinkSync(`/proc/${pid}/exe`).replace(/ \(deleted\)$/, "");
|
|
10506
10081
|
} catch {
|
|
10507
10082
|
return void 0;
|
|
10508
10083
|
}
|
|
@@ -10523,8 +10098,8 @@ var init_process_scan = __esm({
|
|
|
10523
10098
|
|
|
10524
10099
|
// ../../packages/tacho/src/claude-code/stella-adapter.ts
|
|
10525
10100
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
10526
|
-
import { readdirSync as
|
|
10527
|
-
import { join as
|
|
10101
|
+
import { readdirSync as readdirSync2, rmSync } from "node:fs";
|
|
10102
|
+
import { join as join6 } from "node:path";
|
|
10528
10103
|
function parsePsLine(stdout) {
|
|
10529
10104
|
const match = /^\s*(\d+)\s+(.+?)\s*$/m.exec(stdout);
|
|
10530
10105
|
if (match === null) return void 0;
|
|
@@ -10561,7 +10136,7 @@ function procLookupFor(platform) {
|
|
|
10561
10136
|
return (pid) => readProcParent(pid);
|
|
10562
10137
|
}
|
|
10563
10138
|
function cachePath(cacheDir, pid) {
|
|
10564
|
-
return
|
|
10139
|
+
return join6(cacheDir, `${pid}.json`);
|
|
10565
10140
|
}
|
|
10566
10141
|
function readCachedIdentity(cacheDir, pid) {
|
|
10567
10142
|
try {
|
|
@@ -10590,12 +10165,12 @@ function dropCachedIdentity(cacheDir, pid) {
|
|
|
10590
10165
|
}
|
|
10591
10166
|
function pruneCachedIdentities(cacheDir, keep, isAlive) {
|
|
10592
10167
|
try {
|
|
10593
|
-
for (const name of
|
|
10168
|
+
for (const name of readdirSync2(cacheDir)) {
|
|
10594
10169
|
const match = /^(\d+)\.json$/.exec(name);
|
|
10595
10170
|
if (match === null) continue;
|
|
10596
10171
|
const pid = Number(match[1]);
|
|
10597
10172
|
if (pid !== keep && !isAlive(pid))
|
|
10598
|
-
rmSync(
|
|
10173
|
+
rmSync(join6(cacheDir, name), { force: true });
|
|
10599
10174
|
}
|
|
10600
10175
|
} catch {
|
|
10601
10176
|
}
|
|
@@ -12356,10 +11931,10 @@ var init_hooks = __esm({
|
|
|
12356
11931
|
});
|
|
12357
11932
|
|
|
12358
11933
|
// ../../packages/tacho/src/claude-code/hook-client.ts
|
|
12359
|
-
import { readdirSync as
|
|
11934
|
+
import { readdirSync as readdirSync3 } from "node:fs";
|
|
12360
11935
|
import { request } from "node:http";
|
|
12361
11936
|
import { homedir as homedir2 } from "node:os";
|
|
12362
|
-
import { join as
|
|
11937
|
+
import { join as join7 } from "node:path";
|
|
12363
11938
|
function cursorRefusal(raw, message) {
|
|
12364
11939
|
const named = typeof raw === "object" && raw !== null ? raw["hook_event_name"] : void 0;
|
|
12365
11940
|
const claudeEvent = typeof named === "string" && named in CURSOR_TO_CLAUDE_EVENT ? CURSOR_TO_CLAUDE_EVENT[named] : void 0;
|
|
@@ -12712,14 +12287,14 @@ function quarantineHookPayload(quarantineDir, record) {
|
|
|
12712
12287
|
const { hookId, receivedAt, reason: reason3, rawText, label: label2 } = record;
|
|
12713
12288
|
try {
|
|
12714
12289
|
ensureDir(quarantineDir);
|
|
12715
|
-
const held =
|
|
12290
|
+
const held = readdirSync3(quarantineDir).filter(
|
|
12716
12291
|
(name) => name.endsWith(HOOK_PAYLOAD_SUFFIX)
|
|
12717
12292
|
).length;
|
|
12718
12293
|
if (held >= MAX_QUARANTINED_HOOK_PAYLOADS) return;
|
|
12719
12294
|
const fileId = typeof hookId === "string" && ULID_PATTERN.test(hookId) ? hookId : ulid();
|
|
12720
12295
|
const truncated = rawText.length > MAX_QUARANTINED_PAYLOAD_BYTES;
|
|
12721
12296
|
writeSensitiveFileAtomic(
|
|
12722
|
-
|
|
12297
|
+
join7(quarantineDir, `${fileId}${HOOK_PAYLOAD_SUFFIX}`),
|
|
12723
12298
|
JSON.stringify({
|
|
12724
12299
|
schema: "tacho.quarantined-hook-payload.v1",
|
|
12725
12300
|
received_at: receivedAt,
|
|
@@ -12987,7 +12562,7 @@ async function runTachoHook(deps) {
|
|
|
12987
12562
|
try {
|
|
12988
12563
|
ensureDir(deps.paths.spool);
|
|
12989
12564
|
writeSensitiveFileAtomic(
|
|
12990
|
-
|
|
12565
|
+
join7(deps.paths.spool, `${hookId}.json`),
|
|
12991
12566
|
JSON.stringify({
|
|
12992
12567
|
schema: "tacho.spool.v1",
|
|
12993
12568
|
received_at: receivedAt,
|
|
@@ -19248,16 +18823,16 @@ var init_registry = __esm({
|
|
|
19248
18823
|
|
|
19249
18824
|
// ../../packages/tacho/src/collector/transcript-tailer.ts
|
|
19250
18825
|
import { promises as fs } from "node:fs";
|
|
19251
|
-
import { basename as
|
|
18826
|
+
import { basename as basename2, join as join8 } from "node:path";
|
|
19252
18827
|
function hasTranscriptNormalizer(session) {
|
|
19253
18828
|
return session.harness === void 0 || TRANSCRIPT_NORMALIZED_HARNESSES.has(session.harness);
|
|
19254
18829
|
}
|
|
19255
18830
|
function subagentDirOf(transcriptPath) {
|
|
19256
18831
|
if (!transcriptPath.endsWith(".jsonl")) return void 0;
|
|
19257
|
-
return
|
|
18832
|
+
return join8(transcriptPath.slice(0, -".jsonl".length), "subagents");
|
|
19258
18833
|
}
|
|
19259
18834
|
function subagentIdOf(path2) {
|
|
19260
|
-
return /^agent-(.+)\.jsonl$/.exec(
|
|
18835
|
+
return /^agent-(.+)\.jsonl$/.exec(basename2(path2))?.[1];
|
|
19261
18836
|
}
|
|
19262
18837
|
function isPersistedTailState(value) {
|
|
19263
18838
|
return value !== null && typeof value === "object" && value.schema === "tacho.transcript-tail.v1" && typeof value.cursors === "object";
|
|
@@ -19767,7 +19342,7 @@ var init_transcript_tailer = __esm({
|
|
|
19767
19342
|
if (session.harness === "codex") return void 0;
|
|
19768
19343
|
const dir = session.transcriptPath === void 0 ? void 0 : subagentDirOf(session.transcriptPath);
|
|
19769
19344
|
if (dir === void 0) return void 0;
|
|
19770
|
-
const own =
|
|
19345
|
+
const own = join8(dir, `agent-${subagentId}.jsonl`);
|
|
19771
19346
|
if (own === path2) return void 0;
|
|
19772
19347
|
return await statIfExists(own) === void 0 ? void 0 : own;
|
|
19773
19348
|
}
|
|
@@ -19844,11 +19419,11 @@ var init_transcript_tailer = __esm({
|
|
|
19844
19419
|
* those were 3,634 of 5,059 subagent transcripts.
|
|
19845
19420
|
*/
|
|
19846
19421
|
async subagentTranscripts(dir) {
|
|
19847
|
-
const paths = (await this.listDir(dir)).map((name) =>
|
|
19848
|
-
const workflows =
|
|
19422
|
+
const paths = (await this.listDir(dir)).map((name) => join8(dir, name));
|
|
19423
|
+
const workflows = join8(dir, "workflows");
|
|
19849
19424
|
for (const workflow of await this.listDir(workflows)) {
|
|
19850
|
-
const at =
|
|
19851
|
-
for (const name of await this.listDir(at)) paths.push(
|
|
19425
|
+
const at = join8(workflows, workflow);
|
|
19426
|
+
for (const name of await this.listDir(at)) paths.push(join8(at, name));
|
|
19852
19427
|
}
|
|
19853
19428
|
return paths.filter((path2) => subagentIdOf(path2) !== void 0).sort();
|
|
19854
19429
|
}
|
|
@@ -20124,7 +19699,7 @@ var init_transcript_tailer = __esm({
|
|
|
20124
19699
|
|
|
20125
19700
|
// ../../packages/tacho/src/collector/backfill.ts
|
|
20126
19701
|
import { promises as fs2 } from "node:fs";
|
|
20127
|
-
import { join as
|
|
19702
|
+
import { join as join9 } from "node:path";
|
|
20128
19703
|
function parseBackfillRequest(value) {
|
|
20129
19704
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
20130
19705
|
return { error: "the request must be a JSON object" };
|
|
@@ -20281,7 +19856,7 @@ async function discover(request3, deps, tally2) {
|
|
|
20281
19856
|
const untilMs = request3.until === void 0 ? void 0 : Date.parse(`${request3.until}T00:00:00.000Z`);
|
|
20282
19857
|
for (const root of deps.roots) {
|
|
20283
19858
|
for (const slug of (await listDir(root)).sort()) {
|
|
20284
|
-
const dir =
|
|
19859
|
+
const dir = join9(root, slug);
|
|
20285
19860
|
if (!await isDirectory(dir)) continue;
|
|
20286
19861
|
const included = (only === void 0 || only.has(slug)) && !skip2.has(slug);
|
|
20287
19862
|
const names2 = (await listDir(dir)).filter((name) => name.endsWith(".jsonl") && !name.startsWith("agent-")).sort();
|
|
@@ -20298,13 +19873,13 @@ async function discover(request3, deps, tally2) {
|
|
|
20298
19873
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
20299
19874
|
if (sessionsWanted !== void 0 && !sessionsWanted.has(sessionId))
|
|
20300
19875
|
continue;
|
|
20301
|
-
const path2 =
|
|
19876
|
+
const path2 = join9(dir, name);
|
|
20302
19877
|
project2.sessions += 1;
|
|
20303
19878
|
if (!included) {
|
|
20304
|
-
project2.subagents += await countSubagents(
|
|
19879
|
+
project2.subagents += await countSubagents(join9(dir, sessionId));
|
|
20305
19880
|
continue;
|
|
20306
19881
|
}
|
|
20307
|
-
const subagents = await subagentFiles(
|
|
19882
|
+
const subagents = await subagentFiles(join9(dir, sessionId), tally2);
|
|
20308
19883
|
project2.subagents += subagents.length;
|
|
20309
19884
|
let stat6;
|
|
20310
19885
|
try {
|
|
@@ -20355,7 +19930,7 @@ async function isDirectory(path2) {
|
|
|
20355
19930
|
}
|
|
20356
19931
|
}
|
|
20357
19932
|
async function subagentFiles(sessionDir, tally2) {
|
|
20358
|
-
const dir =
|
|
19933
|
+
const dir = join9(sessionDir, "subagents");
|
|
20359
19934
|
const out = [];
|
|
20360
19935
|
const add2 = async (folder, name) => {
|
|
20361
19936
|
const match = /^agent-(.+)\.jsonl$/.exec(name);
|
|
@@ -20363,14 +19938,14 @@ async function subagentFiles(sessionDir, tally2) {
|
|
|
20363
19938
|
const agentId = match[1];
|
|
20364
19939
|
out.push({
|
|
20365
19940
|
agentId,
|
|
20366
|
-
path:
|
|
20367
|
-
meta: await readMeta(
|
|
19941
|
+
path: join9(folder, name),
|
|
19942
|
+
meta: await readMeta(join9(folder, `agent-${agentId}.meta.json`))
|
|
20368
19943
|
});
|
|
20369
19944
|
};
|
|
20370
19945
|
for (const name of (await listDir(dir)).sort()) await add2(dir, name);
|
|
20371
|
-
const workflows =
|
|
19946
|
+
const workflows = join9(dir, "workflows");
|
|
20372
19947
|
for (const workflow of (await listDir(workflows)).sort()) {
|
|
20373
|
-
const folder =
|
|
19948
|
+
const folder = join9(workflows, workflow);
|
|
20374
19949
|
for (const name of (await listDir(folder)).sort()) {
|
|
20375
19950
|
if (name === "journal.jsonl") {
|
|
20376
19951
|
tally2.recordsIgnored["workflow-journal"] = (tally2.recordsIgnored["workflow-journal"] ?? 0) + 1;
|
|
@@ -20382,11 +19957,11 @@ async function subagentFiles(sessionDir, tally2) {
|
|
|
20382
19957
|
return out;
|
|
20383
19958
|
}
|
|
20384
19959
|
async function countSubagents(sessionDir) {
|
|
20385
|
-
const dir =
|
|
19960
|
+
const dir = join9(sessionDir, "subagents");
|
|
20386
19961
|
const isAgent = (name) => /^agent-.+\.jsonl$/.test(name);
|
|
20387
19962
|
let count12 = (await listDir(dir)).filter(isAgent).length;
|
|
20388
|
-
for (const workflow of await listDir(
|
|
20389
|
-
count12 += (await listDir(
|
|
19963
|
+
for (const workflow of await listDir(join9(dir, "workflows")))
|
|
19964
|
+
count12 += (await listDir(join9(dir, "workflows", workflow))).filter(
|
|
20390
19965
|
isAgent
|
|
20391
19966
|
).length;
|
|
20392
19967
|
return count12;
|
|
@@ -21100,7 +20675,7 @@ var init_backfill3 = __esm({
|
|
|
21100
20675
|
});
|
|
21101
20676
|
|
|
21102
20677
|
// ../../packages/tacho/src/host/claude-code-mcp-writer.ts
|
|
21103
|
-
import { dirname as
|
|
20678
|
+
import { dirname as dirname3, join as join10, resolve } from "node:path";
|
|
21104
20679
|
function mergeClaudeCodeMcpConfig(existing, config) {
|
|
21105
20680
|
return mergeOxagenMcpServer(existing, config, "stdio");
|
|
21106
20681
|
}
|
|
@@ -21124,11 +20699,11 @@ function claudeCodeSessionHasOxagenTools(check2) {
|
|
|
21124
20699
|
}
|
|
21125
20700
|
function shadowedInProject(userConfig, cwd, enrollmentId, readProjectConfig) {
|
|
21126
20701
|
const projects = member2(userConfig, "projects");
|
|
21127
|
-
for (let dir =
|
|
20702
|
+
for (let dir = resolve(cwd); ; dir = dirname3(dir)) {
|
|
21128
20703
|
if (shadows(member2(projects, dir), enrollmentId)) return true;
|
|
21129
|
-
if (shadows(readProjectConfig(
|
|
20704
|
+
if (shadows(readProjectConfig(join10(dir, ".mcp.json")), enrollmentId))
|
|
21130
20705
|
return true;
|
|
21131
|
-
if (
|
|
20706
|
+
if (dirname3(dir) === dir) return false;
|
|
21132
20707
|
}
|
|
21133
20708
|
}
|
|
21134
20709
|
function shadows(config, enrollmentId) {
|
|
@@ -21156,22 +20731,367 @@ var init_claude_code_mcp_writer = __esm({
|
|
|
21156
20731
|
}
|
|
21157
20732
|
});
|
|
21158
20733
|
|
|
20734
|
+
// ../../packages/tacho/src/host/harness-file.ts
|
|
20735
|
+
import {
|
|
20736
|
+
chmodSync as chmodSync2,
|
|
20737
|
+
existsSync as existsSync3,
|
|
20738
|
+
lstatSync,
|
|
20739
|
+
mkdirSync as mkdirSync2,
|
|
20740
|
+
readdirSync as readdirSync4,
|
|
20741
|
+
readFileSync as readFileSync4,
|
|
20742
|
+
readlinkSync as readlinkSync2,
|
|
20743
|
+
rmdirSync,
|
|
20744
|
+
statSync,
|
|
20745
|
+
unlinkSync as unlinkSync2
|
|
20746
|
+
} from "node:fs";
|
|
20747
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
20748
|
+
import { dirname as dirname4, join as join11, resolve as resolve2 } from "node:path";
|
|
20749
|
+
import { isDeepStrictEqual } from "node:util";
|
|
20750
|
+
function enrollmentIdsIn(text5) {
|
|
20751
|
+
const ids = /* @__PURE__ */ new Set();
|
|
20752
|
+
for (const match of text5.matchAll(ENROLLMENT_MARKER)) {
|
|
20753
|
+
const id2 = match[1] ?? match[2];
|
|
20754
|
+
if (id2 !== void 0) ids.add(id2);
|
|
20755
|
+
}
|
|
20756
|
+
return ids;
|
|
20757
|
+
}
|
|
20758
|
+
function withoutBom(text5) {
|
|
20759
|
+
return text5.startsWith(BOM) ? text5.slice(BOM.length) : text5;
|
|
20760
|
+
}
|
|
20761
|
+
function realTarget(path2) {
|
|
20762
|
+
let current = path2;
|
|
20763
|
+
for (let hops = 0; hops < 16; hops += 1) {
|
|
20764
|
+
let stat6;
|
|
20765
|
+
try {
|
|
20766
|
+
stat6 = lstatSync(current);
|
|
20767
|
+
} catch {
|
|
20768
|
+
return current;
|
|
20769
|
+
}
|
|
20770
|
+
if (!stat6.isSymbolicLink()) return current;
|
|
20771
|
+
current = resolve2(dirname4(current), readlinkSync2(current));
|
|
20772
|
+
}
|
|
20773
|
+
throw new HarnessFileError(path2, "too many levels of symbolic links");
|
|
20774
|
+
}
|
|
20775
|
+
function writeAtomic(path2, data, mode) {
|
|
20776
|
+
writeFileAtomic(path2, data, { mode });
|
|
20777
|
+
}
|
|
20778
|
+
function digestOf(text5) {
|
|
20779
|
+
return createHash4("sha256").update(text5).digest("hex");
|
|
20780
|
+
}
|
|
20781
|
+
function isBlank(text5) {
|
|
20782
|
+
if (text5.trim() === "") return true;
|
|
20783
|
+
try {
|
|
20784
|
+
return isDeepStrictEqual(JSON.parse(withoutBom(text5)), {});
|
|
20785
|
+
} catch {
|
|
20786
|
+
return false;
|
|
20787
|
+
}
|
|
20788
|
+
}
|
|
20789
|
+
function sameDocument(a, b5) {
|
|
20790
|
+
if (a === b5) return true;
|
|
20791
|
+
try {
|
|
20792
|
+
return isDeepStrictEqual(
|
|
20793
|
+
sortKeys(withoutStrippedEmpties(JSON.parse(withoutBom(a)))),
|
|
20794
|
+
sortKeys(withoutStrippedEmpties(JSON.parse(withoutBom(b5))))
|
|
20795
|
+
);
|
|
20796
|
+
} catch {
|
|
20797
|
+
return false;
|
|
20798
|
+
}
|
|
20799
|
+
}
|
|
20800
|
+
function isEmptyContainer(value) {
|
|
20801
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
20802
|
+
return typeof value === "object" && value !== null && Object.keys(value).length === 0;
|
|
20803
|
+
}
|
|
20804
|
+
function withoutStrippedEmpties(value) {
|
|
20805
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
20806
|
+
return value;
|
|
20807
|
+
const document = { ...value };
|
|
20808
|
+
const hooks = document["hooks"];
|
|
20809
|
+
if (typeof hooks === "object" && hooks !== null && !Array.isArray(hooks))
|
|
20810
|
+
document["hooks"] = Object.fromEntries(
|
|
20811
|
+
Object.entries(hooks).filter(([, list]) => !isEmptyContainer(list))
|
|
20812
|
+
);
|
|
20813
|
+
for (const key of ["env", "hooks", "mcpServers"])
|
|
20814
|
+
if (isEmptyContainer(document[key])) delete document[key];
|
|
20815
|
+
return document;
|
|
20816
|
+
}
|
|
20817
|
+
function sortKeys(value) {
|
|
20818
|
+
if (Array.isArray(value)) return value.map(sortKeys);
|
|
20819
|
+
if (typeof value !== "object" || value === null) return value;
|
|
20820
|
+
return Object.fromEntries(
|
|
20821
|
+
Object.entries(value).sort(([a], [b5]) => a < b5 ? -1 : a > b5 ? 1 : 0).map(([key, child]) => [key, sortKeys(child)])
|
|
20822
|
+
);
|
|
20823
|
+
}
|
|
20824
|
+
var HarnessFileError, ENROLLMENT_MARKER, BOM, HARNESS_RECEIPTS, HARNESS_BACKUPS, HarnessFiles;
|
|
20825
|
+
var init_harness_file = __esm({
|
|
20826
|
+
"../../packages/tacho/src/host/harness-file.ts"() {
|
|
20827
|
+
"use strict";
|
|
20828
|
+
init_fs();
|
|
20829
|
+
HarnessFileError = class extends Error {
|
|
20830
|
+
constructor(path2, reason3) {
|
|
20831
|
+
super(`${path2}: ${reason3}`);
|
|
20832
|
+
this.path = path2;
|
|
20833
|
+
this.reason = reason3;
|
|
20834
|
+
this.name = "HarnessFileError";
|
|
20835
|
+
}
|
|
20836
|
+
path;
|
|
20837
|
+
reason;
|
|
20838
|
+
};
|
|
20839
|
+
ENROLLMENT_MARKER = /--enrollment(?:\s+|"\s*,\s*")(tch_[a-z0-9]{22})|\/hook\/(tch_[a-z0-9]{22})/g;
|
|
20840
|
+
BOM = "\uFEFF";
|
|
20841
|
+
HARNESS_RECEIPTS = "install-receipts.json";
|
|
20842
|
+
HARNESS_BACKUPS = "backups";
|
|
20843
|
+
HarnessFiles = class {
|
|
20844
|
+
/**
|
|
20845
|
+
* `root` is the agent's directory (`TachoPaths.dir`). Each agent keeps the
|
|
20846
|
+
* receipts for the files its own enroll touched, so its unenroll settles
|
|
20847
|
+
* those and no other agent's.
|
|
20848
|
+
*/
|
|
20849
|
+
constructor(root) {
|
|
20850
|
+
this.root = root;
|
|
20851
|
+
this.receiptsPath = join11(root, HARNESS_RECEIPTS);
|
|
20852
|
+
this.backupsDir = join11(root, HARNESS_BACKUPS);
|
|
20853
|
+
}
|
|
20854
|
+
root;
|
|
20855
|
+
receiptsPath;
|
|
20856
|
+
backupsDir;
|
|
20857
|
+
/** The file's text, or undefined when it does not exist. */
|
|
20858
|
+
readText(path2) {
|
|
20859
|
+
try {
|
|
20860
|
+
return readFileSync4(path2, "utf8");
|
|
20861
|
+
} catch (error) {
|
|
20862
|
+
if (error.code === "ENOENT") return void 0;
|
|
20863
|
+
throw new HarnessFileError(
|
|
20864
|
+
path2,
|
|
20865
|
+
`cannot be read (${error.code ?? "error"})`
|
|
20866
|
+
);
|
|
20867
|
+
}
|
|
20868
|
+
}
|
|
20869
|
+
/** The file parsed as JSON; undefined when absent; a named error when malformed. */
|
|
20870
|
+
readJson(path2) {
|
|
20871
|
+
const text5 = this.readText(path2);
|
|
20872
|
+
if (text5 === void 0) return void 0;
|
|
20873
|
+
if (text5.trim() === "") return void 0;
|
|
20874
|
+
try {
|
|
20875
|
+
return JSON.parse(withoutBom(text5));
|
|
20876
|
+
} catch (error) {
|
|
20877
|
+
throw new HarnessFileError(
|
|
20878
|
+
path2,
|
|
20879
|
+
`is not valid JSON (${error instanceof Error ? error.message : String(error)}); fix or remove it and run this again`
|
|
20880
|
+
);
|
|
20881
|
+
}
|
|
20882
|
+
}
|
|
20883
|
+
/**
|
|
20884
|
+
* Whether `write` would be refused, without writing: the file, or the
|
|
20885
|
+
* nearest existing directory above it, is not writable by this user.
|
|
20886
|
+
*/
|
|
20887
|
+
writeProblem(path2) {
|
|
20888
|
+
const target2 = realTarget(path2);
|
|
20889
|
+
if (existsSync3(target2)) {
|
|
20890
|
+
if ((statSync(target2).mode & 128) === 0)
|
|
20891
|
+
return "is read-only; Oxagen does not replace a file you have locked (chmod u+w it to allow the hooks)";
|
|
20892
|
+
return void 0;
|
|
20893
|
+
}
|
|
20894
|
+
let dir = dirname4(target2);
|
|
20895
|
+
while (!existsSync3(dir) && dirname4(dir) !== dir) dir = dirname4(dir);
|
|
20896
|
+
if ((statSync(dir).mode & 128) === 0)
|
|
20897
|
+
return `cannot be created: ${dir} is read-only`;
|
|
20898
|
+
return void 0;
|
|
20899
|
+
}
|
|
20900
|
+
/**
|
|
20901
|
+
* Write `text`, taking a receipt the first time this path is touched.
|
|
20902
|
+
*
|
|
20903
|
+
* `vestigial` is the writer saying that what it is about to write holds
|
|
20904
|
+
* nothing but the scaffolding it had to add itself (Cursor's `version`
|
|
20905
|
+
* is the one instance), so `settle` may take the whole file back. It
|
|
20906
|
+
* defaults to false, and every ordinary write leaves it false, because a
|
|
20907
|
+
* teardown writes through here too: the stripped document is the bytes
|
|
20908
|
+
* Tacho last wrote, and a hook the user added while enrolled survives
|
|
20909
|
+
* inside it. Deleting on the digest alone would take that hook with the
|
|
20910
|
+
* file.
|
|
20911
|
+
*/
|
|
20912
|
+
write(path2, text5, vestigial = false) {
|
|
20913
|
+
const problem = this.writeProblem(path2);
|
|
20914
|
+
if (problem !== void 0) throw new HarnessFileError(path2, problem);
|
|
20915
|
+
const target2 = realTarget(path2);
|
|
20916
|
+
const receipts = this.load();
|
|
20917
|
+
if (receipts.files[path2] === void 0) {
|
|
20918
|
+
receipts.files[path2] = this.takeReceipt(path2, target2);
|
|
20919
|
+
this.save(receipts);
|
|
20920
|
+
}
|
|
20921
|
+
for (const dir of receipts.files[path2]?.created_dirs ?? []) {
|
|
20922
|
+
if (!existsSync3(dir)) mkdirSync2(dir, { mode: 448 });
|
|
20923
|
+
}
|
|
20924
|
+
mkdirSync2(dirname4(target2), { recursive: true, mode: 448 });
|
|
20925
|
+
const before = this.readText(target2);
|
|
20926
|
+
const bom = !text5.startsWith(BOM) && before?.startsWith(BOM) === true ? BOM : "";
|
|
20927
|
+
writeAtomic(target2, `${bom}${text5}`, 384);
|
|
20928
|
+
const receipt = receipts.files[path2];
|
|
20929
|
+
if (receipt !== void 0) {
|
|
20930
|
+
receipt.last_written = digestOf(`${bom}${text5}`);
|
|
20931
|
+
receipt.vestigial = vestigial;
|
|
20932
|
+
receipt.enrollments = [
|
|
20933
|
+
.../* @__PURE__ */ new Set([
|
|
20934
|
+
...receipt.enrollments ?? enrollmentIdsIn(before ?? ""),
|
|
20935
|
+
...enrollmentIdsIn(text5)
|
|
20936
|
+
])
|
|
20937
|
+
].sort();
|
|
20938
|
+
this.save(receipts);
|
|
20939
|
+
}
|
|
20940
|
+
}
|
|
20941
|
+
/**
|
|
20942
|
+
* Give every file back (see the module comment). Safe to call with no
|
|
20943
|
+
* receipts, twice, or after a run that died half way.
|
|
20944
|
+
*/
|
|
20945
|
+
settle() {
|
|
20946
|
+
const receipts = this.load();
|
|
20947
|
+
const outcomes = [];
|
|
20948
|
+
for (const [path2, receipt] of Object.entries(receipts.files)) {
|
|
20949
|
+
const outcome = this.settleOne(path2, receipt);
|
|
20950
|
+
outcomes.push(outcome);
|
|
20951
|
+
if (outcome.result === "failed") continue;
|
|
20952
|
+
delete receipts.files[path2];
|
|
20953
|
+
this.save(receipts);
|
|
20954
|
+
}
|
|
20955
|
+
this.save(receipts);
|
|
20956
|
+
return outcomes;
|
|
20957
|
+
}
|
|
20958
|
+
settleOne(path2, receipt) {
|
|
20959
|
+
const target2 = realTarget(path2);
|
|
20960
|
+
const backupPath = this.backupOf(receipt);
|
|
20961
|
+
const backup = backupPath !== void 0 ? readFileSync4(backupPath) : void 0;
|
|
20962
|
+
let result2;
|
|
20963
|
+
let current;
|
|
20964
|
+
try {
|
|
20965
|
+
current = readFileSync4(target2, "utf8");
|
|
20966
|
+
} catch (error) {
|
|
20967
|
+
if (error.code !== "ENOENT") throw error;
|
|
20968
|
+
current = void 0;
|
|
20969
|
+
}
|
|
20970
|
+
const original = enrollmentIdsIn(backup?.toString("utf8") ?? "");
|
|
20971
|
+
const added = [...enrollmentIdsIn(current ?? "")].filter(
|
|
20972
|
+
(id2) => !original.has(id2)
|
|
20973
|
+
);
|
|
20974
|
+
const ours = added.filter(
|
|
20975
|
+
(id2) => receipt.enrollments?.includes(id2) ?? true
|
|
20976
|
+
);
|
|
20977
|
+
if (ours.length > 0) {
|
|
20978
|
+
return {
|
|
20979
|
+
path: path2,
|
|
20980
|
+
result: "failed",
|
|
20981
|
+
reason: `still carries Tacho's hooks, so it was not given back; run \`oxagen agent unenroll\` again from the environment that enrolled, or remove the entries that name ${ours.map((id2) => `\`${id2}\``).join(" or ")}`
|
|
20982
|
+
};
|
|
20983
|
+
}
|
|
20984
|
+
if (added.length > 0) {
|
|
20985
|
+
if (backupPath !== void 0 && existsSync3(backupPath))
|
|
20986
|
+
unlinkSync2(backupPath);
|
|
20987
|
+
return { path: path2, result: "left-to-another-enrollment" };
|
|
20988
|
+
}
|
|
20989
|
+
if (current === void 0) {
|
|
20990
|
+
result2 = "missing";
|
|
20991
|
+
} else if (!receipt.existed) {
|
|
20992
|
+
const oursAlone = receipt.vestigial === true && digestOf(current) === receipt.last_written;
|
|
20993
|
+
if (isBlank(current) || oursAlone) {
|
|
20994
|
+
unlinkSync2(target2);
|
|
20995
|
+
result2 = "deleted";
|
|
20996
|
+
} else {
|
|
20997
|
+
result2 = "kept-user-edit";
|
|
20998
|
+
}
|
|
20999
|
+
} else if (backup !== void 0 && sameDocument(current, backup.toString("utf8"))) {
|
|
21000
|
+
writeAtomic(target2, backup, receipt.mode ?? 420);
|
|
21001
|
+
result2 = "restored";
|
|
21002
|
+
} else {
|
|
21003
|
+
if (receipt.mode !== void 0) chmodSync2(target2, receipt.mode);
|
|
21004
|
+
result2 = "kept-user-edit";
|
|
21005
|
+
}
|
|
21006
|
+
if (backupPath !== void 0 && existsSync3(backupPath))
|
|
21007
|
+
unlinkSync2(backupPath);
|
|
21008
|
+
for (const dir of [...receipt.created_dirs].reverse()) {
|
|
21009
|
+
try {
|
|
21010
|
+
if (readdirSync4(dir).length === 0) rmdirSync(dir);
|
|
21011
|
+
} catch {
|
|
21012
|
+
}
|
|
21013
|
+
}
|
|
21014
|
+
return { path: path2, result: result2 };
|
|
21015
|
+
}
|
|
21016
|
+
/** The receipt's byte copy, or undefined when it is gone. */
|
|
21017
|
+
backupOf(receipt) {
|
|
21018
|
+
if (receipt.backup === void 0) return void 0;
|
|
21019
|
+
return existsSync3(receipt.backup) ? receipt.backup : void 0;
|
|
21020
|
+
}
|
|
21021
|
+
takeReceipt(path2, target2) {
|
|
21022
|
+
const created = [];
|
|
21023
|
+
let dir = dirname4(target2);
|
|
21024
|
+
while (!existsSync3(dir) && dirname4(dir) !== dir) {
|
|
21025
|
+
created.unshift(dir);
|
|
21026
|
+
dir = dirname4(dir);
|
|
21027
|
+
}
|
|
21028
|
+
if (!existsSync3(target2))
|
|
21029
|
+
return { existed: false, created_dirs: created, enrollments: [] };
|
|
21030
|
+
mkdirSync2(this.backupsDir, { recursive: true, mode: 448 });
|
|
21031
|
+
const backup = join11(
|
|
21032
|
+
this.backupsDir,
|
|
21033
|
+
`${createHash4("sha256").update(path2).digest("hex").slice(0, 24)}.orig`
|
|
21034
|
+
);
|
|
21035
|
+
writeAtomic(backup, readFileSync4(target2), 384);
|
|
21036
|
+
return {
|
|
21037
|
+
existed: true,
|
|
21038
|
+
mode: statSync(target2).mode & 511,
|
|
21039
|
+
backup,
|
|
21040
|
+
created_dirs: created,
|
|
21041
|
+
enrollments: []
|
|
21042
|
+
};
|
|
21043
|
+
}
|
|
21044
|
+
load() {
|
|
21045
|
+
try {
|
|
21046
|
+
const parsed2 = JSON.parse(
|
|
21047
|
+
readFileSync4(this.receiptsPath, "utf8")
|
|
21048
|
+
);
|
|
21049
|
+
if (typeof parsed2.files === "object" && parsed2.files !== null)
|
|
21050
|
+
return { schema: "tacho.install-receipts.v1", files: parsed2.files };
|
|
21051
|
+
} catch {
|
|
21052
|
+
}
|
|
21053
|
+
return { schema: "tacho.install-receipts.v1", files: {} };
|
|
21054
|
+
}
|
|
21055
|
+
save(receipts) {
|
|
21056
|
+
if (Object.keys(receipts.files).length === 0) {
|
|
21057
|
+
for (const path2 of [this.receiptsPath]) {
|
|
21058
|
+
if (existsSync3(path2)) unlinkSync2(path2);
|
|
21059
|
+
}
|
|
21060
|
+
try {
|
|
21061
|
+
if (readdirSync4(this.backupsDir).length === 0)
|
|
21062
|
+
rmdirSync(this.backupsDir);
|
|
21063
|
+
} catch {
|
|
21064
|
+
}
|
|
21065
|
+
return;
|
|
21066
|
+
}
|
|
21067
|
+
mkdirSync2(this.root, { recursive: true, mode: 448 });
|
|
21068
|
+
writeAtomic(
|
|
21069
|
+
this.receiptsPath,
|
|
21070
|
+
`${JSON.stringify(receipts, null, 2)}
|
|
21071
|
+
`,
|
|
21072
|
+
384
|
|
21073
|
+
);
|
|
21074
|
+
}
|
|
21075
|
+
};
|
|
21076
|
+
}
|
|
21077
|
+
});
|
|
21078
|
+
|
|
21159
21079
|
// ../../packages/tacho/src/host/install-lock.ts
|
|
21160
21080
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
21161
21081
|
import {
|
|
21162
21082
|
closeSync as closeSync3,
|
|
21163
21083
|
existsSync as existsSync4,
|
|
21164
21084
|
linkSync,
|
|
21165
|
-
mkdirSync as
|
|
21085
|
+
mkdirSync as mkdirSync3,
|
|
21166
21086
|
openSync as openSync3,
|
|
21167
21087
|
readdirSync as readdirSync5,
|
|
21168
21088
|
readFileSync as readFileSync5,
|
|
21169
|
-
renameSync as
|
|
21170
|
-
rmdirSync as
|
|
21089
|
+
renameSync as renameSync2,
|
|
21090
|
+
rmdirSync as rmdirSync2,
|
|
21171
21091
|
unlinkSync as unlinkSync3,
|
|
21172
21092
|
writeSync as writeSync2
|
|
21173
21093
|
} from "node:fs";
|
|
21174
|
-
import { dirname as dirname5, join as
|
|
21094
|
+
import { dirname as dirname5, join as join12 } from "node:path";
|
|
21175
21095
|
function readLock(path2) {
|
|
21176
21096
|
try {
|
|
21177
21097
|
return readFileSync5(path2, "utf8");
|
|
@@ -21201,14 +21121,14 @@ function pidAlive(pid) {
|
|
|
21201
21121
|
}
|
|
21202
21122
|
}
|
|
21203
21123
|
function acquireInstallLock(root, now = Date.now, alive = pidAlive) {
|
|
21204
|
-
const path2 =
|
|
21124
|
+
const path2 = join12(root, "install.lock");
|
|
21205
21125
|
const created = [];
|
|
21206
21126
|
let dir = root;
|
|
21207
21127
|
while (!existsSync4(dir) && dirname5(dir) !== dir) {
|
|
21208
21128
|
created.unshift(dir);
|
|
21209
21129
|
dir = dirname5(dir);
|
|
21210
21130
|
}
|
|
21211
|
-
|
|
21131
|
+
mkdirSync3(root, { recursive: true, mode: 448 });
|
|
21212
21132
|
const token = randomBytes3(12).toString("hex");
|
|
21213
21133
|
const liveHolder = (holder) => typeof holder.pid === "number" && typeof holder.at === "number" && now() - holder.at < STALE_AFTER_MS && alive(holder.pid) ? holder.pid : void 0;
|
|
21214
21134
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
@@ -21221,7 +21141,7 @@ function acquireInstallLock(root, now = Date.now, alive = pidAlive) {
|
|
|
21221
21141
|
if (holderOf(readLock(path2)).token === token) removeQuietly(path2);
|
|
21222
21142
|
for (const made of [...created].reverse()) {
|
|
21223
21143
|
try {
|
|
21224
|
-
if (readdirSync5(made).length === 0)
|
|
21144
|
+
if (readdirSync5(made).length === 0) rmdirSync2(made);
|
|
21225
21145
|
} catch {
|
|
21226
21146
|
}
|
|
21227
21147
|
}
|
|
@@ -21233,7 +21153,7 @@ function acquireInstallLock(root, now = Date.now, alive = pidAlive) {
|
|
|
21233
21153
|
if (live !== void 0) return { heldBy: live };
|
|
21234
21154
|
const aside = `${path2}.${process.pid}.${token}.stale`;
|
|
21235
21155
|
try {
|
|
21236
|
-
|
|
21156
|
+
renameSync2(path2, aside);
|
|
21237
21157
|
} catch (renameError) {
|
|
21238
21158
|
if (renameError.code === "ENOENT") continue;
|
|
21239
21159
|
throw renameError;
|
|
@@ -21514,12 +21434,12 @@ import { createHash as createHash5 } from "node:crypto";
|
|
|
21514
21434
|
import {
|
|
21515
21435
|
chmodSync as chmodSync3,
|
|
21516
21436
|
existsSync as existsSync5,
|
|
21517
|
-
mkdirSync as
|
|
21437
|
+
mkdirSync as mkdirSync4,
|
|
21518
21438
|
readFileSync as readFileSync6,
|
|
21519
|
-
statSync as
|
|
21439
|
+
statSync as statSync2,
|
|
21520
21440
|
unlinkSync as unlinkSync4
|
|
21521
21441
|
} from "node:fs";
|
|
21522
|
-
import { basename as
|
|
21442
|
+
import { basename as basename3, dirname as dirname6, join as join13 } from "node:path";
|
|
21523
21443
|
function claudeToolSearchEnabled(value) {
|
|
21524
21444
|
return typeof value === "string" && /^(true|auto(:\d+)?)$/i.test(value);
|
|
21525
21445
|
}
|
|
@@ -21533,18 +21453,18 @@ function isModelProxyBaseUrl(harness, value) {
|
|
|
21533
21453
|
}
|
|
21534
21454
|
function modelBaseUrlFile(harness, homes) {
|
|
21535
21455
|
if (harness === "claude-code")
|
|
21536
|
-
return
|
|
21456
|
+
return join13(
|
|
21537
21457
|
homes.claudeConfigDir ?? harnessConfigDirs(homes.home).claudeConfigDir,
|
|
21538
21458
|
"settings.json"
|
|
21539
21459
|
);
|
|
21540
21460
|
if (harness === "codex")
|
|
21541
|
-
return
|
|
21461
|
+
return join13(
|
|
21542
21462
|
homes.codexHome ?? harnessConfigDirs(homes.home).codexHome,
|
|
21543
21463
|
"config.toml"
|
|
21544
21464
|
);
|
|
21545
|
-
const stellaHome = homes.stellaHome ??
|
|
21546
|
-
const toml =
|
|
21547
|
-
const json2 =
|
|
21465
|
+
const stellaHome = homes.stellaHome ?? join13(homes.home, ".stella");
|
|
21466
|
+
const toml = join13(stellaHome, "stella.toml");
|
|
21467
|
+
const json2 = join13(stellaHome, "settings.json");
|
|
21548
21468
|
return !existsSync5(toml) && existsSync5(json2) ? json2 : toml;
|
|
21549
21469
|
}
|
|
21550
21470
|
function keyLabel(harness) {
|
|
@@ -21555,7 +21475,7 @@ function isJsonFile(file) {
|
|
|
21555
21475
|
return file.endsWith(".json");
|
|
21556
21476
|
}
|
|
21557
21477
|
function sidecarFor(file) {
|
|
21558
|
-
return
|
|
21478
|
+
return join13(dirname6(file), `.${basename3(file)}.oxagen-model-base-url.json`);
|
|
21559
21479
|
}
|
|
21560
21480
|
function modelBaseUrlBackupPath(harness, home, stellaHome, dirs = {}) {
|
|
21561
21481
|
return sidecarFor(fileFor(harness, homesOf(home, stellaHome, dirs)));
|
|
@@ -21599,11 +21519,11 @@ function readSidecar(path2) {
|
|
|
21599
21519
|
}
|
|
21600
21520
|
}
|
|
21601
21521
|
function writeAtomicPreserving(path2, data) {
|
|
21602
|
-
|
|
21522
|
+
mkdirSync4(dirname6(path2), { recursive: true });
|
|
21603
21523
|
let mode = 384;
|
|
21604
21524
|
let owner;
|
|
21605
21525
|
try {
|
|
21606
|
-
const stat6 =
|
|
21526
|
+
const stat6 = statSync2(path2);
|
|
21607
21527
|
mode = stat6.mode & 4095;
|
|
21608
21528
|
owner = { uid: stat6.uid, gid: stat6.gid };
|
|
21609
21529
|
} catch {
|
|
@@ -21706,8 +21626,8 @@ function stellaManagedSettingsPath(platform = process.platform, env = process.en
|
|
|
21706
21626
|
const named = env["STELLA_MANAGED_SETTINGS"];
|
|
21707
21627
|
if (named !== void 0 && named.length > 0) return named;
|
|
21708
21628
|
const dir = platform === "darwin" ? "/Library/Application Support/stella" : "/etc/stella";
|
|
21709
|
-
const toml =
|
|
21710
|
-
const json2 =
|
|
21629
|
+
const toml = join13(dir, "stella.toml");
|
|
21630
|
+
const json2 = join13(dir, "settings.json");
|
|
21711
21631
|
return !existsSync5(toml) && existsSync5(json2) ? json2 : toml;
|
|
21712
21632
|
}
|
|
21713
21633
|
function managedShadow(harness, managedFile, expected) {
|
|
@@ -22281,12 +22201,12 @@ import {
|
|
|
22281
22201
|
chmodSync as chmodSync4,
|
|
22282
22202
|
existsSync as existsSync6,
|
|
22283
22203
|
lstatSync as lstatSync2,
|
|
22284
|
-
mkdirSync as
|
|
22204
|
+
mkdirSync as mkdirSync5,
|
|
22285
22205
|
readFileSync as readFileSync8,
|
|
22286
|
-
statSync as
|
|
22206
|
+
statSync as statSync3,
|
|
22287
22207
|
unlinkSync as unlinkSync5
|
|
22288
22208
|
} from "node:fs";
|
|
22289
|
-
import { basename as
|
|
22209
|
+
import { basename as basename4, dirname as dirname7, join as join14 } from "node:path";
|
|
22290
22210
|
function isTachoHelper(value) {
|
|
22291
22211
|
return typeof value === "string" && HELPER_MARK.test(value);
|
|
22292
22212
|
}
|
|
@@ -22294,16 +22214,16 @@ function helperCommandFor(tachoCommand) {
|
|
|
22294
22214
|
return `${tachoCommand} credential issue --harness claude-code`;
|
|
22295
22215
|
}
|
|
22296
22216
|
function fileFor2(harness, homes) {
|
|
22297
|
-
return harness === "claude-code" ?
|
|
22217
|
+
return harness === "claude-code" ? join14(
|
|
22298
22218
|
homes.claudeConfigDir ?? harnessConfigDirs(homes.home).claudeConfigDir,
|
|
22299
22219
|
"settings.json"
|
|
22300
|
-
) :
|
|
22220
|
+
) : join14(
|
|
22301
22221
|
homes.codexHome ?? harnessConfigDirs(homes.home).codexHome,
|
|
22302
22222
|
"auth.json"
|
|
22303
22223
|
);
|
|
22304
22224
|
}
|
|
22305
22225
|
function sidecarFor2(file) {
|
|
22306
|
-
return
|
|
22226
|
+
return join14(dirname7(file), `.${basename4(file)}.oxagen-model-credential.json`);
|
|
22307
22227
|
}
|
|
22308
22228
|
function modelCredentialBackupPath(harness, home, dirs = {}) {
|
|
22309
22229
|
return sidecarFor2(fileFor2(harness, { ...dirs, home }));
|
|
@@ -22334,11 +22254,11 @@ function readSidecar2(path2) {
|
|
|
22334
22254
|
}
|
|
22335
22255
|
}
|
|
22336
22256
|
function writeAtomicPreserving2(path2, data) {
|
|
22337
|
-
|
|
22257
|
+
mkdirSync5(dirname7(path2), { recursive: true });
|
|
22338
22258
|
let mode = 384;
|
|
22339
22259
|
let owner;
|
|
22340
22260
|
try {
|
|
22341
|
-
const stat6 =
|
|
22261
|
+
const stat6 = statSync3(path2);
|
|
22342
22262
|
mode = stat6.mode & 4095;
|
|
22343
22263
|
owner = { uid: stat6.uid, gid: stat6.gid };
|
|
22344
22264
|
} catch {
|
|
@@ -23309,7 +23229,7 @@ import {
|
|
|
23309
23229
|
fsyncSync as fsyncSync2,
|
|
23310
23230
|
openSync as openSync4,
|
|
23311
23231
|
readFileSync as readFileSync9,
|
|
23312
|
-
statSync as
|
|
23232
|
+
statSync as statSync4,
|
|
23313
23233
|
unlinkSync as unlinkSync6,
|
|
23314
23234
|
writeSync as writeSync3
|
|
23315
23235
|
} from "node:fs";
|
|
@@ -23343,7 +23263,7 @@ function requireKey(path2) {
|
|
|
23343
23263
|
function overwriteInPlace(path2) {
|
|
23344
23264
|
let fd2;
|
|
23345
23265
|
try {
|
|
23346
|
-
const size =
|
|
23266
|
+
const size = statSync4(path2).size;
|
|
23347
23267
|
fd2 = openSync4(path2, "r+");
|
|
23348
23268
|
writeSync3(fd2, randomBytes5(Math.max(size, KEY_BYTES2 * 2)), 0, void 0, 0);
|
|
23349
23269
|
fsyncSync2(fd2);
|
|
@@ -23520,7 +23440,7 @@ var init_credential_store = __esm({
|
|
|
23520
23440
|
});
|
|
23521
23441
|
|
|
23522
23442
|
// ../../packages/tacho/src/host/claude-config-lock.ts
|
|
23523
|
-
import { mkdirSync as
|
|
23443
|
+
import { mkdirSync as mkdirSync6, rmdirSync as rmdirSync3, statSync as statSync5 } from "node:fs";
|
|
23524
23444
|
function sleepSync(ms) {
|
|
23525
23445
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
23526
23446
|
}
|
|
@@ -23537,7 +23457,7 @@ function withClaudeConfigLock(file, edit, options = {}) {
|
|
|
23537
23457
|
let held = false;
|
|
23538
23458
|
for (; ; ) {
|
|
23539
23459
|
try {
|
|
23540
|
-
|
|
23460
|
+
mkdirSync6(lock);
|
|
23541
23461
|
held = true;
|
|
23542
23462
|
break;
|
|
23543
23463
|
} catch (error) {
|
|
@@ -23547,15 +23467,15 @@ function withClaudeConfigLock(file, edit, options = {}) {
|
|
|
23547
23467
|
}
|
|
23548
23468
|
let modified;
|
|
23549
23469
|
try {
|
|
23550
|
-
modified =
|
|
23470
|
+
modified = statSync5(lock).mtimeMs;
|
|
23551
23471
|
} catch {
|
|
23552
23472
|
modified = void 0;
|
|
23553
23473
|
}
|
|
23554
23474
|
let retryNow = modified === void 0;
|
|
23555
23475
|
if (modified !== void 0 && now() - modified > staleMs) {
|
|
23556
23476
|
try {
|
|
23557
|
-
if (
|
|
23558
|
-
|
|
23477
|
+
if (statSync5(lock).mtimeMs === modified) {
|
|
23478
|
+
rmdirSync3(lock);
|
|
23559
23479
|
retryNow = true;
|
|
23560
23480
|
}
|
|
23561
23481
|
} catch {
|
|
@@ -23573,7 +23493,7 @@ function withClaudeConfigLock(file, edit, options = {}) {
|
|
|
23573
23493
|
} finally {
|
|
23574
23494
|
if (held) {
|
|
23575
23495
|
try {
|
|
23576
|
-
|
|
23496
|
+
rmdirSync3(lock);
|
|
23577
23497
|
} catch {
|
|
23578
23498
|
}
|
|
23579
23499
|
}
|
|
@@ -23591,12 +23511,12 @@ var init_claude_config_lock = __esm({
|
|
|
23591
23511
|
});
|
|
23592
23512
|
|
|
23593
23513
|
// ../../packages/tacho/src/host/service.ts
|
|
23594
|
-
import { join as
|
|
23514
|
+
import { join as join15 } from "node:path";
|
|
23595
23515
|
import {
|
|
23596
23516
|
existsSync as existsSync9,
|
|
23597
23517
|
readdirSync as readdirSync6,
|
|
23598
23518
|
readFileSync as readFileSync10,
|
|
23599
|
-
rmdirSync as
|
|
23519
|
+
rmdirSync as rmdirSync4,
|
|
23600
23520
|
unlinkSync as unlinkSync7
|
|
23601
23521
|
} from "node:fs";
|
|
23602
23522
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
@@ -23671,8 +23591,8 @@ function blockingSleep(ms) {
|
|
|
23671
23591
|
}
|
|
23672
23592
|
function launchdManager(options) {
|
|
23673
23593
|
const sleep3 = options.sleep ?? blockingSleep;
|
|
23674
|
-
const dir =
|
|
23675
|
-
const unitPath =
|
|
23594
|
+
const dir = join15(options.home, "Library", "LaunchAgents");
|
|
23595
|
+
const unitPath = join15(dir, `${SERVICE_LABEL}.plist`);
|
|
23676
23596
|
const domain = `gui/${options.uid ?? process.getuid?.() ?? 501}`;
|
|
23677
23597
|
const target2 = `${domain}/${SERVICE_LABEL}`;
|
|
23678
23598
|
const loaded = () => options.exec("launchctl", ["print", target2]).status === 0;
|
|
@@ -23777,9 +23697,9 @@ function stopByPidFile(options) {
|
|
|
23777
23697
|
);
|
|
23778
23698
|
}
|
|
23779
23699
|
function systemdManager(options) {
|
|
23780
|
-
const dir =
|
|
23781
|
-
const unitPath =
|
|
23782
|
-
const wants =
|
|
23700
|
+
const dir = join15(options.home, ".config", "systemd", "user");
|
|
23701
|
+
const unitPath = join15(dir, "tachod.service");
|
|
23702
|
+
const wants = join15(dir, "default.target.wants");
|
|
23783
23703
|
return {
|
|
23784
23704
|
kind: "systemd",
|
|
23785
23705
|
unitPath,
|
|
@@ -23858,7 +23778,7 @@ function systemdManager(options) {
|
|
|
23858
23778
|
}
|
|
23859
23779
|
if (unit4?.includes(CREATED_WANTS_MARK) === true) {
|
|
23860
23780
|
try {
|
|
23861
|
-
if (readdirSync6(wants).length === 0)
|
|
23781
|
+
if (readdirSync6(wants).length === 0) rmdirSync4(wants);
|
|
23862
23782
|
} catch {
|
|
23863
23783
|
}
|
|
23864
23784
|
}
|
|
@@ -23926,8 +23846,8 @@ function windowsCreatedMs(exec4, pid) {
|
|
|
23926
23846
|
return result2.status === 0 && /^\d+$/.test(text5) ? Number(text5) : void 0;
|
|
23927
23847
|
}
|
|
23928
23848
|
function schtasksManager(options) {
|
|
23929
|
-
const launcher = options.launcherPath ??
|
|
23930
|
-
const pidPath = options.pidPath ??
|
|
23849
|
+
const launcher = options.launcherPath ?? join15(options.home, "tachod.cmd");
|
|
23850
|
+
const pidPath = options.pidPath ?? join15(launcher, "..", "tachod.pid");
|
|
23931
23851
|
const liveRecord = () => {
|
|
23932
23852
|
if (!existsSync9(pidPath)) return void 0;
|
|
23933
23853
|
const record = parseDaemonPid(readFileSync10(pidPath, "utf8"));
|
|
@@ -23972,7 +23892,7 @@ function schtasksManager(options) {
|
|
|
23972
23892
|
unitPath: launcher,
|
|
23973
23893
|
install: (spec) => {
|
|
23974
23894
|
stopDaemon();
|
|
23975
|
-
ensureDir(
|
|
23895
|
+
ensureDir(join15(launcher, ".."), 493);
|
|
23976
23896
|
writeSensitiveFileAtomic(
|
|
23977
23897
|
launcher,
|
|
23978
23898
|
renderWindowsLauncher(
|
|
@@ -24104,7 +24024,7 @@ import { readFileSync as readFileSync11 } from "node:fs";
|
|
|
24104
24024
|
import { dirname as dirname9, resolve as resolve3 } from "node:path";
|
|
24105
24025
|
import { fileURLToPath } from "node:url";
|
|
24106
24026
|
function readVersion() {
|
|
24107
|
-
if (true) return "2.1.4-
|
|
24027
|
+
if (true) return "2.1.4-679";
|
|
24108
24028
|
try {
|
|
24109
24029
|
const here = dirname9(fileURLToPath(import.meta.url));
|
|
24110
24030
|
const pkg = JSON.parse(
|
|
@@ -25314,11 +25234,11 @@ import {
|
|
|
25314
25234
|
existsSync as existsSync11,
|
|
25315
25235
|
openSync as openSync5,
|
|
25316
25236
|
readSync as readSync2,
|
|
25317
|
-
statSync as
|
|
25237
|
+
statSync as statSync6,
|
|
25318
25238
|
unlinkSync as unlinkSync8
|
|
25319
25239
|
} from "node:fs";
|
|
25320
25240
|
import { open as open2 } from "node:fs/promises";
|
|
25321
|
-
import { join as
|
|
25241
|
+
import { join as join16 } from "node:path";
|
|
25322
25242
|
function parseStoredBody(text5) {
|
|
25323
25243
|
let value;
|
|
25324
25244
|
try {
|
|
@@ -25332,7 +25252,7 @@ function parseStoredBody(text5) {
|
|
|
25332
25252
|
return void 0;
|
|
25333
25253
|
return stored;
|
|
25334
25254
|
}
|
|
25335
|
-
function readTailLine(path2, size =
|
|
25255
|
+
function readTailLine(path2, size = statSync6(path2).size, window2 = SCAN_CHUNK_BYTES) {
|
|
25336
25256
|
if (size === 0) return void 0;
|
|
25337
25257
|
const fd2 = openSync5(path2, "r");
|
|
25338
25258
|
try {
|
|
@@ -25516,7 +25436,7 @@ var init_wal_index = __esm({
|
|
|
25516
25436
|
/** The scan `ensureAsync` has running for a session, shared by callers. */
|
|
25517
25437
|
building = /* @__PURE__ */ new Map();
|
|
25518
25438
|
sidecarFor(sessionUuid2) {
|
|
25519
|
-
return
|
|
25439
|
+
return join16(this.dir, `${sessionUuid2}${SIDECAR_SUFFIX}`);
|
|
25520
25440
|
}
|
|
25521
25441
|
/** Whether a name in the WAL directory is one of these sidecars. */
|
|
25522
25442
|
static isSidecar(name) {
|
|
@@ -25549,7 +25469,7 @@ var init_wal_index = __esm({
|
|
|
25549
25469
|
}
|
|
25550
25470
|
/** The index to extend, and the byte the scan starts from. */
|
|
25551
25471
|
base(sessionUuid2, bodiesPath) {
|
|
25552
|
-
const size =
|
|
25472
|
+
const size = statSync6(bodiesPath).size;
|
|
25553
25473
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
25554
25474
|
if (held !== void 0 && held.covered <= size) return held;
|
|
25555
25475
|
this.discard(sessionUuid2);
|
|
@@ -25623,7 +25543,7 @@ ${lines.join("\n")}
|
|
|
25623
25543
|
* answers undefined.
|
|
25624
25544
|
*/
|
|
25625
25545
|
covering(sessionUuid2, bodiesPath) {
|
|
25626
|
-
const size =
|
|
25546
|
+
const size = statSync6(bodiesPath).size;
|
|
25627
25547
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
25628
25548
|
if (held === void 0 || held.covered !== size) return void 0;
|
|
25629
25549
|
this.remember(sessionUuid2, held);
|
|
@@ -25637,7 +25557,7 @@ ${lines.join("\n")}
|
|
|
25637
25557
|
* file.
|
|
25638
25558
|
*/
|
|
25639
25559
|
held(sessionUuid2, bodiesPath) {
|
|
25640
|
-
const size =
|
|
25560
|
+
const size = statSync6(bodiesPath).size;
|
|
25641
25561
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
25642
25562
|
if (held === void 0 || held.covered > size) return void 0;
|
|
25643
25563
|
this.remember(sessionUuid2, held);
|
|
@@ -25646,7 +25566,7 @@ ${lines.join("\n")}
|
|
|
25646
25566
|
/** The index of a body file, built or extended to cover the whole file. */
|
|
25647
25567
|
ensure(sessionUuid2, bodiesPath, onInvalidRecord, onWriteFailure) {
|
|
25648
25568
|
const index = this.base(sessionUuid2, bodiesPath);
|
|
25649
|
-
const size =
|
|
25569
|
+
const size = statSync6(bodiesPath).size;
|
|
25650
25570
|
if (index.covered < size) {
|
|
25651
25571
|
const result2 = {
|
|
25652
25572
|
added: [],
|
|
@@ -25700,7 +25620,7 @@ ${lines.join("\n")}
|
|
|
25700
25620
|
for (let attempt = 0; ; attempt += 1) {
|
|
25701
25621
|
const generation = this.generationOf(sessionUuid2);
|
|
25702
25622
|
const index = this.base(sessionUuid2, bodiesPath);
|
|
25703
|
-
const size =
|
|
25623
|
+
const size = statSync6(bodiesPath).size;
|
|
25704
25624
|
if (index.covered >= size) {
|
|
25705
25625
|
this.remember(sessionUuid2, index);
|
|
25706
25626
|
return index;
|
|
@@ -25739,19 +25659,19 @@ import {
|
|
|
25739
25659
|
readdirSync as readdirSync7,
|
|
25740
25660
|
readSync as readSync3,
|
|
25741
25661
|
truncateSync,
|
|
25742
|
-
renameSync as
|
|
25743
|
-
statSync as
|
|
25662
|
+
renameSync as renameSync3,
|
|
25663
|
+
statSync as statSync7,
|
|
25744
25664
|
unlinkSync as unlinkSync9,
|
|
25745
25665
|
writeSync as writeSync4
|
|
25746
25666
|
} from "node:fs";
|
|
25747
25667
|
import { randomUUID } from "node:crypto";
|
|
25748
|
-
import { join as
|
|
25668
|
+
import { join as join17 } from "node:path";
|
|
25749
25669
|
function activityAt(event) {
|
|
25750
25670
|
const at = Date.parse(event.ts);
|
|
25751
25671
|
return Number.isFinite(at) ? at : Number.NEGATIVE_INFINITY;
|
|
25752
25672
|
}
|
|
25753
25673
|
function sizeOf(path2) {
|
|
25754
|
-
return
|
|
25674
|
+
return statSync7(path2, { throwIfNoEntry: false })?.size ?? 0;
|
|
25755
25675
|
}
|
|
25756
25676
|
var BODY_READ_SLICE, BODY_DROP_SLICE_BYTES, BODY_DROP_SCANS, NEWLINE, EVENT_TAIL_WINDOW, WalRecoveryConflict, Wal;
|
|
25757
25677
|
var init_wal = __esm({
|
|
@@ -25783,7 +25703,7 @@ var init_wal = __esm({
|
|
|
25783
25703
|
this.dir = dir;
|
|
25784
25704
|
ensureDir(dir);
|
|
25785
25705
|
this.bodyIndexes = new BodyIndexStore(dir);
|
|
25786
|
-
this.cursorPath =
|
|
25706
|
+
this.cursorPath = join17(dir, "cursor.json");
|
|
25787
25707
|
let raw;
|
|
25788
25708
|
if (onCursorSetAside !== void 0)
|
|
25789
25709
|
raw = readJsonStateFile(this.cursorPath, onCursorSetAside);
|
|
@@ -25862,10 +25782,10 @@ var init_wal = __esm({
|
|
|
25862
25782
|
*/
|
|
25863
25783
|
dirtyPaths = /* @__PURE__ */ new Set();
|
|
25864
25784
|
fileFor(sessionUuid2) {
|
|
25865
|
-
return
|
|
25785
|
+
return join17(this.dir, `${sessionUuid2}.ndjson`);
|
|
25866
25786
|
}
|
|
25867
25787
|
bodyFileFor(sessionUuid2) {
|
|
25868
|
-
return
|
|
25788
|
+
return join17(this.dir, `${sessionUuid2}.bodies.jsonl`);
|
|
25869
25789
|
}
|
|
25870
25790
|
persistCursor() {
|
|
25871
25791
|
this.flush();
|
|
@@ -26111,7 +26031,7 @@ ${lines.join("\n")}
|
|
|
26111
26031
|
for (const session of sessions) {
|
|
26112
26032
|
if (sizes.has(session)) continue;
|
|
26113
26033
|
const path2 = pathOf2(session);
|
|
26114
|
-
sizes.set(session, existsSync12(path2) ?
|
|
26034
|
+
sizes.set(session, existsSync12(path2) ? statSync7(path2).size : void 0);
|
|
26115
26035
|
}
|
|
26116
26036
|
return sizes;
|
|
26117
26037
|
}
|
|
@@ -26127,7 +26047,7 @@ ${lines.join("\n")}
|
|
|
26127
26047
|
try {
|
|
26128
26048
|
if (!existsSync12(path2)) continue;
|
|
26129
26049
|
if (size === void 0) unlinkSync9(path2);
|
|
26130
|
-
else if (
|
|
26050
|
+
else if (statSync7(path2).size !== size) truncateSync(path2, size);
|
|
26131
26051
|
} catch (error) {
|
|
26132
26052
|
onFailure(session, error);
|
|
26133
26053
|
}
|
|
@@ -26810,7 +26730,7 @@ ${lines.join("\n")}
|
|
|
26810
26730
|
const lastSeq = this.lastWrittenSeq(sessionUuid2);
|
|
26811
26731
|
if (lastSeq === void 0) return 0;
|
|
26812
26732
|
const path2 = this.bodyFileFor(sessionUuid2);
|
|
26813
|
-
const size =
|
|
26733
|
+
const size = statSync7(path2).size;
|
|
26814
26734
|
let keep = size;
|
|
26815
26735
|
let cut2 = 0;
|
|
26816
26736
|
while (keep > 0) {
|
|
@@ -26843,7 +26763,7 @@ ${lines.join("\n")}
|
|
|
26843
26763
|
*/
|
|
26844
26764
|
lastWrittenSeq(sessionUuid2) {
|
|
26845
26765
|
const path2 = this.fileFor(sessionUuid2);
|
|
26846
|
-
if (!existsSync12(path2) ||
|
|
26766
|
+
if (!existsSync12(path2) || statSync7(path2).size === 0) return -1;
|
|
26847
26767
|
return this.lastEvent(sessionUuid2)?.seq;
|
|
26848
26768
|
}
|
|
26849
26769
|
/**
|
|
@@ -26874,7 +26794,7 @@ ${lines.join("\n")}
|
|
|
26874
26794
|
*eventsBackward(sessionUuid2) {
|
|
26875
26795
|
const path2 = this.fileFor(sessionUuid2);
|
|
26876
26796
|
if (!existsSync12(path2)) return;
|
|
26877
|
-
let end =
|
|
26797
|
+
let end = statSync7(path2).size;
|
|
26878
26798
|
while (end > 0) {
|
|
26879
26799
|
const line = readTailLine(path2, end, EVENT_TAIL_WINDOW);
|
|
26880
26800
|
if (line === void 0) return;
|
|
@@ -26905,7 +26825,7 @@ ${lines.join("\n")}
|
|
|
26905
26825
|
this.unverifiedResume.delete(sessionUuid2);
|
|
26906
26826
|
let holds2 = false;
|
|
26907
26827
|
try {
|
|
26908
|
-
if (mark.offset <=
|
|
26828
|
+
if (mark.offset <= statSync7(path2).size) {
|
|
26909
26829
|
const line = readTailLine(path2, mark.offset, EVENT_TAIL_WINDOW);
|
|
26910
26830
|
holds2 = line !== void 0 && line.terminated && line.end === mark.offset && JSON.parse(line.text).seq === mark.afterSeq;
|
|
26911
26831
|
}
|
|
@@ -27258,7 +27178,7 @@ ${lines.join("\n")}
|
|
|
27258
27178
|
}
|
|
27259
27179
|
if (cut2 === 0) return 0;
|
|
27260
27180
|
if (kept === 0) unlinkSync9(path2);
|
|
27261
|
-
else
|
|
27181
|
+
else renameSync3(tmp, path2);
|
|
27262
27182
|
this.bodyIndexes.invalidate(sessionUuid2);
|
|
27263
27183
|
return cut2;
|
|
27264
27184
|
} finally {
|
|
@@ -27289,7 +27209,7 @@ ${lines.join("\n")}
|
|
|
27289
27209
|
for (const name of readdirSync7(this.dir)) {
|
|
27290
27210
|
if (abandonedRewrite.test(name)) {
|
|
27291
27211
|
try {
|
|
27292
|
-
unlinkSync9(
|
|
27212
|
+
unlinkSync9(join17(this.dir, name));
|
|
27293
27213
|
} catch (error) {
|
|
27294
27214
|
this.bodyFailure(name.slice(0, 36), "cleanup", error);
|
|
27295
27215
|
}
|
|
@@ -27301,7 +27221,7 @@ ${lines.join("\n")}
|
|
|
27301
27221
|
if (sealedAt === void 0) continue;
|
|
27302
27222
|
const path2 = this.fileFor(session);
|
|
27303
27223
|
try {
|
|
27304
|
-
const age = now - Math.max(Date.parse(sealedAt),
|
|
27224
|
+
const age = now - Math.max(Date.parse(sealedAt), statSync7(path2).mtimeMs);
|
|
27305
27225
|
if (age < retainMs) continue;
|
|
27306
27226
|
const last = this.lastSeqOf(session);
|
|
27307
27227
|
if (last < 0 || last > this.shippedThrough(session)) continue;
|
|
@@ -27323,7 +27243,7 @@ ${lines.join("\n")}
|
|
|
27323
27243
|
if (removed.includes(session) || existsSync12(this.fileFor(session)))
|
|
27324
27244
|
continue;
|
|
27325
27245
|
try {
|
|
27326
|
-
if (now -
|
|
27246
|
+
if (now - statSync7(this.bodyFileFor(session)).mtimeMs < retainMs)
|
|
27327
27247
|
continue;
|
|
27328
27248
|
} catch (error) {
|
|
27329
27249
|
this.bodyFailure(session, "cleanup", error);
|
|
@@ -27679,7 +27599,7 @@ var init_policy_mode = __esm({
|
|
|
27679
27599
|
|
|
27680
27600
|
// ../../packages/tacho/src/host/wal-ceiling.ts
|
|
27681
27601
|
import { statfsSync } from "node:fs";
|
|
27682
|
-
import { join as
|
|
27602
|
+
import { join as join18 } from "node:path";
|
|
27683
27603
|
function freeBytesOn(dir) {
|
|
27684
27604
|
try {
|
|
27685
27605
|
const stats2 = statfsSync(dir);
|
|
@@ -27726,7 +27646,7 @@ function isDrop(value) {
|
|
|
27726
27646
|
function readWalCeilingState(walDir) {
|
|
27727
27647
|
let raw;
|
|
27728
27648
|
try {
|
|
27729
|
-
raw = readJsonFileIfExists(
|
|
27649
|
+
raw = readJsonFileIfExists(join18(walDir, STATE_FILE));
|
|
27730
27650
|
} catch {
|
|
27731
27651
|
return void 0;
|
|
27732
27652
|
}
|
|
@@ -27927,7 +27847,7 @@ var init_wal_ceiling = __esm({
|
|
|
27927
27847
|
if (!changed) return;
|
|
27928
27848
|
try {
|
|
27929
27849
|
writeSensitiveFileAtomic(
|
|
27930
|
-
|
|
27850
|
+
join18(this.walDir, STATE_FILE),
|
|
27931
27851
|
JSON.stringify(next)
|
|
27932
27852
|
);
|
|
27933
27853
|
this.unsaved = false;
|
|
@@ -28410,11 +28330,11 @@ import {
|
|
|
28410
28330
|
existsSync as existsSync15,
|
|
28411
28331
|
lstatSync as lstatSync3,
|
|
28412
28332
|
readdirSync as readdirSync8,
|
|
28413
|
-
rmdirSync as
|
|
28333
|
+
rmdirSync as rmdirSync5,
|
|
28414
28334
|
rmSync as rmSync2,
|
|
28415
28335
|
unlinkSync as unlinkSync10
|
|
28416
28336
|
} from "node:fs";
|
|
28417
|
-
import { dirname as dirname12, join as
|
|
28337
|
+
import { dirname as dirname12, join as join19 } from "node:path";
|
|
28418
28338
|
async function revokeOnControlPlane(host, options, deps, warnings) {
|
|
28419
28339
|
const resolved = resolveCredentials(
|
|
28420
28340
|
{
|
|
@@ -28729,7 +28649,7 @@ async function unenroll(options, deps) {
|
|
|
28729
28649
|
}
|
|
28730
28650
|
for (const agent of target2) {
|
|
28731
28651
|
if (many) deps.out(`Unenrolling ${describeAgent(agent)}`);
|
|
28732
|
-
|
|
28652
|
+
dirs.push(agent.paths.dir);
|
|
28733
28653
|
results.push(await unenrollLocked(options, depsForAgent(deps, agent)));
|
|
28734
28654
|
}
|
|
28735
28655
|
const result2 = combined(results);
|
|
@@ -28795,7 +28715,7 @@ function restartForRemaining(installed, deps) {
|
|
|
28795
28715
|
}
|
|
28796
28716
|
function removeIfEmpty(dir) {
|
|
28797
28717
|
try {
|
|
28798
|
-
if (readdirSync8(dir).length === 0)
|
|
28718
|
+
if (readdirSync8(dir).length === 0) rmdirSync5(dir);
|
|
28799
28719
|
} catch {
|
|
28800
28720
|
}
|
|
28801
28721
|
}
|
|
@@ -28997,8 +28917,8 @@ async function unenrollLocked(options, deps) {
|
|
|
28997
28917
|
rmSync2(dir, { recursive: true, force: true });
|
|
28998
28918
|
}
|
|
28999
28919
|
rmSync2(deps.paths.pendingEnds, { force: true });
|
|
29000
|
-
if (!existsSync15(
|
|
29001
|
-
rmSync2(
|
|
28920
|
+
if (!existsSync15(join19(deps.paths.dir, HARNESS_RECEIPTS)))
|
|
28921
|
+
rmSync2(join19(deps.paths.dir, HARNESS_BACKUPS), {
|
|
29002
28922
|
recursive: true,
|
|
29003
28923
|
force: true
|
|
29004
28924
|
});
|
|
@@ -29054,7 +28974,7 @@ var init_unenroll = __esm({
|
|
|
29054
28974
|
|
|
29055
28975
|
// ../../packages/tacho/src/cli/enroll.ts
|
|
29056
28976
|
import { existsSync as existsSync16, lstatSync as lstatSync4, rmSync as rmSync3 } from "node:fs";
|
|
29057
|
-
import { dirname as dirname13, isAbsolute, join as
|
|
28977
|
+
import { dirname as dirname13, isAbsolute, join as join20 } from "node:path";
|
|
29058
28978
|
function rootRefusal(command2, deps, allowRoot) {
|
|
29059
28979
|
if (allowRoot === true || deps.getuid?.() !== 0) return void 0;
|
|
29060
28980
|
const user = deps.env["SUDO_USER"] ?? "<user>";
|
|
@@ -29080,7 +29000,7 @@ function runtimeOf(host) {
|
|
|
29080
29000
|
if (first === void 0 || !files3.every((file) => existsSync16(file)))
|
|
29081
29001
|
return void 0;
|
|
29082
29002
|
const binDir = dirname13(first);
|
|
29083
|
-
const tacho = host.daemon_command[0] === first ? shellQuote(first) : `${host.daemon_command[0]} ${shellQuote(
|
|
29003
|
+
const tacho = host.daemon_command[0] === first ? shellQuote(first) : `${host.daemon_command[0]} ${shellQuote(join20(binDir, "tacho.mjs"))}`;
|
|
29084
29004
|
return {
|
|
29085
29005
|
hookCommand: host.hook_command,
|
|
29086
29006
|
credentialHelperCommand: helperCommandFor(tacho),
|
|
@@ -29302,7 +29222,7 @@ function enrollTarget(options, paths, mint) {
|
|
|
29302
29222
|
const [only] = held;
|
|
29303
29223
|
if (only !== void 0) return { paths: only.paths, fresh: false };
|
|
29304
29224
|
const retired = listAgents(paths).filter(
|
|
29305
|
-
(agent) => !
|
|
29225
|
+
(agent) => !agentIsLive(agent) && harnesses.some((harness) => agent.host?.harnesses.includes(harness))
|
|
29306
29226
|
).at(-1);
|
|
29307
29227
|
if (retired !== void 0) return { paths: retired.paths, fresh: false };
|
|
29308
29228
|
if (!existsSync16(paths.hostFile))
|
|
@@ -31241,26 +31161,26 @@ import {
|
|
|
31241
31161
|
readFileSync as readFileSync14,
|
|
31242
31162
|
readlinkSync as readlinkSync3,
|
|
31243
31163
|
realpathSync as realpathSync2,
|
|
31244
|
-
rmdirSync as
|
|
31164
|
+
rmdirSync as rmdirSync6,
|
|
31245
31165
|
rmSync as rmSync4,
|
|
31246
|
-
statSync as
|
|
31166
|
+
statSync as statSync8,
|
|
31247
31167
|
unlinkSync as unlinkSync11
|
|
31248
31168
|
} from "node:fs";
|
|
31249
|
-
import { dirname as dirname14, isAbsolute as isAbsolute2, join as
|
|
31169
|
+
import { dirname as dirname14, isAbsolute as isAbsolute2, join as join21, relative, resolve as resolve7, sep } from "node:path";
|
|
31250
31170
|
function dataLocalDir(home, env, platform) {
|
|
31251
31171
|
if (platform === "darwin")
|
|
31252
|
-
return
|
|
31172
|
+
return join21(home, "Library", "Application Support");
|
|
31253
31173
|
if (platform === "win32")
|
|
31254
|
-
return env["LOCALAPPDATA"] ??
|
|
31174
|
+
return env["LOCALAPPDATA"] ?? join21(home, "AppData", "Local");
|
|
31255
31175
|
const xdg = env["XDG_DATA_HOME"];
|
|
31256
|
-
return xdg !== void 0 && isAbsolute2(xdg) ? xdg :
|
|
31176
|
+
return xdg !== void 0 && isAbsolute2(xdg) ? xdg : join21(home, ".local", "share");
|
|
31257
31177
|
}
|
|
31258
31178
|
function desktopPlaces(deps) {
|
|
31259
|
-
const oxagenDir =
|
|
31179
|
+
const oxagenDir = join21(deps.home, ".config", "oxagen");
|
|
31260
31180
|
return {
|
|
31261
31181
|
oxagenDir,
|
|
31262
|
-
desktopConfig:
|
|
31263
|
-
copies:
|
|
31182
|
+
desktopConfig: join21(oxagenDir, "desktop.json"),
|
|
31183
|
+
copies: join21(
|
|
31264
31184
|
dataLocalDir(deps.home, deps.env, deps.platform),
|
|
31265
31185
|
"oxagen",
|
|
31266
31186
|
"bin"
|
|
@@ -31400,7 +31320,7 @@ function removeFile(path2, tally2, note = "") {
|
|
|
31400
31320
|
function removeDirIfEmpty(dir) {
|
|
31401
31321
|
try {
|
|
31402
31322
|
if (readdirSync9(dir).length > 0) return false;
|
|
31403
|
-
|
|
31323
|
+
rmdirSync6(dir);
|
|
31404
31324
|
return true;
|
|
31405
31325
|
} catch {
|
|
31406
31326
|
return false;
|
|
@@ -31421,7 +31341,7 @@ function removeProfileBlock(path2, tally2) {
|
|
|
31421
31341
|
if (updated === text5) return;
|
|
31422
31342
|
try {
|
|
31423
31343
|
const real = realpathSync2(path2);
|
|
31424
|
-
writeFileAtomic(real, updated, { mode:
|
|
31344
|
+
writeFileAtomic(real, updated, { mode: statSync8(real).mode & 4095 });
|
|
31425
31345
|
tally2.removed.push(`the Oxagen PATH lines in ${path2}`);
|
|
31426
31346
|
} catch (error) {
|
|
31427
31347
|
tally2.left.push(`cannot rewrite ${path2}: ${reasonOf3(error)}`);
|
|
@@ -31506,7 +31426,7 @@ function undoEntry(entry2, deps, tally2) {
|
|
|
31506
31426
|
}
|
|
31507
31427
|
function versionDirs(copies) {
|
|
31508
31428
|
try {
|
|
31509
|
-
return readdirSync9(copies, { withFileTypes: true }).filter((entry2) => entry2.isDirectory() && !entry2.name.startsWith(".")).map((entry2) =>
|
|
31429
|
+
return readdirSync9(copies, { withFileTypes: true }).filter((entry2) => entry2.isDirectory() && !entry2.name.startsWith(".")).map((entry2) => join21(copies, entry2.name)).sort();
|
|
31510
31430
|
} catch {
|
|
31511
31431
|
return [];
|
|
31512
31432
|
}
|
|
@@ -31542,7 +31462,7 @@ function journaledCopies(journal, copies, tally2) {
|
|
|
31542
31462
|
function removeSidecars(dir, platform, tally2) {
|
|
31543
31463
|
const note = platform === "win32" ? `. Windows keeps a running program's file, so delete ${dir} after this command exits` : "";
|
|
31544
31464
|
for (const name of ["oxagen", "tacho"]) {
|
|
31545
|
-
const file =
|
|
31465
|
+
const file = join21(dir, platform === "win32" ? `${name}.exe` : name);
|
|
31546
31466
|
removeFile(file, tally2, note);
|
|
31547
31467
|
}
|
|
31548
31468
|
}
|
|
@@ -31630,7 +31550,7 @@ async function uninstall(options, deps) {
|
|
|
31630
31550
|
tally2.left.push(`cannot remove ${dir}: ${reasonOf3(error)}`);
|
|
31631
31551
|
}
|
|
31632
31552
|
}
|
|
31633
|
-
const configDir =
|
|
31553
|
+
const configDir = join21(deps.home, ".config");
|
|
31634
31554
|
if (record.configDirCreated && removeDirIfEmpty(configDir))
|
|
31635
31555
|
tally2.removed.push(configDir);
|
|
31636
31556
|
for (const path2 of tally2.removed) deps.out(` removed ${path2}`);
|
|
@@ -32180,109 +32100,13 @@ var init_agent_run = __esm({
|
|
|
32180
32100
|
}
|
|
32181
32101
|
});
|
|
32182
32102
|
|
|
32183
|
-
// ../../packages/tacho/src/cli/move-commands.ts
|
|
32184
|
-
import { posix as posix4, win32 as win325 } from "node:path";
|
|
32185
|
-
function executableName(word) {
|
|
32186
|
-
const base2 = (/^[A-Za-z]:\\|\\/.test(word) ? win325 : posix4).basename(word);
|
|
32187
|
-
return base2.replace(/\.exe$/i, "").toLowerCase();
|
|
32188
|
-
}
|
|
32189
|
-
function namesTachoExecutable(host) {
|
|
32190
|
-
const legacyHook = /(?:^|[\s'"/\\])tacho-hook(?:\.mjs)?(?=$|[\s'"])/i.test(
|
|
32191
|
-
host.hook_command
|
|
32192
|
-
) || /(?:^|[\s'"/\\])tacho(?:-[a-z0-9_]+(?:-[a-z0-9_]+){2,3})?(?:\.exe)?['"]?\s+hook(?=$|\s)/i.test(
|
|
32193
|
-
host.hook_command
|
|
32194
|
-
);
|
|
32195
|
-
const legacyDaemon = host.daemon_command.some((word, index) => {
|
|
32196
|
-
const name = executableName(word);
|
|
32197
|
-
if (name === "tachod" || name === "tachod.mjs") return true;
|
|
32198
|
-
return TACHO_NAME.test(name) && host.daemon_command[index + 1] === "daemon";
|
|
32199
|
-
});
|
|
32200
|
-
return legacyHook || legacyDaemon;
|
|
32201
|
-
}
|
|
32202
|
-
function relocatedHarnessFiles(host, paths) {
|
|
32203
|
-
const recorded = host.harness_files ?? {};
|
|
32204
|
-
const named = (value) => {
|
|
32205
|
-
const files3 = [value].flat().filter((path2) => typeof path2 === "string");
|
|
32206
|
-
return files3.length > 0 ? files3.join(", ") : "(none)";
|
|
32207
|
-
};
|
|
32208
|
-
return Object.entries(harnessFilesRecord(paths)).flatMap(([key, here]) => {
|
|
32209
|
-
const then = recorded[key];
|
|
32210
|
-
return then === void 0 || JSON.stringify(then) === JSON.stringify(here) ? [] : [{ recorded: named(then), here: named(here) }];
|
|
32211
|
-
});
|
|
32212
|
-
}
|
|
32213
|
-
async function currentCredentialMode(host, deps) {
|
|
32214
|
-
if (deps.modelCredentials === void 0) return void 0;
|
|
32215
|
-
const harnesses = host.harnesses.filter(
|
|
32216
|
-
(harness) => MODEL_CREDENTIAL_HARNESSES.includes(harness)
|
|
32217
|
-
);
|
|
32218
|
-
if (harnesses.length === 0) return void 0;
|
|
32219
|
-
const state = await deps.modelCredentials.read({
|
|
32220
|
-
home: deps.home,
|
|
32221
|
-
harnesses,
|
|
32222
|
-
helperCommand: deps.runtime.credentialHelperCommand
|
|
32223
|
-
});
|
|
32224
|
-
return state.harnesses.some((entry2) => entry2.brokered) ? "brokered" : "passthrough";
|
|
32225
|
-
}
|
|
32226
|
-
async function moveOffTachoNames(deps, run3 = enroll) {
|
|
32227
|
-
const runtime = deps.runtime;
|
|
32228
|
-
if (runtime.program !== "oxagen" || runtime.transient !== void 0 || runtime.executableProblem !== void 0)
|
|
32229
|
-
return [];
|
|
32230
|
-
const moved = [];
|
|
32231
|
-
for (const agent of listAgents(deps.paths)) {
|
|
32232
|
-
if (!agentIsLive(agent) || !namesTachoExecutable(agent.host)) continue;
|
|
32233
|
-
const host = agent.host;
|
|
32234
|
-
const relocated = relocatedHarnessFiles(host, agent.paths);
|
|
32235
|
-
if (relocated.length > 0) {
|
|
32236
|
-
deps.err(
|
|
32237
|
-
`${host.agent_key} was enrolled with its harness files at ${relocated.map((file) => file.recorded).join(", ")}, and this command finds them at ${relocated.map((file) => file.here).join(", ")}, so its hooks stay where they are. Run \`oxagen agent enroll\` from a shell that sets the harness homes it was enrolled with, such as CLAUDE_CONFIG_DIR.`
|
|
32238
|
-
);
|
|
32239
|
-
moved.push({
|
|
32240
|
-
agentKey: host.agent_key,
|
|
32241
|
-
from: host.hook_command,
|
|
32242
|
-
ok: false,
|
|
32243
|
-
skipped: "harness_files_elsewhere"
|
|
32244
|
-
});
|
|
32245
|
-
continue;
|
|
32246
|
-
}
|
|
32247
|
-
const own = depsForAgent(deps, agent);
|
|
32248
|
-
const credentials2 = await currentCredentialMode(host, own);
|
|
32249
|
-
const serviceInstalled2 = deps.serviceManager.status().installed;
|
|
32250
|
-
const result2 = await run3(
|
|
32251
|
-
{
|
|
32252
|
-
harnesses: host.harnesses,
|
|
32253
|
-
...credentials2 !== void 0 ? { credentials: credentials2 } : {},
|
|
32254
|
-
...serviceInstalled2 ? {} : { service: false }
|
|
32255
|
-
},
|
|
32256
|
-
own
|
|
32257
|
-
);
|
|
32258
|
-
moved.push({
|
|
32259
|
-
agentKey: host.agent_key,
|
|
32260
|
-
from: host.hook_command,
|
|
32261
|
-
ok: result2.ok
|
|
32262
|
-
});
|
|
32263
|
-
}
|
|
32264
|
-
return moved;
|
|
32265
|
-
}
|
|
32266
|
-
var TACHO_NAME;
|
|
32267
|
-
var init_move_commands = __esm({
|
|
32268
|
-
"../../packages/tacho/src/cli/move-commands.ts"() {
|
|
32269
|
-
"use strict";
|
|
32270
|
-
init_agents();
|
|
32271
|
-
init_host_file();
|
|
32272
|
-
init_agent_deps();
|
|
32273
|
-
init_credential();
|
|
32274
|
-
init_enroll();
|
|
32275
|
-
TACHO_NAME = /^tacho(?:-[a-z0-9_]+(?:-[a-z0-9_]+){2,3})?$/;
|
|
32276
|
-
}
|
|
32277
|
-
});
|
|
32278
|
-
|
|
32279
32103
|
// ../../packages/tacho/src/host/work-orders.ts
|
|
32280
32104
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
32281
|
-
import { join as
|
|
32105
|
+
import { join as join22 } from "node:path";
|
|
32282
32106
|
function orderFile(paths, id2) {
|
|
32283
32107
|
if (!WORK_ORDER_ID_PATTERN.test(id2))
|
|
32284
32108
|
throw new Error(`${JSON.stringify(id2)} is not a work order id`);
|
|
32285
|
-
return
|
|
32109
|
+
return join22(paths.workOrders, `${id2}.json`);
|
|
32286
32110
|
}
|
|
32287
32111
|
function readWorkOrder(paths, id2) {
|
|
32288
32112
|
let raw;
|
|
@@ -32327,7 +32151,7 @@ function removeWorkOrder(paths, id2) {
|
|
|
32327
32151
|
function runningFile(paths, id2) {
|
|
32328
32152
|
if (!WORK_ORDER_ID_PATTERN.test(id2))
|
|
32329
32153
|
throw new Error(`${JSON.stringify(id2)} is not a work order id`);
|
|
32330
|
-
return
|
|
32154
|
+
return join22(paths.workOrders, `${id2}.running`);
|
|
32331
32155
|
}
|
|
32332
32156
|
function processIsAlive(pid) {
|
|
32333
32157
|
try {
|
|
@@ -32751,8 +32575,6 @@ __export(cli_exports, {
|
|
|
32751
32575
|
harnessFileProblems: () => harnessFileProblems,
|
|
32752
32576
|
isCredentialHarness: () => isCredentialHarness,
|
|
32753
32577
|
isNativeBuild: () => isNativeBuild,
|
|
32754
|
-
moveOffTachoNames: () => moveOffTachoNames,
|
|
32755
|
-
namesTachoExecutable: () => namesTachoExecutable,
|
|
32756
32578
|
needsClaudeCodeMcp: () => needsClaudeCodeMcp,
|
|
32757
32579
|
observedTiers: () => observedTiers,
|
|
32758
32580
|
oxagenRuntimeCommands: () => oxagenRuntimeCommands,
|
|
@@ -32820,7 +32642,6 @@ var init_cli = __esm({
|
|
|
32820
32642
|
init_verify();
|
|
32821
32643
|
init_run();
|
|
32822
32644
|
init_agent_run();
|
|
32823
|
-
init_move_commands();
|
|
32824
32645
|
init_work();
|
|
32825
32646
|
}
|
|
32826
32647
|
});
|
|
@@ -36612,7 +36433,7 @@ var init_bridge = __esm({
|
|
|
36612
36433
|
|
|
36613
36434
|
// ../../packages/tacho/src/contained/workspace.ts
|
|
36614
36435
|
import { lstatSync as lstatSync6, readFileSync as readFileSync15, readdirSync as readdirSync11, realpathSync as realpathSync3 } from "node:fs";
|
|
36615
|
-
import { isAbsolute as isAbsolute3, join as
|
|
36436
|
+
import { isAbsolute as isAbsolute3, join as join23, relative as relative2, resolve as resolve9, sep as sep2 } from "node:path";
|
|
36616
36437
|
function within(root, path2) {
|
|
36617
36438
|
const rel = relative2(root, path2);
|
|
36618
36439
|
return rel === "" || !isAbsolute3(rel) && rel !== ".." && !rel.startsWith(`..${sep2}`);
|
|
@@ -36643,7 +36464,7 @@ function validateContainedWorkspace(workspace, sessionDirectory, mountInfo = rea
|
|
|
36643
36464
|
throw new Error(
|
|
36644
36465
|
"Remove local credential files from the contained checkout before launch"
|
|
36645
36466
|
);
|
|
36646
|
-
const path2 =
|
|
36467
|
+
const path2 = join23(directory, entry2);
|
|
36647
36468
|
const stat6 = lstatSync6(path2);
|
|
36648
36469
|
if (stat6.isSymbolicLink()) {
|
|
36649
36470
|
let target2;
|
|
@@ -36797,7 +36618,7 @@ import {
|
|
|
36797
36618
|
writeFileSync as writeFileSync2
|
|
36798
36619
|
} from "node:fs";
|
|
36799
36620
|
import { tmpdir } from "node:os";
|
|
36800
|
-
import { isAbsolute as isAbsolute4, join as
|
|
36621
|
+
import { isAbsolute as isAbsolute4, join as join24 } from "node:path";
|
|
36801
36622
|
import { promisify } from "node:util";
|
|
36802
36623
|
async function launchContainedAgent(options) {
|
|
36803
36624
|
validateContainedArguments(options.request.harness, options.request.args);
|
|
@@ -36830,7 +36651,7 @@ async function launchContainedAgent(options) {
|
|
|
36830
36651
|
if (digest7 === void 0)
|
|
36831
36652
|
throw new Error("The operator's contained image is not installed");
|
|
36832
36653
|
const sessionId = `contained-${randomBytes8(16).toString("hex")}`;
|
|
36833
|
-
const directory = mkdtempSync(
|
|
36654
|
+
const directory = mkdtempSync(join24(tmpdir(), "oxagen-contained-"));
|
|
36834
36655
|
chmodSync6(directory, 448);
|
|
36835
36656
|
let prepared;
|
|
36836
36657
|
let containerCreated = false;
|
|
@@ -36850,7 +36671,7 @@ async function launchContainedAgent(options) {
|
|
|
36850
36671
|
for (const [name2, contents] of entries2) {
|
|
36851
36672
|
if (!/^[a-z0-9.-]+$/.test(name2))
|
|
36852
36673
|
throw new Error("Invalid contained configuration filename");
|
|
36853
|
-
writeFileSync2(
|
|
36674
|
+
writeFileSync2(join24(directory, name2), contents, {
|
|
36854
36675
|
mode: 256,
|
|
36855
36676
|
flag: "wx"
|
|
36856
36677
|
});
|
|
@@ -37238,7 +37059,7 @@ var init_privilege = __esm({
|
|
|
37238
37059
|
|
|
37239
37060
|
// ../../packages/tacho/src/contained/sandbox/launcher.ts
|
|
37240
37061
|
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
37241
|
-
import { join as
|
|
37062
|
+
import { join as join25 } from "node:path";
|
|
37242
37063
|
function shellQuote2(value) {
|
|
37243
37064
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
37244
37065
|
}
|
|
@@ -37328,7 +37149,7 @@ async function launchSandboxAgent(options) {
|
|
|
37328
37149
|
{ ...asAgent, cwd: SANDBOX_AGENT_HOME, timeoutMs: 15 * 6e4 }
|
|
37329
37150
|
);
|
|
37330
37151
|
for (const [name, contents] of Object.entries(claudeCodeUserState())) {
|
|
37331
|
-
const path2 =
|
|
37152
|
+
const path2 = join25(SANDBOX_AGENT_HOME, name);
|
|
37332
37153
|
system.writeFile(path2, contents, 384);
|
|
37333
37154
|
system.chown(path2, SANDBOX_AGENT_UID, SANDBOX_AGENT_GID);
|
|
37334
37155
|
}
|
|
@@ -37457,9 +37278,9 @@ import {
|
|
|
37457
37278
|
chmodSync as chmodSync7,
|
|
37458
37279
|
chownSync as chownSync2,
|
|
37459
37280
|
existsSync as existsSync17,
|
|
37460
|
-
mkdirSync as
|
|
37281
|
+
mkdirSync as mkdirSync7,
|
|
37461
37282
|
readFileSync as readFileSync16,
|
|
37462
|
-
statSync as
|
|
37283
|
+
statSync as statSync9,
|
|
37463
37284
|
writeFileSync as writeFileSync3
|
|
37464
37285
|
} from "node:fs";
|
|
37465
37286
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -37507,7 +37328,7 @@ var init_system = __esm({
|
|
|
37507
37328
|
exists: (path2) => existsSync17(path2),
|
|
37508
37329
|
stat: (path2) => {
|
|
37509
37330
|
try {
|
|
37510
|
-
const found =
|
|
37331
|
+
const found = statSync9(path2);
|
|
37511
37332
|
return {
|
|
37512
37333
|
uid: found.uid,
|
|
37513
37334
|
gid: found.gid,
|
|
@@ -37525,7 +37346,7 @@ var init_system = __esm({
|
|
|
37525
37346
|
chmodSync7(path2, mode);
|
|
37526
37347
|
},
|
|
37527
37348
|
mkdir: (path2, mode) => {
|
|
37528
|
-
|
|
37349
|
+
mkdirSync7(path2, { recursive: true, mode });
|
|
37529
37350
|
chmodSync7(path2, mode);
|
|
37530
37351
|
},
|
|
37531
37352
|
chown: (path2, uid, gid) => chownSync2(path2, uid, gid)
|
|
@@ -37534,10 +37355,10 @@ var init_system = __esm({
|
|
|
37534
37355
|
});
|
|
37535
37356
|
|
|
37536
37357
|
// ../../packages/tacho/src/contained/runner.ts
|
|
37537
|
-
import { join as
|
|
37358
|
+
import { join as join26 } from "node:path";
|
|
37538
37359
|
function containedHookEnv(harness, workspace) {
|
|
37539
|
-
const home =
|
|
37540
|
-
return harness === "codex" ? { CODEX_HOME:
|
|
37360
|
+
const home = join26(workspace, ".oxagen-contained", "home");
|
|
37361
|
+
return harness === "codex" ? { CODEX_HOME: join26(home, ".codex") } : { CLAUDE_CONFIG_DIR: join26(home, ".claude") };
|
|
37541
37362
|
}
|
|
37542
37363
|
function containedLaunchEndpoint(host) {
|
|
37543
37364
|
const ingest = new URL(host.endpoints.ingest);
|
|
@@ -37733,7 +37554,7 @@ function createContainedRunner(options) {
|
|
|
37733
37554
|
sessionUuid2 = started.recorder.sessionUuid;
|
|
37734
37555
|
active2.set(sessionUuid2, controller);
|
|
37735
37556
|
const bridge = await startContainedBridge({
|
|
37736
|
-
socketPath:
|
|
37557
|
+
socketPath: join26(directory, "bridge.sock"),
|
|
37737
37558
|
...bridgeRoutes({
|
|
37738
37559
|
sessionId,
|
|
37739
37560
|
workspace,
|
|
@@ -37817,7 +37638,7 @@ function createContainedRunner(options) {
|
|
|
37817
37638
|
const abort = () => controller.abort();
|
|
37818
37639
|
signal?.addEventListener("abort", abort, { once: true });
|
|
37819
37640
|
if (signal?.aborted) abort();
|
|
37820
|
-
const env = { CLAUDE_CONFIG_DIR:
|
|
37641
|
+
const env = { CLAUDE_CONFIG_DIR: join26(SANDBOX_AGENT_HOME, ".claude") };
|
|
37821
37642
|
let sessionUuid2;
|
|
37822
37643
|
let launchedSessionId;
|
|
37823
37644
|
let opened = false;
|
|
@@ -37952,7 +37773,7 @@ var init_runner = __esm({
|
|
|
37952
37773
|
|
|
37953
37774
|
// ../../packages/tacho/src/collector/detector.ts
|
|
37954
37775
|
import { promises as fs3 } from "node:fs";
|
|
37955
|
-
import { basename as
|
|
37776
|
+
import { basename as basename5, join as join27 } from "node:path";
|
|
37956
37777
|
async function eachLimited(items, limit, task) {
|
|
37957
37778
|
let next = 0;
|
|
37958
37779
|
const workers = Array.from(
|
|
@@ -37978,7 +37799,7 @@ async function scanProject(dir) {
|
|
|
37978
37799
|
await eachLimited(names2, SCAN_CONCURRENCY, async (name) => {
|
|
37979
37800
|
const match = SESSION_FILE.exec(name);
|
|
37980
37801
|
if (match === null) return;
|
|
37981
|
-
const path2 =
|
|
37802
|
+
const path2 = join27(dir, name);
|
|
37982
37803
|
try {
|
|
37983
37804
|
const st = await fs3.stat(path2);
|
|
37984
37805
|
out.push({ sessionId: match[1], path: path2, mtimeMs: st.mtimeMs });
|
|
@@ -38019,7 +37840,7 @@ var init_detector = __esm({
|
|
|
38019
37840
|
continue;
|
|
38020
37841
|
}
|
|
38021
37842
|
await eachLimited(names2, SCAN_CONCURRENCY, async (name) => {
|
|
38022
|
-
const dir =
|
|
37843
|
+
const dir = join27(root, name);
|
|
38023
37844
|
try {
|
|
38024
37845
|
const st = await fs3.stat(dir);
|
|
38025
37846
|
if (st.isDirectory()) dirs.push({ dir, mtimeMs: st.mtimeMs });
|
|
@@ -38258,7 +38079,7 @@ var init_detector = __esm({
|
|
|
38258
38079
|
transcript_path: transcript.path,
|
|
38259
38080
|
transcript_mtime: new Date(transcript.mtimeMs).toISOString(),
|
|
38260
38081
|
claude_pids: processes.map((p) => p.pid),
|
|
38261
|
-
project:
|
|
38082
|
+
project: basename5(join27(transcript.path, ".."))
|
|
38262
38083
|
}
|
|
38263
38084
|
})
|
|
38264
38085
|
);
|
|
@@ -38676,7 +38497,7 @@ import {
|
|
|
38676
38497
|
rm,
|
|
38677
38498
|
unlink
|
|
38678
38499
|
} from "node:fs/promises";
|
|
38679
|
-
import { dirname as dirname16, join as
|
|
38500
|
+
import { dirname as dirname16, join as join28 } from "node:path";
|
|
38680
38501
|
async function statOf(absolutePath) {
|
|
38681
38502
|
try {
|
|
38682
38503
|
const info = await lstat(absolutePath);
|
|
@@ -38716,7 +38537,7 @@ async function contentHash(absolutePath, kind, keep) {
|
|
|
38716
38537
|
if (keep !== void 0) {
|
|
38717
38538
|
try {
|
|
38718
38539
|
await mkdir(keep.dir, { recursive: true, mode: 448 });
|
|
38719
|
-
const temp2 =
|
|
38540
|
+
const temp2 = join28(keep.dir, `.partial-${randomUUID3()}`);
|
|
38720
38541
|
copy = {
|
|
38721
38542
|
temp: temp2,
|
|
38722
38543
|
handle: await open3(temp2, "wx", keep.executable ? 448 : 384)
|
|
@@ -38760,7 +38581,7 @@ async function settleCopy(temp, name) {
|
|
|
38760
38581
|
if (temp === void 0) return;
|
|
38761
38582
|
if (name !== void 0)
|
|
38762
38583
|
try {
|
|
38763
|
-
await rename(temp,
|
|
38584
|
+
await rename(temp, join28(dirname16(temp), name));
|
|
38764
38585
|
return;
|
|
38765
38586
|
} catch {
|
|
38766
38587
|
}
|
|
@@ -38776,7 +38597,7 @@ async function copiedBytes(dir) {
|
|
|
38776
38597
|
let total2 = 0;
|
|
38777
38598
|
for (const name of names2) {
|
|
38778
38599
|
try {
|
|
38779
|
-
total2 += (await lstat(
|
|
38600
|
+
total2 += (await lstat(join28(dir, name))).size;
|
|
38780
38601
|
} catch {
|
|
38781
38602
|
}
|
|
38782
38603
|
}
|
|
@@ -38792,7 +38613,7 @@ async function removeCopiesOutside(root, live) {
|
|
|
38792
38613
|
const keep = new Set(live());
|
|
38793
38614
|
await Promise.all(
|
|
38794
38615
|
names2.filter((name) => !keep.has(name)).map(
|
|
38795
|
-
(name) => rm(
|
|
38616
|
+
(name) => rm(join28(root, name), { recursive: true, force: true }).catch(
|
|
38796
38617
|
() => void 0
|
|
38797
38618
|
)
|
|
38798
38619
|
)
|
|
@@ -38900,7 +38721,7 @@ async function contributionOf(exec4, cwd, root, repoRelative, entry2, copies) {
|
|
|
38900
38721
|
let copy = null;
|
|
38901
38722
|
if (entry2 !== null) {
|
|
38902
38723
|
if (copies === void 0 || !COPY_NAME.test(entry2[0])) return void 0;
|
|
38903
|
-
copy =
|
|
38724
|
+
copy = join28(copies, entry2[0]);
|
|
38904
38725
|
const kept = await statOf(copy);
|
|
38905
38726
|
if (kept === void 0 || kept === "absent" || kept.kind !== "file")
|
|
38906
38727
|
return void 0;
|
|
@@ -39298,7 +39119,7 @@ var init_session_changes = __esm({
|
|
|
39298
39119
|
});
|
|
39299
39120
|
|
|
39300
39121
|
// ../../packages/tacho/src/collector/session-commits.ts
|
|
39301
|
-
import { join as
|
|
39122
|
+
import { join as join29 } from "node:path";
|
|
39302
39123
|
function parseMeta(stdout) {
|
|
39303
39124
|
const out = [];
|
|
39304
39125
|
for (const record of stdout.split("\0")) {
|
|
@@ -39435,7 +39256,7 @@ async function readSessionCommits(exec4, cwd, input) {
|
|
|
39435
39256
|
const test = input.tests[commit.sha];
|
|
39436
39257
|
const toolUseId = callAt(times.get(commit.sha), calls);
|
|
39437
39258
|
const written = input.written;
|
|
39438
|
-
const outside = merge || written === void 0 || root === void 0 ? void 0 : files3.some((file) => !written.has(
|
|
39259
|
+
const outside = merge || written === void 0 || root === void 0 ? void 0 : files3.some((file) => !written.has(join29(root, file.path)));
|
|
39439
39260
|
return {
|
|
39440
39261
|
sha: commit.sha,
|
|
39441
39262
|
parent_shas: commit.parents.slice(0, MAX_COMMIT_PARENTS),
|
|
@@ -39481,7 +39302,7 @@ var init_session_commits = __esm({
|
|
|
39481
39302
|
|
|
39482
39303
|
// ../../packages/tacho/src/collector/worktree-snapshot.ts
|
|
39483
39304
|
import { lstat as lstat2 } from "node:fs/promises";
|
|
39484
|
-
import { join as
|
|
39305
|
+
import { join as join30 } from "node:path";
|
|
39485
39306
|
function headerPath(prefix, path2) {
|
|
39486
39307
|
const name = `${prefix}${path2}`;
|
|
39487
39308
|
let quoted3 = false;
|
|
@@ -39556,7 +39377,7 @@ async function worktreeFingerprint(status2, root) {
|
|
|
39556
39377
|
const path2 = statusPath(record);
|
|
39557
39378
|
if (path2 === null) return "";
|
|
39558
39379
|
try {
|
|
39559
|
-
const info = await lstat2(
|
|
39380
|
+
const info = await lstat2(join30(root, path2));
|
|
39560
39381
|
return `${info.size}:${info.mtimeMs}:${info.ctimeMs}`;
|
|
39561
39382
|
} catch {
|
|
39562
39383
|
return "absent";
|
|
@@ -39662,7 +39483,7 @@ async function readWorktreeSnapshot(exec4, cwd, baseline, measured) {
|
|
|
39662
39483
|
}
|
|
39663
39484
|
let present;
|
|
39664
39485
|
try {
|
|
39665
|
-
present = (await lstat2(
|
|
39486
|
+
present = (await lstat2(join30(root, path2))).isFile();
|
|
39666
39487
|
} catch {
|
|
39667
39488
|
present = false;
|
|
39668
39489
|
}
|
|
@@ -39763,10 +39584,10 @@ var init_worktree_snapshot = __esm({
|
|
|
39763
39584
|
});
|
|
39764
39585
|
|
|
39765
39586
|
// ../../packages/tacho/src/collector/git-lane.ts
|
|
39766
|
-
import { join as
|
|
39587
|
+
import { join as join31 } from "node:path";
|
|
39767
39588
|
function copiesDirOf(root, session) {
|
|
39768
39589
|
const uuid = session.recorder.sessionUuid;
|
|
39769
|
-
return /^[0-9a-f-]{36}$/i.test(uuid) ?
|
|
39590
|
+
return /^[0-9a-f-]{36}$/i.test(uuid) ? join31(root, uuid) : void 0;
|
|
39770
39591
|
}
|
|
39771
39592
|
function holdsBaseline(session) {
|
|
39772
39593
|
return session.baselineCommit !== void 0 || Object.keys(session.baselines ?? {}).length > 0;
|
|
@@ -42758,7 +42579,7 @@ var init_hook_queues = __esm({
|
|
|
42758
42579
|
});
|
|
42759
42580
|
|
|
42760
42581
|
// ../../packages/tacho/src/collector/memory-capture/memory-reader.ts
|
|
42761
|
-
import { isAbsolute as isAbsolute7, join as
|
|
42582
|
+
import { isAbsolute as isAbsolute7, join as join32, sep as sep4 } from "node:path";
|
|
42762
42583
|
function claudeCodeLocation(projectsDir, memoryDir) {
|
|
42763
42584
|
return {
|
|
42764
42585
|
harness: "claude-code",
|
|
@@ -42770,13 +42591,13 @@ function claudeCodeLocation(projectsDir, memoryDir) {
|
|
|
42770
42591
|
}
|
|
42771
42592
|
function claudeCodeMemoryLocations(configDir, projectDirs = []) {
|
|
42772
42593
|
const locations = [
|
|
42773
|
-
claudeCodeLocation(() =>
|
|
42774
|
-
claudeCodeLocation(() =>
|
|
42594
|
+
claudeCodeLocation(() => join32(configDir, "projects"), "memory"),
|
|
42595
|
+
claudeCodeLocation(() => join32(configDir, "agent-memory"), "")
|
|
42775
42596
|
];
|
|
42776
42597
|
for (const dir of projectDirs.slice(0, MEMORY_PROJECT_DIRS_MAX))
|
|
42777
42598
|
locations.push(
|
|
42778
|
-
claudeCodeLocation(() =>
|
|
42779
|
-
claudeCodeLocation(() =>
|
|
42599
|
+
claudeCodeLocation(() => join32(dir, ".claude", "agent-memory"), ""),
|
|
42600
|
+
claudeCodeLocation(() => join32(dir, ".claude", "agent-memory-local"), "")
|
|
42780
42601
|
);
|
|
42781
42602
|
return locations;
|
|
42782
42603
|
}
|
|
@@ -42955,13 +42776,13 @@ function createMemoryReader(deps) {
|
|
|
42955
42776
|
const projects = await list(top);
|
|
42956
42777
|
let complete = projects.complete;
|
|
42957
42778
|
for (const project2 of projects.names) {
|
|
42958
|
-
const dir = location.memoryDir === "" ?
|
|
42779
|
+
const dir = location.memoryDir === "" ? join32(top, project2) : join32(top, project2, location.memoryDir);
|
|
42959
42780
|
const files3 = await list(dir);
|
|
42960
42781
|
if (!files3.complete) complete = false;
|
|
42961
42782
|
for (const name of files3.names) {
|
|
42962
42783
|
if (!name.endsWith(location.extension)) continue;
|
|
42963
42784
|
if (location.skip.includes(name)) continue;
|
|
42964
|
-
const path2 =
|
|
42785
|
+
const path2 = join32(dir, name);
|
|
42965
42786
|
const file = await readAt2(location.harness, path2);
|
|
42966
42787
|
if (file.kind === "absent" || file.kind === "empty") continue;
|
|
42967
42788
|
paths.push(path2);
|
|
@@ -43047,8 +42868,8 @@ var init_memory_reader = __esm({
|
|
|
43047
42868
|
MEMORY_TYPE_PATTERN = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
43048
42869
|
MEMORY_PROJECT_DIRS_MAX = 200;
|
|
43049
42870
|
HARNESS_MEMORY_LOCATIONS = [
|
|
43050
|
-
claudeCodeLocation((home) =>
|
|
43051
|
-
claudeCodeLocation((home) =>
|
|
42871
|
+
claudeCodeLocation((home) => join32(home, ".claude", "projects"), "memory"),
|
|
42872
|
+
claudeCodeLocation((home) => join32(home, ".claude", "agent-memory"), "")
|
|
43052
42873
|
];
|
|
43053
42874
|
FRONTMATTER = /^---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/;
|
|
43054
42875
|
FRONTMATTER_LINE = /^([ \t]*)([A-Za-z_][\w-]*)[ \t]*:[ \t]*(.*)$/;
|
|
@@ -43534,17 +43355,17 @@ var init_memory_upload = __esm({
|
|
|
43534
43355
|
});
|
|
43535
43356
|
|
|
43536
43357
|
// ../../packages/tacho/src/collector/memory-capture/memory-uses.ts
|
|
43537
|
-
import { basename as
|
|
43358
|
+
import { basename as basename6, dirname as dirname18, isAbsolute as isAbsolute8, join as join33, resolve as resolve12 } from "node:path";
|
|
43538
43359
|
function memoryFileOf(path2, locations, home) {
|
|
43539
43360
|
if (!isAbsolute8(path2)) return void 0;
|
|
43540
43361
|
const file = resolve12(path2);
|
|
43541
|
-
const name =
|
|
43362
|
+
const name = basename6(file);
|
|
43542
43363
|
const folder = dirname18(file);
|
|
43543
43364
|
for (const location of locations) {
|
|
43544
43365
|
if (!name.endsWith(location.extension)) continue;
|
|
43545
43366
|
if (location.skip.includes(name)) continue;
|
|
43546
43367
|
const projectDir = location.memoryDir === "" ? folder : dirname18(folder);
|
|
43547
|
-
if (location.memoryDir !== "" &&
|
|
43368
|
+
if (location.memoryDir !== "" && basename6(folder) !== location.memoryDir)
|
|
43548
43369
|
continue;
|
|
43549
43370
|
if (dirname18(projectDir) !== resolve12(location.projectsDir(home))) continue;
|
|
43550
43371
|
return { harness: location.harness, path: file };
|
|
@@ -43552,7 +43373,7 @@ function memoryFileOf(path2, locations, home) {
|
|
|
43552
43373
|
return void 0;
|
|
43553
43374
|
}
|
|
43554
43375
|
function pathOf(word, cwd, home) {
|
|
43555
|
-
const expanded = /^(?:~|\$HOME|\$\{HOME\})\//.test(word) ?
|
|
43376
|
+
const expanded = /^(?:~|\$HOME|\$\{HOME\})\//.test(word) ? join33(home, word.slice(word.indexOf("/") + 1)) : word;
|
|
43556
43377
|
if (isAbsolute8(expanded)) return expanded;
|
|
43557
43378
|
if (cwd !== void 0 && isAbsolute8(cwd)) return resolve12(cwd, expanded);
|
|
43558
43379
|
return void 0;
|
|
@@ -43829,7 +43650,7 @@ ${use.path}`;
|
|
|
43829
43650
|
|
|
43830
43651
|
// ../../packages/tacho/src/collector/memory-capture/stella-store.ts
|
|
43831
43652
|
import { createRequire as createRequire3 } from "node:module";
|
|
43832
|
-
import { dirname as dirname19, isAbsolute as isAbsolute9, join as
|
|
43653
|
+
import { dirname as dirname19, isAbsolute as isAbsolute9, join as join34, resolve as resolve13 } from "node:path";
|
|
43833
43654
|
function sqlite2() {
|
|
43834
43655
|
sqliteModule2 ??= createRequire3(import.meta.url)(
|
|
43835
43656
|
"node:sqlite"
|
|
@@ -43932,7 +43753,7 @@ async function stellaStoreOf(dir, exists) {
|
|
|
43932
43753
|
if (!isAbsolute9(dir)) return void 0;
|
|
43933
43754
|
let at = resolve13(dir);
|
|
43934
43755
|
for (let depth = 0; depth < WORKSPACE_SEARCH_DEPTH; depth += 1) {
|
|
43935
|
-
const candidate =
|
|
43756
|
+
const candidate = join34(at, STELLA_CONTEXT_DB);
|
|
43936
43757
|
if (await exists(candidate)) return candidate;
|
|
43937
43758
|
const up = dirname19(at);
|
|
43938
43759
|
if (up === at) return void 0;
|
|
@@ -43945,7 +43766,7 @@ var init_stella_store = __esm({
|
|
|
43945
43766
|
"../../packages/tacho/src/collector/memory-capture/stella-store.ts"() {
|
|
43946
43767
|
"use strict";
|
|
43947
43768
|
init_memory_reader();
|
|
43948
|
-
STELLA_CONTEXT_DB =
|
|
43769
|
+
STELLA_CONTEXT_DB = join34(".stella", "private", "context.db");
|
|
43949
43770
|
STELLA_MEMORIES_VIEW = "export_memories_v1";
|
|
43950
43771
|
STELLA_USES_VIEW = "export_memory_uses_v1";
|
|
43951
43772
|
STELLA_USES_PER_READ = 5e3;
|
|
@@ -44576,7 +44397,7 @@ var init_cloud_link = __esm({
|
|
|
44576
44397
|
});
|
|
44577
44398
|
|
|
44578
44399
|
// ../../packages/tacho/src/collector/local-servers/digest.ts
|
|
44579
|
-
import { join as
|
|
44400
|
+
import { join as join35 } from "node:path";
|
|
44580
44401
|
function objectOf(value) {
|
|
44581
44402
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
44582
44403
|
}
|
|
@@ -44606,7 +44427,7 @@ function npmNameSegment(name) {
|
|
|
44606
44427
|
return name.startsWith("@") ? `@${encodeURIComponent(name.slice(1))}` : encodeURIComponent(name);
|
|
44607
44428
|
}
|
|
44608
44429
|
async function whichOnPath(command2, pathValue, search) {
|
|
44609
|
-
const candidates = command2.includes("/") || command2.includes("\\") ? [command2] : (pathValue ?? "").split(search.delimiter).filter((dir) => dir.length > 0).map((dir) =>
|
|
44430
|
+
const candidates = command2.includes("/") || command2.includes("\\") ? [command2] : (pathValue ?? "").split(search.delimiter).filter((dir) => dir.length > 0).map((dir) => join35(dir, command2));
|
|
44610
44431
|
for (const candidate of candidates) {
|
|
44611
44432
|
for (const extension of search.extensions) {
|
|
44612
44433
|
if (await search.isExecutable(candidate + extension))
|
|
@@ -45748,7 +45569,7 @@ var init_codec = __esm({
|
|
|
45748
45569
|
import { createHash as createHash13 } from "node:crypto";
|
|
45749
45570
|
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rm as rm2, writeFile } from "node:fs/promises";
|
|
45750
45571
|
import { homedir as homedir5 } from "node:os";
|
|
45751
|
-
import { dirname as dirname20, join as
|
|
45572
|
+
import { dirname as dirname20, join as join36 } from "node:path";
|
|
45752
45573
|
function envDir(env, key) {
|
|
45753
45574
|
const value = env[key];
|
|
45754
45575
|
return value === void 0 || value.trim() === "" ? null : value;
|
|
@@ -45756,17 +45577,17 @@ function envDir(env, key) {
|
|
|
45756
45577
|
function skillsRoot(harness, env = process.env, home = homedir5()) {
|
|
45757
45578
|
switch (harness) {
|
|
45758
45579
|
case "claude-code":
|
|
45759
|
-
return
|
|
45760
|
-
envDir(env, "CLAUDE_CONFIG_DIR") ??
|
|
45580
|
+
return join36(
|
|
45581
|
+
envDir(env, "CLAUDE_CONFIG_DIR") ?? join36(home, ".claude"),
|
|
45761
45582
|
"skills"
|
|
45762
45583
|
);
|
|
45763
45584
|
case "codex": {
|
|
45764
45585
|
const codexHome = envDir(env, "CODEX_HOME");
|
|
45765
|
-
return codexHome === null ?
|
|
45586
|
+
return codexHome === null ? join36(home, ".agents", "skills") : join36(codexHome, "skills");
|
|
45766
45587
|
}
|
|
45767
45588
|
case "stella":
|
|
45768
|
-
return
|
|
45769
|
-
envDir(env, "STELLA_HOME") ??
|
|
45589
|
+
return join36(
|
|
45590
|
+
envDir(env, "STELLA_HOME") ?? join36(home, ".stella"),
|
|
45770
45591
|
"skills"
|
|
45771
45592
|
);
|
|
45772
45593
|
case "cursor":
|
|
@@ -45825,7 +45646,7 @@ async function readMarker(folder) {
|
|
|
45825
45646
|
if (!entries2.includes(SESSION_MARKER)) return { state: "foreign" };
|
|
45826
45647
|
try {
|
|
45827
45648
|
const parsed2 = JSON.parse(
|
|
45828
|
-
await readFile2(
|
|
45649
|
+
await readFile2(join36(folder, SESSION_MARKER), "utf8")
|
|
45829
45650
|
);
|
|
45830
45651
|
return isMarker(parsed2) ? { state: "ours", marker: parsed2 } : { state: "foreign" };
|
|
45831
45652
|
} catch {
|
|
@@ -45843,7 +45664,7 @@ function liveSessions(marker, now) {
|
|
|
45843
45664
|
}
|
|
45844
45665
|
async function writeMarker(folder, marker) {
|
|
45845
45666
|
await writeFile(
|
|
45846
|
-
|
|
45667
|
+
join36(folder, SESSION_MARKER),
|
|
45847
45668
|
`${JSON.stringify(marker, null, 2)}
|
|
45848
45669
|
`
|
|
45849
45670
|
);
|
|
@@ -45851,9 +45672,9 @@ async function writeMarker(folder, marker) {
|
|
|
45851
45672
|
async function writeSkill(folder, skill) {
|
|
45852
45673
|
await rm2(folder, { recursive: true, force: true });
|
|
45853
45674
|
await mkdir2(folder, { recursive: true });
|
|
45854
|
-
await writeFile(
|
|
45675
|
+
await writeFile(join36(folder, "SKILL.md"), skillMarkdown(skill));
|
|
45855
45676
|
for (const file of skill.files) {
|
|
45856
|
-
const target2 =
|
|
45677
|
+
const target2 = join36(folder, file.path);
|
|
45857
45678
|
await mkdir2(dirname20(target2), { recursive: true });
|
|
45858
45679
|
await writeFile(target2, file.content);
|
|
45859
45680
|
}
|
|
@@ -45881,7 +45702,7 @@ async function placeSkills(root, sessionId, skills, now = /* @__PURE__ */ new Da
|
|
|
45881
45702
|
result2.warnings.push(refusal);
|
|
45882
45703
|
continue;
|
|
45883
45704
|
}
|
|
45884
|
-
const folder =
|
|
45705
|
+
const folder = join36(root, skill.name);
|
|
45885
45706
|
if (taken.has(skill.name)) {
|
|
45886
45707
|
result2.skipped.push(skill.name);
|
|
45887
45708
|
result2.warnings.push(
|
|
@@ -45948,7 +45769,7 @@ async function removeSkills(root, sessionId, now = /* @__PURE__ */ new Date()) {
|
|
|
45948
45769
|
throw error;
|
|
45949
45770
|
}
|
|
45950
45771
|
for (const name of names2.sort(compareText)) {
|
|
45951
|
-
const folder =
|
|
45772
|
+
const folder = join36(root, name);
|
|
45952
45773
|
const found = await readMarker(folder);
|
|
45953
45774
|
if (found.state !== "ours") continue;
|
|
45954
45775
|
const sessions = liveSessions(found.marker, now);
|
|
@@ -48944,7 +48765,7 @@ var init_model_proxy_listener = __esm({
|
|
|
48944
48765
|
import {
|
|
48945
48766
|
createServer as createServer5
|
|
48946
48767
|
} from "node:http";
|
|
48947
|
-
import { chmodSync as chmodSync8, existsSync as existsSync19, statSync as
|
|
48768
|
+
import { chmodSync as chmodSync8, existsSync as existsSync19, statSync as statSync10, unlinkSync as unlinkSync12 } from "node:fs";
|
|
48948
48769
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
48949
48770
|
import { createConnection } from "node:net";
|
|
48950
48771
|
function readBody(req) {
|
|
@@ -49227,7 +49048,7 @@ function createRequestHandler(api, log, options = {}) {
|
|
|
49227
49048
|
}
|
|
49228
49049
|
async function removeStaleSocket(socketPath) {
|
|
49229
49050
|
if (!existsSync19(socketPath)) return;
|
|
49230
|
-
if (!
|
|
49051
|
+
if (!statSync10(socketPath).isSocket()) {
|
|
49231
49052
|
throw new Error(`collector socket path is not a socket: ${socketPath}`);
|
|
49232
49053
|
}
|
|
49233
49054
|
const stale = await new Promise((resolve23, reject) => {
|
|
@@ -49335,7 +49156,7 @@ var init_server = __esm({
|
|
|
49335
49156
|
|
|
49336
49157
|
// ../../packages/tacho/src/collector/spool.ts
|
|
49337
49158
|
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "node:fs";
|
|
49338
|
-
import { join as
|
|
49159
|
+
import { join as join37 } from "node:path";
|
|
49339
49160
|
function sessionOwnedElsewhere(error) {
|
|
49340
49161
|
return error.status === 403 && error.body.includes(SESSION_OWNED_ELSEWHERE);
|
|
49341
49162
|
}
|
|
@@ -49495,7 +49316,7 @@ var init_spool = __esm({
|
|
|
49495
49316
|
* gone for good.
|
|
49496
49317
|
*/
|
|
49497
49318
|
stash(event, reason3, body2) {
|
|
49498
|
-
const path2 =
|
|
49319
|
+
const path2 = join37(
|
|
49499
49320
|
this.options.quarantineDir,
|
|
49500
49321
|
`${event.session_uuid}-${String(event.seq).padStart(8, "0")}.json`
|
|
49501
49322
|
);
|
|
@@ -49513,7 +49334,7 @@ var init_spool = __esm({
|
|
|
49513
49334
|
}
|
|
49514
49335
|
/** Add a body to a quarantine record that was written without one. */
|
|
49515
49336
|
stashBodyBeside(event, body2) {
|
|
49516
|
-
const path2 =
|
|
49337
|
+
const path2 = join37(
|
|
49517
49338
|
this.options.quarantineDir,
|
|
49518
49339
|
`${event.session_uuid}-${String(event.seq).padStart(8, "0")}.json`
|
|
49519
49340
|
);
|
|
@@ -50019,14 +49840,14 @@ import {
|
|
|
50019
49840
|
existsSync as existsSync21,
|
|
50020
49841
|
readdirSync as readdirSync12,
|
|
50021
49842
|
readFileSync as readFileSync19,
|
|
50022
|
-
renameSync as
|
|
50023
|
-
statSync as
|
|
49843
|
+
renameSync as renameSync4,
|
|
49844
|
+
statSync as statSync11,
|
|
50024
49845
|
unlinkSync as unlinkSync13,
|
|
50025
49846
|
writeFileSync as writeFileSync4
|
|
50026
49847
|
} from "node:fs";
|
|
50027
49848
|
import { readdir as readdir3, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
50028
49849
|
import { homedir as homedir7, hostname as osHostname2 } from "node:os";
|
|
50029
|
-
import { dirname as dirname21, join as
|
|
49850
|
+
import { dirname as dirname21, join as join38 } from "node:path";
|
|
50030
49851
|
import { execFile as execFile4, spawnSync as spawnSync7 } from "node:child_process";
|
|
50031
49852
|
function cloudGatewayUpstreams(origin = CLOUD_GATEWAY_ORIGIN) {
|
|
50032
49853
|
const base2 = new URL(origin).origin;
|
|
@@ -50316,7 +50137,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
50316
50137
|
processStarts: hookProcessStarts,
|
|
50317
50138
|
adoptedChain: (sessionUuid2) => backfillLedger.chainHead(sessionUuid2)
|
|
50318
50139
|
});
|
|
50319
|
-
const priorStateWrittenAt = existsSync21(paths.daemonState) ?
|
|
50140
|
+
const priorStateWrittenAt = existsSync21(paths.daemonState) ? statSync11(paths.daemonState).mtimeMs : void 0;
|
|
50320
50141
|
const sealedState = parseSealedState(
|
|
50321
50142
|
readJsonStateFile(
|
|
50322
50143
|
paths.daemonSealedState,
|
|
@@ -50653,7 +50474,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
50653
50474
|
controlReachable: lastControlAt !== void 0 && now() - lastControlAt < 2 * timers.bundleRefreshMs
|
|
50654
50475
|
};
|
|
50655
50476
|
}
|
|
50656
|
-
const bodyPurgeOwedPath =
|
|
50477
|
+
const bodyPurgeOwedPath = join38(paths.wal, "body-purge-owed");
|
|
50657
50478
|
function markBodyPurgeOwed(retention, dropped) {
|
|
50658
50479
|
try {
|
|
50659
50480
|
ensureDir(paths.wal);
|
|
@@ -51392,7 +51213,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51392
51213
|
let sessionId;
|
|
51393
51214
|
try {
|
|
51394
51215
|
const file = JSON.parse(
|
|
51395
|
-
readFileSync19(
|
|
51216
|
+
readFileSync19(join38(paths.spool, name), "utf8")
|
|
51396
51217
|
);
|
|
51397
51218
|
const named = file.payload?.session_id;
|
|
51398
51219
|
sessionId = typeof named === "string" ? named : void 0;
|
|
@@ -51537,7 +51358,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51537
51358
|
function setAsideConflictingTerminal(uuid, pending, conflict) {
|
|
51538
51359
|
const name = `${uuid}-terminal-conflict-${String(conflict.seq).padStart(8, "0")}.json`;
|
|
51539
51360
|
writeSensitiveFileAtomic(
|
|
51540
|
-
|
|
51361
|
+
join38(paths.quarantine, name),
|
|
51541
51362
|
JSON.stringify(
|
|
51542
51363
|
{
|
|
51543
51364
|
reason: conflict.message,
|
|
@@ -51616,8 +51437,8 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51616
51437
|
function moveToFailedSpool(path2, name, reason3) {
|
|
51617
51438
|
log(`spool file ${name} moved to spool/failed/: ${reason3}`);
|
|
51618
51439
|
try {
|
|
51619
|
-
ensureDir(
|
|
51620
|
-
|
|
51440
|
+
ensureDir(join38(paths.spool, "failed"));
|
|
51441
|
+
renameSync4(path2, join38(paths.spool, "failed", name));
|
|
51621
51442
|
} catch (error) {
|
|
51622
51443
|
log(
|
|
51623
51444
|
`spool file ${name} could not be moved to spool/failed/: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -51666,7 +51487,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51666
51487
|
continue;
|
|
51667
51488
|
}
|
|
51668
51489
|
reads += 1;
|
|
51669
|
-
const path2 =
|
|
51490
|
+
const path2 = join38(paths.spool, name);
|
|
51670
51491
|
let file;
|
|
51671
51492
|
try {
|
|
51672
51493
|
file = JSON.parse(readFileSync19(path2, "utf8"));
|
|
@@ -51879,7 +51700,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51879
51700
|
let requested;
|
|
51880
51701
|
try {
|
|
51881
51702
|
const file = JSON.parse(
|
|
51882
|
-
await readFile3(
|
|
51703
|
+
await readFile3(join38(paths.spool, name), "utf8")
|
|
51883
51704
|
);
|
|
51884
51705
|
const payload = file.payload;
|
|
51885
51706
|
requested = payload?.hook_event_name === "PreToolUse" && typeof payload.tool_use_id === "string" ? payload.tool_use_id : void 0;
|
|
@@ -52420,9 +52241,9 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
52420
52241
|
let removed = 0;
|
|
52421
52242
|
for (const name of readdirSync12(paths.quarantine)) {
|
|
52422
52243
|
if (!name.endsWith(".json")) continue;
|
|
52423
|
-
const file =
|
|
52244
|
+
const file = join38(paths.quarantine, name);
|
|
52424
52245
|
try {
|
|
52425
|
-
if (at -
|
|
52246
|
+
if (at - statSync11(file).mtimeMs < retainMs) continue;
|
|
52426
52247
|
unlinkSync13(file);
|
|
52427
52248
|
removed += 1;
|
|
52428
52249
|
} catch {
|
|
@@ -52732,7 +52553,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
52732
52553
|
let memoryTimer;
|
|
52733
52554
|
if (options.listen ?? true) {
|
|
52734
52555
|
const codexMemories = createCodexMemoryStore({
|
|
52735
|
-
path:
|
|
52556
|
+
path: join38(dirname21(paths.codexHooks), CODEX_MEMORY_STORE_FILE),
|
|
52736
52557
|
stat: (path2) => stat2(path2),
|
|
52737
52558
|
log
|
|
52738
52559
|
});
|
|
@@ -53106,17 +52927,6 @@ async function runDaemonProcess(options = {}) {
|
|
|
53106
52927
|
process.stderr.write(line);
|
|
53107
52928
|
};
|
|
53108
52929
|
guardDaemonProcess({ stop: stopOnce, exit, log });
|
|
53109
|
-
try {
|
|
53110
|
-
const moved = migrateLegacyLayout(paths);
|
|
53111
|
-
if (moved !== void 0)
|
|
53112
|
-
log(`tachod: moved this machine's enrollment into agents/${moved}
|
|
53113
|
-
`);
|
|
53114
|
-
} catch (error) {
|
|
53115
|
-
log(
|
|
53116
|
-
`tachod: could not move the enrollment into agents/: ${error instanceof Error ? error.message : String(error)}
|
|
53117
|
-
`
|
|
53118
|
-
);
|
|
53119
|
-
}
|
|
53120
52930
|
writeDaemonPid(paths.pid, /* @__PURE__ */ new Date(), process.execPath, ownProcStart());
|
|
53121
52931
|
try {
|
|
53122
52932
|
await startAgents(daemonAgents(paths), daemons, log);
|
|
@@ -53163,53 +52973,6 @@ var init_run2 = __esm({
|
|
|
53163
52973
|
}
|
|
53164
52974
|
});
|
|
53165
52975
|
|
|
53166
|
-
// ../../packages/tacho/src/cli/alias.ts
|
|
53167
|
-
function aliasNotice(executable, argv, stdinIsTTY, env = {}) {
|
|
53168
|
-
if (env["OXAGEN_DESKTOP_SIDECAR"] === "1") return void 0;
|
|
53169
|
-
if (executable === "tachod")
|
|
53170
|
-
return "tachod is now `oxagen daemon`. Run `oxagen agent status` to move this machine's service to the new name.";
|
|
53171
|
-
if (executable === "tacho-hook")
|
|
53172
|
-
return stdinIsTTY ? "tacho-hook is now `oxagen hook`." : void 0;
|
|
53173
|
-
const command2 = argv[2];
|
|
53174
|
-
const replacement = command2 === void 0 ? void 0 : OXAGEN_COMMAND_FOR[command2];
|
|
53175
|
-
if (command2 === void 0 || replacement === void 0)
|
|
53176
|
-
return "tacho is now the `oxagen` CLI. Run `oxagen agent --help` for the commands that replaced it.";
|
|
53177
|
-
if (MACHINE_COMMANDS.has(command2) && !stdinIsTTY) return void 0;
|
|
53178
|
-
return `\`tacho ${command2}\` is now \`${replacement}\`. The old name still works.`;
|
|
53179
|
-
}
|
|
53180
|
-
function printAliasNotice(executable, argv = process.argv, stdinIsTTY = process.stdin.isTTY === true, write = (text5) => {
|
|
53181
|
-
process.stderr.write(text5);
|
|
53182
|
-
}, env = process.env) {
|
|
53183
|
-
const notice = aliasNotice(executable, argv, stdinIsTTY, env);
|
|
53184
|
-
if (notice !== void 0) write(`${notice}
|
|
53185
|
-
`);
|
|
53186
|
-
}
|
|
53187
|
-
var OXAGEN_COMMAND_FOR, MACHINE_COMMANDS;
|
|
53188
|
-
var init_alias = __esm({
|
|
53189
|
-
"../../packages/tacho/src/cli/alias.ts"() {
|
|
53190
|
-
"use strict";
|
|
53191
|
-
OXAGEN_COMMAND_FOR = {
|
|
53192
|
-
enroll: "oxagen agent enroll",
|
|
53193
|
-
status: "oxagen agent status",
|
|
53194
|
-
unenroll: "oxagen agent unenroll",
|
|
53195
|
-
uninstall: "oxagen agent uninstall",
|
|
53196
|
-
reassign: "oxagen agent reassign",
|
|
53197
|
-
export: "oxagen agent export",
|
|
53198
|
-
backfill: "oxagen agent backfill",
|
|
53199
|
-
verify: "oxagen agent verify",
|
|
53200
|
-
run: "oxagen agent run",
|
|
53201
|
-
detect: "oxagen agent detect",
|
|
53202
|
-
daemon: "oxagen daemon",
|
|
53203
|
-
hook: "oxagen hook",
|
|
53204
|
-
"mcp-stdio": "oxagen mcp-stdio",
|
|
53205
|
-
credential: "oxagen credential",
|
|
53206
|
-
github: "oxagen github",
|
|
53207
|
-
arp: "oxagen arp"
|
|
53208
|
-
};
|
|
53209
|
-
MACHINE_COMMANDS = /* @__PURE__ */ new Set(["hook", "mcp-stdio", "credential", "github"]);
|
|
53210
|
-
}
|
|
53211
|
-
});
|
|
53212
|
-
|
|
53213
52976
|
// ../../packages/tacho/src/arp/schema.ts
|
|
53214
52977
|
function safeRelativePath(path2) {
|
|
53215
52978
|
if (!path2 || path2.length > 4096 || /[\\:\x00-\x1f\x7f<>"|?*]/u.test(path2)) {
|
|
@@ -53346,16 +53109,16 @@ import {
|
|
|
53346
53109
|
constants as constants3,
|
|
53347
53110
|
fstatSync as fstatSync2,
|
|
53348
53111
|
lstatSync as lstatSync7,
|
|
53349
|
-
mkdirSync as
|
|
53112
|
+
mkdirSync as mkdirSync8,
|
|
53350
53113
|
openSync as openSync7,
|
|
53351
53114
|
readSync as readSync4,
|
|
53352
53115
|
realpathSync as realpathSync5,
|
|
53353
53116
|
writeFileSync as writeFileSync5
|
|
53354
53117
|
} from "node:fs";
|
|
53355
|
-
import { dirname as dirname22, join as
|
|
53118
|
+
import { dirname as dirname22, join as join39, resolve as resolve15 } from "node:path";
|
|
53356
53119
|
function bundlePath(root, relative10, create2 = false) {
|
|
53357
53120
|
const absolute = resolve15(root);
|
|
53358
|
-
if (create2)
|
|
53121
|
+
if (create2) mkdirSync8(absolute, { recursive: true, mode: 448 });
|
|
53359
53122
|
if (lstatSync7(absolute).isSymbolicLink() || !lstatSync7(absolute).isDirectory()) {
|
|
53360
53123
|
throw new Error("ARP bundle root must be a directory, not a symlink");
|
|
53361
53124
|
}
|
|
@@ -53363,7 +53126,7 @@ function bundlePath(root, relative10, create2 = false) {
|
|
|
53363
53126
|
let current = base2;
|
|
53364
53127
|
const parts = relative10.split("/");
|
|
53365
53128
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
53366
|
-
current =
|
|
53129
|
+
current = join39(current, parts[i2]);
|
|
53367
53130
|
try {
|
|
53368
53131
|
const stat6 = lstatSync7(current);
|
|
53369
53132
|
if (stat6.isSymbolicLink() || i2 < parts.length - 1 && !stat6.isDirectory()) {
|
|
@@ -53371,7 +53134,7 @@ function bundlePath(root, relative10, create2 = false) {
|
|
|
53371
53134
|
}
|
|
53372
53135
|
} catch (error) {
|
|
53373
53136
|
if (error.code !== "ENOENT") throw error;
|
|
53374
|
-
if (create2 && i2 < parts.length - 1)
|
|
53137
|
+
if (create2 && i2 < parts.length - 1) mkdirSync8(current, { mode: 448 });
|
|
53375
53138
|
else if (i2 < parts.length - 1) throw error;
|
|
53376
53139
|
}
|
|
53377
53140
|
}
|
|
@@ -54241,14 +54004,14 @@ import {
|
|
|
54241
54004
|
constants as constants4,
|
|
54242
54005
|
fstatSync as fstatSync3,
|
|
54243
54006
|
lstatSync as lstatSync8,
|
|
54244
|
-
mkdirSync as
|
|
54007
|
+
mkdirSync as mkdirSync9,
|
|
54245
54008
|
openSync as openSync8,
|
|
54246
54009
|
readSync as readSync5,
|
|
54247
54010
|
realpathSync as realpathSync6,
|
|
54248
54011
|
rmSync as rmSync8,
|
|
54249
54012
|
writeFileSync as writeFileSync6
|
|
54250
54013
|
} from "node:fs";
|
|
54251
|
-
import { dirname as dirname23, isAbsolute as isAbsolute11, join as
|
|
54014
|
+
import { dirname as dirname23, isAbsolute as isAbsolute11, join as join40, relative as relative5, resolve as resolve16, sep as sep6 } from "node:path";
|
|
54252
54015
|
function fail2(message) {
|
|
54253
54016
|
throw new Error(`ARP: ${message}`);
|
|
54254
54017
|
}
|
|
@@ -54291,7 +54054,7 @@ function within2(root, path2) {
|
|
|
54291
54054
|
}
|
|
54292
54055
|
function newPath(path2) {
|
|
54293
54056
|
const full = resolve16(path2);
|
|
54294
|
-
return
|
|
54057
|
+
return join40(
|
|
54295
54058
|
realpathSync6(dirname23(full)),
|
|
54296
54059
|
full.slice(dirname23(full).length + 1)
|
|
54297
54060
|
);
|
|
@@ -54307,7 +54070,7 @@ function sourcePath(root, path2) {
|
|
|
54307
54070
|
}
|
|
54308
54071
|
let current = root;
|
|
54309
54072
|
for (const part2 of path2.split("/")) {
|
|
54310
|
-
current =
|
|
54073
|
+
current = join40(current, part2);
|
|
54311
54074
|
if (lstatSync8(current).isSymbolicLink())
|
|
54312
54075
|
fail2("Symlinks require a resource adapter.");
|
|
54313
54076
|
}
|
|
@@ -54371,7 +54134,7 @@ function captureCheckpoint(options) {
|
|
|
54371
54134
|
executable: (file.mode & 73) !== 0
|
|
54372
54135
|
});
|
|
54373
54136
|
}
|
|
54374
|
-
|
|
54137
|
+
mkdirSync9(out, { mode: 448 });
|
|
54375
54138
|
try {
|
|
54376
54139
|
const blob = (value) => storeBlob(out, Buffer.from(jcs(value)), "application/json");
|
|
54377
54140
|
const entries2 = [];
|
|
@@ -54558,16 +54321,16 @@ function prepareCheckpoint(options) {
|
|
|
54558
54321
|
}
|
|
54559
54322
|
return { entry: entry2, bytes: null };
|
|
54560
54323
|
});
|
|
54561
|
-
|
|
54324
|
+
mkdirSync9(destination, { mode: 448 });
|
|
54562
54325
|
try {
|
|
54563
|
-
const restored =
|
|
54564
|
-
|
|
54326
|
+
const restored = join40(destination, "workspace");
|
|
54327
|
+
mkdirSync9(restored, { mode: 448 });
|
|
54565
54328
|
for (const { entry: entry2, bytes } of files3) {
|
|
54566
|
-
const path2 =
|
|
54329
|
+
const path2 = join40(restored, entry2.path);
|
|
54567
54330
|
if (entry2.kind === "directory")
|
|
54568
|
-
|
|
54331
|
+
mkdirSync9(path2, { recursive: true, mode: 448 });
|
|
54569
54332
|
else {
|
|
54570
|
-
|
|
54333
|
+
mkdirSync9(dirname23(path2), { recursive: true, mode: 448 });
|
|
54571
54334
|
if (bytes === null) fail2("Workspace file has no bytes.");
|
|
54572
54335
|
writeFileSync6(path2, bytes, {
|
|
54573
54336
|
flag: "wx",
|
|
@@ -54575,9 +54338,9 @@ function prepareCheckpoint(options) {
|
|
|
54575
54338
|
});
|
|
54576
54339
|
}
|
|
54577
54340
|
}
|
|
54578
|
-
const promptDir =
|
|
54579
|
-
|
|
54580
|
-
const promptFile =
|
|
54341
|
+
const promptDir = join40(restored, ".arp");
|
|
54342
|
+
mkdirSync9(promptDir, { mode: 448 });
|
|
54343
|
+
const promptFile = join40(promptDir, "handoff.json");
|
|
54581
54344
|
const prompt = {
|
|
54582
54345
|
checkpoint_digest: checkpointDigest,
|
|
54583
54346
|
task: task.request,
|
|
@@ -54594,7 +54357,7 @@ function prepareCheckpoint(options) {
|
|
|
54594
54357
|
flag: "wx",
|
|
54595
54358
|
mode: 384
|
|
54596
54359
|
});
|
|
54597
|
-
const reportPath =
|
|
54360
|
+
const reportPath = join40(destination, "report.json");
|
|
54598
54361
|
writeFileSync6(
|
|
54599
54362
|
reportPath,
|
|
54600
54363
|
jcs({
|
|
@@ -55124,7 +54887,6 @@ var init_main = __esm({
|
|
|
55124
54887
|
init_paths();
|
|
55125
54888
|
init_wire();
|
|
55126
54889
|
init_github();
|
|
55127
|
-
init_alias();
|
|
55128
54890
|
init_arp();
|
|
55129
54891
|
init_credential();
|
|
55130
54892
|
init_backfill3();
|
|
@@ -55140,7 +54902,6 @@ var init_main = __esm({
|
|
|
55140
54902
|
init_uninstall();
|
|
55141
54903
|
init_verify();
|
|
55142
54904
|
if (!isNativeBuild() && process.argv[1] !== void 0 && /tacho(\.mjs|\/main\.ts)?$/.test(process.argv[1])) {
|
|
55143
|
-
printAliasNotice("tacho");
|
|
55144
54905
|
main().catch((error) => {
|
|
55145
54906
|
process.stderr.write(
|
|
55146
54907
|
`tacho: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -55176,7 +54937,7 @@ var init_package = __esm({
|
|
|
55176
54937
|
"package.json"() {
|
|
55177
54938
|
package_default = {
|
|
55178
54939
|
name: "@oxagen/cli",
|
|
55179
|
-
version: "2.1.4-
|
|
54940
|
+
version: "2.1.4-679",
|
|
55180
54941
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
55181
54942
|
type: "module",
|
|
55182
54943
|
main: "./dist/index.js",
|
|
@@ -55241,39 +55002,18 @@ var init_package = __esm({
|
|
|
55241
55002
|
}
|
|
55242
55003
|
});
|
|
55243
55004
|
|
|
55244
|
-
// src/commands/retired.ts
|
|
55245
|
-
function printRetiredNotice(what) {
|
|
55246
|
-
process.stderr.write(
|
|
55247
|
-
`${what} was retired when Oxagen became a pure governance plane (docs/adr/ADR-043-runtime-excision.md). Use the \`stella\` CLI with the oxagen MCP server instead.
|
|
55248
|
-
`
|
|
55249
|
-
);
|
|
55250
|
-
process.exitCode = 1;
|
|
55251
|
-
}
|
|
55252
|
-
function printTachoAliasNotice(subcommand, env = process.env) {
|
|
55253
|
-
if (env["OXAGEN_DESKTOP_SIDECAR"] === "1") return;
|
|
55254
|
-
process.stderr.write(
|
|
55255
|
-
// tacho-command-check: alias (this line names the old spelling on purpose)
|
|
55256
|
-
`\`oxagen tacho ${subcommand}\` is now \`oxagen agent ${subcommand}\`. The old name still works.
|
|
55257
|
-
`
|
|
55258
|
-
);
|
|
55259
|
-
}
|
|
55260
|
-
var init_retired = __esm({
|
|
55261
|
-
"src/commands/retired.ts"() {
|
|
55262
|
-
}
|
|
55263
|
-
});
|
|
55264
|
-
|
|
55265
55005
|
// src/lib/atomic-write.ts
|
|
55266
|
-
import { writeFileSync as writeFileSync7, renameSync as
|
|
55267
|
-
import { dirname as dirname24, join as
|
|
55006
|
+
import { writeFileSync as writeFileSync7, renameSync as renameSync5, unlinkSync as unlinkSync15, existsSync as existsSync22 } from "node:fs";
|
|
55007
|
+
import { dirname as dirname24, join as join41 } from "node:path";
|
|
55268
55008
|
function atomicWriteFileSync(path2, data) {
|
|
55269
55009
|
const dir = dirname24(path2);
|
|
55270
|
-
const tmp =
|
|
55010
|
+
const tmp = join41(
|
|
55271
55011
|
dir,
|
|
55272
55012
|
`.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`
|
|
55273
55013
|
);
|
|
55274
55014
|
try {
|
|
55275
55015
|
writeFileSync7(tmp, data, "utf8");
|
|
55276
|
-
|
|
55016
|
+
renameSync5(tmp, path2);
|
|
55277
55017
|
} catch (err2) {
|
|
55278
55018
|
try {
|
|
55279
55019
|
if (existsSync22(tmp)) unlinkSync15(tmp);
|
|
@@ -55289,8 +55029,8 @@ var init_atomic_write = __esm({
|
|
|
55289
55029
|
|
|
55290
55030
|
// src/lib/config.ts
|
|
55291
55031
|
import { homedir as homedir8 } from "os";
|
|
55292
|
-
import { join as
|
|
55293
|
-
import { readFileSync as readFileSync22, mkdirSync as
|
|
55032
|
+
import { join as join42 } from "path";
|
|
55033
|
+
import { readFileSync as readFileSync22, mkdirSync as mkdirSync10, existsSync as existsSync23 } from "fs";
|
|
55294
55034
|
function getConfigDir() {
|
|
55295
55035
|
return CONFIG_DIR;
|
|
55296
55036
|
}
|
|
@@ -55311,7 +55051,7 @@ Run \`oxagen login\` to re-authenticate.
|
|
|
55311
55051
|
function writeConfig(patch) {
|
|
55312
55052
|
const current = readConfig();
|
|
55313
55053
|
const next = { ...current, ...patch };
|
|
55314
|
-
if (!existsSync23(CONFIG_DIR))
|
|
55054
|
+
if (!existsSync23(CONFIG_DIR)) mkdirSync10(CONFIG_DIR, { recursive: true });
|
|
55315
55055
|
atomicWriteFileSync(CONFIG_FILE, JSON.stringify(next, null, 2));
|
|
55316
55056
|
}
|
|
55317
55057
|
function clearConfig() {
|
|
@@ -55340,8 +55080,8 @@ var CONFIG_DIR, CONFIG_FILE;
|
|
|
55340
55080
|
var init_config = __esm({
|
|
55341
55081
|
"src/lib/config.ts"() {
|
|
55342
55082
|
init_atomic_write();
|
|
55343
|
-
CONFIG_DIR =
|
|
55344
|
-
CONFIG_FILE =
|
|
55083
|
+
CONFIG_DIR = join42(homedir8(), ".config", "oxagen");
|
|
55084
|
+
CONFIG_FILE = join42(CONFIG_DIR, "config.json");
|
|
55345
55085
|
}
|
|
55346
55086
|
});
|
|
55347
55087
|
|
|
@@ -55373,16 +55113,16 @@ import {
|
|
|
55373
55113
|
writeFile as writeFile2
|
|
55374
55114
|
} from "node:fs/promises";
|
|
55375
55115
|
import { homedir as homedir9 } from "node:os";
|
|
55376
|
-
import { join as
|
|
55116
|
+
import { join as join43 } from "node:path";
|
|
55377
55117
|
function isDebugEnabled() {
|
|
55378
55118
|
const v = process.env[DEBUG_ENV];
|
|
55379
55119
|
return v === "1" || v === "true";
|
|
55380
55120
|
}
|
|
55381
55121
|
function logsDir() {
|
|
55382
|
-
return
|
|
55122
|
+
return join43(homedir9(), ".oxagen", "logs");
|
|
55383
55123
|
}
|
|
55384
55124
|
function debugLogFile() {
|
|
55385
|
-
return
|
|
55125
|
+
return join43(logsDir(), "cli.output");
|
|
55386
55126
|
}
|
|
55387
55127
|
function sanitize(value, depth = 0) {
|
|
55388
55128
|
if (value === null || value === void 0) return value;
|
|
@@ -55894,30 +55634,6 @@ var init_add_claude_code_mcp = __esm({
|
|
|
55894
55634
|
}
|
|
55895
55635
|
});
|
|
55896
55636
|
|
|
55897
|
-
// src/commands/move-off-tacho.ts
|
|
55898
|
-
async function moveOffTacho(writer) {
|
|
55899
|
-
const { defaultCliDeps: defaultCliDeps2, moveOffTachoNames: moveOffTachoNames2, oxagenRuntimeCommands: oxagenRuntimeCommands2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
55900
|
-
const moved = await moveOffTachoNames2(
|
|
55901
|
-
defaultCliDeps2({
|
|
55902
|
-
out: () => void 0,
|
|
55903
|
-
err: (line) => writer.writeErr(line),
|
|
55904
|
-
runtime: oxagenRuntimeCommands2()
|
|
55905
|
-
})
|
|
55906
|
-
);
|
|
55907
|
-
for (const agent of moved)
|
|
55908
|
-
writer.writeErr(
|
|
55909
|
-
agent.ok ? `Moved ${agent.agentKey}'s hooks and service from ${agent.from} to the oxagen CLI.` : agent.skipped === "harness_files_elsewhere" ? (
|
|
55910
|
-
// The recorder already said which shell to run it from. Running
|
|
55911
|
-
// enroll again from this one would leave the agent again.
|
|
55912
|
-
`Left ${agent.agentKey}'s hooks and service on ${agent.from}; they keep working. The line above says how to move them.`
|
|
55913
|
-
) : `Could not move ${agent.agentKey}'s hooks and service off ${agent.from}; they keep working. Run \`oxagen agent enroll\` to try again.`
|
|
55914
|
-
);
|
|
55915
|
-
}
|
|
55916
|
-
var init_move_off_tacho = __esm({
|
|
55917
|
-
"src/commands/move-off-tacho.ts"() {
|
|
55918
|
-
}
|
|
55919
|
-
});
|
|
55920
|
-
|
|
55921
55637
|
// src/commands/tacho.ts
|
|
55922
55638
|
var tacho_exports = {};
|
|
55923
55639
|
__export(tacho_exports, {
|
|
@@ -55983,7 +55699,6 @@ async function handleTachoEnroll(opts, writer = stdoutWriter) {
|
|
|
55983
55699
|
);
|
|
55984
55700
|
if (!result2.ok) return false;
|
|
55985
55701
|
const shipping = result2.shipping?.healthy !== false;
|
|
55986
|
-
if (opts.printManaged !== true) await moveOffTacho(writer);
|
|
55987
55702
|
if (opts.verify === true) {
|
|
55988
55703
|
const wrapped2 = harnesses?.find((harness) => harness !== "claude-desktop");
|
|
55989
55704
|
const verified = await verify6(
|
|
@@ -55999,7 +55714,6 @@ async function handleTachoEnroll(opts, writer = stdoutWriter) {
|
|
|
55999
55714
|
}
|
|
56000
55715
|
async function handleTachoStatus(opts, writer = stdoutWriter) {
|
|
56001
55716
|
const { status: status2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
56002
|
-
await moveOffTacho(writer);
|
|
56003
55717
|
await addClaudeCodeMcp(writer);
|
|
56004
55718
|
const report = await status2(opts, await tachoDeps(writer));
|
|
56005
55719
|
const reports = [report, ...report.enrollments ?? []];
|
|
@@ -56225,7 +55939,6 @@ var init_tacho = __esm({
|
|
|
56225
55939
|
init_capture_writer();
|
|
56226
55940
|
init_api();
|
|
56227
55941
|
init_add_claude_code_mcp();
|
|
56228
|
-
init_move_off_tacho();
|
|
56229
55942
|
getuid = () => process.getuid?.();
|
|
56230
55943
|
}
|
|
56231
55944
|
});
|
|
@@ -58753,9 +58466,9 @@ var init_git = __esm({
|
|
|
58753
58466
|
|
|
58754
58467
|
// ../../packages/steering-freshness/src/cache.ts
|
|
58755
58468
|
import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
|
|
58756
|
-
import { dirname as dirname25, join as
|
|
58469
|
+
import { dirname as dirname25, join as join44 } from "node:path";
|
|
58757
58470
|
function stampPath(gitCommonDir) {
|
|
58758
|
-
return
|
|
58471
|
+
return join44(gitCommonDir, "oxagen", "steering-freshness.json");
|
|
58759
58472
|
}
|
|
58760
58473
|
async function readFetchStamp(gitCommonDir, io = defaultIo) {
|
|
58761
58474
|
try {
|
|
@@ -58809,24 +58522,24 @@ var init_cache = __esm({
|
|
|
58809
58522
|
// ../../packages/steering-freshness/src/hooks.ts
|
|
58810
58523
|
import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
|
|
58811
58524
|
import { homedir as homedir10 } from "node:os";
|
|
58812
|
-
import { dirname as dirname26, join as
|
|
58525
|
+
import { dirname as dirname26, join as join45 } from "node:path";
|
|
58813
58526
|
function hookCommand(harness) {
|
|
58814
58527
|
return `oxagen steering gate --harness ${harness}`;
|
|
58815
58528
|
}
|
|
58816
58529
|
function hookConfigPath(projectRoot, harness, env = process.env, home = homedir10()) {
|
|
58817
58530
|
switch (harness) {
|
|
58818
58531
|
case "claude-code":
|
|
58819
|
-
return
|
|
58532
|
+
return join45(projectRoot, ".claude", "settings.json");
|
|
58820
58533
|
case "codex":
|
|
58821
|
-
return
|
|
58534
|
+
return join45(env["CODEX_HOME"] ?? join45(home, ".codex"), "hooks.json");
|
|
58822
58535
|
case "cursor":
|
|
58823
|
-
return
|
|
58536
|
+
return join45(home, ".cursor", "hooks.json");
|
|
58824
58537
|
case "stella":
|
|
58825
|
-
return
|
|
58538
|
+
return join45(env["STELLA_HOME"] ?? join45(home, ".stella"), "stella.toml");
|
|
58826
58539
|
}
|
|
58827
58540
|
}
|
|
58828
58541
|
function stellaJsonPath(env, home) {
|
|
58829
|
-
return
|
|
58542
|
+
return join45(env["STELLA_HOME"] ?? join45(home, ".stella"), "settings.json");
|
|
58830
58543
|
}
|
|
58831
58544
|
function isRecord8(v) {
|
|
58832
58545
|
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
@@ -59555,7 +59268,7 @@ var init_policy = __esm({
|
|
|
59555
59268
|
// ../../packages/steering-freshness/src/settings.ts
|
|
59556
59269
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
59557
59270
|
import { homedir as homedir11 } from "node:os";
|
|
59558
|
-
import { join as
|
|
59271
|
+
import { join as join46 } from "node:path";
|
|
59559
59272
|
async function readLayer(scope, path2, read2) {
|
|
59560
59273
|
let text5;
|
|
59561
59274
|
try {
|
|
@@ -59607,14 +59320,14 @@ function parseLayer(scope, path2, text5) {
|
|
|
59607
59320
|
}
|
|
59608
59321
|
async function loadSteeringSettings({
|
|
59609
59322
|
projectRoot,
|
|
59610
|
-
userSettingsPath =
|
|
59323
|
+
userSettingsPath = join46(homedir11(), USER_SETTINGS_RELATIVE),
|
|
59611
59324
|
read: read2 = readFile8,
|
|
59612
59325
|
workspacePolicy = null
|
|
59613
59326
|
}) {
|
|
59614
59327
|
const targets = [
|
|
59615
59328
|
["user", userSettingsPath],
|
|
59616
|
-
["project",
|
|
59617
|
-
["local",
|
|
59329
|
+
["project", join46(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
|
|
59330
|
+
["local", join46(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
|
|
59618
59331
|
];
|
|
59619
59332
|
const layers = [];
|
|
59620
59333
|
const warnings = [];
|
|
@@ -59662,7 +59375,7 @@ var init_settings = __esm({
|
|
|
59662
59375
|
"use strict";
|
|
59663
59376
|
init_git();
|
|
59664
59377
|
init_policy();
|
|
59665
|
-
USER_SETTINGS_RELATIVE =
|
|
59378
|
+
USER_SETTINGS_RELATIVE = join46(
|
|
59666
59379
|
".config",
|
|
59667
59380
|
"oxagen",
|
|
59668
59381
|
"settings.json"
|
|
@@ -59675,7 +59388,7 @@ var init_settings = __esm({
|
|
|
59675
59388
|
|
|
59676
59389
|
// ../../packages/steering-freshness/src/check.ts
|
|
59677
59390
|
import { lstat as lstat3 } from "node:fs/promises";
|
|
59678
|
-
import { isAbsolute as isAbsolute12, join as
|
|
59391
|
+
import { isAbsolute as isAbsolute12, join as join47, resolve as resolve17 } from "node:path";
|
|
59679
59392
|
function publishedCommits(platform) {
|
|
59680
59393
|
if (platform.headCommits && platform.headCommits.length > 0)
|
|
59681
59394
|
return platform.headCommits;
|
|
@@ -59989,7 +59702,7 @@ async function absentFromDisk(root, paths) {
|
|
|
59989
59702
|
const flags = await Promise.all(
|
|
59990
59703
|
paths.map(async (path2) => {
|
|
59991
59704
|
try {
|
|
59992
|
-
await lstat3(
|
|
59705
|
+
await lstat3(join47(root, path2));
|
|
59993
59706
|
return false;
|
|
59994
59707
|
} catch {
|
|
59995
59708
|
return true;
|
|
@@ -60637,14 +60350,14 @@ var init_src2 = __esm({
|
|
|
60637
60350
|
// src/commands/workspace-link.ts
|
|
60638
60351
|
import {
|
|
60639
60352
|
existsSync as existsSync24,
|
|
60640
|
-
mkdirSync as
|
|
60353
|
+
mkdirSync as mkdirSync11,
|
|
60641
60354
|
readFileSync as readFileSync23,
|
|
60642
60355
|
rmSync as rmSync9,
|
|
60643
60356
|
writeFileSync as writeFileSync8
|
|
60644
60357
|
} from "node:fs";
|
|
60645
|
-
import { join as
|
|
60358
|
+
import { join as join48 } from "node:path";
|
|
60646
60359
|
function workspaceLinkPath(cwd) {
|
|
60647
|
-
return
|
|
60360
|
+
return join48(cwd, ".oxagen", "workspace.json");
|
|
60648
60361
|
}
|
|
60649
60362
|
function readWorkspaceLink(cwd) {
|
|
60650
60363
|
const filePath = workspaceLinkPath(cwd);
|
|
@@ -60661,8 +60374,8 @@ function readWorkspaceLink(cwd) {
|
|
|
60661
60374
|
}
|
|
60662
60375
|
}
|
|
60663
60376
|
function writeWorkspaceLink(cwd, link) {
|
|
60664
|
-
const dir =
|
|
60665
|
-
|
|
60377
|
+
const dir = join48(cwd, ".oxagen");
|
|
60378
|
+
mkdirSync11(dir, { recursive: true });
|
|
60666
60379
|
writeFileSync8(workspaceLinkPath(cwd), JSON.stringify(link, null, 2), "utf8");
|
|
60667
60380
|
}
|
|
60668
60381
|
var init_workspace_link = __esm({
|
|
@@ -60687,7 +60400,7 @@ __export(steering_exports, {
|
|
|
60687
60400
|
});
|
|
60688
60401
|
import { execFileSync } from "node:child_process";
|
|
60689
60402
|
import { existsSync as existsSync25, realpathSync as realpathSync7 } from "node:fs";
|
|
60690
|
-
import { dirname as dirname27, join as
|
|
60403
|
+
import { dirname as dirname27, join as join49, normalize, parse as parsePath } from "node:path";
|
|
60691
60404
|
function findProjectRoot(start) {
|
|
60692
60405
|
const { root } = parsePath(start);
|
|
60693
60406
|
const rawGitRoot = gitRootOr(start);
|
|
@@ -60696,7 +60409,7 @@ function findProjectRoot(start) {
|
|
|
60696
60409
|
if (gitRoot !== null) return gitRoot;
|
|
60697
60410
|
let dir = from;
|
|
60698
60411
|
for (; ; ) {
|
|
60699
|
-
if (existsSync25(
|
|
60412
|
+
if (existsSync25(join49(dir, PROJECT_DIR_NAME))) return dir;
|
|
60700
60413
|
if (dir === root) return from;
|
|
60701
60414
|
const parent = dirname27(dir);
|
|
60702
60415
|
if (parent === dir) return from;
|
|
@@ -72026,7 +71739,7 @@ function recordLineageFromPath(path2) {
|
|
|
72026
71739
|
return parts[parts.length - 1].slice(0, -3);
|
|
72027
71740
|
return null;
|
|
72028
71741
|
}
|
|
72029
|
-
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_FILE, ROOT_FILES, SERVER_FILES,
|
|
71742
|
+
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_FILE, ROOT_FILES, SERVER_FILES, WORKSPACE_LINK_PATH;
|
|
72030
71743
|
var init_paths2 = __esm({
|
|
72031
71744
|
"../../packages/oxagen/src/steering-repo/paths.ts"() {
|
|
72032
71745
|
"use strict";
|
|
@@ -72066,7 +71779,6 @@ var init_paths2 = __esm({
|
|
|
72066
71779
|
"overlay.yaml": "server-definition",
|
|
72067
71780
|
"schema.graphql": "server-definition"
|
|
72068
71781
|
};
|
|
72069
|
-
LEGACY_OXAGEN_DIR = ".oxagen";
|
|
72070
71782
|
WORKSPACE_LINK_PATH = ".oxagen/workspace.json";
|
|
72071
71783
|
}
|
|
72072
71784
|
});
|
|
@@ -75937,7 +75649,7 @@ function agentFindings(tree, context) {
|
|
|
75937
75649
|
field: "runtime",
|
|
75938
75650
|
message: `No runtime named ${runtime} is enrolled in Oxagen.${didYouMean(runtime, context.runtimes)}`,
|
|
75939
75651
|
expected: "A runtime enrolled in Oxagen.",
|
|
75940
|
-
fix: `Enroll ${runtime} with
|
|
75652
|
+
fix: `Enroll ${runtime} with oxagen agent enroll, or name an enrolled runtime.`
|
|
75941
75653
|
})
|
|
75942
75654
|
);
|
|
75943
75655
|
}
|
|
@@ -77181,7 +76893,7 @@ var init_memory_client = __esm({
|
|
|
77181
76893
|
// src/lib/markdown-import.ts
|
|
77182
76894
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
77183
76895
|
import {
|
|
77184
|
-
basename as
|
|
76896
|
+
basename as basename7,
|
|
77185
76897
|
dirname as dirname28,
|
|
77186
76898
|
isAbsolute as isAbsolute13,
|
|
77187
76899
|
relative as relative6,
|
|
@@ -77196,8 +76908,8 @@ function importFilename(path2, folder) {
|
|
|
77196
76908
|
if (!inside(rel) && folder !== void 0) {
|
|
77197
76909
|
rel = relative6(dirname28(resolve18(folder)), resolve18(path2));
|
|
77198
76910
|
}
|
|
77199
|
-
const name = inside(rel) ? rel.split(sep7).join("/") :
|
|
77200
|
-
return name.length > 256 ?
|
|
76911
|
+
const name = inside(rel) ? rel.split(sep7).join("/") : basename7(path2);
|
|
76912
|
+
return name.length > 256 ? basename7(path2).slice(-256) : name;
|
|
77201
76913
|
}
|
|
77202
76914
|
async function readImportDocuments(sources, target2, writer) {
|
|
77203
76915
|
const documents = [];
|
|
@@ -77433,7 +77145,7 @@ __export(steering_import_exports, {
|
|
|
77433
77145
|
handleSteeringImport: () => handleSteeringImport
|
|
77434
77146
|
});
|
|
77435
77147
|
import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
|
|
77436
|
-
import { basename as
|
|
77148
|
+
import { basename as basename8, extname, join as join50 } from "node:path";
|
|
77437
77149
|
function byName(a, b5) {
|
|
77438
77150
|
return a.name < b5.name ? -1 : 1;
|
|
77439
77151
|
}
|
|
@@ -77462,7 +77174,7 @@ async function findMarkdownFiles(paths) {
|
|
|
77462
77174
|
entries2.sort(byName);
|
|
77463
77175
|
const extensions2 = place2 === "rules" ? CURSOR_RULE_EXTENSIONS : MARKDOWN_EXTENSIONS;
|
|
77464
77176
|
for (const entry2 of entries2) {
|
|
77465
|
-
const path2 =
|
|
77177
|
+
const path2 = join50(dir, entry2.name);
|
|
77466
77178
|
if (entry2.isDirectory()) {
|
|
77467
77179
|
if (place2 === "cursor") {
|
|
77468
77180
|
if (entry2.name === CURSOR_RULES_FOLDER) {
|
|
@@ -77491,7 +77203,7 @@ async function findMarkdownFiles(paths) {
|
|
|
77491
77203
|
continue;
|
|
77492
77204
|
}
|
|
77493
77205
|
if (isFolder) {
|
|
77494
|
-
const place2 =
|
|
77206
|
+
const place2 = basename8(path2) === CURSOR_FOLDER ? "cursor" : "plain";
|
|
77495
77207
|
await walk2(path2, path2, place2);
|
|
77496
77208
|
} else await take(path2);
|
|
77497
77209
|
}
|
|
@@ -79083,11 +78795,11 @@ __export(verify_exports, {
|
|
|
79083
78795
|
readBundle: () => readBundle,
|
|
79084
78796
|
verifyBundle: () => verifyBundle3
|
|
79085
78797
|
});
|
|
79086
|
-
import { existsSync as existsSync26, readFileSync as readFileSync24, statSync as
|
|
79087
|
-
import { join as
|
|
78798
|
+
import { existsSync as existsSync26, readFileSync as readFileSync24, statSync as statSync12 } from "node:fs";
|
|
78799
|
+
import { join as join51 } from "node:path";
|
|
79088
78800
|
function readDirectory(dir) {
|
|
79089
78801
|
const read2 = (name) => {
|
|
79090
|
-
const path2 =
|
|
78802
|
+
const path2 = join51(dir, name);
|
|
79091
78803
|
return existsSync26(path2) ? readFileSync24(path2, "utf8") : void 0;
|
|
79092
78804
|
};
|
|
79093
78805
|
return assemble(read2, dir);
|
|
@@ -79129,7 +78841,7 @@ function readBundle(path2) {
|
|
|
79129
78841
|
if (!existsSync26(path2)) {
|
|
79130
78842
|
throw new BundleReadError(`${path2} does not exist.`);
|
|
79131
78843
|
}
|
|
79132
|
-
return
|
|
78844
|
+
return statSync12(path2).isDirectory() ? readDirectory(path2) : readZip(path2);
|
|
79133
78845
|
}
|
|
79134
78846
|
function digestLabel(state) {
|
|
79135
78847
|
return state === "not_carried" ? "not carried" : state;
|
|
@@ -80174,14 +79886,14 @@ import {
|
|
|
80174
79886
|
appendFileSync as appendFileSync4,
|
|
80175
79887
|
existsSync as existsSync27,
|
|
80176
79888
|
lstatSync as lstatSync9,
|
|
80177
|
-
mkdirSync as
|
|
79889
|
+
mkdirSync as mkdirSync12,
|
|
80178
79890
|
readFileSync as readFileSync25,
|
|
80179
79891
|
readdirSync as readdirSync13,
|
|
80180
79892
|
realpathSync as realpathSync8,
|
|
80181
79893
|
writeFileSync as writeFileSync10
|
|
80182
79894
|
} from "node:fs";
|
|
80183
79895
|
import { homedir as homedir12, hostname as osHostname3 } from "node:os";
|
|
80184
|
-
import { join as
|
|
79896
|
+
import { join as join52, relative as relative7, resolve as resolve20, sep as sep8 } from "node:path";
|
|
80185
79897
|
function git4(cwd, args) {
|
|
80186
79898
|
return new Promise((done) => {
|
|
80187
79899
|
try {
|
|
@@ -80228,7 +79940,7 @@ function parseRemoteRepository(url) {
|
|
|
80228
79940
|
}
|
|
80229
79941
|
function oxagenPresent(root) {
|
|
80230
79942
|
try {
|
|
80231
|
-
return readdirSync13(
|
|
79943
|
+
return readdirSync13(join52(root, ".oxagen")).some(
|
|
80232
79944
|
(name) => name !== "workspace.json"
|
|
80233
79945
|
);
|
|
80234
79946
|
} catch {
|
|
@@ -80237,18 +79949,18 @@ function oxagenPresent(root) {
|
|
|
80237
79949
|
}
|
|
80238
79950
|
function symlinkState(root) {
|
|
80239
79951
|
try {
|
|
80240
|
-
if (!lstatSync9(
|
|
79952
|
+
if (!lstatSync9(join52(root, ".stella")).isDirectory()) return "none";
|
|
80241
79953
|
} catch {
|
|
80242
79954
|
return "none";
|
|
80243
79955
|
}
|
|
80244
79956
|
let oxagenReal;
|
|
80245
79957
|
try {
|
|
80246
|
-
oxagenReal = realpathSync8(
|
|
79958
|
+
oxagenReal = realpathSync8(join52(root, ".oxagen"));
|
|
80247
79959
|
} catch {
|
|
80248
79960
|
return "missing";
|
|
80249
79961
|
}
|
|
80250
79962
|
for (const link of STELLA_LINKS) {
|
|
80251
|
-
const at =
|
|
79963
|
+
const at = join52(root, link);
|
|
80252
79964
|
try {
|
|
80253
79965
|
if (!lstatSync9(at).isSymbolicLink()) return "missing";
|
|
80254
79966
|
const target2 = realpathSync8(at);
|
|
@@ -80262,7 +79974,7 @@ function symlinkState(root) {
|
|
|
80262
79974
|
return "linked";
|
|
80263
79975
|
}
|
|
80264
79976
|
function machineId(configDir = getConfigDir()) {
|
|
80265
|
-
const file =
|
|
79977
|
+
const file = join52(configDir, MACHINE_ID_FILE);
|
|
80266
79978
|
let secret = null;
|
|
80267
79979
|
try {
|
|
80268
79980
|
if (existsSync27(file)) {
|
|
@@ -80271,7 +79983,7 @@ function machineId(configDir = getConfigDir()) {
|
|
|
80271
79983
|
}
|
|
80272
79984
|
if (secret === null) {
|
|
80273
79985
|
secret = randomBytes12(32).toString("hex");
|
|
80274
|
-
|
|
79986
|
+
mkdirSync12(configDir, { recursive: true });
|
|
80275
79987
|
writeFileSync10(file, `${secret}
|
|
80276
79988
|
`, { encoding: "utf8", mode: 384 });
|
|
80277
79989
|
}
|
|
@@ -80344,12 +80056,12 @@ async function ensureWorkspaceLinkIgnored(root) {
|
|
|
80344
80056
|
const topDir = resolve20(top);
|
|
80345
80057
|
const entry2 = relative7(
|
|
80346
80058
|
topDir,
|
|
80347
|
-
|
|
80059
|
+
join52(realpathOr2(root), ".oxagen", "workspace.json")
|
|
80348
80060
|
).split(sep8).join("/");
|
|
80349
80061
|
if (entry2.startsWith("../")) return null;
|
|
80350
80062
|
const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
|
|
80351
80063
|
if (rule !== null) return null;
|
|
80352
|
-
const gitignore =
|
|
80064
|
+
const gitignore = join52(resolve20(top), ".gitignore");
|
|
80353
80065
|
let existing = "";
|
|
80354
80066
|
try {
|
|
80355
80067
|
existing = readFileSync25(gitignore, "utf8");
|
|
@@ -80823,19 +80535,19 @@ __export(pull_exports, {
|
|
|
80823
80535
|
import { createHash as createHash20 } from "node:crypto";
|
|
80824
80536
|
import {
|
|
80825
80537
|
lstatSync as lstatSync10,
|
|
80826
|
-
mkdirSync as
|
|
80538
|
+
mkdirSync as mkdirSync13,
|
|
80827
80539
|
readFileSync as readFileSync26,
|
|
80828
80540
|
readdirSync as readdirSync14,
|
|
80829
80541
|
realpathSync as realpathSync9,
|
|
80830
80542
|
rmSync as rmSync10,
|
|
80831
|
-
rmdirSync as
|
|
80543
|
+
rmdirSync as rmdirSync7
|
|
80832
80544
|
} from "node:fs";
|
|
80833
80545
|
import {
|
|
80834
80546
|
dirname as dirname29,
|
|
80835
80547
|
isAbsolute as isAbsolute14,
|
|
80836
|
-
join as
|
|
80548
|
+
join as join53,
|
|
80837
80549
|
parse as parsePath2,
|
|
80838
|
-
posix as
|
|
80550
|
+
posix as posix4,
|
|
80839
80551
|
sep as sep9
|
|
80840
80552
|
} from "node:path";
|
|
80841
80553
|
function checkSteeringPath(path2) {
|
|
@@ -80846,10 +80558,10 @@ function checkSteeringPath(path2) {
|
|
|
80846
80558
|
if (path2.includes("\\")) {
|
|
80847
80559
|
return { ok: false, reason: "contains a backslash" };
|
|
80848
80560
|
}
|
|
80849
|
-
if (
|
|
80561
|
+
if (posix4.isAbsolute(path2) || isAbsolute14(path2) || /^[A-Za-z]:/.test(path2)) {
|
|
80850
80562
|
return { ok: false, reason: "absolute path" };
|
|
80851
80563
|
}
|
|
80852
|
-
const normalized =
|
|
80564
|
+
const normalized = posix4.normalize(path2);
|
|
80853
80565
|
if (normalized !== path2 || normalized.split("/").some((s4) => s4 === ".." || s4 === ".")) {
|
|
80854
80566
|
return { ok: false, reason: "not a canonical path" };
|
|
80855
80567
|
}
|
|
@@ -80946,7 +80658,7 @@ function findLinkedRoot(start) {
|
|
|
80946
80658
|
}
|
|
80947
80659
|
function fsReader(root) {
|
|
80948
80660
|
return (path2) => {
|
|
80949
|
-
const abs =
|
|
80661
|
+
const abs = join53(root, ...path2.split("/"));
|
|
80950
80662
|
try {
|
|
80951
80663
|
const st = lstatSync10(abs);
|
|
80952
80664
|
if (!st.isFile()) return Buffer.from(`\0not-a-file:${abs}`);
|
|
@@ -80957,14 +80669,14 @@ function fsReader(root) {
|
|
|
80957
80669
|
};
|
|
80958
80670
|
}
|
|
80959
80671
|
function assertInsideOxagen(root, path2) {
|
|
80960
|
-
const oxagenAbs =
|
|
80672
|
+
const oxagenAbs = join53(root, OXAGEN_DIR);
|
|
80961
80673
|
let oxagenReal;
|
|
80962
80674
|
try {
|
|
80963
80675
|
oxagenReal = realpathSync9(oxagenAbs);
|
|
80964
80676
|
} catch {
|
|
80965
80677
|
return;
|
|
80966
80678
|
}
|
|
80967
|
-
const abs =
|
|
80679
|
+
const abs = join53(root, ...path2.split("/"));
|
|
80968
80680
|
try {
|
|
80969
80681
|
if (lstatSync10(abs).isSymbolicLink()) {
|
|
80970
80682
|
throw new Error(
|
|
@@ -80994,12 +80706,12 @@ function assertInsideOxagen(root, path2) {
|
|
|
80994
80706
|
}
|
|
80995
80707
|
}
|
|
80996
80708
|
function pruneEmptyDirs(root, path2) {
|
|
80997
|
-
const stop =
|
|
80998
|
-
let dir = dirname29(
|
|
80709
|
+
const stop = join53(root, OXAGEN_DIR);
|
|
80710
|
+
let dir = dirname29(join53(root, ...path2.split("/")));
|
|
80999
80711
|
while (dir.startsWith(stop + sep9)) {
|
|
81000
80712
|
try {
|
|
81001
80713
|
if (readdirSync14(dir).length > 0) return;
|
|
81002
|
-
|
|
80714
|
+
rmdirSync7(dir);
|
|
81003
80715
|
} catch {
|
|
81004
80716
|
return;
|
|
81005
80717
|
}
|
|
@@ -81010,12 +80722,12 @@ function applyPlan(root, plan) {
|
|
|
81010
80722
|
for (const w of plan.writes) assertInsideOxagen(root, w.path);
|
|
81011
80723
|
for (const d of plan.deletes) assertInsideOxagen(root, d);
|
|
81012
80724
|
for (const w of plan.writes) {
|
|
81013
|
-
const abs =
|
|
81014
|
-
|
|
80725
|
+
const abs = join53(root, ...w.path.split("/"));
|
|
80726
|
+
mkdirSync13(dirname29(abs), { recursive: true });
|
|
81015
80727
|
atomicWriteFileSync(abs, w.content);
|
|
81016
80728
|
}
|
|
81017
80729
|
for (const d of plan.deletes) {
|
|
81018
|
-
rmSync10(
|
|
80730
|
+
rmSync10(join53(root, ...d.split("/")), { force: true });
|
|
81019
80731
|
pruneEmptyDirs(root, d);
|
|
81020
80732
|
}
|
|
81021
80733
|
}
|
|
@@ -81184,7 +80896,7 @@ var init_pull = __esm({
|
|
|
81184
80896
|
init_output();
|
|
81185
80897
|
init_working_copy();
|
|
81186
80898
|
init_workspace_link();
|
|
81187
|
-
OXAGEN_DIR =
|
|
80899
|
+
OXAGEN_DIR = ".oxagen";
|
|
81188
80900
|
LINK_PATH = WORKSPACE_LINK_PATH;
|
|
81189
80901
|
NOT_LINKED = "This directory is not linked to a workspace. Run `oxagen init --org <org> --workspace <workspace>` first.";
|
|
81190
80902
|
BINDING_ID = /^rpb_[0-9A-Za-z]+$/;
|
|
@@ -124308,12 +124020,12 @@ import { execFileSync as execFileSync2 } from "node:child_process";
|
|
|
124308
124020
|
import { createHash as createHash22 } from "node:crypto";
|
|
124309
124021
|
import {
|
|
124310
124022
|
lstatSync as lstatSync11,
|
|
124311
|
-
mkdirSync as
|
|
124023
|
+
mkdirSync as mkdirSync14,
|
|
124312
124024
|
readFileSync as readFileSync27,
|
|
124313
124025
|
readlinkSync as readlinkSync4,
|
|
124314
|
-
statSync as
|
|
124026
|
+
statSync as statSync13
|
|
124315
124027
|
} from "node:fs";
|
|
124316
|
-
import { dirname as dirname30, isAbsolute as isAbsolute15, join as
|
|
124028
|
+
import { dirname as dirname30, isAbsolute as isAbsolute15, join as join54, relative as relative8, resolve as resolve22, sep as sep10 } from "node:path";
|
|
124317
124029
|
function git5(cwd, args, input) {
|
|
124318
124030
|
try {
|
|
124319
124031
|
return execFileSync2("git", args, {
|
|
@@ -124345,7 +124057,7 @@ function commitOf(root, ref2) {
|
|
|
124345
124057
|
return sha2.length > 0 ? sha2 : null;
|
|
124346
124058
|
}
|
|
124347
124059
|
function readWorkingFile(root, path2) {
|
|
124348
|
-
const abs =
|
|
124060
|
+
const abs = join54(root, ...path2.split("/"));
|
|
124349
124061
|
try {
|
|
124350
124062
|
const stat6 = lstatSync11(abs);
|
|
124351
124063
|
if (stat6.isSymbolicLink()) return readlinkSync4(abs, "utf8");
|
|
@@ -124424,14 +124136,14 @@ function chooseBase(root, ref2) {
|
|
|
124424
124136
|
}
|
|
124425
124137
|
function isFile(path2) {
|
|
124426
124138
|
try {
|
|
124427
|
-
return
|
|
124139
|
+
return statSync13(path2).isFile();
|
|
124428
124140
|
} catch {
|
|
124429
124141
|
return false;
|
|
124430
124142
|
}
|
|
124431
124143
|
}
|
|
124432
124144
|
function isDir(path2) {
|
|
124433
124145
|
try {
|
|
124434
|
-
return
|
|
124146
|
+
return statSync13(path2).isDirectory();
|
|
124435
124147
|
} catch {
|
|
124436
124148
|
return false;
|
|
124437
124149
|
}
|
|
@@ -124439,7 +124151,7 @@ function isDir(path2) {
|
|
|
124439
124151
|
function findSteeringRoot(start) {
|
|
124440
124152
|
let dir = resolve22(start);
|
|
124441
124153
|
for (; ; ) {
|
|
124442
|
-
if (isFile(
|
|
124154
|
+
if (isFile(join54(dir, WORKSPACE_TOML_PATH)) || isFile(join54(dir, AGENTS_MD_PATH)) && isDir(join54(dir, STEERING_DIR))) {
|
|
124443
124155
|
return dir;
|
|
124444
124156
|
}
|
|
124445
124157
|
const parent = dirname30(dir);
|
|
@@ -124519,7 +124231,7 @@ function cacheFile(cacheDir, root) {
|
|
|
124519
124231
|
key: token === void 0 ? null : createHash22("sha256").update(token).digest("hex").slice(0, 16)
|
|
124520
124232
|
};
|
|
124521
124233
|
const key = createHash22("sha256").update(JSON.stringify([root, identity])).digest("hex").slice(0, 32);
|
|
124522
|
-
return
|
|
124234
|
+
return join54(cacheDir, `${key}.json`);
|
|
124523
124235
|
}
|
|
124524
124236
|
function readCache(file, now) {
|
|
124525
124237
|
let entry2;
|
|
@@ -124547,7 +124259,7 @@ async function publishedInputs(root, deps, refresh, out) {
|
|
|
124547
124259
|
}
|
|
124548
124260
|
if (file !== null) {
|
|
124549
124261
|
try {
|
|
124550
|
-
|
|
124262
|
+
mkdirSync14(dirname30(file), { recursive: true });
|
|
124551
124263
|
atomicWriteFileSync(
|
|
124552
124264
|
file,
|
|
124553
124265
|
JSON.stringify({
|
|
@@ -124633,7 +124345,7 @@ function defaultDeps2() {
|
|
|
124633
124345
|
return {
|
|
124634
124346
|
fetchPublished: fetchSteeringIndex,
|
|
124635
124347
|
cedar: cedarHooks,
|
|
124636
|
-
cacheDir:
|
|
124348
|
+
cacheDir: join54(getConfigDir(), "cache", "steering-check"),
|
|
124637
124349
|
now: () => Date.now()
|
|
124638
124350
|
};
|
|
124639
124351
|
}
|
|
@@ -126487,7 +126199,7 @@ var init_common2 = __esm({
|
|
|
126487
126199
|
function call(name, request3, result2) {
|
|
126488
126200
|
return { call: name, request: request3, result: result2, response: responseSchema(result2) };
|
|
126489
126201
|
}
|
|
126490
|
-
var unit3, count10, names, excluded, withinSchema, testRefSchema, SEARCH_GROUPS, searchHitSchema, searchCodeGraphRequest, searchCodeGraphResult, blastTargetSchema, blastGroupsSchema, getBlastRadiusRequest, getBlastRadiusResult, listUnitTestsRequest, listUnitTestsResult, flowDataSchema, flowNodeSchema, jobStepSchema, getExecutionFlowRequest, getExecutionFlowResult, traceSpecRequest, traceSpecResult, listGoverningDecisionsRequest, listGoverningDecisionsResult, getEnvVarsRequest, getEnvVarsResult, connectionSchema, getInfraRequest, getInfraResult, listCiJobsRequest, listCiJobsResult, scriptEffectSchema, listScriptsRequest, listScriptsResult, getApiDocsRequest, getApiDocsResult, exportOpenapiDraftRequest, exportOpenapiDraftResult, listCoChangesRequest, listCoChangesResult, rankSymbolsRequest, rankSymbolsResult, getRepoMapRequest, getRepoMapResult, getDomainBriefRequest, getDomainBriefResult, checkChangeRequest, checkChangeResult, findDefinitionRequest, findDefinitionResult, findReferencesRequest, findReferencesResult, findImplementationsRequest, findImplementationsResult, listNeighborsRequest, listNeighborsResult, CODEGRAPH_CALLS;
|
|
126202
|
+
var unit3, count10, names, excluded, withinSchema, testRefSchema, SEARCH_GROUPS, searchHitSchema, searchCodeGraphRequest, searchCodeGraphResult, blastTargetSchema, decisionItemSchema, blastGroupsSchema, getBlastRadiusRequest, getBlastRadiusResult, listUnitTestsRequest, listUnitTestsResult, flowDataSchema, flowNodeSchema, jobStepSchema, getExecutionFlowRequest, getExecutionFlowResult, traceSpecRequest, traceSpecResult, listGoverningDecisionsRequest, listGoverningDecisionsResult, getEnvVarsRequest, getEnvVarsResult, connectionSchema, getInfraRequest, getInfraResult, listCiJobsRequest, listCiJobsResult, scriptEffectSchema, listScriptsRequest, listScriptsResult, getApiDocsRequest, getApiDocsResult, exportOpenapiDraftRequest, exportOpenapiDraftResult, listCoChangesRequest, listCoChangesResult, rankSymbolsRequest, rankSymbolsResult, getRepoMapRequest, getRepoMapResult, getDomainBriefRequest, getDomainBriefResult, checkChangeRequest, checkChangeResult, findDefinitionRequest, findDefinitionResult, findReferencesRequest, findReferencesResult, findImplementationsRequest, findImplementationsResult, listNeighborsRequest, listNeighborsResult, CODEGRAPH_CALLS;
|
|
126491
126203
|
var init_calls = __esm({
|
|
126492
126204
|
"../../packages/codegraph/src/query/calls.ts"() {
|
|
126493
126205
|
"use strict";
|
|
@@ -126564,6 +126276,10 @@ var init_calls = __esm({
|
|
|
126564
126276
|
name: external_exports.string().min(1),
|
|
126565
126277
|
id: external_exports.string().min(1).optional()
|
|
126566
126278
|
}).strict();
|
|
126279
|
+
decisionItemSchema = graphItemSchema.extend({
|
|
126280
|
+
status: external_exports.string().optional(),
|
|
126281
|
+
enforcedBy: external_exports.string().optional()
|
|
126282
|
+
}).strict();
|
|
126567
126283
|
blastGroupsSchema = external_exports.object({
|
|
126568
126284
|
code: external_exports.array(graphItemSchema),
|
|
126569
126285
|
data: external_exports.array(graphItemSchema),
|
|
@@ -126576,6 +126292,11 @@ var init_calls = __esm({
|
|
|
126576
126292
|
entryPoints: names,
|
|
126577
126293
|
buildTargets: names,
|
|
126578
126294
|
deployables: names,
|
|
126295
|
+
config: external_exports.array(graphItemSchema),
|
|
126296
|
+
infrastructure: external_exports.array(graphItemSchema),
|
|
126297
|
+
ci: external_exports.array(graphItemSchema),
|
|
126298
|
+
scripts: external_exports.array(graphItemSchema),
|
|
126299
|
+
packages: external_exports.array(graphItemSchema),
|
|
126579
126300
|
tests: external_exports.array(testRefSchema),
|
|
126580
126301
|
docs: external_exports.array(
|
|
126581
126302
|
graphItemSchema.extend({ flag: external_exports.string().optional() }).strict()
|
|
@@ -126586,15 +126307,11 @@ var init_calls = __esm({
|
|
|
126586
126307
|
status: specStatusSchema.optional()
|
|
126587
126308
|
}).strict()
|
|
126588
126309
|
),
|
|
126589
|
-
decisions: external_exports.array(
|
|
126590
|
-
graphItemSchema.extend({
|
|
126591
|
-
status: external_exports.string().optional(),
|
|
126592
|
-
enforcedBy: external_exports.string().optional()
|
|
126593
|
-
}).strict()
|
|
126594
|
-
),
|
|
126310
|
+
decisions: external_exports.array(decisionItemSchema),
|
|
126595
126311
|
historical: external_exports.array(
|
|
126596
126312
|
graphItemSchema.extend({ coChangeConfidence: unit3.optional() }).strict()
|
|
126597
|
-
)
|
|
126313
|
+
),
|
|
126314
|
+
other: external_exports.array(graphItemSchema)
|
|
126598
126315
|
}).partial().strict();
|
|
126599
126316
|
getBlastRadiusRequest = requestSchema({ target: targetSchema });
|
|
126600
126317
|
getBlastRadiusResult = external_exports.object({
|
|
@@ -126891,7 +126608,7 @@ var init_calls = __esm({
|
|
|
126891
126608
|
seeds: external_exports.array(seedSchema),
|
|
126892
126609
|
boundaryCrossings: external_exports.array(graphItemSchema),
|
|
126893
126610
|
conventions: names,
|
|
126894
|
-
decisions: external_exports.array(
|
|
126611
|
+
decisions: external_exports.array(decisionItemSchema),
|
|
126895
126612
|
needsDecisionRecord: external_exports.boolean(),
|
|
126896
126613
|
env: external_exports.object({ added: names, missing: names }).strict(),
|
|
126897
126614
|
infrastructure: external_exports.array(graphItemSchema),
|
|
@@ -128464,7 +128181,7 @@ var init_src9 = __esm({
|
|
|
128464
128181
|
|
|
128465
128182
|
// src/commands/codegraph-upload/files.ts
|
|
128466
128183
|
import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
|
|
128467
|
-
import { join as
|
|
128184
|
+
import { join as join55, relative as relative9, sep as sep11 } from "node:path";
|
|
128468
128185
|
function hasGlobChars(pattern) {
|
|
128469
128186
|
return /[*?[\]{}]/.test(pattern);
|
|
128470
128187
|
}
|
|
@@ -128476,7 +128193,7 @@ async function walk(root, dir, out) {
|
|
|
128476
128193
|
const entries2 = await readdir5(dir, { withFileTypes: true });
|
|
128477
128194
|
for (const entry2 of entries2) {
|
|
128478
128195
|
if (entry2.isSymbolicLink()) continue;
|
|
128479
|
-
const full =
|
|
128196
|
+
const full = join55(dir, entry2.name);
|
|
128480
128197
|
if (entry2.isDirectory()) {
|
|
128481
128198
|
if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
|
|
128482
128199
|
} else if (entry2.isFile()) {
|
|
@@ -128488,7 +128205,7 @@ async function expandPattern(root, pattern) {
|
|
|
128488
128205
|
const wanted = normalize2(pattern.trim());
|
|
128489
128206
|
if (!hasGlobChars(wanted)) {
|
|
128490
128207
|
try {
|
|
128491
|
-
const info = await stat5(
|
|
128208
|
+
const info = await stat5(join55(root, wanted));
|
|
128492
128209
|
return info.isFile() ? [wanted] : [];
|
|
128493
128210
|
} catch {
|
|
128494
128211
|
return [];
|
|
@@ -128639,7 +128356,7 @@ var init_token = __esm({
|
|
|
128639
128356
|
});
|
|
128640
128357
|
|
|
128641
128358
|
// src/commands/codegraph-upload/run.ts
|
|
128642
|
-
import { join as
|
|
128359
|
+
import { join as join56 } from "node:path";
|
|
128643
128360
|
function addDropped(into, more) {
|
|
128644
128361
|
into.sensitiveValues += more.sensitiveValues;
|
|
128645
128362
|
into.secretData += more.secretData;
|
|
@@ -128657,7 +128374,7 @@ async function uploadOne(deps, config, token, group, path2, totals2) {
|
|
|
128657
128374
|
const label2 = `${group.kind}/${group.source} ${path2}`;
|
|
128658
128375
|
let bytes;
|
|
128659
128376
|
try {
|
|
128660
|
-
bytes = await deps.readFile(
|
|
128377
|
+
bytes = await deps.readFile(join56(deps.cwd, path2));
|
|
128661
128378
|
} catch (error) {
|
|
128662
128379
|
totals2.failed += 1;
|
|
128663
128380
|
deps.log(`error: ${label2}: cannot read the file: ${error.message}`);
|
|
@@ -128923,7 +128640,6 @@ var init_logs = __esm({
|
|
|
128923
128640
|
var usage_exports = {};
|
|
128924
128641
|
__export(usage_exports, {
|
|
128925
128642
|
ALLOWED_KEYS: () => ALLOWED_KEYS,
|
|
128926
|
-
addSteps: () => addSteps,
|
|
128927
128643
|
buildUsageEvent: () => buildUsageEvent,
|
|
128928
128644
|
classifyCommand: () => classifyCommand,
|
|
128929
128645
|
classifyErrorType: () => classifyErrorType,
|
|
@@ -128931,14 +128647,10 @@ __export(usage_exports, {
|
|
|
128931
128647
|
getOrCreateInstallId: () => getOrCreateInstallId,
|
|
128932
128648
|
isTelemetryEnabled: () => isTelemetryEnabled,
|
|
128933
128649
|
markGraphUsed: () => markGraphUsed,
|
|
128934
|
-
markPipelineUsed: () => markPipelineUsed,
|
|
128935
128650
|
recordModelTier: () => recordModelTier,
|
|
128936
|
-
recordToolCall: () => recordToolCall,
|
|
128937
128651
|
recordUsageEvent: () => recordUsageEvent,
|
|
128938
128652
|
resetUsageSessionStats: () => resetUsageSessionStats,
|
|
128939
128653
|
sendUsageEvent: () => sendUsageEvent,
|
|
128940
|
-
setBestOfN: () => setBestOfN,
|
|
128941
|
-
setByok: () => setByok,
|
|
128942
128654
|
topLevelCommand: () => topLevelCommand
|
|
128943
128655
|
});
|
|
128944
128656
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
@@ -128966,39 +128678,18 @@ function ensureDisclosureShown() {
|
|
|
128966
128678
|
function emptyStats() {
|
|
128967
128679
|
return {
|
|
128968
128680
|
modelTiers: /* @__PURE__ */ new Set(),
|
|
128969
|
-
|
|
128970
|
-
graphUsed: false,
|
|
128971
|
-
pipelineUsed: false,
|
|
128972
|
-
byok: false,
|
|
128973
|
-
toolCalls: {},
|
|
128974
|
-
stepCount: 0
|
|
128681
|
+
graphUsed: false
|
|
128975
128682
|
};
|
|
128976
128683
|
}
|
|
128977
128684
|
function resetUsageSessionStats() {
|
|
128978
128685
|
stats = emptyStats();
|
|
128979
128686
|
}
|
|
128980
|
-
function recordToolCall(toolName3, count12 = 1) {
|
|
128981
|
-
const key = toolName3.toLowerCase().replace(/[^a-z0-9_]/g, "_").slice(0, 32) || "unknown";
|
|
128982
|
-
stats.toolCalls[key] = (stats.toolCalls[key] ?? 0) + count12;
|
|
128983
|
-
}
|
|
128984
128687
|
function recordModelTier(tier) {
|
|
128985
128688
|
if (tier) stats.modelTiers.add(tier);
|
|
128986
128689
|
}
|
|
128987
|
-
function setBestOfN(n4) {
|
|
128988
|
-
stats.bestOfN = Math.max(stats.bestOfN, Math.trunc(n4));
|
|
128989
|
-
}
|
|
128990
128690
|
function markGraphUsed() {
|
|
128991
128691
|
stats.graphUsed = true;
|
|
128992
128692
|
}
|
|
128993
|
-
function markPipelineUsed(used = true) {
|
|
128994
|
-
stats.pipelineUsed = used;
|
|
128995
|
-
}
|
|
128996
|
-
function setByok(byok) {
|
|
128997
|
-
stats.byok = byok;
|
|
128998
|
-
}
|
|
128999
|
-
function addSteps(n4) {
|
|
129000
|
-
stats.stepCount += Math.max(0, Math.trunc(n4));
|
|
129001
|
-
}
|
|
129002
128693
|
function resolveModelTier() {
|
|
129003
128694
|
if (stats.modelTiers.size === 0) return "";
|
|
129004
128695
|
if (stats.modelTiers.size > 1) return "mixed";
|
|
@@ -129019,13 +128710,10 @@ function classifyErrorType(err2) {
|
|
|
129019
128710
|
return "unknown";
|
|
129020
128711
|
}
|
|
129021
128712
|
function classifyCommand(argv, knownCommands) {
|
|
129022
|
-
const
|
|
129023
|
-
const first = rest[0];
|
|
128713
|
+
const first = argv.slice(2)[0];
|
|
129024
128714
|
if (first && !first.startsWith("-") && knownCommands.includes(first))
|
|
129025
128715
|
return first;
|
|
129026
|
-
|
|
129027
|
-
if (hasPositional) return "prompt";
|
|
129028
|
-
return process.stdout.isTTY ? "repl" : "stdin";
|
|
128716
|
+
return "help";
|
|
129029
128717
|
}
|
|
129030
128718
|
function topLevelCommand(action, root) {
|
|
129031
128719
|
let node2 = action;
|
|
@@ -129041,14 +128729,8 @@ function buildUsageEvent(input, installId) {
|
|
|
129041
128729
|
arch: process.arch,
|
|
129042
128730
|
command: input.command,
|
|
129043
128731
|
model_tier: resolveModelTier(),
|
|
129044
|
-
best_of_n: stats.bestOfN,
|
|
129045
128732
|
graph_used: stats.graphUsed ? 1 : 0,
|
|
129046
|
-
pipeline_used: stats.pipelineUsed ? 1 : 0,
|
|
129047
|
-
tui: input.tui ? 1 : 0,
|
|
129048
128733
|
headless: input.headless ?? !process.stdout.isTTY ? 1 : 0,
|
|
129049
|
-
byok: stats.byok ? 1 : 0,
|
|
129050
|
-
tool_calls_json: JSON.stringify(stats.toolCalls),
|
|
129051
|
-
step_count: stats.stepCount,
|
|
129052
128734
|
duration_ms: Math.max(0, Math.trunc(input.durationMs)),
|
|
129053
128735
|
error_type: input.errorType ?? "",
|
|
129054
128736
|
exit_status: input.exitStatus
|
|
@@ -129094,14 +128776,8 @@ var init_usage = __esm({
|
|
|
129094
128776
|
"arch",
|
|
129095
128777
|
"command",
|
|
129096
128778
|
"model_tier",
|
|
129097
|
-
"best_of_n",
|
|
129098
128779
|
"graph_used",
|
|
129099
|
-
"pipeline_used",
|
|
129100
|
-
"tui",
|
|
129101
128780
|
"headless",
|
|
129102
|
-
"byok",
|
|
129103
|
-
"tool_calls_json",
|
|
129104
|
-
"step_count",
|
|
129105
128781
|
"duration_ms",
|
|
129106
128782
|
"error_type",
|
|
129107
128783
|
"exit_status"
|
|
@@ -130137,14 +129813,12 @@ async function handleAgentEnroll(opts, writer = stdoutWriter) {
|
|
|
130137
129813
|
deps
|
|
130138
129814
|
);
|
|
130139
129815
|
if (!result2.ok) return false;
|
|
130140
|
-
await moveOffTacho(writer);
|
|
130141
129816
|
return result2.shipping?.healthy !== false;
|
|
130142
129817
|
}
|
|
130143
129818
|
var init_agent_enroll = __esm({
|
|
130144
129819
|
"src/commands/agent-enroll.ts"() {
|
|
130145
129820
|
init_config();
|
|
130146
129821
|
init_capture_writer();
|
|
130147
|
-
init_move_off_tacho();
|
|
130148
129822
|
}
|
|
130149
129823
|
});
|
|
130150
129824
|
|
|
@@ -130676,40 +130350,10 @@ function buildProgram() {
|
|
|
130676
130350
|
const program2 = new Command();
|
|
130677
130351
|
program2.name("oxagen").description(
|
|
130678
130352
|
"Oxagen governance CLI \u2014 spend, traces, grounding, credentials, and audit"
|
|
130679
|
-
).version(version).
|
|
130353
|
+
).version(version).option(
|
|
130680
130354
|
"-m, --model <slug>",
|
|
130681
130355
|
"Model slug for subcommands that price or filter by model (e.g. cost)"
|
|
130682
|
-
)
|
|
130683
|
-
printRetiredNotice("The oxagen coding agent (REPL / one-shot prompt)");
|
|
130684
|
-
});
|
|
130685
|
-
function retiredCommand(name, what) {
|
|
130686
|
-
program2.command(name).description(`(retired) ${what} \u2014 use the \`stella\` CLI`).argument("[args...]").allowUnknownOption(true).allowExcessArguments(true).action(async () => {
|
|
130687
|
-
printRetiredNotice(what);
|
|
130688
|
-
});
|
|
130689
|
-
}
|
|
130690
|
-
retiredCommand("view", "The agent-work dashboard");
|
|
130691
|
-
retiredCommand("agents", "The fleet agents screen");
|
|
130692
|
-
retiredCommand("solve", "Best-of-N task solving");
|
|
130693
|
-
retiredCommand("replay", "Local turn replay");
|
|
130694
|
-
retiredCommand("fleet", "The session fleet");
|
|
130695
|
-
retiredCommand("sandbox", "Agent sandbox sessions");
|
|
130696
|
-
retiredCommand("sandbox-template", "Sandbox template management");
|
|
130697
|
-
retiredCommand("code", "Local code diff/patch/format utilities");
|
|
130698
|
-
retiredCommand("eval", "Eval datasets and runs");
|
|
130699
|
-
retiredCommand("file-lock", "Agent file locks");
|
|
130700
|
-
retiredCommand("a2a", "The Agent2Agent protocol surface");
|
|
130701
|
-
retiredCommand("models", "On-device model runtime selection");
|
|
130702
|
-
retiredCommand("skill", "Loadable skill bundles");
|
|
130703
|
-
retiredCommand("prompt", "Saved prompt snippets");
|
|
130704
|
-
retiredCommand("command", "User-defined slash commands");
|
|
130705
|
-
retiredCommand("rules", "Local agent rule files");
|
|
130706
|
-
retiredCommand("settings", "The local settings.json driver");
|
|
130707
|
-
retiredCommand("config", "The local CLI config file");
|
|
130708
|
-
retiredCommand("mcp", "Local MCP server configuration");
|
|
130709
|
-
retiredCommand("import", "Foreign-platform artifact import");
|
|
130710
|
-
retiredCommand("pr", "Pull-request CI watching and merging");
|
|
130711
|
-
retiredCommand("recover", "Agent commit-ledger recovery");
|
|
130712
|
-
retiredCommand("lineage", "The subagent dispatch-tree explorer");
|
|
130356
|
+
);
|
|
130713
130357
|
program2.command("hook", { hidden: true }).description(
|
|
130714
130358
|
"The command hook a wrapped harness runs: reads the payload on stdin and prints the answer"
|
|
130715
130359
|
).helpOption(false).allowUnknownOption().allowExcessArguments().action(async () => {
|
|
@@ -131410,52 +131054,6 @@ function buildProgram() {
|
|
|
131410
131054
|
const { handleTelemetry: handleTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), telemetry_exports));
|
|
131411
131055
|
handleTelemetry2(subcommand);
|
|
131412
131056
|
});
|
|
131413
|
-
const tacho = program2.command("tacho", { hidden: true }).description(
|
|
131414
|
-
"Deprecated. Wrap this machine's agent sessions: record and gate them through Oxagen"
|
|
131415
|
-
);
|
|
131416
|
-
tacho.hook("preSubcommand", (_group, subcommand) => {
|
|
131417
|
-
printTachoAliasNotice(subcommand.name());
|
|
131418
|
-
});
|
|
131419
|
-
tacho.command("enroll").description(
|
|
131420
|
-
"Enroll this machine: device key, host API key, collector service, Claude Code hooks"
|
|
131421
|
-
).option(
|
|
131422
|
-
"--token <apiKey>",
|
|
131423
|
-
"Platform API token (default: the logged-in session)"
|
|
131424
|
-
).option("--org <slug>", "Organization slug (default: the logged-in org)").option(
|
|
131425
|
-
"--workspace <slug>",
|
|
131426
|
-
"Workspace slug (default: the logged-in workspace)"
|
|
131427
|
-
).option(
|
|
131428
|
-
"--port <n>",
|
|
131429
|
-
"Loopback port for the collector daemon (1024 to 65535)",
|
|
131430
|
-
parsePort2
|
|
131431
|
-
).option("--no-service", "Do not install the user service").option("--managed", "Also print the managed settings document for MDM").option(
|
|
131432
|
-
"--print-managed",
|
|
131433
|
-
"Only print the managed settings document; do not write user settings"
|
|
131434
|
-
).option("--force", "Enroll again even if already enrolled").option(
|
|
131435
|
-
"--harness <list>",
|
|
131436
|
-
"Harnesses to hook: claude-code, codex, cursor, stella, or a comma list such as claude-code,cursor"
|
|
131437
|
-
).option("--verify", "Run a headless Claude Code turn afterwards").option("--allow-root", "Enroll even when running as root").action(
|
|
131438
|
-
async (opts) => {
|
|
131439
|
-
const { handleTachoEnroll: handleTachoEnroll2 } = await Promise.resolve().then(() => (init_tacho(), tacho_exports));
|
|
131440
|
-
if (!await handleTachoEnroll2(opts)) process.exitCode = 1;
|
|
131441
|
-
}
|
|
131442
|
-
);
|
|
131443
|
-
addHostWrapCommands(tacho);
|
|
131444
|
-
tacho.command("status").description("Enrollment, daemon, hooks, bundle, and spool status").option("--json", "Machine-readable output").action(async (opts) => {
|
|
131445
|
-
const { handleTachoStatus: handleTachoStatus2 } = await Promise.resolve().then(() => (init_tacho(), tacho_exports));
|
|
131446
|
-
if (!await handleTachoStatus2(opts)) process.exitCode = 1;
|
|
131447
|
-
});
|
|
131448
|
-
tacho.command("unenroll").description(
|
|
131449
|
-
"Remove the hooks and the service, revoke the enrollment, delete the host key"
|
|
131450
|
-
).option("--token <apiKey>", "Operator token for the server-side revoke").option("--purge", "Also delete the local WAL, spool, and quarantine").option("--reason <text>", "Reason recorded with the revoke").option(
|
|
131451
|
-
"--harness <name>",
|
|
131452
|
-
"The agent to unenroll, by the harness it hooks, when this machine holds more than one enrollment"
|
|
131453
|
-
).option("--all", "Unenroll every agent on this machine").action(
|
|
131454
|
-
async (opts) => {
|
|
131455
|
-
const { handleTachoUnenroll: handleTachoUnenroll2 } = await Promise.resolve().then(() => (init_tacho(), tacho_exports));
|
|
131456
|
-
if (!await handleTachoUnenroll2(opts)) process.exitCode = 1;
|
|
131457
|
-
}
|
|
131458
|
-
);
|
|
131459
131057
|
program2.command("login").description(
|
|
131460
131058
|
"Authenticate the CLI \u2014 opens a browser by default (interactive). Use --token for CI/headless."
|
|
131461
131059
|
).option(
|
|
@@ -131836,7 +131434,6 @@ var init_program = __esm({
|
|
|
131836
131434
|
"src/program.ts"() {
|
|
131837
131435
|
init_esm();
|
|
131838
131436
|
init_package();
|
|
131839
|
-
init_retired();
|
|
131840
131437
|
({ version } = package_default);
|
|
131841
131438
|
ENROLLMENT_TOKEN_PREFIX = "oxe_1time_";
|
|
131842
131439
|
}
|
|
@@ -131927,14 +131524,14 @@ var init_main2 = __esm({
|
|
|
131927
131524
|
});
|
|
131928
131525
|
|
|
131929
131526
|
// src/index.ts
|
|
131930
|
-
var
|
|
131527
|
+
var MACHINE_COMMANDS = ["daemon", "mcp-stdio", "credential", "github", "arp"];
|
|
131931
131528
|
var command = process.argv[2];
|
|
131932
131529
|
if (command === "hook") {
|
|
131933
131530
|
Promise.resolve().then(() => (init_hook2(), hook_exports)).then(({ runHook: runHook2 }) => runHook2(process.argv)).catch(() => {
|
|
131934
131531
|
process.stdout.write("{}\n");
|
|
131935
131532
|
process.exitCode = 0;
|
|
131936
131533
|
});
|
|
131937
|
-
} else if (command !== void 0 &&
|
|
131534
|
+
} else if (command !== void 0 && MACHINE_COMMANDS.includes(command)) {
|
|
131938
131535
|
Promise.resolve().then(() => (init_recorder2(), recorder_exports)).then(({ runRecorderCommand: runRecorderCommand2 }) => runRecorderCommand2(process.argv)).catch((error) => {
|
|
131939
131536
|
process.stderr.write(
|
|
131940
131537
|
`oxagen ${command}: ${error instanceof Error ? error.message : String(error)}
|