@lazehq/cli 0.1.14 → 0.1.15
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/dist/laze.mjs +552 -485
- package/package.json +1 -1
package/dist/laze.mjs
CHANGED
|
@@ -18733,8 +18733,8 @@ var require_snapshot_utils = __commonJS({
|
|
|
18733
18733
|
var require_snapshot_recorder = __commonJS({
|
|
18734
18734
|
"../../node_modules/.pnpm/undici@8.10.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
18735
18735
|
"use strict";
|
|
18736
|
-
var { writeFile:
|
|
18737
|
-
var { dirname:
|
|
18736
|
+
var { writeFile: writeFile21, readFile: readFile33, mkdir: mkdir19 } = __require("node:fs/promises");
|
|
18737
|
+
var { dirname: dirname19, resolve: resolve17 } = __require("node:path");
|
|
18738
18738
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
18739
18739
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
18740
18740
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -18950,7 +18950,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
18950
18950
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
18951
18951
|
}
|
|
18952
18952
|
try {
|
|
18953
|
-
const data = await
|
|
18953
|
+
const data = await readFile33(resolve17(path), "utf8");
|
|
18954
18954
|
const parsed = JSON.parse(data);
|
|
18955
18955
|
if (Array.isArray(parsed)) {
|
|
18956
18956
|
this.#snapshots.clear();
|
|
@@ -18980,12 +18980,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
18980
18980
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
18981
18981
|
}
|
|
18982
18982
|
const resolvedPath = resolve17(path);
|
|
18983
|
-
await
|
|
18983
|
+
await mkdir19(dirname19(resolvedPath), { recursive: true });
|
|
18984
18984
|
const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
18985
18985
|
hash: hash2,
|
|
18986
18986
|
snapshot
|
|
18987
18987
|
}));
|
|
18988
|
-
await
|
|
18988
|
+
await writeFile21(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
|
|
18989
18989
|
}
|
|
18990
18990
|
/**
|
|
18991
18991
|
* Clears all recorded snapshots
|
|
@@ -35606,7 +35606,7 @@ function flagText({
|
|
|
35606
35606
|
}
|
|
35607
35607
|
|
|
35608
35608
|
// src/rules/cli-version.rules.ts
|
|
35609
|
-
var STAMPED = "0.1.
|
|
35609
|
+
var STAMPED = "0.1.15";
|
|
35610
35610
|
function cliVersionOf({ stamped = STAMPED } = {}) {
|
|
35611
35611
|
return stamped.startsWith("__") ? "dev" : stamped;
|
|
35612
35612
|
}
|
|
@@ -65390,7 +65390,7 @@ async function copyAgent({
|
|
|
65390
65390
|
}
|
|
65391
65391
|
|
|
65392
65392
|
// src/services/agent-commands.service.ts
|
|
65393
|
-
import { mkdir as
|
|
65393
|
+
import { mkdir as mkdir13, readFile as readFile11, writeFile as writeFile13 } from "node:fs/promises";
|
|
65394
65394
|
import { join as join12, resolve as resolve4 } from "node:path";
|
|
65395
65395
|
|
|
65396
65396
|
// src/rules/agent-profile.rules.ts
|
|
@@ -67264,10 +67264,327 @@ async function claudeProjectOf({
|
|
|
67264
67264
|
return candidates.find((folder) => holds({ folder, inner: context.cwd })) ?? resolve2(context.cwd);
|
|
67265
67265
|
}
|
|
67266
67266
|
|
|
67267
|
+
// src/services/claude-wait.service.ts
|
|
67268
|
+
import { readFile as readFile5, rm as rm2, writeFile as writeFile5, mkdir as mkdir5 } from "node:fs/promises";
|
|
67269
|
+
import { dirname as dirname5 } from "node:path";
|
|
67270
|
+
|
|
67271
|
+
// src/services/harness-session.service.ts
|
|
67272
|
+
import { mkdir as mkdir4, readdir, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
|
|
67273
|
+
import { hostname as hostname3 } from "node:os";
|
|
67274
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
67275
|
+
|
|
67276
|
+
// src/rules/session-headers.rules.ts
|
|
67277
|
+
import { relative as relative2, sep } from "node:path";
|
|
67278
|
+
function sessionKeyOf({ session }) {
|
|
67279
|
+
return `${session.harness}:${session.sessionId}`;
|
|
67280
|
+
}
|
|
67281
|
+
function sessionHeadersOf({
|
|
67282
|
+
session
|
|
67283
|
+
}) {
|
|
67284
|
+
if (!session) return {};
|
|
67285
|
+
return {
|
|
67286
|
+
[AGENT_SESSION_HEADER]: sessionKeyOf({ session }),
|
|
67287
|
+
[AGENT_SESSION_FOLDER_HEADER]: encodeURIComponent(session.folder),
|
|
67288
|
+
[AGENT_SESSION_HOST_HEADER]: encodeURIComponent(session.host)
|
|
67289
|
+
};
|
|
67290
|
+
}
|
|
67291
|
+
function displayFolderOf({ folder, home }) {
|
|
67292
|
+
if (!home) return folder;
|
|
67293
|
+
const below = relative2(home, folder);
|
|
67294
|
+
if (below === "") return "~";
|
|
67295
|
+
if (below.startsWith("..") || below.startsWith(sep)) return folder;
|
|
67296
|
+
return `~/${below.split(sep).join("/")}`;
|
|
67297
|
+
}
|
|
67298
|
+
|
|
67299
|
+
// src/services/harness-session.service.ts
|
|
67300
|
+
function sessionOf({
|
|
67301
|
+
context,
|
|
67302
|
+
harness,
|
|
67303
|
+
sessionId
|
|
67304
|
+
}) {
|
|
67305
|
+
if (!sessionId) return void 0;
|
|
67306
|
+
const inherited = context.environment.inherited;
|
|
67307
|
+
const folder = inherited.CLAUDE_PROJECT_DIR || context.cwd;
|
|
67308
|
+
return {
|
|
67309
|
+
harness,
|
|
67310
|
+
sessionId,
|
|
67311
|
+
folder: displayFolderOf({ folder, home: inherited.HOME }),
|
|
67312
|
+
host: hostname3()
|
|
67313
|
+
};
|
|
67314
|
+
}
|
|
67315
|
+
function forSession({
|
|
67316
|
+
client,
|
|
67317
|
+
session
|
|
67318
|
+
}) {
|
|
67319
|
+
return client.withHeaders(sessionHeadersOf({ session }));
|
|
67320
|
+
}
|
|
67321
|
+
async function rememberSession({
|
|
67322
|
+
context,
|
|
67323
|
+
claudePid,
|
|
67324
|
+
session
|
|
67325
|
+
}) {
|
|
67326
|
+
if (!session || !claudePid) return;
|
|
67327
|
+
const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
|
|
67328
|
+
await mkdir4(dirname4(path), { recursive: true, mode: 448 });
|
|
67329
|
+
await writeFile4(path, JSON.stringify(session), { mode: 384 });
|
|
67330
|
+
}
|
|
67331
|
+
async function currentSessionOf({
|
|
67332
|
+
context,
|
|
67333
|
+
args
|
|
67334
|
+
}) {
|
|
67335
|
+
const inherited = context.environment.inherited;
|
|
67336
|
+
const named = flagText({ args, name: "session" });
|
|
67337
|
+
const harness = context.environment.harness;
|
|
67338
|
+
if (named) return sessionOf({ context, harness, sessionId: named });
|
|
67339
|
+
if (harness === "claude-code" && inherited.CLAUDE_CODE_SESSION_ID) {
|
|
67340
|
+
return sessionOf({ context, harness, sessionId: inherited.CLAUDE_CODE_SESSION_ID });
|
|
67341
|
+
}
|
|
67342
|
+
if (harness === "codex" && inherited.CODEX_THREAD_ID) {
|
|
67343
|
+
return sessionOf({ context, harness, sessionId: inherited.CODEX_THREAD_ID });
|
|
67344
|
+
}
|
|
67345
|
+
const nearest = await nearestHarnessOf({ context });
|
|
67346
|
+
if (!nearest) return void 0;
|
|
67347
|
+
const path = statePathOf({ context, kind: "sessions", profile: String(nearest.pid) });
|
|
67348
|
+
return readFile4(path, "utf8").then(
|
|
67349
|
+
(text2) => JSON.parse(text2),
|
|
67350
|
+
() => void 0
|
|
67351
|
+
);
|
|
67352
|
+
}
|
|
67353
|
+
async function sessionProfileArgs({
|
|
67354
|
+
context,
|
|
67355
|
+
args,
|
|
67356
|
+
session
|
|
67357
|
+
}) {
|
|
67358
|
+
if (!session) return args;
|
|
67359
|
+
const key = sessionKeyOf({ session });
|
|
67360
|
+
const config2 = await context.store.read();
|
|
67361
|
+
const bound = config2.sessions?.[key];
|
|
67362
|
+
if (bound && config2.profiles[bound]) {
|
|
67363
|
+
return { ...args, flags: { ...args.flags, profile: bound } };
|
|
67364
|
+
}
|
|
67365
|
+
const own2 = flagText({ args, name: "profile" });
|
|
67366
|
+
if (own2 && config2.profiles[own2]?.kind === "agent") {
|
|
67367
|
+
await context.store.bindSession({ session: key, profile: own2 });
|
|
67368
|
+
}
|
|
67369
|
+
return args;
|
|
67370
|
+
}
|
|
67371
|
+
async function liveElsewhere({
|
|
67372
|
+
context,
|
|
67373
|
+
key,
|
|
67374
|
+
claudePid
|
|
67375
|
+
}) {
|
|
67376
|
+
const folder = dirname4(statePathOf({ context, kind: "sessions", profile: "x" }));
|
|
67377
|
+
for (const file3 of await readdir(folder).catch(() => [])) {
|
|
67378
|
+
const pid = Number(file3.replace(/\.json$/, ""));
|
|
67379
|
+
if (!pid || pid === claudePid || !context.processes.alive(pid)) continue;
|
|
67380
|
+
const noted = await readFile4(join4(folder, file3), "utf8").then(
|
|
67381
|
+
(text2) => JSON.parse(text2),
|
|
67382
|
+
() => void 0
|
|
67383
|
+
);
|
|
67384
|
+
if (noted && sessionKeyOf({ session: noted }) === key) return true;
|
|
67385
|
+
}
|
|
67386
|
+
return false;
|
|
67387
|
+
}
|
|
67388
|
+
function notBoundText({ meta: meta3 }) {
|
|
67389
|
+
return `Laze: this agent listens in another session${meta3.bound ? `: ${meta3.bound}` : ""}. Create a new Laze agent with this session: laze agent request. Or move this agent here: laze agent bind.`;
|
|
67390
|
+
}
|
|
67391
|
+
async function notBoundNotice({
|
|
67392
|
+
context,
|
|
67393
|
+
client,
|
|
67394
|
+
session,
|
|
67395
|
+
error: error62
|
|
67396
|
+
}) {
|
|
67397
|
+
if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
|
|
67398
|
+
const meta3 = error62.meta ?? {};
|
|
67399
|
+
if (client && session && meta3.session && meta3.host === session.host) {
|
|
67400
|
+
const claudePid = (await nearestHarnessOf({ context }))?.pid;
|
|
67401
|
+
if (!await liveElsewhere({ context, key: meta3.session, claudePid })) {
|
|
67402
|
+
await client.post("/api/agents/me/bind", {});
|
|
67403
|
+
return { notice: void 0, rebound: true };
|
|
67404
|
+
}
|
|
67405
|
+
}
|
|
67406
|
+
const key = session ? sessionKeyOf({ session }) : "unknown";
|
|
67407
|
+
const path = statePathOf({ context, kind: "told", profile: key });
|
|
67408
|
+
const told = await readFile4(path, "utf8").then(
|
|
67409
|
+
() => true,
|
|
67410
|
+
() => false
|
|
67411
|
+
);
|
|
67412
|
+
if (told) return { notice: void 0 };
|
|
67413
|
+
await mkdir4(dirname4(path), { recursive: true, mode: 448 });
|
|
67414
|
+
await writeFile4(path, String(context.nowMs()), { mode: 384 });
|
|
67415
|
+
return { notice: notBoundText({ meta: meta3 }) };
|
|
67416
|
+
}
|
|
67417
|
+
|
|
67418
|
+
// src/services/claude-wait.service.ts
|
|
67419
|
+
var ROUND_SECONDS = 50;
|
|
67420
|
+
var WATCH_MS = 2e3;
|
|
67421
|
+
var CHANNEL_CHECK_MS = 5e3;
|
|
67422
|
+
async function holderOf({ path }) {
|
|
67423
|
+
return readFile5(path, "utf8").then(
|
|
67424
|
+
(text2) => JSON.parse(text2),
|
|
67425
|
+
() => void 0
|
|
67426
|
+
);
|
|
67427
|
+
}
|
|
67428
|
+
async function holderClaudeOf({ context, holder }) {
|
|
67429
|
+
if (holder.claudePid) return holder.claudePid;
|
|
67430
|
+
return (await nearestHarnessOf({ context, from: holder.pid }))?.pid;
|
|
67431
|
+
}
|
|
67432
|
+
async function takeLock({
|
|
67433
|
+
context,
|
|
67434
|
+
path,
|
|
67435
|
+
sessionId,
|
|
67436
|
+
claudePid,
|
|
67437
|
+
preempt = false
|
|
67438
|
+
}) {
|
|
67439
|
+
const holder = await holderOf({ path });
|
|
67440
|
+
const self2 = context.processes.pid;
|
|
67441
|
+
if (holder && holder.pid !== self2 && context.processes.alive(holder.pid)) {
|
|
67442
|
+
const served = await holderClaudeOf({ context, holder });
|
|
67443
|
+
const mine3 = preempt && served === claudePid && !holder.monitor;
|
|
67444
|
+
if (served && context.processes.alive(served) && !mine3) return false;
|
|
67445
|
+
context.processes.stop(holder.pid);
|
|
67446
|
+
}
|
|
67447
|
+
await mkdir5(dirname5(path), { recursive: true, mode: 448 });
|
|
67448
|
+
await writeFile5(
|
|
67449
|
+
path,
|
|
67450
|
+
JSON.stringify({
|
|
67451
|
+
pid: self2,
|
|
67452
|
+
claudePid,
|
|
67453
|
+
...sessionId ? { sessionId } : {},
|
|
67454
|
+
...preempt ? { monitor: true } : {}
|
|
67455
|
+
})
|
|
67456
|
+
);
|
|
67457
|
+
return true;
|
|
67458
|
+
}
|
|
67459
|
+
async function channelLive({ context, profile }) {
|
|
67460
|
+
const holder = await holderOf({ path: statePathOf({ context, kind: "channels", profile }) });
|
|
67461
|
+
return holder !== void 0 && context.processes.alive(holder.pid);
|
|
67462
|
+
}
|
|
67463
|
+
async function takeRound({
|
|
67464
|
+
context,
|
|
67465
|
+
client,
|
|
67466
|
+
claudePid,
|
|
67467
|
+
session
|
|
67468
|
+
}) {
|
|
67469
|
+
const controller = new AbortController();
|
|
67470
|
+
const { signal } = controller;
|
|
67471
|
+
const watch = (async () => {
|
|
67472
|
+
while (!signal.aborted) {
|
|
67473
|
+
await context.sleep(WATCH_MS, signal);
|
|
67474
|
+
if (claudePid && !context.processes.alive(claudePid)) controller.abort();
|
|
67475
|
+
}
|
|
67476
|
+
})();
|
|
67477
|
+
try {
|
|
67478
|
+
return await forSession({ client, session }).post(
|
|
67479
|
+
"/api/agents/me/inbox",
|
|
67480
|
+
{ waitSeconds: ROUND_SECONDS },
|
|
67481
|
+
{ signal }
|
|
67482
|
+
);
|
|
67483
|
+
} catch (error62) {
|
|
67484
|
+
if (signal.aborted) return [];
|
|
67485
|
+
throw error62;
|
|
67486
|
+
} finally {
|
|
67487
|
+
controller.abort();
|
|
67488
|
+
await watch;
|
|
67489
|
+
}
|
|
67490
|
+
}
|
|
67491
|
+
async function roundOf({ context, client, name: name2, lock, claudePid, session, seen }) {
|
|
67492
|
+
if ((await holderOf({ path: lock }))?.pid !== context.processes.pid) return void 0;
|
|
67493
|
+
if (claudePid && !context.processes.alive(claudePid)) return void 0;
|
|
67494
|
+
const due = await dueFromSpool({ context, profile: name2, seen, pushedToo: true });
|
|
67495
|
+
if (due.length > 0) return due;
|
|
67496
|
+
if (await channelLive({ context, profile: name2 })) {
|
|
67497
|
+
await context.sleep(CHANNEL_CHECK_MS);
|
|
67498
|
+
return [];
|
|
67499
|
+
}
|
|
67500
|
+
const taken = await takeRound({ context, client, claudePid, session });
|
|
67501
|
+
if (taken.length === 0) {
|
|
67502
|
+
await context.sleep(1e3);
|
|
67503
|
+
return [];
|
|
67504
|
+
}
|
|
67505
|
+
await keepTaken({ context, profile: name2, messages: taken });
|
|
67506
|
+
return taken;
|
|
67507
|
+
}
|
|
67508
|
+
async function claudePidOf({ context }) {
|
|
67509
|
+
const harness = await nearestHarnessOf({ context });
|
|
67510
|
+
if (harness?.harness === "claude-code") return harness.pid;
|
|
67511
|
+
return await context.processes.parentOf(context.processes.pid) ?? 0;
|
|
67512
|
+
}
|
|
67513
|
+
async function settleRound(round) {
|
|
67514
|
+
const { context, client, name: name2, session } = round;
|
|
67515
|
+
const messages = await roundOf(round).catch(async (error62) => {
|
|
67516
|
+
const refused = await notBoundNotice({
|
|
67517
|
+
context,
|
|
67518
|
+
client: forSession({ client, session }),
|
|
67519
|
+
session,
|
|
67520
|
+
error: error62
|
|
67521
|
+
});
|
|
67522
|
+
if (!refused) throw error62;
|
|
67523
|
+
return refused;
|
|
67524
|
+
});
|
|
67525
|
+
if (messages === void 0) return 0;
|
|
67526
|
+
if (!Array.isArray(messages)) {
|
|
67527
|
+
if (messages.rebound) return "again";
|
|
67528
|
+
if (!messages.notice) return 0;
|
|
67529
|
+
context.err(`${messages.notice}
|
|
67530
|
+
`);
|
|
67531
|
+
return 2;
|
|
67532
|
+
}
|
|
67533
|
+
if (messages.length === 0) return "again";
|
|
67534
|
+
await turnStarted({ context, client, agent: name2, messages }).catch(() => void 0);
|
|
67535
|
+
const self2 = await currentNameOf({ context, client, profile: name2 });
|
|
67536
|
+
context.err(`${hookContextOf({ messages, self: self2 })}
|
|
67537
|
+
`);
|
|
67538
|
+
const messageIds = messages.map((message2) => message2.messageId);
|
|
67539
|
+
await dropFromSpool({ context, profile: name2, messageIds });
|
|
67540
|
+
return 2;
|
|
67541
|
+
}
|
|
67542
|
+
async function waitForMessages({ context, args }) {
|
|
67543
|
+
const raw = await context.readStdin();
|
|
67544
|
+
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
67545
|
+
const session = sessionOf({ context, harness: "claude-code", sessionId: input2.session_id });
|
|
67546
|
+
const named = await sessionProfileArgs({ context, args, session });
|
|
67547
|
+
const { client, name: name2 } = await signedIn({ context, args: named });
|
|
67548
|
+
const claudePid = await claudePidOf({ context });
|
|
67549
|
+
await rememberSession({ context, claudePid, session });
|
|
67550
|
+
const lock = statePathOf({ context, kind: "waiters", profile: name2 });
|
|
67551
|
+
if (!await takeLock({ context, path: lock, sessionId: input2.session_id, claudePid })) return 0;
|
|
67552
|
+
const seen = () => input2.transcript_path ? readFile5(input2.transcript_path, "utf8") : Promise.resolve("");
|
|
67553
|
+
const deadline = context.nowMs() + (WAIT_HOOK_TIMEOUT_SECONDS - 60) * 1e3;
|
|
67554
|
+
try {
|
|
67555
|
+
while (context.nowMs() < deadline) {
|
|
67556
|
+
const code = await settleRound({ context, client, name: name2, lock, claudePid, session, seen });
|
|
67557
|
+
if (code !== "again") return code;
|
|
67558
|
+
}
|
|
67559
|
+
return 0;
|
|
67560
|
+
} finally {
|
|
67561
|
+
if ((await holderOf({ path: lock }))?.pid === context.processes.pid)
|
|
67562
|
+
await rm2(lock, { force: true });
|
|
67563
|
+
}
|
|
67564
|
+
}
|
|
67565
|
+
async function waitHook({ context, args }) {
|
|
67566
|
+
try {
|
|
67567
|
+
return await waitForMessages({ context, args });
|
|
67568
|
+
} catch (error62) {
|
|
67569
|
+
context.err(`laze: the background waiter stopped: ${String(error62)}
|
|
67570
|
+
`);
|
|
67571
|
+
return 0;
|
|
67572
|
+
}
|
|
67573
|
+
}
|
|
67574
|
+
async function monitorServes({
|
|
67575
|
+
context,
|
|
67576
|
+
profile,
|
|
67577
|
+
claudePid
|
|
67578
|
+
}) {
|
|
67579
|
+
const holder = await holderOf({ path: statePathOf({ context, kind: "waiters", profile }) });
|
|
67580
|
+
if (!holder?.monitor || !context.processes.alive(holder.pid)) return false;
|
|
67581
|
+
return await holderClaudeOf({ context, holder }) === claudePid;
|
|
67582
|
+
}
|
|
67583
|
+
|
|
67267
67584
|
// src/services/codex-link.service.ts
|
|
67268
67585
|
import { createReadStream } from "node:fs";
|
|
67269
|
-
import { readdir as
|
|
67270
|
-
import { join as
|
|
67586
|
+
import { readdir as readdir4, rm as rm6, stat as stat2 } from "node:fs/promises";
|
|
67587
|
+
import { join as join10, resolve as resolve3 } from "node:path";
|
|
67271
67588
|
import { createInterface as createInterface2 } from "node:readline";
|
|
67272
67589
|
|
|
67273
67590
|
// src/rules/connect-service.rules.ts
|
|
@@ -67387,8 +67704,8 @@ function rolloutEventOf({
|
|
|
67387
67704
|
|
|
67388
67705
|
// src/services/codex-adopt.service.ts
|
|
67389
67706
|
import { spawn as spawn2 } from "node:child_process";
|
|
67390
|
-
import { mkdir as
|
|
67391
|
-
import { dirname as
|
|
67707
|
+
import { mkdir as mkdir6, readdir as readdir2, readFile as readFile6, rm as rm3, stat, writeFile as writeFile6 } from "node:fs/promises";
|
|
67708
|
+
import { dirname as dirname6, join as join5 } from "node:path";
|
|
67392
67709
|
import { createInterface } from "node:readline";
|
|
67393
67710
|
|
|
67394
67711
|
// src/rules/codex-requests.rules.ts
|
|
@@ -67508,11 +67825,11 @@ var CodexAppServer = class _CodexAppServer {
|
|
|
67508
67825
|
}
|
|
67509
67826
|
};
|
|
67510
67827
|
async function newestThreadId({ codexHome }) {
|
|
67511
|
-
const root =
|
|
67512
|
-
const files2 = await
|
|
67828
|
+
const root = join5(codexHome, "sessions");
|
|
67829
|
+
const files2 = await readdir2(root, { recursive: true }).catch(() => []);
|
|
67513
67830
|
const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
|
|
67514
67831
|
const dated = await Promise.all(
|
|
67515
|
-
rollouts.map(async (file3) => ({ file: file3, at: (await stat(
|
|
67832
|
+
rollouts.map(async (file3) => ({ file: file3, at: (await stat(join5(root, file3))).mtimeMs }))
|
|
67516
67833
|
);
|
|
67517
67834
|
const newest = dated.toSorted((a, b) => b.at - a.at)[0]?.file ?? "";
|
|
67518
67835
|
const id = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/.exec(newest);
|
|
@@ -67587,7 +67904,7 @@ async function answer({
|
|
|
67587
67904
|
var MAX_RESTART_WAIT_SECONDS = 60;
|
|
67588
67905
|
var HEALTHY_RUN_MS = 6e4;
|
|
67589
67906
|
async function recordOf({ path }) {
|
|
67590
|
-
return
|
|
67907
|
+
return readFile6(path, "utf8").then(
|
|
67591
67908
|
(text2) => JSON.parse(text2),
|
|
67592
67909
|
() => void 0
|
|
67593
67910
|
);
|
|
@@ -67609,8 +67926,8 @@ async function startAdoptInBackground({
|
|
|
67609
67926
|
const adopt = ["adopt", "codex", "--profile", profile, ...threadFlag({ thread: thread2 })];
|
|
67610
67927
|
const argv = [...context.program, ...adopt, "--supervise"];
|
|
67611
67928
|
const pid = context.processes.spawnDetached({ argv, logPath: log });
|
|
67612
|
-
await
|
|
67613
|
-
await
|
|
67929
|
+
await mkdir6(dirname6(path), { recursive: true, mode: 448 });
|
|
67930
|
+
await writeFile6(path, JSON.stringify({ pid, thread: thread2, log, startedAt: context.nowMs() }));
|
|
67614
67931
|
return [
|
|
67615
67932
|
`Started \`${laze} adopt codex\` in the background (pid ${pid}). It answers each Laze message`,
|
|
67616
67933
|
`as a turn in ${thread2 ? `this Codex thread (${thread2})` : "the newest Codex thread"}, and starts again if it stops.`,
|
|
@@ -67665,7 +67982,7 @@ Log: ${record4.log}
|
|
|
67665
67982
|
async function adoptStop({ context, profile }) {
|
|
67666
67983
|
const path = statePathOf({ context, kind: "adopt", profile });
|
|
67667
67984
|
const record4 = await recordOf({ path });
|
|
67668
|
-
await
|
|
67985
|
+
await rm3(path, { force: true });
|
|
67669
67986
|
if (!record4 || !context.processes.stop(record4.pid)) {
|
|
67670
67987
|
context.out(`laze adopt codex was not running in the background for profile "${profile}".
|
|
67671
67988
|
`);
|
|
@@ -67690,7 +68007,7 @@ async function adoptedThreadOf({
|
|
|
67690
68007
|
);
|
|
67691
68008
|
if (!held) return threadId;
|
|
67692
68009
|
const path = statePathOf({ context, kind: "adopt", profile, extension: "forks.json" });
|
|
67693
|
-
const forks = await
|
|
68010
|
+
const forks = await readFile6(path, "utf8").then(
|
|
67694
68011
|
(text2) => JSON.parse(text2),
|
|
67695
68012
|
() => ({})
|
|
67696
68013
|
);
|
|
@@ -67705,8 +68022,8 @@ async function adoptedThreadOf({
|
|
|
67705
68022
|
}
|
|
67706
68023
|
const forked = record3((await codex.call("thread/fork", { threadId })).thread).id;
|
|
67707
68024
|
if (typeof forked !== "string") throw new Error("thread/fork answered no thread id");
|
|
67708
|
-
await
|
|
67709
|
-
await
|
|
68025
|
+
await mkdir6(dirname6(path), { recursive: true, mode: 448 });
|
|
68026
|
+
await writeFile6(path, JSON.stringify({ ...forks, [threadId]: forked }));
|
|
67710
68027
|
context.out(
|
|
67711
68028
|
`Codex holds thread ${threadId} open elsewhere; answering in its new fork ${forked}.
|
|
67712
68029
|
`
|
|
@@ -67761,43 +68078,20 @@ async function adoptCodex({ context, args }) {
|
|
|
67761
68078
|
}
|
|
67762
68079
|
|
|
67763
68080
|
// src/services/connect-delivery.service.ts
|
|
67764
|
-
import { mkdir as
|
|
67765
|
-
import { homedir as homedir2, hostname as
|
|
67766
|
-
import { dirname as
|
|
67767
|
-
|
|
67768
|
-
// src/rules/session-headers.rules.ts
|
|
67769
|
-
import { relative as relative2, sep } from "node:path";
|
|
67770
|
-
function sessionKeyOf({ session }) {
|
|
67771
|
-
return `${session.harness}:${session.sessionId}`;
|
|
67772
|
-
}
|
|
67773
|
-
function sessionHeadersOf({
|
|
67774
|
-
session
|
|
67775
|
-
}) {
|
|
67776
|
-
if (!session) return {};
|
|
67777
|
-
return {
|
|
67778
|
-
[AGENT_SESSION_HEADER]: sessionKeyOf({ session }),
|
|
67779
|
-
[AGENT_SESSION_FOLDER_HEADER]: encodeURIComponent(session.folder),
|
|
67780
|
-
[AGENT_SESSION_HOST_HEADER]: encodeURIComponent(session.host)
|
|
67781
|
-
};
|
|
67782
|
-
}
|
|
67783
|
-
function displayFolderOf({ folder, home }) {
|
|
67784
|
-
if (!home) return folder;
|
|
67785
|
-
const below = relative2(home, folder);
|
|
67786
|
-
if (below === "") return "~";
|
|
67787
|
-
if (below.startsWith("..") || below.startsWith(sep)) return folder;
|
|
67788
|
-
return `~/${below.split(sep).join("/")}`;
|
|
67789
|
-
}
|
|
68081
|
+
import { mkdir as mkdir8, readFile as readFile8, rename as rename3, rm as rm4, writeFile as writeFile8 } from "node:fs/promises";
|
|
68082
|
+
import { homedir as homedir2, hostname as hostname4 } from "node:os";
|
|
68083
|
+
import { dirname as dirname8, join as join8 } from "node:path";
|
|
67790
68084
|
|
|
67791
68085
|
// src/services/codex-turn-watch.service.ts
|
|
67792
|
-
import { open as open2, readdir as
|
|
67793
|
-
import { join as
|
|
68086
|
+
import { open as open2, readdir as readdir3 } from "node:fs/promises";
|
|
68087
|
+
import { join as join6 } from "node:path";
|
|
67794
68088
|
var READ_MS = 1500;
|
|
67795
68089
|
var KEEP_WORKING_MS = 3e4;
|
|
67796
68090
|
async function rolloutPathOf({ delivery }) {
|
|
67797
|
-
const root =
|
|
67798
|
-
const files2 = await
|
|
68091
|
+
const root = join6(delivery.codexHome, "sessions");
|
|
68092
|
+
const files2 = await readdir3(root, { recursive: true }).catch(() => []);
|
|
67799
68093
|
const file3 = files2.find((name2) => name2.endsWith(`-${delivery.threadId}.jsonl`));
|
|
67800
|
-
return file3 ?
|
|
68094
|
+
return file3 ? join6(root, file3) : void 0;
|
|
67801
68095
|
}
|
|
67802
68096
|
async function readFrom({ path, offset }) {
|
|
67803
68097
|
const handle = await open2(path, "r");
|
|
@@ -67883,8 +68177,8 @@ var CodexTurnWatch = class _CodexTurnWatch {
|
|
|
67883
68177
|
};
|
|
67884
68178
|
|
|
67885
68179
|
// src/services/openclaw-relay.service.ts
|
|
67886
|
-
import { chmod as chmod2, mkdir as
|
|
67887
|
-
import { dirname as
|
|
68180
|
+
import { chmod as chmod2, mkdir as mkdir7, readFile as readFile7, writeFile as writeFile7 } from "node:fs/promises";
|
|
68181
|
+
import { dirname as dirname7, join as join7 } from "node:path";
|
|
67888
68182
|
|
|
67889
68183
|
// ../../modules/openclaw/contract/src/openclaw.ts
|
|
67890
68184
|
var workspaceIdSchema14 = external_exports.string().min(1);
|
|
@@ -68112,11 +68406,11 @@ var STOPS = /* @__PURE__ */ new Map([
|
|
|
68112
68406
|
[OPENCLAW_RELAY_CLOSE.replaced.code, "another relay for this gateway took over"]
|
|
68113
68407
|
]);
|
|
68114
68408
|
function relaysPathOf({ context }) {
|
|
68115
|
-
return
|
|
68409
|
+
return join7(dirname7(context.environment.configPath), "connect", "openclaw-relays.json");
|
|
68116
68410
|
}
|
|
68117
68411
|
async function readRelays({ context }) {
|
|
68118
68412
|
try {
|
|
68119
|
-
return JSON.parse(await
|
|
68413
|
+
return JSON.parse(await readFile7(relaysPathOf({ context }), "utf8"));
|
|
68120
68414
|
} catch {
|
|
68121
68415
|
return {};
|
|
68122
68416
|
}
|
|
@@ -68126,8 +68420,8 @@ async function saveRelays({
|
|
|
68126
68420
|
relays
|
|
68127
68421
|
}) {
|
|
68128
68422
|
const path = relaysPathOf({ context });
|
|
68129
|
-
await
|
|
68130
|
-
await
|
|
68423
|
+
await mkdir7(dirname7(path), { recursive: true, mode: 448 });
|
|
68424
|
+
await writeFile7(path, `${JSON.stringify(relays, null, 2)}
|
|
68131
68425
|
`, { mode: 384 });
|
|
68132
68426
|
await chmod2(path, 384);
|
|
68133
68427
|
}
|
|
@@ -68313,14 +68607,14 @@ var RelayLoops = class _RelayLoops {
|
|
|
68313
68607
|
|
|
68314
68608
|
// src/services/connect-delivery.service.ts
|
|
68315
68609
|
function connectFolderOf({ context }) {
|
|
68316
|
-
return
|
|
68610
|
+
return join8(dirname8(context.environment.configPath), "connect");
|
|
68317
68611
|
}
|
|
68318
68612
|
function runStatePathOf({ context }) {
|
|
68319
|
-
return
|
|
68613
|
+
return join8(connectFolderOf({ context }), "run.json");
|
|
68320
68614
|
}
|
|
68321
68615
|
async function readJson({ path }) {
|
|
68322
68616
|
try {
|
|
68323
|
-
return JSON.parse(await
|
|
68617
|
+
return JSON.parse(await readFile8(path, "utf8"));
|
|
68324
68618
|
} catch {
|
|
68325
68619
|
return void 0;
|
|
68326
68620
|
}
|
|
@@ -68328,7 +68622,7 @@ async function readJson({ path }) {
|
|
|
68328
68622
|
async function runStateOf({ context }) {
|
|
68329
68623
|
return readJson({ path: runStatePathOf({ context }) });
|
|
68330
68624
|
}
|
|
68331
|
-
var
|
|
68625
|
+
var ROUND_SECONDS2 = 50;
|
|
68332
68626
|
var REFRESH_MS = 3e4;
|
|
68333
68627
|
var MAX_RETRY_SECONDS2 = 60;
|
|
68334
68628
|
var CodexQueueError = class extends Error {
|
|
@@ -68360,7 +68654,7 @@ async function queueInCodex({
|
|
|
68360
68654
|
throw new CodexQueueError(codexQueueFailureOf({ stderr: stderr2 }), stderr2.trim() || `exit ${code}`);
|
|
68361
68655
|
}
|
|
68362
68656
|
}
|
|
68363
|
-
async function
|
|
68657
|
+
async function takeRound2({
|
|
68364
68658
|
client,
|
|
68365
68659
|
signal,
|
|
68366
68660
|
delivery
|
|
@@ -68369,10 +68663,10 @@ async function takeRound({
|
|
|
68369
68663
|
harness: "codex",
|
|
68370
68664
|
sessionId: delivery.threadId,
|
|
68371
68665
|
folder: displayFolderOf({ folder: delivery.cwd, home: homedir2() }),
|
|
68372
|
-
host:
|
|
68666
|
+
host: hostname4()
|
|
68373
68667
|
};
|
|
68374
68668
|
try {
|
|
68375
|
-
return await client.withHeaders(sessionHeadersOf({ session })).post("/api/agents/me/inbox", { waitSeconds:
|
|
68669
|
+
return await client.withHeaders(sessionHeadersOf({ session })).post("/api/agents/me/inbox", { waitSeconds: ROUND_SECONDS2 }, { signal });
|
|
68376
68670
|
} catch (error62) {
|
|
68377
68671
|
if (signal.aborted) return [];
|
|
68378
68672
|
throw error62;
|
|
@@ -68387,7 +68681,7 @@ async function deliverRound({
|
|
|
68387
68681
|
watch
|
|
68388
68682
|
}) {
|
|
68389
68683
|
const kept = await dueFromSpool({ context, profile, seen: async () => "", pushedToo: true });
|
|
68390
|
-
const messages = kept.length > 0 ? kept : await
|
|
68684
|
+
const messages = kept.length > 0 ? kept : await takeRound2({ client, signal, delivery });
|
|
68391
68685
|
if (messages.length === 0) return 0;
|
|
68392
68686
|
if (kept.length === 0) await keepTaken({ context, profile, messages });
|
|
68393
68687
|
const self2 = await currentNameOf({ context, client, profile });
|
|
@@ -68470,9 +68764,9 @@ async function serveRounds({
|
|
|
68470
68764
|
}
|
|
68471
68765
|
var saves = 0;
|
|
68472
68766
|
async function save(run4) {
|
|
68473
|
-
await
|
|
68767
|
+
await mkdir8(dirname8(run4.path), { recursive: true, mode: 448 });
|
|
68474
68768
|
const temporary = `${run4.path}.${run4.self}.${saves += 1}.tmp`;
|
|
68475
|
-
await
|
|
68769
|
+
await writeFile8(temporary, JSON.stringify(run4.state));
|
|
68476
68770
|
await rename3(temporary, run4.path);
|
|
68477
68771
|
}
|
|
68478
68772
|
async function holdsLock(run4) {
|
|
@@ -68546,15 +68840,15 @@ async function runConnectLoop({ context }) {
|
|
|
68546
68840
|
await relays.stopAll();
|
|
68547
68841
|
for (const current2 of run4.served.values()) current2.stop.abort();
|
|
68548
68842
|
await Promise.all([...run4.served.values()].map((current2) => current2.done));
|
|
68549
|
-
if (await holdsLock(run4)) await
|
|
68843
|
+
if (await holdsLock(run4)) await rm4(run4.path, { force: true });
|
|
68550
68844
|
}
|
|
68551
68845
|
return 0;
|
|
68552
68846
|
}
|
|
68553
68847
|
|
|
68554
68848
|
// src/services/connect-service.service.ts
|
|
68555
68849
|
import { createHash } from "node:crypto";
|
|
68556
|
-
import { mkdir as
|
|
68557
|
-
import { dirname as
|
|
68850
|
+
import { mkdir as mkdir9, rm as rm5, writeFile as writeFile9 } from "node:fs/promises";
|
|
68851
|
+
import { dirname as dirname9, join as join9 } from "node:path";
|
|
68558
68852
|
var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the service that delivers to linked Codex sessions.
|
|
68559
68853
|
|
|
68560
68854
|
laze connect install install and start it (systemd --user, a LaunchAgent, or detached)
|
|
@@ -68567,17 +68861,17 @@ var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the
|
|
|
68567
68861
|
\`laze openclaw connect --local\`, whose OpenClaw relay it also runs.
|
|
68568
68862
|
`;
|
|
68569
68863
|
function installedPathOf({ context }) {
|
|
68570
|
-
return
|
|
68864
|
+
return join9(connectFolderOf({ context }), "service.json");
|
|
68571
68865
|
}
|
|
68572
68866
|
function logPathOf({ context }) {
|
|
68573
|
-
return
|
|
68867
|
+
return join9(connectFolderOf({ context }), "connect.log");
|
|
68574
68868
|
}
|
|
68575
68869
|
function homeOf({ context }) {
|
|
68576
|
-
return context.environment.inherited.HOME ??
|
|
68870
|
+
return context.environment.inherited.HOME ?? dirname9(dirname9(context.environment.configPath));
|
|
68577
68871
|
}
|
|
68578
68872
|
function serviceNameOf({ context }) {
|
|
68579
68873
|
const { configPath } = context.environment;
|
|
68580
|
-
if (configPath ===
|
|
68874
|
+
if (configPath === join9(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
|
|
68581
68875
|
return `laze-connect-${createHash("sha256").update(configPath).digest("hex").slice(0, 8)}`;
|
|
68582
68876
|
}
|
|
68583
68877
|
function serviceEnvOf({ context }) {
|
|
@@ -68600,10 +68894,10 @@ async function run({ context, command }) {
|
|
|
68600
68894
|
async function installSystemd({ context }) {
|
|
68601
68895
|
const name2 = serviceNameOf({ context });
|
|
68602
68896
|
const env = context.environment.inherited;
|
|
68603
|
-
const base = env.XDG_CONFIG_HOME ||
|
|
68604
|
-
const file3 =
|
|
68605
|
-
await
|
|
68606
|
-
await
|
|
68897
|
+
const base = env.XDG_CONFIG_HOME || join9(homeOf({ context }), ".config");
|
|
68898
|
+
const file3 = join9(base, "systemd", "user", `${name2}.service`);
|
|
68899
|
+
await mkdir9(dirname9(file3), { recursive: true });
|
|
68900
|
+
await writeFile9(
|
|
68607
68901
|
file3,
|
|
68608
68902
|
systemdUnitOf({ argv: runArgvOf({ context }), env: serviceEnvOf({ context }) })
|
|
68609
68903
|
);
|
|
@@ -68616,10 +68910,10 @@ async function installSystemd({ context }) {
|
|
|
68616
68910
|
async function installLaunchd({ context }) {
|
|
68617
68911
|
const name2 = serviceNameOf({ context });
|
|
68618
68912
|
const label2 = `ai.laze.${name2}`;
|
|
68619
|
-
const file3 =
|
|
68913
|
+
const file3 = join9(homeOf({ context }), "Library", "LaunchAgents", `${label2}.plist`);
|
|
68620
68914
|
const log = logPathOf({ context });
|
|
68621
|
-
await
|
|
68622
|
-
await
|
|
68915
|
+
await mkdir9(dirname9(file3), { recursive: true });
|
|
68916
|
+
await writeFile9(
|
|
68623
68917
|
file3,
|
|
68624
68918
|
launchAgentOf({
|
|
68625
68919
|
label: label2,
|
|
@@ -68671,8 +68965,8 @@ async function installConnectService({ context }) {
|
|
|
68671
68965
|
const manager = await managerOf({ context });
|
|
68672
68966
|
const install = { systemd: installSystemd, launchd: installLaunchd, detached: installDetached };
|
|
68673
68967
|
const installed = await install[manager]({ context });
|
|
68674
|
-
await
|
|
68675
|
-
await
|
|
68968
|
+
await mkdir9(dirname9(path), { recursive: true, mode: 448 });
|
|
68969
|
+
await writeFile9(path, JSON.stringify(installed));
|
|
68676
68970
|
return describeInstalled({ installed });
|
|
68677
68971
|
}
|
|
68678
68972
|
function describeInstalled({ installed }) {
|
|
@@ -68738,11 +69032,11 @@ async function uninstall({ context }) {
|
|
|
68738
69032
|
command: ["systemctl", "--user", "disable", `${installed.name}.service`]
|
|
68739
69033
|
});
|
|
68740
69034
|
}
|
|
68741
|
-
if (installed.file) await
|
|
69035
|
+
if (installed.file) await rm5(installed.file, { force: true });
|
|
68742
69036
|
if (installed.manager === "systemd") {
|
|
68743
69037
|
await run({ context, command: ["systemctl", "--user", "daemon-reload"] });
|
|
68744
69038
|
}
|
|
68745
|
-
await
|
|
69039
|
+
await rm5(path, { force: true });
|
|
68746
69040
|
context.out(
|
|
68747
69041
|
`Removed the connect service (${installed.manager}, ${installed.name}). Linked Codex agents get no messages until \`laze connect install\`.
|
|
68748
69042
|
`
|
|
@@ -68784,13 +69078,13 @@ async function newestThreadIn({
|
|
|
68784
69078
|
codexHome,
|
|
68785
69079
|
directory
|
|
68786
69080
|
}) {
|
|
68787
|
-
const root =
|
|
68788
|
-
const files2 = await
|
|
69081
|
+
const root = join10(codexHome, "sessions");
|
|
69082
|
+
const files2 = await readdir4(root, { recursive: true }).catch(() => []);
|
|
68789
69083
|
const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
|
|
68790
69084
|
const dated = await Promise.all(
|
|
68791
69085
|
rollouts.map(async (file3) => ({
|
|
68792
|
-
path:
|
|
68793
|
-
at: await stat2(
|
|
69086
|
+
path: join10(root, file3),
|
|
69087
|
+
at: await stat2(join10(root, file3)).then(
|
|
68794
69088
|
(info) => info.mtimeMs,
|
|
68795
69089
|
() => 0
|
|
68796
69090
|
)
|
|
@@ -68821,7 +69115,7 @@ async function stopAdopt({ context, profile }) {
|
|
|
68821
69115
|
const running = await readJson({ path });
|
|
68822
69116
|
if (!running) return;
|
|
68823
69117
|
context.processes.stop(running.pid);
|
|
68824
|
-
await
|
|
69118
|
+
await rm6(path, { force: true });
|
|
68825
69119
|
}
|
|
68826
69120
|
async function linkCodexSession({
|
|
68827
69121
|
context,
|
|
@@ -68857,131 +69151,9 @@ async function linkCodexSession({
|
|
|
68857
69151
|
].join("\n");
|
|
68858
69152
|
}
|
|
68859
69153
|
|
|
68860
|
-
// src/services/harness-session.service.ts
|
|
68861
|
-
import { mkdir as mkdir8, readdir as readdir4, readFile as readFile7, writeFile as writeFile8 } from "node:fs/promises";
|
|
68862
|
-
import { hostname as hostname4 } from "node:os";
|
|
68863
|
-
import { dirname as dirname8, join as join10 } from "node:path";
|
|
68864
|
-
function sessionOf({
|
|
68865
|
-
context,
|
|
68866
|
-
harness,
|
|
68867
|
-
sessionId
|
|
68868
|
-
}) {
|
|
68869
|
-
if (!sessionId) return void 0;
|
|
68870
|
-
const inherited = context.environment.inherited;
|
|
68871
|
-
const folder = inherited.CLAUDE_PROJECT_DIR || context.cwd;
|
|
68872
|
-
return {
|
|
68873
|
-
harness,
|
|
68874
|
-
sessionId,
|
|
68875
|
-
folder: displayFolderOf({ folder, home: inherited.HOME }),
|
|
68876
|
-
host: hostname4()
|
|
68877
|
-
};
|
|
68878
|
-
}
|
|
68879
|
-
function forSession({
|
|
68880
|
-
client,
|
|
68881
|
-
session
|
|
68882
|
-
}) {
|
|
68883
|
-
return client.withHeaders(sessionHeadersOf({ session }));
|
|
68884
|
-
}
|
|
68885
|
-
async function rememberSession({
|
|
68886
|
-
context,
|
|
68887
|
-
claudePid,
|
|
68888
|
-
session
|
|
68889
|
-
}) {
|
|
68890
|
-
if (!session || !claudePid) return;
|
|
68891
|
-
const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
|
|
68892
|
-
await mkdir8(dirname8(path), { recursive: true, mode: 448 });
|
|
68893
|
-
await writeFile8(path, JSON.stringify(session), { mode: 384 });
|
|
68894
|
-
}
|
|
68895
|
-
async function currentSessionOf({
|
|
68896
|
-
context,
|
|
68897
|
-
args
|
|
68898
|
-
}) {
|
|
68899
|
-
const inherited = context.environment.inherited;
|
|
68900
|
-
const named = flagText({ args, name: "session" });
|
|
68901
|
-
const harness = context.environment.harness;
|
|
68902
|
-
if (named) return sessionOf({ context, harness, sessionId: named });
|
|
68903
|
-
if (harness === "claude-code" && inherited.CLAUDE_CODE_SESSION_ID) {
|
|
68904
|
-
return sessionOf({ context, harness, sessionId: inherited.CLAUDE_CODE_SESSION_ID });
|
|
68905
|
-
}
|
|
68906
|
-
if (harness === "codex" && inherited.CODEX_THREAD_ID) {
|
|
68907
|
-
return sessionOf({ context, harness, sessionId: inherited.CODEX_THREAD_ID });
|
|
68908
|
-
}
|
|
68909
|
-
const nearest = await nearestHarnessOf({ context });
|
|
68910
|
-
if (!nearest) return void 0;
|
|
68911
|
-
const path = statePathOf({ context, kind: "sessions", profile: String(nearest.pid) });
|
|
68912
|
-
return readFile7(path, "utf8").then(
|
|
68913
|
-
(text2) => JSON.parse(text2),
|
|
68914
|
-
() => void 0
|
|
68915
|
-
);
|
|
68916
|
-
}
|
|
68917
|
-
async function sessionProfileArgs({
|
|
68918
|
-
context,
|
|
68919
|
-
args,
|
|
68920
|
-
session
|
|
68921
|
-
}) {
|
|
68922
|
-
if (!session) return args;
|
|
68923
|
-
const key = sessionKeyOf({ session });
|
|
68924
|
-
const config2 = await context.store.read();
|
|
68925
|
-
const bound = config2.sessions?.[key];
|
|
68926
|
-
if (bound && config2.profiles[bound]) {
|
|
68927
|
-
return { ...args, flags: { ...args.flags, profile: bound } };
|
|
68928
|
-
}
|
|
68929
|
-
const own2 = flagText({ args, name: "profile" });
|
|
68930
|
-
if (own2 && config2.profiles[own2]?.kind === "agent") {
|
|
68931
|
-
await context.store.bindSession({ session: key, profile: own2 });
|
|
68932
|
-
}
|
|
68933
|
-
return args;
|
|
68934
|
-
}
|
|
68935
|
-
async function liveElsewhere({
|
|
68936
|
-
context,
|
|
68937
|
-
key,
|
|
68938
|
-
claudePid
|
|
68939
|
-
}) {
|
|
68940
|
-
const folder = dirname8(statePathOf({ context, kind: "sessions", profile: "x" }));
|
|
68941
|
-
for (const file3 of await readdir4(folder).catch(() => [])) {
|
|
68942
|
-
const pid = Number(file3.replace(/\.json$/, ""));
|
|
68943
|
-
if (!pid || pid === claudePid || !context.processes.alive(pid)) continue;
|
|
68944
|
-
const noted = await readFile7(join10(folder, file3), "utf8").then(
|
|
68945
|
-
(text2) => JSON.parse(text2),
|
|
68946
|
-
() => void 0
|
|
68947
|
-
);
|
|
68948
|
-
if (noted && sessionKeyOf({ session: noted }) === key) return true;
|
|
68949
|
-
}
|
|
68950
|
-
return false;
|
|
68951
|
-
}
|
|
68952
|
-
function notBoundText({ meta: meta3 }) {
|
|
68953
|
-
return `Laze: this agent listens in another session${meta3.bound ? `: ${meta3.bound}` : ""}. Create a new Laze agent with this session: laze agent request. Or move this agent here: laze agent bind.`;
|
|
68954
|
-
}
|
|
68955
|
-
async function notBoundNotice({
|
|
68956
|
-
context,
|
|
68957
|
-
client,
|
|
68958
|
-
session,
|
|
68959
|
-
error: error62
|
|
68960
|
-
}) {
|
|
68961
|
-
if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
|
|
68962
|
-
const meta3 = error62.meta ?? {};
|
|
68963
|
-
if (client && session && meta3.session && meta3.host === session.host) {
|
|
68964
|
-
const claudePid = (await nearestHarnessOf({ context }))?.pid;
|
|
68965
|
-
if (!await liveElsewhere({ context, key: meta3.session, claudePid })) {
|
|
68966
|
-
await client.post("/api/agents/me/bind", {});
|
|
68967
|
-
return { notice: void 0, rebound: true };
|
|
68968
|
-
}
|
|
68969
|
-
}
|
|
68970
|
-
const key = session ? sessionKeyOf({ session }) : "unknown";
|
|
68971
|
-
const path = statePathOf({ context, kind: "told", profile: key });
|
|
68972
|
-
const told = await readFile7(path, "utf8").then(
|
|
68973
|
-
() => true,
|
|
68974
|
-
() => false
|
|
68975
|
-
);
|
|
68976
|
-
if (told) return { notice: void 0 };
|
|
68977
|
-
await mkdir8(dirname8(path), { recursive: true, mode: 448 });
|
|
68978
|
-
await writeFile8(path, String(context.nowMs()), { mode: 384 });
|
|
68979
|
-
return { notice: notBoundText({ meta: meta3 }) };
|
|
68980
|
-
}
|
|
68981
|
-
|
|
68982
69154
|
// src/services/laze-plugin.service.ts
|
|
68983
|
-
import { mkdir as
|
|
68984
|
-
import { dirname as
|
|
69155
|
+
import { mkdir as mkdir10, readFile as readFile9, writeFile as writeFile10 } from "node:fs/promises";
|
|
69156
|
+
import { dirname as dirname10, join as join11 } from "node:path";
|
|
68985
69157
|
|
|
68986
69158
|
// src/rules/laze-plugin.rules.ts
|
|
68987
69159
|
var LAZE_PLUGIN = "laze";
|
|
@@ -69073,11 +69245,11 @@ function lazePluginFiles({
|
|
|
69073
69245
|
var REGISTER_LIMIT_MS = 6e4;
|
|
69074
69246
|
var quote2 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
69075
69247
|
function pluginFolderOf({ context }) {
|
|
69076
|
-
return join11(
|
|
69248
|
+
return join11(dirname10(context.environment.configPath), "plugins");
|
|
69077
69249
|
}
|
|
69078
69250
|
async function pluginIsCurrent({ context }) {
|
|
69079
69251
|
const manifest = join11(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
|
|
69080
|
-
const written = await
|
|
69252
|
+
const written = await readFile9(manifest, "utf8").then(
|
|
69081
69253
|
(text2) => JSON.parse(text2).version,
|
|
69082
69254
|
() => void 0
|
|
69083
69255
|
);
|
|
@@ -69088,8 +69260,8 @@ async function writeLazePlugin({ context }) {
|
|
|
69088
69260
|
const files2 = lazePluginFiles({ program: context.program, version: cliVersionOf() });
|
|
69089
69261
|
for (const [path, text2] of Object.entries(files2)) {
|
|
69090
69262
|
const target = join11(folder, path);
|
|
69091
|
-
await
|
|
69092
|
-
await
|
|
69263
|
+
await mkdir10(dirname10(target), { recursive: true });
|
|
69264
|
+
await writeFile10(target, text2);
|
|
69093
69265
|
}
|
|
69094
69266
|
return folder;
|
|
69095
69267
|
}
|
|
@@ -69107,9 +69279,19 @@ async function registerWithClaude({ context, folder }) {
|
|
|
69107
69279
|
done.abort();
|
|
69108
69280
|
return code === 0;
|
|
69109
69281
|
}
|
|
69282
|
+
function registeredMarkOf({ context }) {
|
|
69283
|
+
return join11(pluginFolderOf({ context }), "registered");
|
|
69284
|
+
}
|
|
69285
|
+
async function pluginRegistered({ context }) {
|
|
69286
|
+
return readFile9(registeredMarkOf({ context }), "utf8").then(
|
|
69287
|
+
() => true,
|
|
69288
|
+
() => false
|
|
69289
|
+
);
|
|
69290
|
+
}
|
|
69110
69291
|
async function installLazePlugin({ context }) {
|
|
69111
69292
|
const folder = await writeLazePlugin({ context });
|
|
69112
69293
|
const registered = await registerWithClaude({ context, folder });
|
|
69294
|
+
if (registered) await writeFile10(registeredMarkOf({ context }), cliVersionOf());
|
|
69113
69295
|
return { folder, registered };
|
|
69114
69296
|
}
|
|
69115
69297
|
async function plugin({ context, args }) {
|
|
@@ -69133,11 +69315,11 @@ async function plugin({ context, args }) {
|
|
|
69133
69315
|
}
|
|
69134
69316
|
|
|
69135
69317
|
// src/services/mcp-channel.service.ts
|
|
69136
|
-
import { mkdir as
|
|
69137
|
-
import { dirname as
|
|
69318
|
+
import { mkdir as mkdir11, rm as rm7, writeFile as writeFile11 } from "node:fs/promises";
|
|
69319
|
+
import { dirname as dirname11 } from "node:path";
|
|
69138
69320
|
var LAZE_MCP_SERVER = "laze";
|
|
69139
69321
|
var DEV_CHANNELS_FLAG = "--dangerously-load-development-channels";
|
|
69140
|
-
var
|
|
69322
|
+
var ROUND_SECONDS3 = 50;
|
|
69141
69323
|
var RETRY_MS = 5e3;
|
|
69142
69324
|
function channelInstructionsOf({ server }) {
|
|
69143
69325
|
return [
|
|
@@ -69224,11 +69406,11 @@ async function pushInbox({
|
|
|
69224
69406
|
signal
|
|
69225
69407
|
}) {
|
|
69226
69408
|
const marker = statePathOf({ context, kind: "channels", profile });
|
|
69227
|
-
await
|
|
69228
|
-
await
|
|
69409
|
+
await mkdir11(dirname11(marker), { recursive: true, mode: 448 });
|
|
69410
|
+
await writeFile11(marker, JSON.stringify({ pid: context.processes.pid }));
|
|
69229
69411
|
try {
|
|
69230
69412
|
while (!signal.aborted) {
|
|
69231
|
-
const messages = await client.post("/api/agents/me/inbox", { waitSeconds:
|
|
69413
|
+
const messages = await client.post("/api/agents/me/inbox", { waitSeconds: ROUND_SECONDS3 }, { signal }).catch(async (error62) => {
|
|
69232
69414
|
if (signal.aborted) return [];
|
|
69233
69415
|
context.err(`laze mcp: could not read the inbox: ${String(error62)}
|
|
69234
69416
|
`);
|
|
@@ -69247,10 +69429,41 @@ async function pushInbox({
|
|
|
69247
69429
|
`);
|
|
69248
69430
|
}
|
|
69249
69431
|
} finally {
|
|
69250
|
-
await
|
|
69432
|
+
await rm7(marker, { force: true });
|
|
69251
69433
|
}
|
|
69252
69434
|
}
|
|
69253
69435
|
|
|
69436
|
+
// src/services/plugin-tip.service.ts
|
|
69437
|
+
import { mkdir as mkdir12, readFile as readFile10, writeFile as writeFile12 } from "node:fs/promises";
|
|
69438
|
+
import { dirname as dirname12 } from "node:path";
|
|
69439
|
+
var RELOAD_TIP = "Laze: the Laze plugin is installed in Claude Code, and this session has not loaded it yet. Tell the user once, in one plain line, that it is optional: typing /reload-plugins makes Laze messages arrive right away; until then they still arrive through the hooks.";
|
|
69440
|
+
var LINK_RELOAD_TIP = "Tell the user once, in one plain line, that it is optional: typing /reload-plugins makes Laze messages arrive right away; until then they still arrive through the hooks.";
|
|
69441
|
+
function toldPathOf({ context, session }) {
|
|
69442
|
+
return statePathOf({ context, kind: "told", profile: `plugin-${sessionKeyOf({ session })}` });
|
|
69443
|
+
}
|
|
69444
|
+
async function markReloadTipTold({
|
|
69445
|
+
context,
|
|
69446
|
+
session
|
|
69447
|
+
}) {
|
|
69448
|
+
if (!session) return;
|
|
69449
|
+
const path = toldPathOf({ context, session });
|
|
69450
|
+
await mkdir12(dirname12(path), { recursive: true, mode: 448 });
|
|
69451
|
+
await writeFile12(path, String(context.nowMs()), { mode: 384 });
|
|
69452
|
+
}
|
|
69453
|
+
async function reloadTipOnce({
|
|
69454
|
+
context,
|
|
69455
|
+
session
|
|
69456
|
+
}) {
|
|
69457
|
+
if (!session || !await pluginRegistered({ context })) return void 0;
|
|
69458
|
+
const told = await readFile10(toldPathOf({ context, session }), "utf8").then(
|
|
69459
|
+
() => true,
|
|
69460
|
+
() => false
|
|
69461
|
+
);
|
|
69462
|
+
if (told) return void 0;
|
|
69463
|
+
await markReloadTipTold({ context, session });
|
|
69464
|
+
return RELOAD_TIP;
|
|
69465
|
+
}
|
|
69466
|
+
|
|
69254
69467
|
// src/services/agent-commands.service.ts
|
|
69255
69468
|
function percentOf(agent2) {
|
|
69256
69469
|
const { contextTokens, contextWindow } = agent2.context;
|
|
@@ -69310,7 +69523,7 @@ async function installHooks({
|
|
|
69310
69523
|
}) {
|
|
69311
69524
|
const folder = join12(directory, ".claude");
|
|
69312
69525
|
const path = join12(folder, "settings.local.json");
|
|
69313
|
-
const current2 = await
|
|
69526
|
+
const current2 = await readFile11(path, "utf8").then(
|
|
69314
69527
|
(text2) => JSON.parse(text2),
|
|
69315
69528
|
() => ({})
|
|
69316
69529
|
);
|
|
@@ -69321,8 +69534,8 @@ async function installHooks({
|
|
|
69321
69534
|
waitCommand: command("wait"),
|
|
69322
69535
|
preToolCommand: command("pre-tool")
|
|
69323
69536
|
});
|
|
69324
|
-
await
|
|
69325
|
-
await
|
|
69537
|
+
await mkdir13(folder, { recursive: true });
|
|
69538
|
+
await writeFile13(path, `${JSON.stringify(settings2, null, 2)}
|
|
69326
69539
|
`);
|
|
69327
69540
|
return path;
|
|
69328
69541
|
}
|
|
@@ -69350,7 +69563,8 @@ function pluginLinesOf({ plugin: plugin2 }) {
|
|
|
69350
69563
|
if (plugin2 === void 0) return [];
|
|
69351
69564
|
if (!plugin2) return ["Claude Code did not take the Laze plugin; the hooks deliver on their own."];
|
|
69352
69565
|
return [
|
|
69353
|
-
"The Laze plugin is installed in Claude Code: from the next start or resume it delivers too."
|
|
69566
|
+
"The Laze plugin is installed in Claude Code: from the next start or resume it delivers too.",
|
|
69567
|
+
LINK_RELOAD_TIP
|
|
69354
69568
|
];
|
|
69355
69569
|
}
|
|
69356
69570
|
function mcpLinesOf({
|
|
@@ -69505,6 +69719,9 @@ async function nextStepsFor({
|
|
|
69505
69719
|
if (harness === "codex") return linkCodexSession({ context, args, profile, laze, directory });
|
|
69506
69720
|
if (!hooked) return waiterStepsOf({ profile, laze });
|
|
69507
69721
|
const plugin2 = args.flags["no-plugin"] ? void 0 : await installLazePlugin({ context });
|
|
69722
|
+
if (plugin2?.registered) {
|
|
69723
|
+
await markReloadTipTold({ context, session: await currentSessionOf({ context, args }) });
|
|
69724
|
+
}
|
|
69508
69725
|
const mcp2 = args.flags.mcp ? await registerMcp({ context, directory, profile }) : void 0;
|
|
69509
69726
|
const mcpAdd2 = mcpAddCommandOf({ context, profile });
|
|
69510
69727
|
return claudeStepsOf({ profile, laze, directory, mcp: mcp2, mcpAdd: mcpAdd2, plugin: plugin2?.registered });
|
|
@@ -69514,7 +69731,7 @@ async function reportTranscript({
|
|
|
69514
69731
|
input: input2
|
|
69515
69732
|
}) {
|
|
69516
69733
|
if (!input2.transcript_path || !input2.session_id) return;
|
|
69517
|
-
const lines = (await
|
|
69734
|
+
const lines = (await readFile11(input2.transcript_path, "utf8")).split("\n");
|
|
69518
69735
|
const context = readTranscript({ lines });
|
|
69519
69736
|
await client.post("/api/agents/me/activity", {
|
|
69520
69737
|
sessionId: input2.session_id,
|
|
@@ -69523,6 +69740,10 @@ async function reportTranscript({
|
|
|
69523
69740
|
compactions: context.compactions.slice(-20)
|
|
69524
69741
|
});
|
|
69525
69742
|
}
|
|
69743
|
+
function stopContext({ context, text: text2 }) {
|
|
69744
|
+
const hookSpecificOutput = { hookEventName: "Stop", additionalContext: text2 };
|
|
69745
|
+
context.out(JSON.stringify({ hookSpecificOutput }));
|
|
69746
|
+
}
|
|
69526
69747
|
async function handOver({ context, args }) {
|
|
69527
69748
|
const raw = await context.readStdin();
|
|
69528
69749
|
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
@@ -69534,10 +69755,14 @@ async function handOver({ context, args }) {
|
|
|
69534
69755
|
`)
|
|
69535
69756
|
);
|
|
69536
69757
|
if (input2.stop_hook_active) return;
|
|
69758
|
+
const claudePid = await claudePidOf({ context });
|
|
69759
|
+
if (await monitorServes({ context, profile: agent2, claudePid })) {
|
|
69760
|
+
return turnEnded({ context, client, agent: agent2 });
|
|
69761
|
+
}
|
|
69537
69762
|
const kept = await dueFromSpool({
|
|
69538
69763
|
context,
|
|
69539
69764
|
profile: agent2,
|
|
69540
|
-
seen: () => input2.transcript_path ?
|
|
69765
|
+
seen: () => input2.transcript_path ? readFile11(input2.transcript_path, "utf8") : Promise.resolve(""),
|
|
69541
69766
|
pushedToo: false
|
|
69542
69767
|
});
|
|
69543
69768
|
const claim3 = forSession({ client, session });
|
|
@@ -69547,20 +69772,23 @@ async function handOver({ context, args }) {
|
|
|
69547
69772
|
} catch (error62) {
|
|
69548
69773
|
const refused = await notBoundNotice({ context, client: claim3, session, error: error62 });
|
|
69549
69774
|
if (!refused) throw error62;
|
|
69550
|
-
if (
|
|
69551
|
-
const additionalContext2 = refused.notice;
|
|
69552
|
-
context.out(
|
|
69553
|
-
JSON.stringify({ hookSpecificOutput: { hookEventName: "Stop", additionalContext: additionalContext2 } })
|
|
69554
|
-
);
|
|
69775
|
+
if (refused.notice) stopContext({ context, text: refused.notice });
|
|
69555
69776
|
return;
|
|
69556
69777
|
}
|
|
69557
69778
|
await keepTaken({ context, profile: agent2, messages: fresh });
|
|
69558
69779
|
const messages = [...kept, ...fresh];
|
|
69559
|
-
|
|
69780
|
+
const tip = await reloadTipOnce({ context, session });
|
|
69781
|
+
if (messages.length === 0) {
|
|
69782
|
+
await turnEnded({ context, client, agent: agent2 });
|
|
69783
|
+
if (tip) stopContext({ context, text: tip });
|
|
69784
|
+
return;
|
|
69785
|
+
}
|
|
69560
69786
|
await turnStarted({ context, client, agent: agent2, messages });
|
|
69561
69787
|
const self2 = await currentNameOf({ context, client, profile: agent2 });
|
|
69562
|
-
|
|
69563
|
-
|
|
69788
|
+
stopContext({
|
|
69789
|
+
context,
|
|
69790
|
+
text: [hookContextOf({ messages, self: self2 }), tip].filter(Boolean).join("\n\n")
|
|
69791
|
+
});
|
|
69564
69792
|
const messageIds = messages.map((message2) => message2.messageId);
|
|
69565
69793
|
await dropFromSpool({ context, profile: agent2, messageIds });
|
|
69566
69794
|
}
|
|
@@ -69569,7 +69797,7 @@ async function addSessionStartWaiter({ context, args }) {
|
|
|
69569
69797
|
const profile = flagText({ args, name: "profile" });
|
|
69570
69798
|
if (!directory || !profile) return;
|
|
69571
69799
|
const path = join12(directory, ".claude", "settings.local.json");
|
|
69572
|
-
const settings2 = await
|
|
69800
|
+
const settings2 = await readFile11(path, "utf8").then(
|
|
69573
69801
|
(text2) => JSON.parse(text2),
|
|
69574
69802
|
() => void 0
|
|
69575
69803
|
);
|
|
@@ -69596,7 +69824,7 @@ async function stopHook({ context, args }) {
|
|
|
69596
69824
|
}
|
|
69597
69825
|
|
|
69598
69826
|
// src/services/agent-manage-commands.service.ts
|
|
69599
|
-
import { readFile as
|
|
69827
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
69600
69828
|
import { extname, resolve as resolve5 } from "node:path";
|
|
69601
69829
|
|
|
69602
69830
|
// src/rules/login-format.rules.ts
|
|
@@ -69725,7 +69953,7 @@ async function avatarOf({
|
|
|
69725
69953
|
}) {
|
|
69726
69954
|
const path = flagText({ args, name: "avatar" });
|
|
69727
69955
|
if (!path) return void 0;
|
|
69728
|
-
const bytes = await
|
|
69956
|
+
const bytes = await readFile12(resolve5(context.cwd, path)).catch(() => {
|
|
69729
69957
|
throw new CliUsageError(`laze: cannot read the avatar file ${path}.`);
|
|
69730
69958
|
});
|
|
69731
69959
|
const uploaded = await client.post("/api/agents/avatars", {
|
|
@@ -70415,8 +70643,8 @@ async function requestAgent({ context, args }) {
|
|
|
70415
70643
|
}
|
|
70416
70644
|
|
|
70417
70645
|
// src/services/app-commands.service.ts
|
|
70418
|
-
import { mkdir as
|
|
70419
|
-
import { dirname as
|
|
70646
|
+
import { mkdir as mkdir14, readdir as readdir5, readFile as readFile13, writeFile as writeFile15 } from "node:fs/promises";
|
|
70647
|
+
import { dirname as dirname13, join as join14, relative as relative3, resolve as resolve6, sep as sep2 } from "node:path";
|
|
70420
70648
|
|
|
70421
70649
|
// ../../modules/app/contract/src/app.connections.ts
|
|
70422
70650
|
var appFunctionNameSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/);
|
|
@@ -72807,7 +73035,7 @@ async function appPinsCommand({
|
|
|
72807
73035
|
|
|
72808
73036
|
// src/services/app-script-check.service.ts
|
|
72809
73037
|
import { execFile } from "node:child_process";
|
|
72810
|
-
import { mkdtemp, rm as
|
|
73038
|
+
import { mkdtemp, rm as rm8, writeFile as writeFile14 } from "node:fs/promises";
|
|
72811
73039
|
import { tmpdir } from "node:os";
|
|
72812
73040
|
import { join as join13 } from "node:path";
|
|
72813
73041
|
import { promisify } from "node:util";
|
|
@@ -72843,7 +73071,7 @@ async function scriptErrorsOf({
|
|
|
72843
73071
|
const errors = await Promise.all(
|
|
72844
73072
|
scripts.map(async (script, index) => {
|
|
72845
73073
|
const file3 = join13(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
|
|
72846
|
-
await
|
|
73074
|
+
await writeFile14(file3, script.code);
|
|
72847
73075
|
try {
|
|
72848
73076
|
await run2(process.execPath, ["--check", file3]);
|
|
72849
73077
|
return null;
|
|
@@ -72855,7 +73083,7 @@ async function scriptErrorsOf({
|
|
|
72855
73083
|
);
|
|
72856
73084
|
return [...errors.filter((error62) => error62 !== null), ...unknown2];
|
|
72857
73085
|
} finally {
|
|
72858
|
-
await
|
|
73086
|
+
await rm8(dir, { recursive: true, force: true });
|
|
72859
73087
|
}
|
|
72860
73088
|
}
|
|
72861
73089
|
|
|
@@ -72992,7 +73220,7 @@ async function turnTokenOf({
|
|
|
72992
73220
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
72993
73221
|
if (pinned) return pinned;
|
|
72994
73222
|
if (env.LAZE_TURN_FILE) {
|
|
72995
|
-
return
|
|
73223
|
+
return readFile13(env.LAZE_TURN_FILE, "utf8").then(
|
|
72996
73224
|
(text2) => text2.trim(),
|
|
72997
73225
|
() => ""
|
|
72998
73226
|
);
|
|
@@ -73018,7 +73246,7 @@ function folderOf({ context, word: word3 }) {
|
|
|
73018
73246
|
return resolve6(context.cwd, word3 ?? ".");
|
|
73019
73247
|
}
|
|
73020
73248
|
async function readManifest(folder) {
|
|
73021
|
-
const text2 = await
|
|
73249
|
+
const text2 = await readFile13(join14(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
|
|
73022
73250
|
if (text2 === void 0) return void 0;
|
|
73023
73251
|
const parsed = appManifestSchema.safeParse(JSON.parse(text2));
|
|
73024
73252
|
if (!parsed.success) {
|
|
@@ -73053,7 +73281,7 @@ async function jsonFlag({
|
|
|
73053
73281
|
}) {
|
|
73054
73282
|
const raw = flagText({ args, name: name2 });
|
|
73055
73283
|
if (!raw) return void 0;
|
|
73056
|
-
const text2 = raw.startsWith("@") ? await
|
|
73284
|
+
const text2 = raw.startsWith("@") ? await readFile13(resolve6(context.cwd, raw.slice(1)), "utf8") : raw;
|
|
73057
73285
|
try {
|
|
73058
73286
|
return JSON.parse(text2);
|
|
73059
73287
|
} catch {
|
|
@@ -73107,11 +73335,11 @@ var appCreate = async ({ context, args }) => {
|
|
|
73107
73335
|
...visibility ? { visibility } : {}
|
|
73108
73336
|
});
|
|
73109
73337
|
const folder = resolve6(context.cwd, flagText({ args, name: "dir", fallback: app2.slug }));
|
|
73110
|
-
await
|
|
73338
|
+
await mkdir14(folder, { recursive: true });
|
|
73111
73339
|
const files2 = template ? templateFiles({ template, name: name2 }) : {};
|
|
73112
73340
|
for (const [path, content] of Object.entries(files2)) {
|
|
73113
|
-
await
|
|
73114
|
-
await
|
|
73341
|
+
await mkdir14(dirname13(join14(folder, path)), { recursive: true });
|
|
73342
|
+
await writeFile15(join14(folder, path), content);
|
|
73115
73343
|
}
|
|
73116
73344
|
const manifest = {
|
|
73117
73345
|
app: { id: app2.id, name: app2.name, slug: app2.slug },
|
|
@@ -73119,7 +73347,7 @@ var appCreate = async ({ context, args }) => {
|
|
|
73119
73347
|
views: template?.views ? [...template.views] : [],
|
|
73120
73348
|
seed: template ? { ...template.seed } : {}
|
|
73121
73349
|
};
|
|
73122
|
-
await
|
|
73350
|
+
await writeFile15(join14(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
73123
73351
|
`);
|
|
73124
73352
|
print5({
|
|
73125
73353
|
context,
|
|
@@ -73156,7 +73384,7 @@ var appPush = async ({ context, args }) => {
|
|
|
73156
73384
|
paths.map(
|
|
73157
73385
|
async (path) => buildFileOf({
|
|
73158
73386
|
path: relative3(folder, path).split(sep2).join("/"),
|
|
73159
|
-
bytes: await
|
|
73387
|
+
bytes: await readFile13(path)
|
|
73160
73388
|
})
|
|
73161
73389
|
)
|
|
73162
73390
|
);
|
|
@@ -73531,7 +73759,7 @@ var appExport = async ({ context, args }) => {
|
|
|
73531
73759
|
const out = flagText({ args, name: "out" });
|
|
73532
73760
|
if (!out) return context.out(exported.body);
|
|
73533
73761
|
const target = resolve6(context.cwd, out);
|
|
73534
|
-
await
|
|
73762
|
+
await writeFile15(target, exported.body);
|
|
73535
73763
|
context.out(`Wrote ${exported.rows} records to ${relative3(context.cwd, target)}
|
|
73536
73764
|
`);
|
|
73537
73765
|
};
|
|
@@ -73539,7 +73767,7 @@ var appImport = async ({ context, args }) => {
|
|
|
73539
73767
|
const words = args.words.slice(2);
|
|
73540
73768
|
const [named, collection, file3] = words.length >= 3 ? words : [void 0, ...words];
|
|
73541
73769
|
if (!collection || !file3) throw new CliUsageError(USAGE5);
|
|
73542
|
-
const csv = await
|
|
73770
|
+
const csv = await readFile13(resolve6(context.cwd, file3), "utf8").catch(() => {
|
|
73543
73771
|
throw new CliUsageError(`Cannot read ${file3}`);
|
|
73544
73772
|
});
|
|
73545
73773
|
const scoped = named ? { ...args, flags: { ...args.flags, app: named } } : args;
|
|
@@ -73558,7 +73786,7 @@ var appImport = async ({ context, args }) => {
|
|
|
73558
73786
|
});
|
|
73559
73787
|
const refusedOut = flagText({ args, name: "refused" });
|
|
73560
73788
|
if (refusedOut && result.refusedCsv) {
|
|
73561
|
-
await
|
|
73789
|
+
await writeFile15(resolve6(context.cwd, refusedOut), result.refusedCsv);
|
|
73562
73790
|
}
|
|
73563
73791
|
const fitting = result.rows - result.refused.length;
|
|
73564
73792
|
const skipped = result.refused.slice(0, 20).map((row) => ` line ${row.line}: ${row.reason}
|
|
@@ -74105,8 +74333,8 @@ async function billing({ context, args }) {
|
|
|
74105
74333
|
|
|
74106
74334
|
// src/services/browser-commands.service.ts
|
|
74107
74335
|
import { randomBytes } from "node:crypto";
|
|
74108
|
-
import { mkdir as
|
|
74109
|
-
import { dirname as
|
|
74336
|
+
import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile16 } from "node:fs/promises";
|
|
74337
|
+
import { dirname as dirname14, join as join15 } from "node:path";
|
|
74110
74338
|
|
|
74111
74339
|
// src/services/browser-tab-commands.service.ts
|
|
74112
74340
|
var BROWSER_TAB_PATHS = {
|
|
@@ -74652,7 +74880,7 @@ async function turnTokenOf2({ context }) {
|
|
|
74652
74880
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
74653
74881
|
if (pinned) return pinned;
|
|
74654
74882
|
if (!env.LAZE_TURN_FILE) return "";
|
|
74655
|
-
return
|
|
74883
|
+
return readFile14(env.LAZE_TURN_FILE, "utf8").then(
|
|
74656
74884
|
(text2) => text2.trim(),
|
|
74657
74885
|
() => ""
|
|
74658
74886
|
);
|
|
@@ -74726,7 +74954,7 @@ async function cdp({ context, args }) {
|
|
|
74726
74954
|
}
|
|
74727
74955
|
function bridgeStatePath({ context, machine: machine2 }) {
|
|
74728
74956
|
const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74729
|
-
return join15(
|
|
74957
|
+
return join15(dirname14(context.environment.configPath), "bridges", `${safe}.json`);
|
|
74730
74958
|
}
|
|
74731
74959
|
async function bridgePort({
|
|
74732
74960
|
context,
|
|
@@ -74734,7 +74962,7 @@ async function bridgePort({
|
|
|
74734
74962
|
access
|
|
74735
74963
|
}) {
|
|
74736
74964
|
const path = bridgeStatePath({ context, machine: machine2 });
|
|
74737
|
-
const live = await
|
|
74965
|
+
const live = await readFile14(path, "utf8").then(
|
|
74738
74966
|
(text2) => JSON.parse(text2),
|
|
74739
74967
|
() => void 0
|
|
74740
74968
|
);
|
|
@@ -74747,8 +74975,8 @@ async function bridgePort({
|
|
|
74747
74975
|
key,
|
|
74748
74976
|
...target
|
|
74749
74977
|
});
|
|
74750
|
-
await
|
|
74751
|
-
await
|
|
74978
|
+
await mkdir15(dirname14(path), { recursive: true, mode: 448 });
|
|
74979
|
+
await writeFile16(path, JSON.stringify({ port, key }), { mode: 384 });
|
|
74752
74980
|
return port;
|
|
74753
74981
|
}
|
|
74754
74982
|
async function bridge({ context }) {
|
|
@@ -75392,7 +75620,7 @@ async function channelSettings({ context, args }) {
|
|
|
75392
75620
|
}
|
|
75393
75621
|
|
|
75394
75622
|
// src/services/chat-actions-commands.service.ts
|
|
75395
|
-
import { readFile as
|
|
75623
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
75396
75624
|
import { basename as basename2, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve7 } from "node:path";
|
|
75397
75625
|
|
|
75398
75626
|
// src/services/file-upload.service.ts
|
|
@@ -75697,7 +75925,7 @@ function uploadNameOf({ cwd, path }) {
|
|
|
75697
75925
|
}
|
|
75698
75926
|
var fileUpload = async ({ context, args, client }) => {
|
|
75699
75927
|
const path = resolve7(context.cwd, wordAt(args, 3));
|
|
75700
|
-
const bytes = new Uint8Array(await
|
|
75928
|
+
const bytes = new Uint8Array(await readFile15(path));
|
|
75701
75929
|
const answer4 = await uploadFile({
|
|
75702
75930
|
context,
|
|
75703
75931
|
client,
|
|
@@ -75863,167 +76091,6 @@ async function chatActions({
|
|
|
75863
76091
|
|
|
75864
76092
|
// src/services/claude-monitor.service.ts
|
|
75865
76093
|
import { rm as rm9 } from "node:fs/promises";
|
|
75866
|
-
|
|
75867
|
-
// src/services/claude-wait.service.ts
|
|
75868
|
-
import { readFile as readFile14, rm as rm8, writeFile as writeFile15, mkdir as mkdir14 } from "node:fs/promises";
|
|
75869
|
-
import { dirname as dirname13 } from "node:path";
|
|
75870
|
-
var ROUND_SECONDS3 = 50;
|
|
75871
|
-
var WATCH_MS = 2e3;
|
|
75872
|
-
var CHANNEL_CHECK_MS = 5e3;
|
|
75873
|
-
async function holderOf({ path }) {
|
|
75874
|
-
return readFile14(path, "utf8").then(
|
|
75875
|
-
(text2) => JSON.parse(text2),
|
|
75876
|
-
() => void 0
|
|
75877
|
-
);
|
|
75878
|
-
}
|
|
75879
|
-
async function holderClaudeOf({ context, holder }) {
|
|
75880
|
-
if (holder.claudePid) return holder.claudePid;
|
|
75881
|
-
return (await nearestHarnessOf({ context, from: holder.pid }))?.pid;
|
|
75882
|
-
}
|
|
75883
|
-
async function takeLock({
|
|
75884
|
-
context,
|
|
75885
|
-
path,
|
|
75886
|
-
sessionId,
|
|
75887
|
-
claudePid,
|
|
75888
|
-
preempt = false
|
|
75889
|
-
}) {
|
|
75890
|
-
const holder = await holderOf({ path });
|
|
75891
|
-
const self2 = context.processes.pid;
|
|
75892
|
-
if (holder && holder.pid !== self2 && context.processes.alive(holder.pid)) {
|
|
75893
|
-
const served = await holderClaudeOf({ context, holder });
|
|
75894
|
-
const mine3 = preempt && served === claudePid && !holder.monitor;
|
|
75895
|
-
if (served && context.processes.alive(served) && !mine3) return false;
|
|
75896
|
-
context.processes.stop(holder.pid);
|
|
75897
|
-
}
|
|
75898
|
-
await mkdir14(dirname13(path), { recursive: true, mode: 448 });
|
|
75899
|
-
await writeFile15(
|
|
75900
|
-
path,
|
|
75901
|
-
JSON.stringify({
|
|
75902
|
-
pid: self2,
|
|
75903
|
-
claudePid,
|
|
75904
|
-
...sessionId ? { sessionId } : {},
|
|
75905
|
-
...preempt ? { monitor: true } : {}
|
|
75906
|
-
})
|
|
75907
|
-
);
|
|
75908
|
-
return true;
|
|
75909
|
-
}
|
|
75910
|
-
async function channelLive({ context, profile }) {
|
|
75911
|
-
const holder = await holderOf({ path: statePathOf({ context, kind: "channels", profile }) });
|
|
75912
|
-
return holder !== void 0 && context.processes.alive(holder.pid);
|
|
75913
|
-
}
|
|
75914
|
-
async function takeRound2({
|
|
75915
|
-
context,
|
|
75916
|
-
client,
|
|
75917
|
-
claudePid,
|
|
75918
|
-
session
|
|
75919
|
-
}) {
|
|
75920
|
-
const controller = new AbortController();
|
|
75921
|
-
const { signal } = controller;
|
|
75922
|
-
const watch = (async () => {
|
|
75923
|
-
while (!signal.aborted) {
|
|
75924
|
-
await context.sleep(WATCH_MS, signal);
|
|
75925
|
-
if (claudePid && !context.processes.alive(claudePid)) controller.abort();
|
|
75926
|
-
}
|
|
75927
|
-
})();
|
|
75928
|
-
try {
|
|
75929
|
-
return await forSession({ client, session }).post(
|
|
75930
|
-
"/api/agents/me/inbox",
|
|
75931
|
-
{ waitSeconds: ROUND_SECONDS3 },
|
|
75932
|
-
{ signal }
|
|
75933
|
-
);
|
|
75934
|
-
} catch (error62) {
|
|
75935
|
-
if (signal.aborted) return [];
|
|
75936
|
-
throw error62;
|
|
75937
|
-
} finally {
|
|
75938
|
-
controller.abort();
|
|
75939
|
-
await watch;
|
|
75940
|
-
}
|
|
75941
|
-
}
|
|
75942
|
-
async function roundOf({ context, client, name: name2, lock, claudePid, session, seen }) {
|
|
75943
|
-
if ((await holderOf({ path: lock }))?.pid !== context.processes.pid) return void 0;
|
|
75944
|
-
if (claudePid && !context.processes.alive(claudePid)) return void 0;
|
|
75945
|
-
const due = await dueFromSpool({ context, profile: name2, seen, pushedToo: true });
|
|
75946
|
-
if (due.length > 0) return due;
|
|
75947
|
-
if (await channelLive({ context, profile: name2 })) {
|
|
75948
|
-
await context.sleep(CHANNEL_CHECK_MS);
|
|
75949
|
-
return [];
|
|
75950
|
-
}
|
|
75951
|
-
const taken = await takeRound2({ context, client, claudePid, session });
|
|
75952
|
-
if (taken.length === 0) {
|
|
75953
|
-
await context.sleep(1e3);
|
|
75954
|
-
return [];
|
|
75955
|
-
}
|
|
75956
|
-
await keepTaken({ context, profile: name2, messages: taken });
|
|
75957
|
-
return taken;
|
|
75958
|
-
}
|
|
75959
|
-
async function claudePidOf({ context }) {
|
|
75960
|
-
const harness = await nearestHarnessOf({ context });
|
|
75961
|
-
if (harness?.harness === "claude-code") return harness.pid;
|
|
75962
|
-
return await context.processes.parentOf(context.processes.pid) ?? 0;
|
|
75963
|
-
}
|
|
75964
|
-
async function settleRound(round) {
|
|
75965
|
-
const { context, client, name: name2, session } = round;
|
|
75966
|
-
const messages = await roundOf(round).catch(async (error62) => {
|
|
75967
|
-
const refused = await notBoundNotice({
|
|
75968
|
-
context,
|
|
75969
|
-
client: forSession({ client, session }),
|
|
75970
|
-
session,
|
|
75971
|
-
error: error62
|
|
75972
|
-
});
|
|
75973
|
-
if (!refused) throw error62;
|
|
75974
|
-
return refused;
|
|
75975
|
-
});
|
|
75976
|
-
if (messages === void 0) return 0;
|
|
75977
|
-
if (!Array.isArray(messages)) {
|
|
75978
|
-
if (messages.rebound) return "again";
|
|
75979
|
-
if (!messages.notice) return 0;
|
|
75980
|
-
context.err(`${messages.notice}
|
|
75981
|
-
`);
|
|
75982
|
-
return 2;
|
|
75983
|
-
}
|
|
75984
|
-
if (messages.length === 0) return "again";
|
|
75985
|
-
await turnStarted({ context, client, agent: name2, messages }).catch(() => void 0);
|
|
75986
|
-
const self2 = await currentNameOf({ context, client, profile: name2 });
|
|
75987
|
-
context.err(`${hookContextOf({ messages, self: self2 })}
|
|
75988
|
-
`);
|
|
75989
|
-
const messageIds = messages.map((message2) => message2.messageId);
|
|
75990
|
-
await dropFromSpool({ context, profile: name2, messageIds });
|
|
75991
|
-
return 2;
|
|
75992
|
-
}
|
|
75993
|
-
async function waitForMessages({ context, args }) {
|
|
75994
|
-
const raw = await context.readStdin();
|
|
75995
|
-
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
75996
|
-
const session = sessionOf({ context, harness: "claude-code", sessionId: input2.session_id });
|
|
75997
|
-
const named = await sessionProfileArgs({ context, args, session });
|
|
75998
|
-
const { client, name: name2 } = await signedIn({ context, args: named });
|
|
75999
|
-
const claudePid = await claudePidOf({ context });
|
|
76000
|
-
await rememberSession({ context, claudePid, session });
|
|
76001
|
-
const lock = statePathOf({ context, kind: "waiters", profile: name2 });
|
|
76002
|
-
if (!await takeLock({ context, path: lock, sessionId: input2.session_id, claudePid })) return 0;
|
|
76003
|
-
const seen = () => input2.transcript_path ? readFile14(input2.transcript_path, "utf8") : Promise.resolve("");
|
|
76004
|
-
const deadline = context.nowMs() + (WAIT_HOOK_TIMEOUT_SECONDS - 60) * 1e3;
|
|
76005
|
-
try {
|
|
76006
|
-
while (context.nowMs() < deadline) {
|
|
76007
|
-
const code = await settleRound({ context, client, name: name2, lock, claudePid, session, seen });
|
|
76008
|
-
if (code !== "again") return code;
|
|
76009
|
-
}
|
|
76010
|
-
return 0;
|
|
76011
|
-
} finally {
|
|
76012
|
-
if ((await holderOf({ path: lock }))?.pid === context.processes.pid)
|
|
76013
|
-
await rm8(lock, { force: true });
|
|
76014
|
-
}
|
|
76015
|
-
}
|
|
76016
|
-
async function waitHook({ context, args }) {
|
|
76017
|
-
try {
|
|
76018
|
-
return await waitForMessages({ context, args });
|
|
76019
|
-
} catch (error62) {
|
|
76020
|
-
context.err(`laze: the background waiter stopped: ${String(error62)}
|
|
76021
|
-
`);
|
|
76022
|
-
return 0;
|
|
76023
|
-
}
|
|
76024
|
-
}
|
|
76025
|
-
|
|
76026
|
-
// src/services/claude-monitor.service.ts
|
|
76027
76094
|
var MONITOR_IDLE_MS = 3e4;
|
|
76028
76095
|
async function agentProfileHere({
|
|
76029
76096
|
context,
|
|
@@ -76053,7 +76120,7 @@ async function deliverOnce({
|
|
|
76053
76120
|
const named = { ...args, flags: { ...args.flags, profile } };
|
|
76054
76121
|
const { client } = await signedIn({ context, args: named });
|
|
76055
76122
|
const due = await dueFromSpool({ context, profile, seen: async () => "", pushedToo: true });
|
|
76056
|
-
const taken = due.length > 0 ? [] : await
|
|
76123
|
+
const taken = due.length > 0 ? [] : await takeRound({ context, client, claudePid, session });
|
|
76057
76124
|
const messages = [...due, ...taken];
|
|
76058
76125
|
if (messages.length === 0) {
|
|
76059
76126
|
await context.sleep(1e3);
|
|
@@ -77588,10 +77655,10 @@ async function computer({ context, args }) {
|
|
|
77588
77655
|
}
|
|
77589
77656
|
|
|
77590
77657
|
// src/services/connect-commands.service.ts
|
|
77591
|
-
import { readFile as
|
|
77658
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
77592
77659
|
|
|
77593
77660
|
// src/services/mcp-gateway.service.ts
|
|
77594
|
-
import { readFile as
|
|
77661
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
77595
77662
|
import { createInterface as createInterface3 } from "node:readline";
|
|
77596
77663
|
var TURN_HEADER = "x-laze-turn";
|
|
77597
77664
|
function serveMcpGateway({
|
|
@@ -77634,7 +77701,7 @@ async function relayMcpLines({
|
|
|
77634
77701
|
const github3 = env.LAZE_GITHUB_CONNECTION;
|
|
77635
77702
|
const url2 = `${profile.url.replace(/\/+$/, "")}/api/connectors/mcp/${encodeURIComponent(profile.agentId)}${github3 ? `?github=${encodeURIComponent(github3)}` : ""}`;
|
|
77636
77703
|
const turnFile = env.LAZE_TURN_FILE;
|
|
77637
|
-
const readTurn = () =>
|
|
77704
|
+
const readTurn = () => readFile16(turnFile, "utf8").then(
|
|
77638
77705
|
(text2) => text2.trim(),
|
|
77639
77706
|
() => ""
|
|
77640
77707
|
);
|
|
@@ -77724,7 +77791,7 @@ async function turnOf({ context }) {
|
|
|
77724
77791
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
77725
77792
|
if (pinned) return pinned;
|
|
77726
77793
|
const file3 = env.LAZE_TURN_FILE;
|
|
77727
|
-
const turn = file3 ? await
|
|
77794
|
+
const turn = file3 ? await readFile17(file3, "utf8").then(
|
|
77728
77795
|
(text2) => text2.trim(),
|
|
77729
77796
|
() => ""
|
|
77730
77797
|
) : "";
|
|
@@ -77782,11 +77849,11 @@ async function connect({
|
|
|
77782
77849
|
}
|
|
77783
77850
|
|
|
77784
77851
|
// src/services/connector-commands.service.ts
|
|
77785
|
-
import { readFile as
|
|
77852
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
77786
77853
|
import { resolve as resolve8 } from "node:path";
|
|
77787
77854
|
|
|
77788
77855
|
// src/services/vault-keychain-commands.service.ts
|
|
77789
|
-
import { readFile as
|
|
77856
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
77790
77857
|
|
|
77791
77858
|
// src/rules/vault-input.rules.ts
|
|
77792
77859
|
function secondsOf(text2) {
|
|
@@ -78097,7 +78164,7 @@ async function secretText({ context, args }) {
|
|
|
78097
78164
|
);
|
|
78098
78165
|
}
|
|
78099
78166
|
const file3 = flagText({ args, name: "from-file" });
|
|
78100
|
-
const text2 = file3 ? await
|
|
78167
|
+
const text2 = file3 ? await readFile18(file3, "utf8") : await context.readStdin();
|
|
78101
78168
|
const trimmed = text2.replace(/\r?\n$/, "");
|
|
78102
78169
|
if (!trimmed.trim()) throw new CliUsageError("No value: pipe it on stdin or use --from-file.");
|
|
78103
78170
|
return trimmed;
|
|
@@ -78295,7 +78362,7 @@ async function keyText({ context, args }) {
|
|
|
78295
78362
|
throw new CliUsageError("A key never goes in a flag: pipe it on stdin or use --from-file.");
|
|
78296
78363
|
}
|
|
78297
78364
|
const file3 = flagText({ args, name: "from-file" });
|
|
78298
|
-
const text2 = file3 ? await
|
|
78365
|
+
const text2 = file3 ? await readFile19(resolve8(context.cwd, file3), "utf8") : await context.readStdin();
|
|
78299
78366
|
const trimmed = text2.trim();
|
|
78300
78367
|
if (!trimmed) throw new CliUsageError("No key: pipe it on stdin or use --from-file.");
|
|
78301
78368
|
return trimmed;
|
|
@@ -78714,7 +78781,7 @@ async function domains({ context, args }) {
|
|
|
78714
78781
|
}
|
|
78715
78782
|
|
|
78716
78783
|
// src/services/feed-commands.service.ts
|
|
78717
|
-
import { readFile as
|
|
78784
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
78718
78785
|
import { resolve as resolve10 } from "node:path";
|
|
78719
78786
|
|
|
78720
78787
|
// src/rules/feed-input.rules.ts
|
|
@@ -78839,7 +78906,7 @@ function feedFlagsOf({ args }) {
|
|
|
78839
78906
|
}
|
|
78840
78907
|
|
|
78841
78908
|
// src/services/feed-files.service.ts
|
|
78842
|
-
import { readFile as
|
|
78909
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
78843
78910
|
import { basename as basename3, resolve as resolve9 } from "node:path";
|
|
78844
78911
|
|
|
78845
78912
|
// ../../modules/feed/contract/src/feed.ts
|
|
@@ -79432,7 +79499,7 @@ async function local({ context, path }) {
|
|
|
79432
79499
|
return {
|
|
79433
79500
|
fileName,
|
|
79434
79501
|
contentType: contentTypeOf(fileName),
|
|
79435
|
-
bytes: new Uint8Array(await
|
|
79502
|
+
bytes: new Uint8Array(await readFile20(full))
|
|
79436
79503
|
};
|
|
79437
79504
|
}
|
|
79438
79505
|
async function directWith({ client, to }) {
|
|
@@ -79510,7 +79577,7 @@ async function bodyOf2({
|
|
|
79510
79577
|
flags: flags2
|
|
79511
79578
|
}) {
|
|
79512
79579
|
const body = { ...flags2.fields };
|
|
79513
|
-
const read3 = (source) => "file" in source ?
|
|
79580
|
+
const read3 = (source) => "file" in source ? readFile21(resolve10(context.cwd, source.file), "utf8") : source.text;
|
|
79514
79581
|
for (const [field, source] of Object.entries(flags2.texts)) body[field] = await read3(source);
|
|
79515
79582
|
if (flags2.rich) {
|
|
79516
79583
|
const text2 = await read3(flags2.rich.source);
|
|
@@ -79672,7 +79739,7 @@ async function textFlag({
|
|
|
79672
79739
|
}) {
|
|
79673
79740
|
const value = flagText({ args, name: name2 });
|
|
79674
79741
|
if (!value.startsWith("@")) return value;
|
|
79675
|
-
return
|
|
79742
|
+
return readFile21(resolve10(context.cwd, value.slice(1)), "utf8");
|
|
79676
79743
|
}
|
|
79677
79744
|
async function feedList({ context, args }) {
|
|
79678
79745
|
const { client } = await signedIn({ context, args });
|
|
@@ -79782,7 +79849,7 @@ async function feed({ context, args }) {
|
|
|
79782
79849
|
}
|
|
79783
79850
|
|
|
79784
79851
|
// src/services/github-commands.service.ts
|
|
79785
|
-
import { readFile as
|
|
79852
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
79786
79853
|
|
|
79787
79854
|
// src/rules/github-signature.rules.ts
|
|
79788
79855
|
var TURN_SEPARATOR = "~";
|
|
@@ -79852,7 +79919,7 @@ var REAL_GH = "/usr/bin/gh";
|
|
|
79852
79919
|
var NOT_SET = "laze: agent_github_not_set: this agent has no GitHub connection. Its owner sets one on the agent's settings page or with `laze agent set-github <agent> <connection>`.";
|
|
79853
79920
|
async function turnFileToken({ env }) {
|
|
79854
79921
|
if (!env.LAZE_TURN_FILE) return "";
|
|
79855
|
-
return
|
|
79922
|
+
return readFile22(env.LAZE_TURN_FILE, "utf8").then(
|
|
79856
79923
|
(text2) => text2.trim(),
|
|
79857
79924
|
() => ""
|
|
79858
79925
|
);
|
|
@@ -79886,7 +79953,7 @@ async function githubGh({
|
|
|
79886
79953
|
args: args.rest,
|
|
79887
79954
|
agentName: profile.name ?? "An agent",
|
|
79888
79955
|
threadUrl: threadUrlOf({ env, workspaceId: profile.workspaceId }),
|
|
79889
|
-
readBodyFile: (path) => path === "-" ? context.readStdin() :
|
|
79956
|
+
readBodyFile: (path) => path === "-" ? context.readStdin() : readFile22(path, "utf8")
|
|
79890
79957
|
});
|
|
79891
79958
|
return context.runCommand({
|
|
79892
79959
|
command: [REAL_GH, ...ghArgs],
|
|
@@ -79985,7 +80052,7 @@ async function setAgentGithub({
|
|
|
79985
80052
|
}
|
|
79986
80053
|
|
|
79987
80054
|
// src/services/history-commands.service.ts
|
|
79988
|
-
import { readFile as
|
|
80055
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
79989
80056
|
|
|
79990
80057
|
// src/rules/history-format.rules.ts
|
|
79991
80058
|
function timeOf2(iso) {
|
|
@@ -80081,7 +80148,7 @@ async function turnTokenOf3({ context }) {
|
|
|
80081
80148
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
80082
80149
|
if (pinned) return pinned;
|
|
80083
80150
|
if (!env.LAZE_TURN_FILE) return "";
|
|
80084
|
-
return
|
|
80151
|
+
return readFile23(env.LAZE_TURN_FILE, "utf8").then(
|
|
80085
80152
|
(text2) => text2.trim(),
|
|
80086
80153
|
() => ""
|
|
80087
80154
|
);
|
|
@@ -80273,19 +80340,19 @@ async function ip({ context, args }) {
|
|
|
80273
80340
|
}
|
|
80274
80341
|
|
|
80275
80342
|
// src/services/join-commands.service.ts
|
|
80276
|
-
import { mkdir as
|
|
80277
|
-
import { dirname as
|
|
80343
|
+
import { mkdir as mkdir16, readFile as readFile24, rename as rename5, rm as rm10, writeFile as writeFile17 } from "node:fs/promises";
|
|
80344
|
+
import { dirname as dirname15, join as join16 } from "node:path";
|
|
80278
80345
|
var DEFAULT_WAIT_SECONDS2 = 100;
|
|
80279
80346
|
var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
|
|
80280
80347
|
function pendingPathOf({ context }) {
|
|
80281
|
-
return join16(
|
|
80348
|
+
return join16(dirname15(context.environment.configPath), "join", "pending.json");
|
|
80282
80349
|
}
|
|
80283
80350
|
async function readPending({
|
|
80284
80351
|
context,
|
|
80285
80352
|
url: url2,
|
|
80286
80353
|
args
|
|
80287
80354
|
}) {
|
|
80288
|
-
const pending = await
|
|
80355
|
+
const pending = await readFile24(pendingPathOf({ context }), "utf8").then(
|
|
80289
80356
|
(text2) => JSON.parse(text2),
|
|
80290
80357
|
() => void 0
|
|
80291
80358
|
);
|
|
@@ -80295,9 +80362,9 @@ async function readPending({
|
|
|
80295
80362
|
}
|
|
80296
80363
|
async function keepPending({ context, pending }) {
|
|
80297
80364
|
const path = pendingPathOf({ context });
|
|
80298
|
-
await
|
|
80365
|
+
await mkdir16(dirname15(path), { recursive: true, mode: 448 });
|
|
80299
80366
|
const temporary = `${path}.${process.pid}.tmp`;
|
|
80300
|
-
await
|
|
80367
|
+
await writeFile17(temporary, JSON.stringify(pending), { mode: 384 });
|
|
80301
80368
|
await rename5(temporary, path);
|
|
80302
80369
|
}
|
|
80303
80370
|
async function dropPending({ context }) {
|
|
@@ -80615,9 +80682,9 @@ function machineAccessCommand(name2) {
|
|
|
80615
80682
|
|
|
80616
80683
|
// src/services/vault-commands.service.ts
|
|
80617
80684
|
import { createHash as createHash2 } from "node:crypto";
|
|
80618
|
-
import { mkdir as
|
|
80685
|
+
import { mkdir as mkdir17, readFile as readFile25, rm as rm11, writeFile as writeFile18 } from "node:fs/promises";
|
|
80619
80686
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
80620
|
-
import { dirname as
|
|
80687
|
+
import { dirname as dirname16, join as join17 } from "node:path";
|
|
80621
80688
|
var USAGE10 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
|
|
80622
80689
|
Runs the command with the connection's values in its environment, on a Laze agent's computer
|
|
80623
80690
|
or on a machine it runs on.`;
|
|
@@ -80656,7 +80723,7 @@ async function turnTokenOf4({
|
|
|
80656
80723
|
if (pinned) return pinned;
|
|
80657
80724
|
if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80658
80725
|
try {
|
|
80659
|
-
return (await
|
|
80726
|
+
return (await readFile25(turnFile, "utf8")).trim();
|
|
80660
80727
|
} catch {
|
|
80661
80728
|
throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80662
80729
|
}
|
|
@@ -80666,11 +80733,11 @@ function runKeyPathOf({
|
|
|
80666
80733
|
connection
|
|
80667
80734
|
}) {
|
|
80668
80735
|
const name2 = createHash2("sha256").update(connection).digest("hex");
|
|
80669
|
-
const base = turnFile ?
|
|
80736
|
+
const base = turnFile ? dirname16(turnFile) : join17(tmpdir2(), "laze-vault");
|
|
80670
80737
|
return join17(base, "vault-run-keys", `${name2}.json`);
|
|
80671
80738
|
}
|
|
80672
80739
|
async function runKeyAt({ path }) {
|
|
80673
|
-
const saved3 = await
|
|
80740
|
+
const saved3 = await readFile25(path, "utf8").then(
|
|
80674
80741
|
(text2) => JSON.parse(text2),
|
|
80675
80742
|
() => void 0
|
|
80676
80743
|
);
|
|
@@ -80680,8 +80747,8 @@ async function runKeyAt({ path }) {
|
|
|
80680
80747
|
}
|
|
80681
80748
|
const fresh = await generateEcdhKeys();
|
|
80682
80749
|
const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
|
|
80683
|
-
await
|
|
80684
|
-
await
|
|
80750
|
+
await mkdir17(dirname16(path), { recursive: true, mode: 448 });
|
|
80751
|
+
await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
|
|
80685
80752
|
mode: 384
|
|
80686
80753
|
});
|
|
80687
80754
|
return fresh;
|
|
@@ -81352,14 +81419,14 @@ async function serveMcp({
|
|
|
81352
81419
|
}
|
|
81353
81420
|
|
|
81354
81421
|
// src/services/mount-files.service.ts
|
|
81355
|
-
import { mkdir as
|
|
81356
|
-
import { dirname as
|
|
81422
|
+
import { mkdir as mkdir18, readFile as readFile26, rm as rm12, writeFile as writeFile19 } from "node:fs/promises";
|
|
81423
|
+
import { dirname as dirname17, relative as relative5, resolve as resolve11 } from "node:path";
|
|
81357
81424
|
async function textArgument({
|
|
81358
81425
|
context,
|
|
81359
81426
|
value
|
|
81360
81427
|
}) {
|
|
81361
81428
|
if (value === "-") return context.readStdin();
|
|
81362
|
-
if (value.startsWith("@")) return
|
|
81429
|
+
if (value.startsWith("@")) return readFile26(resolve11(context.cwd, value.slice(1)), "utf8");
|
|
81363
81430
|
return value;
|
|
81364
81431
|
}
|
|
81365
81432
|
function turnChannel({ context, args }) {
|
|
@@ -81373,14 +81440,14 @@ async function writeMount({
|
|
|
81373
81440
|
}) {
|
|
81374
81441
|
const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
|
|
81375
81442
|
await rm12(root, { recursive: true, force: true });
|
|
81376
|
-
await
|
|
81443
|
+
await mkdir18(root, { recursive: true });
|
|
81377
81444
|
for (const file3 of files2) {
|
|
81378
81445
|
const target = resolve11(root, file3.path);
|
|
81379
81446
|
const inside = relative5(root, target);
|
|
81380
81447
|
if (!inside || inside.startsWith(".."))
|
|
81381
81448
|
throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
|
|
81382
|
-
await
|
|
81383
|
-
await
|
|
81449
|
+
await mkdir18(dirname17(target), { recursive: true });
|
|
81450
|
+
await writeFile19(target, file3.content);
|
|
81384
81451
|
}
|
|
81385
81452
|
return root;
|
|
81386
81453
|
}
|
|
@@ -82257,7 +82324,7 @@ async function schedule({ context, args }) {
|
|
|
82257
82324
|
}
|
|
82258
82325
|
|
|
82259
82326
|
// src/services/skill-commands.service.ts
|
|
82260
|
-
import { readdir as readdir6, readFile as
|
|
82327
|
+
import { readdir as readdir6, readFile as readFile27 } from "node:fs/promises";
|
|
82261
82328
|
import { join as join18, relative as relative6, resolve as resolve12 } from "node:path";
|
|
82262
82329
|
var USAGE16 = `Usage:
|
|
82263
82330
|
laze skill list [--agent <agentId>]
|
|
@@ -82280,7 +82347,7 @@ async function folderFiles({ root }) {
|
|
|
82280
82347
|
for (const entry of entries) {
|
|
82281
82348
|
if (!entry.isFile()) continue;
|
|
82282
82349
|
const full = join18(entry.parentPath, entry.name);
|
|
82283
|
-
files2.push({ path: relative6(root, full), content: await
|
|
82350
|
+
files2.push({ path: relative6(root, full), content: await readFile27(full, "utf8") });
|
|
82284
82351
|
}
|
|
82285
82352
|
return files2.toSorted((a, b) => a.path.localeCompare(b.path));
|
|
82286
82353
|
}
|
|
@@ -82378,7 +82445,7 @@ async function skillUpdate({ context, args }) {
|
|
|
82378
82445
|
if (!name2 || !newName && description === void 0 && !skillMdFile) {
|
|
82379
82446
|
throw new CliUsageError(USAGE16);
|
|
82380
82447
|
}
|
|
82381
|
-
const skillMd = skillMdFile ? await
|
|
82448
|
+
const skillMd = skillMdFile ? await readFile27(resolve12(context.cwd, skillMdFile), "utf8") : void 0;
|
|
82382
82449
|
const { client } = await signedIn({ context, args });
|
|
82383
82450
|
const updated = await client.post("/api/skills/update", {
|
|
82384
82451
|
name: name2,
|
|
@@ -82424,7 +82491,7 @@ async function skill({ context, args }) {
|
|
|
82424
82491
|
}
|
|
82425
82492
|
|
|
82426
82493
|
// src/services/slack-commands.service.ts
|
|
82427
|
-
import { readFile as
|
|
82494
|
+
import { readFile as readFile28 } from "node:fs/promises";
|
|
82428
82495
|
import { resolve as resolve13 } from "node:path";
|
|
82429
82496
|
var SLACK_USAGE = `Usage (a person's key; Slack stays the source, the bot joins no channel by itself):
|
|
82430
82497
|
laze slack overview connected Slack workspaces, mirrors, your link
|
|
@@ -82472,7 +82539,7 @@ async function secretLines({ context, args }) {
|
|
|
82472
82539
|
throw new CliUsageError("A secret never goes in a flag: pipe it on stdin or use --from-file.");
|
|
82473
82540
|
}
|
|
82474
82541
|
const file3 = flagText({ args, name: "from-file" });
|
|
82475
|
-
const text2 = file3 ? await
|
|
82542
|
+
const text2 = file3 ? await readFile28(resolve13(context.cwd, file3), "utf8") : await context.readStdin();
|
|
82476
82543
|
return text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
82477
82544
|
}
|
|
82478
82545
|
async function secretsOf({
|
|
@@ -82776,7 +82843,7 @@ async function slack({
|
|
|
82776
82843
|
}
|
|
82777
82844
|
|
|
82778
82845
|
// src/services/sso-commands.service.ts
|
|
82779
|
-
import { readFile as
|
|
82846
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
82780
82847
|
var SSO_USAGE = `Usage:
|
|
82781
82848
|
laze sso domains claimed domains and how each signs in (admins)
|
|
82782
82849
|
laze sso claim <domain> the TXT record that proves the domain
|
|
@@ -82863,7 +82930,7 @@ function refuseSecretFlags({ args }) {
|
|
|
82863
82930
|
}
|
|
82864
82931
|
async function clientSecretOf({ context, args }) {
|
|
82865
82932
|
const file3 = flagText({ args, name: "from-file" });
|
|
82866
|
-
const text2 = file3 ? await
|
|
82933
|
+
const text2 = file3 ? await readFile29(file3, "utf8") : await context.readStdin();
|
|
82867
82934
|
const secret = text2.trim();
|
|
82868
82935
|
if (!secret) throw new CliUsageError("No client secret: pipe it on stdin or use --from-file.");
|
|
82869
82936
|
return secret;
|
|
@@ -83196,7 +83263,7 @@ async function vaultScrub({ context, args }) {
|
|
|
83196
83263
|
}
|
|
83197
83264
|
|
|
83198
83265
|
// src/services/whatsapp-business-commands.service.ts
|
|
83199
|
-
import { readFile as
|
|
83266
|
+
import { readFile as readFile30 } from "node:fs/promises";
|
|
83200
83267
|
import { resolve as resolve14 } from "node:path";
|
|
83201
83268
|
|
|
83202
83269
|
// ../../modules/whatsapp-business/contract/src/whatsapp-business.prices.ts
|
|
@@ -83616,7 +83683,7 @@ async function secretsOf2({ context, args }) {
|
|
|
83616
83683
|
const fromConnection = flagText({ args, name: "from-vault" });
|
|
83617
83684
|
if (fromConnection) return { fromConnection };
|
|
83618
83685
|
const file3 = flagText({ args, name: "from-file" });
|
|
83619
|
-
const text2 = file3 ? await
|
|
83686
|
+
const text2 = file3 ? await readFile30(resolve14(context.cwd, file3), "utf8") : await context.readStdin();
|
|
83620
83687
|
const lines = text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
83621
83688
|
if (lines.length !== 2) {
|
|
83622
83689
|
throw new CliUsageError(
|
|
@@ -83817,7 +83884,7 @@ async function whatsappBusiness({
|
|
|
83817
83884
|
}
|
|
83818
83885
|
|
|
83819
83886
|
// src/services/whatsapp-pairing-commands.service.ts
|
|
83820
|
-
import { writeFile as
|
|
83887
|
+
import { writeFile as writeFile20 } from "node:fs/promises";
|
|
83821
83888
|
import { resolve as resolve15 } from "node:path";
|
|
83822
83889
|
var WHATSAPP_PAIRING_USAGE = [
|
|
83823
83890
|
" laze whatsapp pair <machine> [--qr <file.svg>] link WhatsApp on your machine; scan the code (owner)",
|
|
@@ -83838,7 +83905,7 @@ function svgOf(dataUrl) {
|
|
|
83838
83905
|
}
|
|
83839
83906
|
async function report({ context, args, pairing: pairing2 }) {
|
|
83840
83907
|
const qrFile = pairing2.qrSvg ? resolve15(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
|
|
83841
|
-
if (qrFile && pairing2.qrSvg) await
|
|
83908
|
+
if (qrFile && pairing2.qrSvg) await writeFile20(qrFile, svgOf(pairing2.qrSvg), "utf8");
|
|
83842
83909
|
if (args.flags.json) return context.out(`${JSON.stringify({ ...pairing2, qrFile }, null, 2)}
|
|
83843
83910
|
`);
|
|
83844
83911
|
context.out(`${pairing2.pairingId} ${pairing2.state}
|
|
@@ -84197,7 +84264,7 @@ async function flags({ context, args }) {
|
|
|
84197
84264
|
}
|
|
84198
84265
|
|
|
84199
84266
|
// src/services/workspace-commands.service.ts
|
|
84200
|
-
import { readFile as
|
|
84267
|
+
import { readFile as readFile31 } from "node:fs/promises";
|
|
84201
84268
|
import { resolve as resolve16 } from "node:path";
|
|
84202
84269
|
var ROLE_NAMES2 = {
|
|
84203
84270
|
OWNER: "Owner",
|
|
@@ -84380,7 +84447,7 @@ var LOGO_USAGE = "Usage: laze workspace logo set <file.png|jpg|webp> | laze work
|
|
|
84380
84447
|
async function readLogo({ context, file: file3 }) {
|
|
84381
84448
|
let bytes;
|
|
84382
84449
|
try {
|
|
84383
|
-
bytes = new Uint8Array(await
|
|
84450
|
+
bytes = new Uint8Array(await readFile31(resolve16(context.cwd, file3)));
|
|
84384
84451
|
} catch {
|
|
84385
84452
|
throw new CliUsageError(`No file to read at ${file3}.`);
|
|
84386
84453
|
}
|
|
@@ -85041,8 +85108,8 @@ async function runCli({
|
|
|
85041
85108
|
// src/services/processes.service.ts
|
|
85042
85109
|
import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
|
|
85043
85110
|
import { mkdirSync, openSync } from "node:fs";
|
|
85044
|
-
import { readFile as
|
|
85045
|
-
import { dirname as
|
|
85111
|
+
import { readFile as readFile32, readlink } from "node:fs/promises";
|
|
85112
|
+
import { dirname as dirname18 } from "node:path";
|
|
85046
85113
|
import { promisify as promisify2 } from "node:util";
|
|
85047
85114
|
var run3 = promisify2(execFile2);
|
|
85048
85115
|
function alive(pid) {
|
|
@@ -85055,14 +85122,14 @@ function alive(pid) {
|
|
|
85055
85122
|
}
|
|
85056
85123
|
}
|
|
85057
85124
|
async function argsOf(pid) {
|
|
85058
|
-
const raw = await
|
|
85125
|
+
const raw = await readFile32(`/proc/${pid}/cmdline`, "utf8").catch(() => void 0);
|
|
85059
85126
|
if (raw) return raw.split("\0").filter(Boolean);
|
|
85060
85127
|
const listed = await run3("ps", ["-o", "args=", "-p", String(pid)]).catch(() => void 0);
|
|
85061
85128
|
const line = listed?.stdout.trim();
|
|
85062
85129
|
return line ? line.split(/\s+/) : void 0;
|
|
85063
85130
|
}
|
|
85064
85131
|
async function parentOf(pid) {
|
|
85065
|
-
const stat3 = await
|
|
85132
|
+
const stat3 = await readFile32(`/proc/${pid}/stat`, "utf8").catch(() => void 0);
|
|
85066
85133
|
const fromStat = stat3 ? Number(stat3.slice(stat3.lastIndexOf(")") + 2).split(" ")[1]) : NaN;
|
|
85067
85134
|
if (fromStat > 0) return fromStat;
|
|
85068
85135
|
const listed = await run3("ps", ["-o", "ppid=", "-p", String(pid)]).catch(() => void 0);
|
|
@@ -85079,7 +85146,7 @@ async function cwdOf(pid) {
|
|
|
85079
85146
|
return line ? line.slice(1) : void 0;
|
|
85080
85147
|
}
|
|
85081
85148
|
function spawnDetached({ argv, logPath }) {
|
|
85082
|
-
mkdirSync(
|
|
85149
|
+
mkdirSync(dirname18(logPath), { recursive: true, mode: 448 });
|
|
85083
85150
|
const log = openSync(logPath, "a", 384);
|
|
85084
85151
|
const [program = "", ...rest] = argv;
|
|
85085
85152
|
const child = spawn4(program, rest, { detached: true, stdio: ["ignore", log, log] });
|