@byok-sdk/client 0.1.0 → 0.1.1
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 +9 -0
- package/dist/adapters/codex/resolve-bin.d.ts +3 -4
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.js +1921 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/pi/resolve-bin.d.ts +12 -22
- package/dist/bin/byok-agent.js +91 -117
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/index.js +72 -97
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFile, spawn, spawnSync } from 'child_process';
|
|
2
2
|
import { createHash, randomUUID, sign, createPrivateKey, generateKeyPairSync, randomBytes, createHmac, timingSafeEqual } from 'crypto';
|
|
3
|
-
import { promises, mkdirSync, existsSync, renameSync, writeFileSync, chmodSync, statSync, readdirSync, linkSync, fstatSync, lstatSync, unlinkSync, constants,
|
|
4
|
-
import
|
|
3
|
+
import { promises, mkdirSync, existsSync, renameSync, writeFileSync, chmodSync, statSync, readdirSync, linkSync, fstatSync, lstatSync, unlinkSync, constants, realpathSync } from 'fs';
|
|
4
|
+
import path15, { join, isAbsolute } from 'path';
|
|
5
5
|
import os6 from 'os';
|
|
6
6
|
import { partitionAgentEvents, TASK_TRANSITIONS, encodeEnvelope, createEnvelope, MAX_MESSAGES_PER_BATCH, RuntimeIdSchema, PROTOCOL_VERSION, decodeEnvelope, MessagesSendResponseSchema, parseMessage, UnknownMessageTypeError } from '@byok-sdk/protocol';
|
|
7
7
|
import { promisify } from 'util';
|
|
@@ -71,7 +71,7 @@ function gitEnvironment(readOnly) {
|
|
|
71
71
|
return env;
|
|
72
72
|
}
|
|
73
73
|
function stableGitWorkspaceOwnerId(storeDir, productId) {
|
|
74
|
-
const identity = `${
|
|
74
|
+
const identity = `${path15.resolve(storeDir)}\\0${productId}`;
|
|
75
75
|
return `store-product:${createHash("sha256").update(identity).digest("hex")}`;
|
|
76
76
|
}
|
|
77
77
|
var GUIDANCE = [
|
|
@@ -83,11 +83,11 @@ var GUIDANCE = [
|
|
|
83
83
|
"Leave incomplete work visible for recovery."
|
|
84
84
|
].join("\n");
|
|
85
85
|
function canonical(value) {
|
|
86
|
-
return
|
|
86
|
+
return path15.resolve(value);
|
|
87
87
|
}
|
|
88
88
|
function isContained(root, candidate) {
|
|
89
|
-
const relative =
|
|
90
|
-
return relative === "" || !relative.startsWith(`..${
|
|
89
|
+
const relative = path15.relative(root, candidate);
|
|
90
|
+
return relative === "" || !relative.startsWith(`..${path15.sep}`) && !path15.isAbsolute(relative);
|
|
91
91
|
}
|
|
92
92
|
function bounded(value, max) {
|
|
93
93
|
return Buffer.byteLength(value, "utf8") <= max ? value : value.slice(0, max);
|
|
@@ -192,7 +192,7 @@ var GitWorkspaceManager = class {
|
|
|
192
192
|
await this.ensureOwnerMarker();
|
|
193
193
|
}
|
|
194
194
|
async ensureOwnerMarker() {
|
|
195
|
-
const markerPath =
|
|
195
|
+
const markerPath = path15.join(this.workspaceRoot, OWNER_MARKER);
|
|
196
196
|
let existing;
|
|
197
197
|
try {
|
|
198
198
|
existing = JSON.parse(await promises.readFile(markerPath, "utf8"));
|
|
@@ -351,7 +351,7 @@ ${instruction}`;
|
|
|
351
351
|
if (error instanceof GitWorkspaceError || code !== "ENOENT" && code !== "ENOTDIR") {
|
|
352
352
|
throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
|
|
353
353
|
}
|
|
354
|
-
const parent =
|
|
354
|
+
const parent = path15.dirname(current);
|
|
355
355
|
if (parent === current) {
|
|
356
356
|
throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
|
|
357
357
|
}
|
|
@@ -416,7 +416,7 @@ async function atomicWriteFile(filePath, data, options = {}) {
|
|
|
416
416
|
await target.close();
|
|
417
417
|
}
|
|
418
418
|
if (process.platform !== "win32") {
|
|
419
|
-
const directory = await promises.open(
|
|
419
|
+
const directory = await promises.open(path15.dirname(filePath), "r");
|
|
420
420
|
try {
|
|
421
421
|
await directory.sync();
|
|
422
422
|
} finally {
|
|
@@ -541,7 +541,7 @@ function isProtected(record) {
|
|
|
541
541
|
var GitWorkspaceStore = class {
|
|
542
542
|
constructor(storeDir, options = {}) {
|
|
543
543
|
this.storeDir = storeDir;
|
|
544
|
-
this.filePath =
|
|
544
|
+
this.filePath = path15.join(storeDir, FILE_NAME);
|
|
545
545
|
this.maxRecords = Math.max(1, Math.floor(options.maxRecords ?? MAX_RECORDS));
|
|
546
546
|
}
|
|
547
547
|
storeDir;
|
|
@@ -671,39 +671,14 @@ var GitWorkspaceStore = class {
|
|
|
671
671
|
await atomicWriteFile(this.filePath, JSON.stringify(ledger, null, 2), { mode: 384 });
|
|
672
672
|
}
|
|
673
673
|
};
|
|
674
|
+
|
|
675
|
+
// src/adapters/pi/resolve-bin.ts
|
|
674
676
|
var PI_PACKAGE_NAME = "@earendil-works/pi-coding-agent";
|
|
675
|
-
function readPackageJson(dir) {
|
|
676
|
-
const candidate = path16.join(dir, "package.json");
|
|
677
|
-
if (!existsSync(candidate)) return void 0;
|
|
678
|
-
try {
|
|
679
|
-
return JSON.parse(readFileSync(candidate, "utf8"));
|
|
680
|
-
} catch {
|
|
681
|
-
return void 0;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
677
|
function resolvePiBin() {
|
|
685
678
|
const override = process.env.BYOK_PI_BIN;
|
|
686
679
|
if (override) {
|
|
687
680
|
return { command: override, source: "path" };
|
|
688
681
|
}
|
|
689
|
-
try {
|
|
690
|
-
const mainEntryUrl = import.meta.resolve(PI_PACKAGE_NAME);
|
|
691
|
-
let dir = path16.dirname(fileURLToPath(mainEntryUrl));
|
|
692
|
-
for (let depth = 0; depth < 6; depth++) {
|
|
693
|
-
const pkg = readPackageJson(dir);
|
|
694
|
-
if (pkg?.name === PI_PACKAGE_NAME) {
|
|
695
|
-
const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.pi;
|
|
696
|
-
if (binRel) {
|
|
697
|
-
return { command: path16.join(dir, binRel), source: "package" };
|
|
698
|
-
}
|
|
699
|
-
break;
|
|
700
|
-
}
|
|
701
|
-
const parent = path16.dirname(dir);
|
|
702
|
-
if (parent === dir) break;
|
|
703
|
-
dir = parent;
|
|
704
|
-
}
|
|
705
|
-
} catch {
|
|
706
|
-
}
|
|
707
682
|
return { command: "pi", source: "path" };
|
|
708
683
|
}
|
|
709
684
|
|
|
@@ -1256,7 +1231,7 @@ function resolveApprovalMcpBin() {
|
|
|
1256
1231
|
if (override) {
|
|
1257
1232
|
return { command: override, args: [], source: "env" };
|
|
1258
1233
|
}
|
|
1259
|
-
const distBin =
|
|
1234
|
+
const distBin = path15.join(path15.dirname(fileURLToPath(import.meta.url)), "bin", "byok-approval-mcp.js");
|
|
1260
1235
|
return { command: process.execPath, args: [distBin], source: "dist" };
|
|
1261
1236
|
}
|
|
1262
1237
|
|
|
@@ -1336,7 +1311,7 @@ var EXTENSION_CONTENT_TYPES = {
|
|
|
1336
1311
|
".yml": "application/yaml"
|
|
1337
1312
|
};
|
|
1338
1313
|
function guessContentType(filePath) {
|
|
1339
|
-
const ext =
|
|
1314
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
1340
1315
|
return EXTENSION_CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
1341
1316
|
}
|
|
1342
1317
|
function mapAssistant(msg, correlation) {
|
|
@@ -1408,11 +1383,11 @@ function tryBuildArtifactEvent(msg, workspaceDir) {
|
|
|
1408
1383
|
const filePath = toolUseResult && typeof toolUseResult.filePath === "string" ? toolUseResult.filePath : void 0;
|
|
1409
1384
|
if (!filePath) return void 0;
|
|
1410
1385
|
const realWorkspaceDir = tryRealpath(workspaceDir) ?? workspaceDir;
|
|
1411
|
-
const fileDir =
|
|
1386
|
+
const fileDir = path15.dirname(filePath);
|
|
1412
1387
|
const realFileDir = tryRealpath(fileDir) ?? fileDir;
|
|
1413
|
-
const realFilePath =
|
|
1414
|
-
const relative =
|
|
1415
|
-
if (relative === "" || relative.startsWith("..") ||
|
|
1388
|
+
const realFilePath = path15.join(realFileDir, path15.basename(filePath));
|
|
1389
|
+
const relative = path15.relative(realWorkspaceDir, realFilePath);
|
|
1390
|
+
if (relative === "" || relative.startsWith("..") || path15.isAbsolute(relative)) {
|
|
1416
1391
|
return void 0;
|
|
1417
1392
|
}
|
|
1418
1393
|
return { type: "artifact", name: relative, contentType: guessContentType(filePath) };
|
|
@@ -1711,10 +1686,10 @@ var ClaudeAdapter = class {
|
|
|
1711
1686
|
);
|
|
1712
1687
|
}
|
|
1713
1688
|
const approvalMcpBin = (this.options.resolveApprovalMcpBin ?? resolveApprovalMcpBin)();
|
|
1714
|
-
approvalMcpConfigDir = await promises.mkdtemp(
|
|
1689
|
+
approvalMcpConfigDir = await promises.mkdtemp(path15.join(os6.tmpdir(), "byok-approval-mcp-"));
|
|
1715
1690
|
await promises.chmod(approvalMcpConfigDir, 448).catch(() => {
|
|
1716
1691
|
});
|
|
1717
|
-
const mcpConfigPath =
|
|
1692
|
+
const mcpConfigPath = path15.join(approvalMcpConfigDir, "mcp-config.json");
|
|
1718
1693
|
const mcpConfig = {
|
|
1719
1694
|
mcpServers: {
|
|
1720
1695
|
[APPROVAL_MCP_SERVER_NAME]: {
|
|
@@ -2061,8 +2036,8 @@ function extractArtifactEvents(changes, workspaceDir) {
|
|
|
2061
2036
|
const absolutePath = typeof change.path === "string" ? change.path : void 0;
|
|
2062
2037
|
const kind = typeof change.kind === "string" ? change.kind : void 0;
|
|
2063
2038
|
if (!absolutePath || kind === "delete") continue;
|
|
2064
|
-
const relative =
|
|
2065
|
-
if (relative.length === 0 || relative.startsWith("..") ||
|
|
2039
|
+
const relative = path15.relative(workspaceDir, absolutePath);
|
|
2040
|
+
if (relative.length === 0 || relative.startsWith("..") || path15.isAbsolute(relative)) continue;
|
|
2066
2041
|
events.push({ type: "artifact", name: relative, contentType: guessContentType2(relative) });
|
|
2067
2042
|
}
|
|
2068
2043
|
return events;
|
|
@@ -2083,7 +2058,7 @@ var CONTENT_TYPE_BY_EXTENSION = {
|
|
|
2083
2058
|
".csv": "text/csv"
|
|
2084
2059
|
};
|
|
2085
2060
|
function guessContentType2(relativePath) {
|
|
2086
|
-
return CONTENT_TYPE_BY_EXTENSION[
|
|
2061
|
+
return CONTENT_TYPE_BY_EXTENSION[path15.extname(relativePath).toLowerCase()] ?? "application/octet-stream";
|
|
2087
2062
|
}
|
|
2088
2063
|
function extractErrorMessage(rawError) {
|
|
2089
2064
|
if (typeof rawError === "string") return rawError;
|
|
@@ -2689,12 +2664,12 @@ var DeviceStore = class _DeviceStore {
|
|
|
2689
2664
|
*/
|
|
2690
2665
|
constructor(storeDir, secureDirOptions) {
|
|
2691
2666
|
this.secureDirOptions = secureDirOptions;
|
|
2692
|
-
this.filePath =
|
|
2667
|
+
this.filePath = path15.join(storeDir, "device.json");
|
|
2693
2668
|
}
|
|
2694
2669
|
secureDirOptions;
|
|
2695
2670
|
filePath;
|
|
2696
2671
|
static defaultDir(productId) {
|
|
2697
|
-
return
|
|
2672
|
+
return path15.join(os6.homedir(), ".byok", productId);
|
|
2698
2673
|
}
|
|
2699
2674
|
/**
|
|
2700
2675
|
* Resolve the one store pathname every daemon/CLI component must share.
|
|
@@ -2703,7 +2678,7 @@ var DeviceStore = class _DeviceStore {
|
|
|
2703
2678
|
* cwd to pin a quarantine directory inode.
|
|
2704
2679
|
*/
|
|
2705
2680
|
static resolveDir(productId, configured) {
|
|
2706
|
-
return
|
|
2681
|
+
return path15.resolve(configured ?? _DeviceStore.defaultDir(productId));
|
|
2707
2682
|
}
|
|
2708
2683
|
async load() {
|
|
2709
2684
|
const opened = await this.openBounded();
|
|
@@ -2744,7 +2719,7 @@ var DeviceStore = class _DeviceStore {
|
|
|
2744
2719
|
}
|
|
2745
2720
|
}
|
|
2746
2721
|
async save(record) {
|
|
2747
|
-
const storeDir =
|
|
2722
|
+
const storeDir = path15.dirname(this.filePath);
|
|
2748
2723
|
await ensureSecureDir(storeDir, this.secureDirOptions);
|
|
2749
2724
|
await atomicWriteFile(this.filePath, JSON.stringify(record, null, 2), { mode: 384 });
|
|
2750
2725
|
}
|
|
@@ -3178,19 +3153,19 @@ function shortHash(input) {
|
|
|
3178
3153
|
return createHash("sha256").update(input, "utf8").digest("hex").slice(0, 16);
|
|
3179
3154
|
}
|
|
3180
3155
|
function controlSocketPath(storeDir) {
|
|
3181
|
-
const candidate =
|
|
3156
|
+
const candidate = path15.join(storeDir, "control.sock");
|
|
3182
3157
|
if (Buffer.byteLength(candidate, "utf8") <= UNIX_SOCKET_PATH_SOFT_LIMIT) return candidate;
|
|
3183
|
-
return
|
|
3158
|
+
return path15.join(os6.tmpdir(), `byok-${shortHash(storeDir)}`, "sock");
|
|
3184
3159
|
}
|
|
3185
3160
|
function controlPipeName(productId, storeDir) {
|
|
3186
|
-
const id = shortHash(`${productId}|${
|
|
3161
|
+
const id = shortHash(`${productId}|${path15.resolve(storeDir)}`);
|
|
3187
3162
|
return `\\\\.\\pipe\\byok-${id}`;
|
|
3188
3163
|
}
|
|
3189
3164
|
function controlEndpointPath(productId, storeDir, platform = process.platform) {
|
|
3190
3165
|
return platform === "win32" ? controlPipeName(productId, storeDir) : controlSocketPath(storeDir);
|
|
3191
3166
|
}
|
|
3192
3167
|
function controlTokenPath(storeDir) {
|
|
3193
|
-
return
|
|
3168
|
+
return path15.join(storeDir, "control.token");
|
|
3194
3169
|
}
|
|
3195
3170
|
var SERVER_PROOF_LABEL = "byok-control-server|";
|
|
3196
3171
|
var CLIENT_AUTH_LABEL = "byok-control-client|";
|
|
@@ -3335,7 +3310,7 @@ async function assertOwnedPrivateDir(dir) {
|
|
|
3335
3310
|
}
|
|
3336
3311
|
async function bindControlEndpoint(server, endpoint) {
|
|
3337
3312
|
if (process.platform !== "win32") {
|
|
3338
|
-
const endpointDir =
|
|
3313
|
+
const endpointDir = path15.dirname(endpoint);
|
|
3339
3314
|
await promises.mkdir(endpointDir, { recursive: true, mode: 448 });
|
|
3340
3315
|
await promises.chmod(endpointDir, 448).catch(() => {
|
|
3341
3316
|
});
|
|
@@ -4616,7 +4591,7 @@ function sameFileState2(left, right) {
|
|
|
4616
4591
|
return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
|
|
4617
4592
|
}
|
|
4618
4593
|
async function openOperationalHealthFile(storeDir) {
|
|
4619
|
-
const filePath =
|
|
4594
|
+
const filePath = path15.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
|
|
4620
4595
|
let namedBefore;
|
|
4621
4596
|
try {
|
|
4622
4597
|
namedBefore = await promises.lstat(filePath, { bigint: true });
|
|
@@ -4658,7 +4633,7 @@ var OperationalHealthTracker = class {
|
|
|
4658
4633
|
#writeTail = Promise.resolve();
|
|
4659
4634
|
#started = false;
|
|
4660
4635
|
constructor(storeDir, options = {}) {
|
|
4661
|
-
this.#filePath =
|
|
4636
|
+
this.#filePath = path15.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
|
|
4662
4637
|
this.#windowMs = options.windowMs ?? 6e4;
|
|
4663
4638
|
this.#failureThreshold = options.failureThreshold ?? 3;
|
|
4664
4639
|
this.#maxFailures = options.maxFailures ?? 128;
|
|
@@ -4745,7 +4720,7 @@ var OperationalHealthTracker = class {
|
|
|
4745
4720
|
async #load() {
|
|
4746
4721
|
let opened;
|
|
4747
4722
|
try {
|
|
4748
|
-
opened = await openOperationalHealthFile(
|
|
4723
|
+
opened = await openOperationalHealthFile(path15.dirname(this.#filePath));
|
|
4749
4724
|
} catch (err) {
|
|
4750
4725
|
throw new Error("operational health state could not be read");
|
|
4751
4726
|
}
|
|
@@ -4781,7 +4756,7 @@ var OperationalHealthTracker = class {
|
|
|
4781
4756
|
if (!this.#state) return;
|
|
4782
4757
|
const body = JSON.stringify(this.#state, null, 2);
|
|
4783
4758
|
this.#writeTail = this.#writeTail.then(async () => {
|
|
4784
|
-
await ensureSecureDir(
|
|
4759
|
+
await ensureSecureDir(path15.dirname(this.#filePath));
|
|
4785
4760
|
await atomicWriteFile(this.#filePath, body, { mode: 384, fsync: true });
|
|
4786
4761
|
});
|
|
4787
4762
|
try {
|
|
@@ -5100,8 +5075,8 @@ async function acquireDaemonOwner(storeDir, role, clock = () => /* @__PURE__ */
|
|
|
5100
5075
|
await mutex.close().catch(() => void 0);
|
|
5101
5076
|
throw err;
|
|
5102
5077
|
}
|
|
5103
|
-
const ownerPath =
|
|
5104
|
-
const reclaimPath =
|
|
5078
|
+
const ownerPath = path15.join(storeDir, DAEMON_OWNER_FILENAME);
|
|
5079
|
+
const reclaimPath = path15.join(storeDir, RECLAIM_FILENAME);
|
|
5105
5080
|
const record = {
|
|
5106
5081
|
version: 2,
|
|
5107
5082
|
pid: process.pid,
|
|
@@ -5178,7 +5153,7 @@ var CursorStore = class {
|
|
|
5178
5153
|
storeDir;
|
|
5179
5154
|
fileFor(serverUrl, deviceId) {
|
|
5180
5155
|
const key = createHash("sha256").update(`${serverUrl}::${deviceId}`).digest("hex").slice(0, 32);
|
|
5181
|
-
return
|
|
5156
|
+
return path15.join(this.storeDir, `cursor-${key}.json`);
|
|
5182
5157
|
}
|
|
5183
5158
|
async load(serverUrl, deviceId) {
|
|
5184
5159
|
let raw;
|
|
@@ -5198,7 +5173,7 @@ var CursorStore = class {
|
|
|
5198
5173
|
}
|
|
5199
5174
|
async save(serverUrl, deviceId, cursor) {
|
|
5200
5175
|
const file = this.fileFor(serverUrl, deviceId);
|
|
5201
|
-
await promises.mkdir(
|
|
5176
|
+
await promises.mkdir(path15.dirname(file), { recursive: true, mode: 448 });
|
|
5202
5177
|
await atomicWriteFile(file, JSON.stringify({ cursor }));
|
|
5203
5178
|
}
|
|
5204
5179
|
/** Remove any persisted cursor for (serverUrl, deviceId) — a no-op if none exists. Called from `pair()` (finding F5) so a device that's about to be replaced never leaves a cursor a future, unrelated device could somehow inherit. */
|
|
@@ -5494,7 +5469,7 @@ var SessionWorkspaceStore = class {
|
|
|
5494
5469
|
*/
|
|
5495
5470
|
queue = Promise.resolve();
|
|
5496
5471
|
constructor(storeDir) {
|
|
5497
|
-
this.filePath =
|
|
5472
|
+
this.filePath = path15.join(storeDir, "session-workspaces.json");
|
|
5498
5473
|
}
|
|
5499
5474
|
async get(sessionRef) {
|
|
5500
5475
|
return this.enqueue(async () => {
|
|
@@ -5552,7 +5527,7 @@ var SessionWorkspaceStore = class {
|
|
|
5552
5527
|
}
|
|
5553
5528
|
}
|
|
5554
5529
|
async save(all) {
|
|
5555
|
-
const dir =
|
|
5530
|
+
const dir = path15.dirname(this.filePath);
|
|
5556
5531
|
await promises.mkdir(dir, { recursive: true, mode: 448 });
|
|
5557
5532
|
const tmpPath = `${this.filePath}.${process.pid}-${tmpSeq2++}.tmp`;
|
|
5558
5533
|
try {
|
|
@@ -5657,9 +5632,9 @@ function isSqliteAvailable() {
|
|
|
5657
5632
|
}
|
|
5658
5633
|
}
|
|
5659
5634
|
var SECURE_FILE_MODE = 384;
|
|
5660
|
-
function openJournalDatabase(
|
|
5635
|
+
function openJournalDatabase(path19, busyTimeoutMs, faults) {
|
|
5661
5636
|
const { DatabaseSync } = loadSqliteModule();
|
|
5662
|
-
const db = new DatabaseSync(
|
|
5637
|
+
const db = new DatabaseSync(path19, { timeout: busyTimeoutMs });
|
|
5663
5638
|
try {
|
|
5664
5639
|
faults?.onStep?.("after-open");
|
|
5665
5640
|
db.exec("PRAGMA auto_vacuum = INCREMENTAL;");
|
|
@@ -5802,9 +5777,9 @@ var RECEIVED_STATE = "received";
|
|
|
5802
5777
|
function byteLength(value) {
|
|
5803
5778
|
return Buffer.byteLength(value, "utf8");
|
|
5804
5779
|
}
|
|
5805
|
-
function fileBytes(
|
|
5780
|
+
function fileBytes(path19) {
|
|
5806
5781
|
try {
|
|
5807
|
-
return statSync(
|
|
5782
|
+
return statSync(path19).size;
|
|
5808
5783
|
} catch {
|
|
5809
5784
|
return 0;
|
|
5810
5785
|
}
|
|
@@ -7058,8 +7033,8 @@ function estimateEventBytes(event) {
|
|
|
7058
7033
|
}
|
|
7059
7034
|
async function openArtifact(workspaceDir, name) {
|
|
7060
7035
|
const realWorkspaceDir = await promises.realpath(workspaceDir).catch(() => workspaceDir);
|
|
7061
|
-
const candidate =
|
|
7062
|
-
const prefix = realWorkspaceDir.endsWith(
|
|
7036
|
+
const candidate = path15.resolve(realWorkspaceDir, name);
|
|
7037
|
+
const prefix = realWorkspaceDir.endsWith(path15.sep) ? realWorkspaceDir : realWorkspaceDir + path15.sep;
|
|
7063
7038
|
if (candidate !== realWorkspaceDir && !candidate.startsWith(prefix)) {
|
|
7064
7039
|
return { ok: false, reason: `artifact name "${name}" resolves outside the task workspace \u2014 rejected` };
|
|
7065
7040
|
}
|
|
@@ -7457,7 +7432,7 @@ var TaskRunner = class {
|
|
|
7457
7432
|
const sameProtocolTask = ledger?.taskId === taskId;
|
|
7458
7433
|
const interruptedOldTask = ledger?.phase === "interrupted" && sameProtocolTask;
|
|
7459
7434
|
const activeDifferentTask = ledger !== void 0 && ledger.taskId !== taskId && (ledger.phase === "preparing" || ledger.phase === "active");
|
|
7460
|
-
if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== payload.sessionRef ||
|
|
7435
|
+
if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== payload.sessionRef || path15.resolve(ledger.workspaceDir) !== path15.resolve(known.workspaceDir) || interruptedOldTask || activeDifferentTask) {
|
|
7461
7436
|
this.decline(taskId, "session is incompatible with Git workspace mode", true);
|
|
7462
7437
|
return;
|
|
7463
7438
|
}
|
|
@@ -7472,7 +7447,7 @@ var TaskRunner = class {
|
|
|
7472
7447
|
return;
|
|
7473
7448
|
}
|
|
7474
7449
|
} else {
|
|
7475
|
-
workspaceDir =
|
|
7450
|
+
workspaceDir = path15.join(this.deps.workspaceRoot, taskId);
|
|
7476
7451
|
}
|
|
7477
7452
|
try {
|
|
7478
7453
|
gitLease = await gitManager.acquireLease(workspaceDir, payload.sessionRef);
|
|
@@ -7482,7 +7457,7 @@ var TaskRunner = class {
|
|
|
7482
7457
|
}
|
|
7483
7458
|
} else if (!this.deps.gitWorkspaceManager && !this.deps.gitWorkspaceStore) {
|
|
7484
7459
|
known = payload.sessionRef ? await this.deps.sessionWorkspaces.get(payload.sessionRef) : void 0;
|
|
7485
|
-
workspaceDir = known?.workspaceDir ??
|
|
7460
|
+
workspaceDir = known?.workspaceDir ?? path15.join(this.deps.workspaceRoot, taskId);
|
|
7486
7461
|
plainWorkspaceNeedsResolve = true;
|
|
7487
7462
|
} else {
|
|
7488
7463
|
this.decline(taskId, "workspace mode is unavailable", true);
|
|
@@ -8354,7 +8329,7 @@ var TaskRunner = class {
|
|
|
8354
8329
|
}
|
|
8355
8330
|
/** `reuseDir`, when set (a known sessionRef's recorded workspace), is used verbatim instead of a fresh `workspaceRoot/<taskId>` directory — `mkdir recursive` is idempotent either way, so ensuring-exists is safe to do unconditionally. */
|
|
8356
8331
|
async resolveWorkspaceDir(taskId, reuseDir) {
|
|
8357
|
-
const dir = reuseDir ??
|
|
8332
|
+
const dir = reuseDir ?? path15.join(this.deps.workspaceRoot, taskId);
|
|
8358
8333
|
await promises.mkdir(dir, { recursive: true });
|
|
8359
8334
|
return dir;
|
|
8360
8335
|
}
|
|
@@ -9256,8 +9231,8 @@ var TruthMemoryClient = class {
|
|
|
9256
9231
|
#requestId;
|
|
9257
9232
|
#allowedObjectDownloadOrigins;
|
|
9258
9233
|
async listManifest(query = {}) {
|
|
9259
|
-
const
|
|
9260
|
-
const response = await this.#proofFetch(
|
|
9234
|
+
const path19 = manifestPath(query);
|
|
9235
|
+
const response = await this.#proofFetch(path19, {
|
|
9261
9236
|
method: "GET",
|
|
9262
9237
|
operation: "truth.list",
|
|
9263
9238
|
resource: "records",
|
|
@@ -9364,9 +9339,9 @@ var TruthMemoryClient = class {
|
|
|
9364
9339
|
}
|
|
9365
9340
|
async #write(kind, recordKey, requestId, payload, expectedPrimary, expectedSnapshots) {
|
|
9366
9341
|
assertDistinctExpectedWrites([expectedPrimary, ...expectedSnapshots]);
|
|
9367
|
-
const
|
|
9342
|
+
const path19 = recordPath(kind, recordKey);
|
|
9368
9343
|
const body = new TextEncoder().encode(JSON.stringify(payload));
|
|
9369
|
-
const response = await this.#proofFetch(
|
|
9344
|
+
const response = await this.#proofFetch(path19, {
|
|
9370
9345
|
method: "PUT",
|
|
9371
9346
|
operation: "truth.write",
|
|
9372
9347
|
resource: `${kind}/${recordKey}`,
|
|
@@ -9392,8 +9367,8 @@ var TruthMemoryClient = class {
|
|
|
9392
9367
|
};
|
|
9393
9368
|
}
|
|
9394
9369
|
async #readVerified(listed) {
|
|
9395
|
-
const
|
|
9396
|
-
const response = await this.#proofFetch(
|
|
9370
|
+
const path19 = recordPath(listed.kind, listed.recordKey);
|
|
9371
|
+
const response = await this.#proofFetch(path19, {
|
|
9397
9372
|
method: "GET",
|
|
9398
9373
|
operation: "truth.read",
|
|
9399
9374
|
resource: `${listed.kind}/${listed.recordKey}`,
|
|
@@ -9454,16 +9429,16 @@ var TruthMemoryClient = class {
|
|
|
9454
9429
|
}
|
|
9455
9430
|
return { ...listed, bytes };
|
|
9456
9431
|
}
|
|
9457
|
-
async #proofFetch(
|
|
9432
|
+
async #proofFetch(path19, request) {
|
|
9458
9433
|
const proof = await this.options.signer.sign({
|
|
9459
9434
|
method: request.method,
|
|
9460
|
-
path:
|
|
9435
|
+
path: path19,
|
|
9461
9436
|
operation: request.operation,
|
|
9462
9437
|
resource: request.resource,
|
|
9463
9438
|
requestId: request.requestId,
|
|
9464
9439
|
body: request.body
|
|
9465
9440
|
});
|
|
9466
|
-
const response = await this.#fetch(new URL(
|
|
9441
|
+
const response = await this.#fetch(new URL(path19, this.#base), {
|
|
9467
9442
|
method: request.method,
|
|
9468
9443
|
headers: {
|
|
9469
9444
|
...request.headers,
|
|
@@ -9474,7 +9449,7 @@ var TruthMemoryClient = class {
|
|
|
9474
9449
|
if (!response.ok) {
|
|
9475
9450
|
throw new TruthMemoryClientError(
|
|
9476
9451
|
"truth_http_failed",
|
|
9477
|
-
`truth request ${request.method} ${
|
|
9452
|
+
`truth request ${request.method} ${path19} failed with HTTP ${response.status}`,
|
|
9478
9453
|
response.status
|
|
9479
9454
|
);
|
|
9480
9455
|
}
|
|
@@ -9733,8 +9708,8 @@ function generateLaunchdPlist(def) {
|
|
|
9733
9708
|
const { label, program, logDir } = def;
|
|
9734
9709
|
const args = [program.command, ...program.args];
|
|
9735
9710
|
const cwd = program.cwd ?? os6.homedir();
|
|
9736
|
-
const outLog =
|
|
9737
|
-
const errLog =
|
|
9711
|
+
const outLog = path15.join(logDir, `${label}.out.log`);
|
|
9712
|
+
const errLog = path15.join(logDir, `${label}.err.log`);
|
|
9738
9713
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
9739
9714
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
9740
9715
|
<plist version="1.0">
|
|
@@ -9775,7 +9750,7 @@ function createLaunchdLifecycle(def, deps = {}) {
|
|
|
9775
9750
|
return process.getuid();
|
|
9776
9751
|
});
|
|
9777
9752
|
const label = sanitizeServiceName(def.name);
|
|
9778
|
-
const plistPath = () =>
|
|
9753
|
+
const plistPath = () => path15.join(homedir(), "Library", "LaunchAgents", `${label}.plist`);
|
|
9779
9754
|
const domainTarget = () => `gui/${getuid()}`;
|
|
9780
9755
|
const serviceTarget = () => `${domainTarget()}/${label}`;
|
|
9781
9756
|
async function fileExists(p) {
|
|
@@ -9788,7 +9763,7 @@ function createLaunchdLifecycle(def, deps = {}) {
|
|
|
9788
9763
|
}
|
|
9789
9764
|
async function writePlist(program) {
|
|
9790
9765
|
const xml = generateLaunchdPlist({ label, program, logDir: def.logDir });
|
|
9791
|
-
await fs15.mkdir(
|
|
9766
|
+
await fs15.mkdir(path15.dirname(plistPath()), { recursive: true });
|
|
9792
9767
|
await fs15.mkdir(def.logDir, { recursive: true });
|
|
9793
9768
|
await fs15.writeFile(plistPath(), xml, "utf8");
|
|
9794
9769
|
}
|
|
@@ -9862,8 +9837,8 @@ function generateSystemdUnit(def) {
|
|
|
9862
9837
|
assertNoControlChars(displayName, "displayName");
|
|
9863
9838
|
const cwd = program.cwd ?? os6.homedir();
|
|
9864
9839
|
assertNoControlChars(cwd, "program.cwd");
|
|
9865
|
-
const outLog =
|
|
9866
|
-
const errLog =
|
|
9840
|
+
const outLog = path15.join(logDir, `${name}.out.log`);
|
|
9841
|
+
const errLog = path15.join(logDir, `${name}.err.log`);
|
|
9867
9842
|
assertNoControlChars(outLog, "logDir");
|
|
9868
9843
|
assertNoControlChars(errLog, "logDir");
|
|
9869
9844
|
const execStart = [program.command, ...program.args].map(quoteSystemdArg).join(" ");
|
|
@@ -9889,7 +9864,7 @@ function createSystemdLifecycle(def, deps = {}) {
|
|
|
9889
9864
|
const homedir = deps.homedir ?? (() => os6.homedir());
|
|
9890
9865
|
const name = sanitizeServiceName(def.name);
|
|
9891
9866
|
const unitName = `${name}.service`;
|
|
9892
|
-
const unitPath = () =>
|
|
9867
|
+
const unitPath = () => path15.join(homedir(), ".config", "systemd", "user", unitName);
|
|
9893
9868
|
async function fileExists(p) {
|
|
9894
9869
|
try {
|
|
9895
9870
|
await fs15.stat(p);
|
|
@@ -9900,7 +9875,7 @@ function createSystemdLifecycle(def, deps = {}) {
|
|
|
9900
9875
|
}
|
|
9901
9876
|
async function writeUnit(program) {
|
|
9902
9877
|
const unit = generateSystemdUnit({ name, displayName: def.displayName ?? def.name, program, logDir: def.logDir });
|
|
9903
|
-
await fs15.mkdir(
|
|
9878
|
+
await fs15.mkdir(path15.dirname(unitPath()), { recursive: true });
|
|
9904
9879
|
await fs15.mkdir(def.logDir, { recursive: true });
|
|
9905
9880
|
await fs15.writeFile(unitPath(), unit, "utf8");
|
|
9906
9881
|
}
|
|
@@ -9982,8 +9957,8 @@ function createWinswLifecycle(def, deps = {}) {
|
|
|
9982
9957
|
const winswBin = windows.winswBin;
|
|
9983
9958
|
const id = sanitizeServiceName(def.name);
|
|
9984
9959
|
const installDir = windows.installDir ?? def.logDir;
|
|
9985
|
-
const exePath =
|
|
9986
|
-
const xmlPath =
|
|
9960
|
+
const exePath = path15.join(installDir, `${id}.exe`);
|
|
9961
|
+
const xmlPath = path15.join(installDir, `${id}.xml`);
|
|
9987
9962
|
async function fileExists(p) {
|
|
9988
9963
|
try {
|
|
9989
9964
|
await fs15.stat(p);
|