@lazehq/cli 0.1.16 → 0.1.18
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 +528 -447
- package/package.json +1 -1
package/dist/laze.mjs
CHANGED
|
@@ -18733,7 +18733,7 @@ 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: writeFile21, readFile:
|
|
18736
|
+
var { writeFile: writeFile21, readFile: readFile35, mkdir: mkdir19 } = __require("node:fs/promises");
|
|
18737
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();
|
|
@@ -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 readFile35(resolve17(path), "utf8");
|
|
18954
18954
|
const parsed = JSON.parse(data);
|
|
18955
18955
|
if (Array.isArray(parsed)) {
|
|
18956
18956
|
this.#snapshots.clear();
|
|
@@ -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.18";
|
|
35610
35610
|
function cliVersionOf({ stamped = STAMPED } = {}) {
|
|
35611
35611
|
return stamped.startsWith("__") ? "dev" : stamped;
|
|
35612
35612
|
}
|
|
@@ -65390,8 +65390,8 @@ async function copyAgent({
|
|
|
65390
65390
|
}
|
|
65391
65391
|
|
|
65392
65392
|
// src/services/agent-commands.service.ts
|
|
65393
|
-
import { mkdir as mkdir13, readFile as
|
|
65394
|
-
import { join as
|
|
65393
|
+
import { mkdir as mkdir13, readFile as readFile12, writeFile as writeFile13 } from "node:fs/promises";
|
|
65394
|
+
import { join as join13, resolve as resolve4 } from "node:path";
|
|
65395
65395
|
|
|
65396
65396
|
// src/rules/agent-profile.rules.ts
|
|
65397
65397
|
var LEVELS = { fast: "Laze Fast", frontier: "Laze Frontier" };
|
|
@@ -65486,7 +65486,8 @@ function lazeCommandOf({ program }) {
|
|
|
65486
65486
|
|
|
65487
65487
|
// src/rules/hook-settings.rules.ts
|
|
65488
65488
|
var LAZE_HOOK_MARKER = "laze-cli-hook";
|
|
65489
|
-
var
|
|
65489
|
+
var HOOK_TIMEOUTS = { Stop: 30, PreToolUse: 5, SessionStart: 30 };
|
|
65490
|
+
var TIMEOUTS = HOOK_TIMEOUTS;
|
|
65490
65491
|
var WAIT_HOOK_TIMEOUT_SECONDS = 7 * 24 * 60 * 60;
|
|
65491
65492
|
function withHooks({
|
|
65492
65493
|
hooks,
|
|
@@ -65549,12 +65550,17 @@ function hookCommand({
|
|
|
65549
65550
|
const words = [...program, "hook", hook, "--profile", profile].map(quote4).join(" ");
|
|
65550
65551
|
return `${words} # ${LAZE_HOOK_MARKER}`;
|
|
65551
65552
|
}
|
|
65552
|
-
function
|
|
65553
|
+
function holdsOurs({ settings: settings2, event }) {
|
|
65553
65554
|
const hooks = settings2.hooks ?? {};
|
|
65554
|
-
|
|
65555
|
+
return Array.isArray(hooks[event]) && hooks[event].some(
|
|
65555
65556
|
(entry) => entry.hooks?.some((hook) => hook.command?.includes(LAZE_HOOK_MARKER))
|
|
65556
65557
|
);
|
|
65557
|
-
|
|
65558
|
+
}
|
|
65559
|
+
function lacksSessionStartWaiter({ settings: settings2 }) {
|
|
65560
|
+
return holdsOurs({ settings: settings2, event: "Stop" }) && !holdsOurs({ settings: settings2, event: "SessionStart" });
|
|
65561
|
+
}
|
|
65562
|
+
function hasLazeHooks({ settings: settings2 }) {
|
|
65563
|
+
return holdsOurs({ settings: settings2, event: "Stop" });
|
|
65558
65564
|
}
|
|
65559
65565
|
|
|
65560
65566
|
// src/rules/inbox-format.rules.ts
|
|
@@ -66516,15 +66522,323 @@ function formatSearch({
|
|
|
66516
66522
|
}
|
|
66517
66523
|
|
|
66518
66524
|
// src/services/claude-turn.service.ts
|
|
66519
|
-
import { mkdir as
|
|
66525
|
+
import { mkdir as mkdir4, readFile as readFile5, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
66526
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
66527
|
+
|
|
66528
|
+
// src/services/harness-session.service.ts
|
|
66529
|
+
import { mkdir as mkdir3, readdir, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
66530
|
+
import { hostname as hostname3 } from "node:os";
|
|
66531
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
66532
|
+
|
|
66533
|
+
// src/rules/session-headers.rules.ts
|
|
66534
|
+
import { relative, sep } from "node:path";
|
|
66535
|
+
function sessionKeyOf({ session }) {
|
|
66536
|
+
return `${session.harness}:${session.sessionId}`;
|
|
66537
|
+
}
|
|
66538
|
+
function sessionHeadersOf({
|
|
66539
|
+
session
|
|
66540
|
+
}) {
|
|
66541
|
+
if (!session) return {};
|
|
66542
|
+
return {
|
|
66543
|
+
[AGENT_SESSION_HEADER]: sessionKeyOf({ session }),
|
|
66544
|
+
[AGENT_SESSION_FOLDER_HEADER]: encodeURIComponent(session.folder),
|
|
66545
|
+
[AGENT_SESSION_HOST_HEADER]: encodeURIComponent(session.host)
|
|
66546
|
+
};
|
|
66547
|
+
}
|
|
66548
|
+
function displayFolderOf({ folder, home }) {
|
|
66549
|
+
if (!home) return folder;
|
|
66550
|
+
const below = relative(home, folder);
|
|
66551
|
+
if (below === "") return "~";
|
|
66552
|
+
if (below.startsWith("..") || below.startsWith(sep)) return folder;
|
|
66553
|
+
return `~/${below.split(sep).join("/")}`;
|
|
66554
|
+
}
|
|
66555
|
+
|
|
66556
|
+
// src/services/claude-project.service.ts
|
|
66557
|
+
import { basename, isAbsolute, relative as relative2, resolve as resolve2 } from "node:path";
|
|
66558
|
+
function harnessIn({ words }) {
|
|
66559
|
+
const names = words.slice(0, 2).map((word3) => basename(word3).replace(/\.(js|mjs|cjs)$/, ""));
|
|
66560
|
+
if (names.includes("codex")) return "codex";
|
|
66561
|
+
if (words.some((word3) => word3.includes("@openai/codex"))) return "codex";
|
|
66562
|
+
const claude = words.some((word3) => word3.includes("@anthropic-ai/claude-code"));
|
|
66563
|
+
return claude || names.includes("claude") ? "claude-code" : void 0;
|
|
66564
|
+
}
|
|
66565
|
+
async function nearestHarnessOf({
|
|
66566
|
+
context,
|
|
66567
|
+
from = context.processes.pid
|
|
66568
|
+
}) {
|
|
66569
|
+
let pid = await context.processes.parentOf(from);
|
|
66570
|
+
for (let depth = 0; pid !== void 0 && pid > 1 && depth < 12; depth += 1) {
|
|
66571
|
+
const harness = harnessIn({ words: await context.processes.argsOf(pid) ?? [] });
|
|
66572
|
+
if (harness) return { harness, pid };
|
|
66573
|
+
pid = await context.processes.parentOf(pid);
|
|
66574
|
+
}
|
|
66575
|
+
return void 0;
|
|
66576
|
+
}
|
|
66577
|
+
function holds({ folder, inner }) {
|
|
66578
|
+
const rel = relative2(resolve2(folder), resolve2(inner));
|
|
66579
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
66580
|
+
}
|
|
66581
|
+
async function claudeProjectOf({
|
|
66582
|
+
context,
|
|
66583
|
+
claudePid
|
|
66584
|
+
}) {
|
|
66585
|
+
const env = context.environment.inherited;
|
|
66586
|
+
const pid = Number(env.CLAUDE_PID);
|
|
66587
|
+
const candidates = [
|
|
66588
|
+
claudePid ? await context.processes.cwdOf(claudePid) : void 0,
|
|
66589
|
+
env.CLAUDE_PROJECT_DIR ? resolve2(env.CLAUDE_PROJECT_DIR) : void 0,
|
|
66590
|
+
pid > 0 ? await context.processes.cwdOf(pid) : void 0
|
|
66591
|
+
].filter((folder) => Boolean(folder));
|
|
66592
|
+
return candidates.find((folder) => holds({ folder, inner: context.cwd })) ?? resolve2(context.cwd);
|
|
66593
|
+
}
|
|
66594
|
+
|
|
66595
|
+
// src/services/inbox-spool.service.ts
|
|
66596
|
+
import { mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
|
|
66520
66597
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
66598
|
+
var PUSH_GRACE_MS = 3 * 6e4;
|
|
66599
|
+
function fileNameOf({ profile }) {
|
|
66600
|
+
return profile.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
66601
|
+
}
|
|
66602
|
+
function statePathOf({
|
|
66603
|
+
context,
|
|
66604
|
+
kind,
|
|
66605
|
+
profile,
|
|
66606
|
+
extension: extension2 = "json"
|
|
66607
|
+
}) {
|
|
66608
|
+
const directory = join2(dirname2(context.environment.configPath), kind);
|
|
66609
|
+
return join2(directory, `${fileNameOf({ profile })}.${extension2}`);
|
|
66610
|
+
}
|
|
66611
|
+
async function readSpool({ path }) {
|
|
66612
|
+
return readFile2(path, "utf8").then(
|
|
66613
|
+
(text2) => JSON.parse(text2),
|
|
66614
|
+
() => []
|
|
66615
|
+
);
|
|
66616
|
+
}
|
|
66617
|
+
async function writeSpool({ path, entries }) {
|
|
66618
|
+
await mkdir2(dirname2(path), { recursive: true, mode: 448 });
|
|
66619
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
66620
|
+
await writeFile2(temporary, JSON.stringify(entries), { mode: 384 });
|
|
66621
|
+
await rename2(temporary, path);
|
|
66622
|
+
}
|
|
66623
|
+
async function keepTaken({
|
|
66624
|
+
context,
|
|
66625
|
+
profile,
|
|
66626
|
+
messages,
|
|
66627
|
+
pushed = false
|
|
66628
|
+
}) {
|
|
66629
|
+
if (messages.length === 0) return;
|
|
66630
|
+
const path = statePathOf({ context, kind: "spool", profile });
|
|
66631
|
+
const ids = new Set(messages.map((message2) => message2.messageId));
|
|
66632
|
+
const kept = (await readSpool({ path })).filter((entry) => !ids.has(entry.message.messageId));
|
|
66633
|
+
const now = context.nowMs();
|
|
66634
|
+
const taken = messages.map((message2) => ({
|
|
66635
|
+
message: message2,
|
|
66636
|
+
takenAt: now,
|
|
66637
|
+
...pushed ? { pushedAt: now } : {}
|
|
66638
|
+
}));
|
|
66639
|
+
await writeSpool({ path, entries: [...kept, ...taken] });
|
|
66640
|
+
}
|
|
66641
|
+
async function dropFromSpool({
|
|
66642
|
+
context,
|
|
66643
|
+
profile,
|
|
66644
|
+
messageIds
|
|
66645
|
+
}) {
|
|
66646
|
+
if (messageIds.length === 0) return;
|
|
66647
|
+
const path = statePathOf({ context, kind: "spool", profile });
|
|
66648
|
+
const entries = await readSpool({ path });
|
|
66649
|
+
const ids = new Set(messageIds);
|
|
66650
|
+
const kept = entries.filter((entry) => !ids.has(entry.message.messageId));
|
|
66651
|
+
if (kept.length !== entries.length) await writeSpool({ path, entries: kept });
|
|
66652
|
+
}
|
|
66653
|
+
async function dueFromSpool({
|
|
66654
|
+
context,
|
|
66655
|
+
profile,
|
|
66656
|
+
seen,
|
|
66657
|
+
pushedToo
|
|
66658
|
+
}) {
|
|
66659
|
+
const path = statePathOf({ context, kind: "spool", profile });
|
|
66660
|
+
const entries = await readSpool({ path });
|
|
66661
|
+
const pushed = entries.some((entry) => entry.pushedAt !== void 0);
|
|
66662
|
+
const text2 = pushed ? await seen().catch(() => "") : "";
|
|
66663
|
+
const shown = entries.filter(
|
|
66664
|
+
(entry) => entry.pushedAt !== void 0 && text2.includes(entry.message.messageId)
|
|
66665
|
+
);
|
|
66666
|
+
await dropFromSpool({
|
|
66667
|
+
context,
|
|
66668
|
+
profile,
|
|
66669
|
+
messageIds: shown.map((entry) => entry.message.messageId)
|
|
66670
|
+
});
|
|
66671
|
+
const late = context.nowMs() - PUSH_GRACE_MS;
|
|
66672
|
+
return entries.filter((entry) => !shown.includes(entry)).filter((entry) => entry.pushedAt === void 0 || pushedToo && entry.pushedAt <= late).map((entry) => entry.message);
|
|
66673
|
+
}
|
|
66674
|
+
|
|
66675
|
+
// src/services/harness-session.service.ts
|
|
66676
|
+
function sessionOf({
|
|
66677
|
+
context,
|
|
66678
|
+
harness,
|
|
66679
|
+
sessionId
|
|
66680
|
+
}) {
|
|
66681
|
+
if (!sessionId) return void 0;
|
|
66682
|
+
const inherited = context.environment.inherited;
|
|
66683
|
+
const folder = inherited.CLAUDE_PROJECT_DIR || context.cwd;
|
|
66684
|
+
return {
|
|
66685
|
+
harness,
|
|
66686
|
+
sessionId,
|
|
66687
|
+
folder: displayFolderOf({ folder, home: inherited.HOME }),
|
|
66688
|
+
host: hostname3()
|
|
66689
|
+
};
|
|
66690
|
+
}
|
|
66691
|
+
function forSession({
|
|
66692
|
+
client,
|
|
66693
|
+
session
|
|
66694
|
+
}) {
|
|
66695
|
+
return client.withHeaders(sessionHeadersOf({ session }));
|
|
66696
|
+
}
|
|
66697
|
+
async function rememberSession({
|
|
66698
|
+
context,
|
|
66699
|
+
claudePid,
|
|
66700
|
+
session
|
|
66701
|
+
}) {
|
|
66702
|
+
if (!session || !claudePid) return;
|
|
66703
|
+
const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
|
|
66704
|
+
await mkdir3(dirname3(path), { recursive: true, mode: 448 });
|
|
66705
|
+
await writeFile3(path, JSON.stringify(session), { mode: 384 });
|
|
66706
|
+
}
|
|
66707
|
+
async function currentSessionOf({
|
|
66708
|
+
context,
|
|
66709
|
+
args
|
|
66710
|
+
}) {
|
|
66711
|
+
const inherited = context.environment.inherited;
|
|
66712
|
+
const named = flagText({ args, name: "session" });
|
|
66713
|
+
const harness = context.environment.harness;
|
|
66714
|
+
if (named) return sessionOf({ context, harness, sessionId: named });
|
|
66715
|
+
if (harness === "claude-code" && inherited.CLAUDE_CODE_SESSION_ID) {
|
|
66716
|
+
return sessionOf({ context, harness, sessionId: inherited.CLAUDE_CODE_SESSION_ID });
|
|
66717
|
+
}
|
|
66718
|
+
if (harness === "codex" && inherited.CODEX_THREAD_ID) {
|
|
66719
|
+
return sessionOf({ context, harness, sessionId: inherited.CODEX_THREAD_ID });
|
|
66720
|
+
}
|
|
66721
|
+
const nearest = await nearestHarnessOf({ context });
|
|
66722
|
+
if (!nearest) return void 0;
|
|
66723
|
+
const path = statePathOf({ context, kind: "sessions", profile: String(nearest.pid) });
|
|
66724
|
+
return readFile3(path, "utf8").then(
|
|
66725
|
+
(text2) => JSON.parse(text2),
|
|
66726
|
+
() => void 0
|
|
66727
|
+
);
|
|
66728
|
+
}
|
|
66729
|
+
async function sessionProfileArgs({
|
|
66730
|
+
context,
|
|
66731
|
+
args,
|
|
66732
|
+
session
|
|
66733
|
+
}) {
|
|
66734
|
+
if (!session) return args;
|
|
66735
|
+
const key = sessionKeyOf({ session });
|
|
66736
|
+
const config2 = await context.store.read();
|
|
66737
|
+
const bound = config2.sessions?.[key];
|
|
66738
|
+
if (bound && config2.profiles[bound]) {
|
|
66739
|
+
return { ...args, flags: { ...args.flags, profile: bound } };
|
|
66740
|
+
}
|
|
66741
|
+
const own2 = flagText({ args, name: "profile" });
|
|
66742
|
+
if (own2 && config2.profiles[own2]?.kind === "agent") {
|
|
66743
|
+
await context.store.bindSession({ session: key, profile: own2 });
|
|
66744
|
+
}
|
|
66745
|
+
return args;
|
|
66746
|
+
}
|
|
66747
|
+
async function liveElsewhere({
|
|
66748
|
+
context,
|
|
66749
|
+
key,
|
|
66750
|
+
claudePid
|
|
66751
|
+
}) {
|
|
66752
|
+
const folder = dirname3(statePathOf({ context, kind: "sessions", profile: "x" }));
|
|
66753
|
+
for (const file3 of await readdir(folder).catch(() => [])) {
|
|
66754
|
+
const pid = Number(file3.replace(/\.json$/, ""));
|
|
66755
|
+
if (!pid || pid === claudePid || !context.processes.alive(pid)) continue;
|
|
66756
|
+
const noted = await readFile3(join3(folder, file3), "utf8").then(
|
|
66757
|
+
(text2) => JSON.parse(text2),
|
|
66758
|
+
() => void 0
|
|
66759
|
+
);
|
|
66760
|
+
if (noted && sessionKeyOf({ session: noted }) === key) return true;
|
|
66761
|
+
}
|
|
66762
|
+
return false;
|
|
66763
|
+
}
|
|
66764
|
+
function notBoundText({ meta: meta3 }) {
|
|
66765
|
+
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.`;
|
|
66766
|
+
}
|
|
66767
|
+
async function notBoundNotice({
|
|
66768
|
+
context,
|
|
66769
|
+
client,
|
|
66770
|
+
session,
|
|
66771
|
+
error: error62
|
|
66772
|
+
}) {
|
|
66773
|
+
if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
|
|
66774
|
+
const meta3 = error62.meta ?? {};
|
|
66775
|
+
if (client && session && meta3.session && meta3.host === session.host) {
|
|
66776
|
+
const claudePid = (await nearestHarnessOf({ context }))?.pid;
|
|
66777
|
+
if (!await liveElsewhere({ context, key: meta3.session, claudePid })) {
|
|
66778
|
+
await client.post("/api/agents/me/bind", {});
|
|
66779
|
+
return { notice: void 0, rebound: true };
|
|
66780
|
+
}
|
|
66781
|
+
}
|
|
66782
|
+
const key = session ? sessionKeyOf({ session }) : "unknown";
|
|
66783
|
+
const path = statePathOf({ context, kind: "told", profile: key });
|
|
66784
|
+
const told = await readFile3(path, "utf8").then(
|
|
66785
|
+
() => true,
|
|
66786
|
+
() => false
|
|
66787
|
+
);
|
|
66788
|
+
if (told) return { notice: void 0 };
|
|
66789
|
+
await mkdir3(dirname3(path), { recursive: true, mode: 448 });
|
|
66790
|
+
await writeFile3(path, String(context.nowMs()), { mode: 384 });
|
|
66791
|
+
return { notice: notBoundText({ meta: meta3 }) };
|
|
66792
|
+
}
|
|
66793
|
+
|
|
66794
|
+
// src/services/plugin-hook.service.ts
|
|
66795
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
66796
|
+
import { join as join4 } from "node:path";
|
|
66797
|
+
async function agentProfileHere({
|
|
66798
|
+
context,
|
|
66799
|
+
args,
|
|
66800
|
+
session,
|
|
66801
|
+
claudePid
|
|
66802
|
+
}) {
|
|
66803
|
+
const config2 = await context.store.read();
|
|
66804
|
+
const cwd = (claudePid ? await context.processes.cwdOf(claudePid) : void 0) ?? (context.environment.inherited.CLAUDE_PROJECT_DIR || context.cwd);
|
|
66805
|
+
const folder = boundProfileOf({ bindings: config2.bindings, cwd });
|
|
66806
|
+
if (!folder && !session) return void 0;
|
|
66807
|
+
const asked = { ...args, flags: { ...args.flags, ...folder ? { profile: folder } : {} } };
|
|
66808
|
+
const name2 = flagText({
|
|
66809
|
+
args: await sessionProfileArgs({ context, args: asked, session }),
|
|
66810
|
+
name: "profile"
|
|
66811
|
+
});
|
|
66812
|
+
return name2 && config2.profiles[name2]?.kind === "agent" ? name2 : void 0;
|
|
66813
|
+
}
|
|
66814
|
+
async function projectHooksHere({ context }) {
|
|
66815
|
+
const directory = context.environment.inherited.CLAUDE_PROJECT_DIR || context.cwd;
|
|
66816
|
+
const path = join4(directory, ".claude", "settings.local.json");
|
|
66817
|
+
return readFile4(path, "utf8").then(
|
|
66818
|
+
(text2) => hasLazeHooks({ settings: JSON.parse(text2) }),
|
|
66819
|
+
() => false
|
|
66820
|
+
);
|
|
66821
|
+
}
|
|
66822
|
+
async function pluginHookArgs({
|
|
66823
|
+
context,
|
|
66824
|
+
args,
|
|
66825
|
+
session,
|
|
66826
|
+
claudePid
|
|
66827
|
+
}) {
|
|
66828
|
+
if (!args.flags.plugin) return args;
|
|
66829
|
+
if (await projectHooksHere({ context })) return void 0;
|
|
66830
|
+
const profile = await agentProfileHere({ context, args, session, claudePid });
|
|
66831
|
+
return profile ? { ...args, flags: { ...args.flags, profile } } : void 0;
|
|
66832
|
+
}
|
|
66833
|
+
|
|
66834
|
+
// src/services/claude-turn.service.ts
|
|
66521
66835
|
var PRE_TOOL_TIMEOUT_MS = 3e3;
|
|
66522
66836
|
function statePath({ context, agent: agent2 }) {
|
|
66523
66837
|
const safe = agent2.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
66524
|
-
return
|
|
66838
|
+
return join5(dirname4(context.environment.configPath), "turns", `${safe}.json`);
|
|
66525
66839
|
}
|
|
66526
66840
|
async function readState({ context, agent: agent2 }) {
|
|
66527
|
-
return
|
|
66841
|
+
return readFile5(statePath({ context, agent: agent2 }), "utf8").then(
|
|
66528
66842
|
(text2) => JSON.parse(text2),
|
|
66529
66843
|
() => void 0
|
|
66530
66844
|
);
|
|
@@ -66560,8 +66874,8 @@ async function turnStarted({
|
|
|
66560
66874
|
await beat({ client, state: before, working: false }).catch(() => void 0);
|
|
66561
66875
|
}
|
|
66562
66876
|
const path = statePath({ context, agent: agent2 });
|
|
66563
|
-
await
|
|
66564
|
-
await
|
|
66877
|
+
await mkdir4(dirname4(path), { recursive: true, mode: 448 });
|
|
66878
|
+
await writeFile4(path, JSON.stringify(state));
|
|
66565
66879
|
await beat({ client, state, working: true }).catch(() => void 0);
|
|
66566
66880
|
}
|
|
66567
66881
|
async function turnEnded({
|
|
@@ -66576,12 +66890,16 @@ async function turnEnded({
|
|
|
66576
66890
|
}
|
|
66577
66891
|
async function preToolHook({ context, args }) {
|
|
66578
66892
|
try {
|
|
66579
|
-
await context.readStdin();
|
|
66580
|
-
const
|
|
66893
|
+
const raw = await context.readStdin();
|
|
66894
|
+
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
66895
|
+
const session = sessionOf({ context, harness: "claude-code", sessionId: input2.session_id });
|
|
66896
|
+
const asked = await pluginHookArgs({ context, args, session, claudePid: 0 });
|
|
66897
|
+
if (!asked) return;
|
|
66898
|
+
const { name: name2, profile } = await signedIn({ context, args: asked });
|
|
66581
66899
|
const client = LazeClient.create({
|
|
66582
66900
|
baseUrl: profile.url,
|
|
66583
66901
|
token: profile.token,
|
|
66584
|
-
fetcher: (
|
|
66902
|
+
fetcher: (input3, init) => context.fetcher(input3, { ...init, signal: AbortSignal.timeout(PRE_TOOL_TIMEOUT_MS) })
|
|
66585
66903
|
});
|
|
66586
66904
|
const state = await readState({ context, agent: name2 });
|
|
66587
66905
|
const answer4 = await beat({ client, state, working: true });
|
|
@@ -66605,86 +66923,6 @@ async function preToolHook({ context, args }) {
|
|
|
66605
66923
|
}
|
|
66606
66924
|
}
|
|
66607
66925
|
|
|
66608
|
-
// src/services/inbox-spool.service.ts
|
|
66609
|
-
import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
66610
|
-
import { dirname as dirname3, join as join3 } from "node:path";
|
|
66611
|
-
var PUSH_GRACE_MS = 3 * 6e4;
|
|
66612
|
-
function fileNameOf({ profile }) {
|
|
66613
|
-
return profile.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
66614
|
-
}
|
|
66615
|
-
function statePathOf({
|
|
66616
|
-
context,
|
|
66617
|
-
kind,
|
|
66618
|
-
profile,
|
|
66619
|
-
extension: extension2 = "json"
|
|
66620
|
-
}) {
|
|
66621
|
-
const directory = join3(dirname3(context.environment.configPath), kind);
|
|
66622
|
-
return join3(directory, `${fileNameOf({ profile })}.${extension2}`);
|
|
66623
|
-
}
|
|
66624
|
-
async function readSpool({ path }) {
|
|
66625
|
-
return readFile3(path, "utf8").then(
|
|
66626
|
-
(text2) => JSON.parse(text2),
|
|
66627
|
-
() => []
|
|
66628
|
-
);
|
|
66629
|
-
}
|
|
66630
|
-
async function writeSpool({ path, entries }) {
|
|
66631
|
-
await mkdir3(dirname3(path), { recursive: true, mode: 448 });
|
|
66632
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
66633
|
-
await writeFile3(temporary, JSON.stringify(entries), { mode: 384 });
|
|
66634
|
-
await rename2(temporary, path);
|
|
66635
|
-
}
|
|
66636
|
-
async function keepTaken({
|
|
66637
|
-
context,
|
|
66638
|
-
profile,
|
|
66639
|
-
messages,
|
|
66640
|
-
pushed = false
|
|
66641
|
-
}) {
|
|
66642
|
-
if (messages.length === 0) return;
|
|
66643
|
-
const path = statePathOf({ context, kind: "spool", profile });
|
|
66644
|
-
const ids = new Set(messages.map((message2) => message2.messageId));
|
|
66645
|
-
const kept = (await readSpool({ path })).filter((entry) => !ids.has(entry.message.messageId));
|
|
66646
|
-
const now = context.nowMs();
|
|
66647
|
-
const taken = messages.map((message2) => ({
|
|
66648
|
-
message: message2,
|
|
66649
|
-
takenAt: now,
|
|
66650
|
-
...pushed ? { pushedAt: now } : {}
|
|
66651
|
-
}));
|
|
66652
|
-
await writeSpool({ path, entries: [...kept, ...taken] });
|
|
66653
|
-
}
|
|
66654
|
-
async function dropFromSpool({
|
|
66655
|
-
context,
|
|
66656
|
-
profile,
|
|
66657
|
-
messageIds
|
|
66658
|
-
}) {
|
|
66659
|
-
if (messageIds.length === 0) return;
|
|
66660
|
-
const path = statePathOf({ context, kind: "spool", profile });
|
|
66661
|
-
const entries = await readSpool({ path });
|
|
66662
|
-
const ids = new Set(messageIds);
|
|
66663
|
-
const kept = entries.filter((entry) => !ids.has(entry.message.messageId));
|
|
66664
|
-
if (kept.length !== entries.length) await writeSpool({ path, entries: kept });
|
|
66665
|
-
}
|
|
66666
|
-
async function dueFromSpool({
|
|
66667
|
-
context,
|
|
66668
|
-
profile,
|
|
66669
|
-
seen,
|
|
66670
|
-
pushedToo
|
|
66671
|
-
}) {
|
|
66672
|
-
const path = statePathOf({ context, kind: "spool", profile });
|
|
66673
|
-
const entries = await readSpool({ path });
|
|
66674
|
-
const pushed = entries.some((entry) => entry.pushedAt !== void 0);
|
|
66675
|
-
const text2 = pushed ? await seen().catch(() => "") : "";
|
|
66676
|
-
const shown = entries.filter(
|
|
66677
|
-
(entry) => entry.pushedAt !== void 0 && text2.includes(entry.message.messageId)
|
|
66678
|
-
);
|
|
66679
|
-
await dropFromSpool({
|
|
66680
|
-
context,
|
|
66681
|
-
profile,
|
|
66682
|
-
messageIds: shown.map((entry) => entry.message.messageId)
|
|
66683
|
-
});
|
|
66684
|
-
const late = context.nowMs() - PUSH_GRACE_MS;
|
|
66685
|
-
return entries.filter((entry) => !shown.includes(entry)).filter((entry) => entry.pushedAt === void 0 || pushedToo && entry.pushedAt <= late).map((entry) => entry.message);
|
|
66686
|
-
}
|
|
66687
|
-
|
|
66688
66926
|
// src/rules/activity-format.rules.ts
|
|
66689
66927
|
function utcTimeOf(iso) {
|
|
66690
66928
|
return `${iso.slice(0, 10)} ${iso.slice(11, 16)} UTC`;
|
|
@@ -67225,202 +67463,14 @@ function channelLabelIn(channel) {
|
|
|
67225
67463
|
return `#${channel.name}`;
|
|
67226
67464
|
}
|
|
67227
67465
|
|
|
67228
|
-
// src/services/claude-project.service.ts
|
|
67229
|
-
import { basename, isAbsolute, relative, resolve as resolve2 } from "node:path";
|
|
67230
|
-
function harnessIn({ words }) {
|
|
67231
|
-
const names = words.slice(0, 2).map((word3) => basename(word3).replace(/\.(js|mjs|cjs)$/, ""));
|
|
67232
|
-
if (names.includes("codex")) return "codex";
|
|
67233
|
-
if (words.some((word3) => word3.includes("@openai/codex"))) return "codex";
|
|
67234
|
-
const claude = words.some((word3) => word3.includes("@anthropic-ai/claude-code"));
|
|
67235
|
-
return claude || names.includes("claude") ? "claude-code" : void 0;
|
|
67236
|
-
}
|
|
67237
|
-
async function nearestHarnessOf({
|
|
67238
|
-
context,
|
|
67239
|
-
from = context.processes.pid
|
|
67240
|
-
}) {
|
|
67241
|
-
let pid = await context.processes.parentOf(from);
|
|
67242
|
-
for (let depth = 0; pid !== void 0 && pid > 1 && depth < 12; depth += 1) {
|
|
67243
|
-
const harness = harnessIn({ words: await context.processes.argsOf(pid) ?? [] });
|
|
67244
|
-
if (harness) return { harness, pid };
|
|
67245
|
-
pid = await context.processes.parentOf(pid);
|
|
67246
|
-
}
|
|
67247
|
-
return void 0;
|
|
67248
|
-
}
|
|
67249
|
-
function holds({ folder, inner }) {
|
|
67250
|
-
const rel = relative(resolve2(folder), resolve2(inner));
|
|
67251
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
67252
|
-
}
|
|
67253
|
-
async function claudeProjectOf({
|
|
67254
|
-
context,
|
|
67255
|
-
claudePid
|
|
67256
|
-
}) {
|
|
67257
|
-
const env = context.environment.inherited;
|
|
67258
|
-
const pid = Number(env.CLAUDE_PID);
|
|
67259
|
-
const candidates = [
|
|
67260
|
-
claudePid ? await context.processes.cwdOf(claudePid) : void 0,
|
|
67261
|
-
env.CLAUDE_PROJECT_DIR ? resolve2(env.CLAUDE_PROJECT_DIR) : void 0,
|
|
67262
|
-
pid > 0 ? await context.processes.cwdOf(pid) : void 0
|
|
67263
|
-
].filter((folder) => Boolean(folder));
|
|
67264
|
-
return candidates.find((folder) => holds({ folder, inner: context.cwd })) ?? resolve2(context.cwd);
|
|
67265
|
-
}
|
|
67266
|
-
|
|
67267
67466
|
// src/services/claude-wait.service.ts
|
|
67268
|
-
import { readFile as
|
|
67467
|
+
import { readFile as readFile6, rm as rm2, writeFile as writeFile5, mkdir as mkdir5 } from "node:fs/promises";
|
|
67269
67468
|
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
67469
|
var ROUND_SECONDS = 50;
|
|
67420
67470
|
var WATCH_MS = 2e3;
|
|
67421
67471
|
var CHANNEL_CHECK_MS = 5e3;
|
|
67422
67472
|
async function holderOf({ path }) {
|
|
67423
|
-
return
|
|
67473
|
+
return readFile6(path, "utf8").then(
|
|
67424
67474
|
(text2) => JSON.parse(text2),
|
|
67425
67475
|
() => void 0
|
|
67426
67476
|
);
|
|
@@ -67543,13 +67593,15 @@ async function waitForMessages({ context, args }) {
|
|
|
67543
67593
|
const raw = await context.readStdin();
|
|
67544
67594
|
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
67545
67595
|
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
67596
|
const claudePid = await claudePidOf({ context });
|
|
67597
|
+
const asked = await pluginHookArgs({ context, args, session, claudePid });
|
|
67598
|
+
if (!asked) return 0;
|
|
67599
|
+
const named = await sessionProfileArgs({ context, args: asked, session });
|
|
67600
|
+
const { client, name: name2 } = await signedIn({ context, args: named });
|
|
67549
67601
|
await rememberSession({ context, claudePid, session });
|
|
67550
67602
|
const lock = statePathOf({ context, kind: "waiters", profile: name2 });
|
|
67551
67603
|
if (!await takeLock({ context, path: lock, sessionId: input2.session_id, claudePid })) return 0;
|
|
67552
|
-
const seen = () => input2.transcript_path ?
|
|
67604
|
+
const seen = () => input2.transcript_path ? readFile6(input2.transcript_path, "utf8") : Promise.resolve("");
|
|
67553
67605
|
const deadline = context.nowMs() + (WAIT_HOOK_TIMEOUT_SECONDS - 60) * 1e3;
|
|
67554
67606
|
try {
|
|
67555
67607
|
while (context.nowMs() < deadline) {
|
|
@@ -67584,7 +67636,7 @@ async function monitorServes({
|
|
|
67584
67636
|
// src/services/codex-link.service.ts
|
|
67585
67637
|
import { createReadStream } from "node:fs";
|
|
67586
67638
|
import { readdir as readdir4, rm as rm6, stat as stat2 } from "node:fs/promises";
|
|
67587
|
-
import { join as
|
|
67639
|
+
import { join as join11, resolve as resolve3 } from "node:path";
|
|
67588
67640
|
import { createInterface as createInterface2 } from "node:readline";
|
|
67589
67641
|
|
|
67590
67642
|
// src/rules/connect-service.rules.ts
|
|
@@ -67704,8 +67756,8 @@ function rolloutEventOf({
|
|
|
67704
67756
|
|
|
67705
67757
|
// src/services/codex-adopt.service.ts
|
|
67706
67758
|
import { spawn as spawn2 } from "node:child_process";
|
|
67707
|
-
import { mkdir as mkdir6, readdir as readdir2, readFile as
|
|
67708
|
-
import { dirname as dirname6, join as
|
|
67759
|
+
import { mkdir as mkdir6, readdir as readdir2, readFile as readFile7, rm as rm3, stat, writeFile as writeFile6 } from "node:fs/promises";
|
|
67760
|
+
import { dirname as dirname6, join as join6 } from "node:path";
|
|
67709
67761
|
import { createInterface } from "node:readline";
|
|
67710
67762
|
|
|
67711
67763
|
// src/rules/codex-requests.rules.ts
|
|
@@ -67825,11 +67877,11 @@ var CodexAppServer = class _CodexAppServer {
|
|
|
67825
67877
|
}
|
|
67826
67878
|
};
|
|
67827
67879
|
async function newestThreadId({ codexHome }) {
|
|
67828
|
-
const root =
|
|
67880
|
+
const root = join6(codexHome, "sessions");
|
|
67829
67881
|
const files2 = await readdir2(root, { recursive: true }).catch(() => []);
|
|
67830
67882
|
const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
|
|
67831
67883
|
const dated = await Promise.all(
|
|
67832
|
-
rollouts.map(async (file3) => ({ file: file3, at: (await stat(
|
|
67884
|
+
rollouts.map(async (file3) => ({ file: file3, at: (await stat(join6(root, file3))).mtimeMs }))
|
|
67833
67885
|
);
|
|
67834
67886
|
const newest = dated.toSorted((a, b) => b.at - a.at)[0]?.file ?? "";
|
|
67835
67887
|
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);
|
|
@@ -67904,7 +67956,7 @@ async function answer({
|
|
|
67904
67956
|
var MAX_RESTART_WAIT_SECONDS = 60;
|
|
67905
67957
|
var HEALTHY_RUN_MS = 6e4;
|
|
67906
67958
|
async function recordOf({ path }) {
|
|
67907
|
-
return
|
|
67959
|
+
return readFile7(path, "utf8").then(
|
|
67908
67960
|
(text2) => JSON.parse(text2),
|
|
67909
67961
|
() => void 0
|
|
67910
67962
|
);
|
|
@@ -68007,7 +68059,7 @@ async function adoptedThreadOf({
|
|
|
68007
68059
|
);
|
|
68008
68060
|
if (!held) return threadId;
|
|
68009
68061
|
const path = statePathOf({ context, kind: "adopt", profile, extension: "forks.json" });
|
|
68010
|
-
const forks = await
|
|
68062
|
+
const forks = await readFile7(path, "utf8").then(
|
|
68011
68063
|
(text2) => JSON.parse(text2),
|
|
68012
68064
|
() => ({})
|
|
68013
68065
|
);
|
|
@@ -68078,20 +68130,20 @@ async function adoptCodex({ context, args }) {
|
|
|
68078
68130
|
}
|
|
68079
68131
|
|
|
68080
68132
|
// src/services/connect-delivery.service.ts
|
|
68081
|
-
import { mkdir as mkdir8, readFile as
|
|
68133
|
+
import { mkdir as mkdir8, readFile as readFile9, rename as rename3, rm as rm4, writeFile as writeFile8 } from "node:fs/promises";
|
|
68082
68134
|
import { homedir as homedir2, hostname as hostname4 } from "node:os";
|
|
68083
|
-
import { dirname as dirname8, join as
|
|
68135
|
+
import { dirname as dirname8, join as join9 } from "node:path";
|
|
68084
68136
|
|
|
68085
68137
|
// src/services/codex-turn-watch.service.ts
|
|
68086
68138
|
import { open as open2, readdir as readdir3 } from "node:fs/promises";
|
|
68087
|
-
import { join as
|
|
68139
|
+
import { join as join7 } from "node:path";
|
|
68088
68140
|
var READ_MS = 1500;
|
|
68089
68141
|
var KEEP_WORKING_MS = 3e4;
|
|
68090
68142
|
async function rolloutPathOf({ delivery }) {
|
|
68091
|
-
const root =
|
|
68143
|
+
const root = join7(delivery.codexHome, "sessions");
|
|
68092
68144
|
const files2 = await readdir3(root, { recursive: true }).catch(() => []);
|
|
68093
68145
|
const file3 = files2.find((name2) => name2.endsWith(`-${delivery.threadId}.jsonl`));
|
|
68094
|
-
return file3 ?
|
|
68146
|
+
return file3 ? join7(root, file3) : void 0;
|
|
68095
68147
|
}
|
|
68096
68148
|
async function readFrom({ path, offset }) {
|
|
68097
68149
|
const handle = await open2(path, "r");
|
|
@@ -68177,8 +68229,8 @@ var CodexTurnWatch = class _CodexTurnWatch {
|
|
|
68177
68229
|
};
|
|
68178
68230
|
|
|
68179
68231
|
// src/services/openclaw-relay.service.ts
|
|
68180
|
-
import { chmod as chmod2, mkdir as mkdir7, readFile as
|
|
68181
|
-
import { dirname as dirname7, join as
|
|
68232
|
+
import { chmod as chmod2, mkdir as mkdir7, readFile as readFile8, writeFile as writeFile7 } from "node:fs/promises";
|
|
68233
|
+
import { dirname as dirname7, join as join8 } from "node:path";
|
|
68182
68234
|
|
|
68183
68235
|
// ../../modules/openclaw/contract/src/openclaw.ts
|
|
68184
68236
|
var workspaceIdSchema14 = external_exports.string().min(1);
|
|
@@ -68406,11 +68458,11 @@ var STOPS = /* @__PURE__ */ new Map([
|
|
|
68406
68458
|
[OPENCLAW_RELAY_CLOSE.replaced.code, "another relay for this gateway took over"]
|
|
68407
68459
|
]);
|
|
68408
68460
|
function relaysPathOf({ context }) {
|
|
68409
|
-
return
|
|
68461
|
+
return join8(dirname7(context.environment.configPath), "connect", "openclaw-relays.json");
|
|
68410
68462
|
}
|
|
68411
68463
|
async function readRelays({ context }) {
|
|
68412
68464
|
try {
|
|
68413
|
-
return JSON.parse(await
|
|
68465
|
+
return JSON.parse(await readFile8(relaysPathOf({ context }), "utf8"));
|
|
68414
68466
|
} catch {
|
|
68415
68467
|
return {};
|
|
68416
68468
|
}
|
|
@@ -68607,14 +68659,14 @@ var RelayLoops = class _RelayLoops {
|
|
|
68607
68659
|
|
|
68608
68660
|
// src/services/connect-delivery.service.ts
|
|
68609
68661
|
function connectFolderOf({ context }) {
|
|
68610
|
-
return
|
|
68662
|
+
return join9(dirname8(context.environment.configPath), "connect");
|
|
68611
68663
|
}
|
|
68612
68664
|
function runStatePathOf({ context }) {
|
|
68613
|
-
return
|
|
68665
|
+
return join9(connectFolderOf({ context }), "run.json");
|
|
68614
68666
|
}
|
|
68615
68667
|
async function readJson({ path }) {
|
|
68616
68668
|
try {
|
|
68617
|
-
return JSON.parse(await
|
|
68669
|
+
return JSON.parse(await readFile9(path, "utf8"));
|
|
68618
68670
|
} catch {
|
|
68619
68671
|
return void 0;
|
|
68620
68672
|
}
|
|
@@ -68848,7 +68900,7 @@ async function runConnectLoop({ context }) {
|
|
|
68848
68900
|
// src/services/connect-service.service.ts
|
|
68849
68901
|
import { createHash } from "node:crypto";
|
|
68850
68902
|
import { mkdir as mkdir9, rm as rm5, writeFile as writeFile9 } from "node:fs/promises";
|
|
68851
|
-
import { dirname as dirname9, join as
|
|
68903
|
+
import { dirname as dirname9, join as join10 } from "node:path";
|
|
68852
68904
|
var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the service that delivers to linked Codex sessions.
|
|
68853
68905
|
|
|
68854
68906
|
laze connect install install and start it (systemd --user, a LaunchAgent, or detached)
|
|
@@ -68861,17 +68913,17 @@ var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the
|
|
|
68861
68913
|
\`laze openclaw connect --local\`, whose OpenClaw relay it also runs.
|
|
68862
68914
|
`;
|
|
68863
68915
|
function installedPathOf({ context }) {
|
|
68864
|
-
return
|
|
68916
|
+
return join10(connectFolderOf({ context }), "service.json");
|
|
68865
68917
|
}
|
|
68866
68918
|
function logPathOf({ context }) {
|
|
68867
|
-
return
|
|
68919
|
+
return join10(connectFolderOf({ context }), "connect.log");
|
|
68868
68920
|
}
|
|
68869
68921
|
function homeOf({ context }) {
|
|
68870
68922
|
return context.environment.inherited.HOME ?? dirname9(dirname9(context.environment.configPath));
|
|
68871
68923
|
}
|
|
68872
68924
|
function serviceNameOf({ context }) {
|
|
68873
68925
|
const { configPath } = context.environment;
|
|
68874
|
-
if (configPath ===
|
|
68926
|
+
if (configPath === join10(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
|
|
68875
68927
|
return `laze-connect-${createHash("sha256").update(configPath).digest("hex").slice(0, 8)}`;
|
|
68876
68928
|
}
|
|
68877
68929
|
function serviceEnvOf({ context }) {
|
|
@@ -68894,8 +68946,8 @@ async function run({ context, command }) {
|
|
|
68894
68946
|
async function installSystemd({ context }) {
|
|
68895
68947
|
const name2 = serviceNameOf({ context });
|
|
68896
68948
|
const env = context.environment.inherited;
|
|
68897
|
-
const base = env.XDG_CONFIG_HOME ||
|
|
68898
|
-
const file3 =
|
|
68949
|
+
const base = env.XDG_CONFIG_HOME || join10(homeOf({ context }), ".config");
|
|
68950
|
+
const file3 = join10(base, "systemd", "user", `${name2}.service`);
|
|
68899
68951
|
await mkdir9(dirname9(file3), { recursive: true });
|
|
68900
68952
|
await writeFile9(
|
|
68901
68953
|
file3,
|
|
@@ -68910,7 +68962,7 @@ async function installSystemd({ context }) {
|
|
|
68910
68962
|
async function installLaunchd({ context }) {
|
|
68911
68963
|
const name2 = serviceNameOf({ context });
|
|
68912
68964
|
const label2 = `ai.laze.${name2}`;
|
|
68913
|
-
const file3 =
|
|
68965
|
+
const file3 = join10(homeOf({ context }), "Library", "LaunchAgents", `${label2}.plist`);
|
|
68914
68966
|
const log = logPathOf({ context });
|
|
68915
68967
|
await mkdir9(dirname9(file3), { recursive: true });
|
|
68916
68968
|
await writeFile9(
|
|
@@ -69078,13 +69130,13 @@ async function newestThreadIn({
|
|
|
69078
69130
|
codexHome,
|
|
69079
69131
|
directory
|
|
69080
69132
|
}) {
|
|
69081
|
-
const root =
|
|
69133
|
+
const root = join11(codexHome, "sessions");
|
|
69082
69134
|
const files2 = await readdir4(root, { recursive: true }).catch(() => []);
|
|
69083
69135
|
const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
|
|
69084
69136
|
const dated = await Promise.all(
|
|
69085
69137
|
rollouts.map(async (file3) => ({
|
|
69086
|
-
path:
|
|
69087
|
-
at: await stat2(
|
|
69138
|
+
path: join11(root, file3),
|
|
69139
|
+
at: await stat2(join11(root, file3)).then(
|
|
69088
69140
|
(info) => info.mtimeMs,
|
|
69089
69141
|
() => 0
|
|
69090
69142
|
)
|
|
@@ -69152,17 +69204,22 @@ async function linkCodexSession({
|
|
|
69152
69204
|
}
|
|
69153
69205
|
|
|
69154
69206
|
// src/services/laze-plugin.service.ts
|
|
69155
|
-
import { mkdir as mkdir10, readFile as
|
|
69156
|
-
import { dirname as dirname10, join as
|
|
69207
|
+
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile10 } from "node:fs/promises";
|
|
69208
|
+
import { dirname as dirname10, join as join12 } from "node:path";
|
|
69157
69209
|
|
|
69158
69210
|
// src/rules/laze-plugin.rules.ts
|
|
69159
69211
|
var LAZE_PLUGIN = "laze";
|
|
69160
69212
|
var NPX_CLI = ["npx", "-y", "@lazehq/cli@latest"];
|
|
69161
69213
|
var quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
69162
|
-
function cliLineOf({
|
|
69214
|
+
function cliLineOf({
|
|
69215
|
+
program,
|
|
69216
|
+
args,
|
|
69217
|
+
configPath
|
|
69218
|
+
}) {
|
|
69163
69219
|
const here = [...program, ...args].map(quote).join(" ");
|
|
69164
69220
|
const fallback = [...NPX_CLI, ...args].join(" ");
|
|
69165
|
-
|
|
69221
|
+
const run4 = `if [ -e ${quote(program.at(-1) ?? "")} ]; then exec ${here}; else exec ${fallback}; fi`;
|
|
69222
|
+
return `export LAZE_CLI_CONFIG=${quote(configPath)}; ${run4}`;
|
|
69166
69223
|
}
|
|
69167
69224
|
var SKILL = `---
|
|
69168
69225
|
name: laze
|
|
@@ -69196,10 +69253,28 @@ are waiting, if you think one was missed.
|
|
|
69196
69253
|
If \`laze\` is not on the PATH, run the same commands through \`npx -y @lazehq/cli@latest\`.
|
|
69197
69254
|
Never print or repeat your Laze key.
|
|
69198
69255
|
`;
|
|
69256
|
+
function pluginHooksOf({ line }) {
|
|
69257
|
+
const hook = (name2, timeout) => ({
|
|
69258
|
+
type: "command",
|
|
69259
|
+
command: line(["hook", name2, "--plugin"]),
|
|
69260
|
+
timeout
|
|
69261
|
+
});
|
|
69262
|
+
const waiter = { ...hook("wait", WAIT_HOOK_TIMEOUT_SECONDS), async: true, asyncRewake: true };
|
|
69263
|
+
return {
|
|
69264
|
+
description: "Hands Laze messages to the session and wakes it when one arrives",
|
|
69265
|
+
hooks: {
|
|
69266
|
+
Stop: [{ hooks: [hook("stop", HOOK_TIMEOUTS.Stop), waiter] }],
|
|
69267
|
+
SessionStart: [{ hooks: [waiter] }],
|
|
69268
|
+
PreToolUse: [{ hooks: [hook("pre-tool", HOOK_TIMEOUTS.PreToolUse)] }]
|
|
69269
|
+
}
|
|
69270
|
+
};
|
|
69271
|
+
}
|
|
69199
69272
|
function lazePluginFiles({
|
|
69200
69273
|
program,
|
|
69201
|
-
version: version2
|
|
69274
|
+
version: version2,
|
|
69275
|
+
configPath
|
|
69202
69276
|
}) {
|
|
69277
|
+
const line = (args) => cliLineOf({ program, args, configPath });
|
|
69203
69278
|
const json5 = (value) => `${JSON.stringify(value, null, 2)}
|
|
69204
69279
|
`;
|
|
69205
69280
|
const description = "Laze messages reach this session, and the laze tools to answer them";
|
|
@@ -69234,10 +69309,11 @@ function lazePluginFiles({
|
|
|
69234
69309
|
"laze/monitors/monitors.json": json5([
|
|
69235
69310
|
{
|
|
69236
69311
|
name: "laze-messages",
|
|
69237
|
-
command:
|
|
69312
|
+
command: line(["hook", "monitor"]),
|
|
69238
69313
|
description: "Laze messages for this session"
|
|
69239
69314
|
}
|
|
69240
|
-
])
|
|
69315
|
+
]),
|
|
69316
|
+
"laze/hooks/hooks.json": json5(pluginHooksOf({ line }))
|
|
69241
69317
|
};
|
|
69242
69318
|
}
|
|
69243
69319
|
|
|
@@ -69245,11 +69321,11 @@ function lazePluginFiles({
|
|
|
69245
69321
|
var REGISTER_LIMIT_MS = 6e4;
|
|
69246
69322
|
var quote2 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
69247
69323
|
function pluginFolderOf({ context }) {
|
|
69248
|
-
return
|
|
69324
|
+
return join12(dirname10(context.environment.configPath), "plugins");
|
|
69249
69325
|
}
|
|
69250
69326
|
async function pluginIsCurrent({ context }) {
|
|
69251
|
-
const manifest =
|
|
69252
|
-
const written = await
|
|
69327
|
+
const manifest = join12(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
|
|
69328
|
+
const written = await readFile10(manifest, "utf8").then(
|
|
69253
69329
|
(text2) => JSON.parse(text2).version,
|
|
69254
69330
|
() => void 0
|
|
69255
69331
|
);
|
|
@@ -69257,9 +69333,13 @@ async function pluginIsCurrent({ context }) {
|
|
|
69257
69333
|
}
|
|
69258
69334
|
async function writeLazePlugin({ context }) {
|
|
69259
69335
|
const folder = pluginFolderOf({ context });
|
|
69260
|
-
const files2 = lazePluginFiles({
|
|
69336
|
+
const files2 = lazePluginFiles({
|
|
69337
|
+
program: context.program,
|
|
69338
|
+
version: cliVersionOf(),
|
|
69339
|
+
configPath: context.environment.configPath
|
|
69340
|
+
});
|
|
69261
69341
|
for (const [path, text2] of Object.entries(files2)) {
|
|
69262
|
-
const target =
|
|
69342
|
+
const target = join12(folder, path);
|
|
69263
69343
|
await mkdir10(dirname10(target), { recursive: true });
|
|
69264
69344
|
await writeFile10(target, text2);
|
|
69265
69345
|
}
|
|
@@ -69280,10 +69360,10 @@ async function registerWithClaude({ context, folder }) {
|
|
|
69280
69360
|
return code === 0;
|
|
69281
69361
|
}
|
|
69282
69362
|
function registeredMarkOf({ context }) {
|
|
69283
|
-
return
|
|
69363
|
+
return join12(pluginFolderOf({ context }), "registered");
|
|
69284
69364
|
}
|
|
69285
69365
|
async function pluginRegistered({ context }) {
|
|
69286
|
-
return
|
|
69366
|
+
return readFile10(registeredMarkOf({ context }), "utf8").then(
|
|
69287
69367
|
() => true,
|
|
69288
69368
|
() => false
|
|
69289
69369
|
);
|
|
@@ -69297,7 +69377,7 @@ async function installLazePlugin({ context }) {
|
|
|
69297
69377
|
async function plugin({ context, args }) {
|
|
69298
69378
|
const action = args.words[1] ?? "install";
|
|
69299
69379
|
if (action === "path") {
|
|
69300
|
-
context.out(`${
|
|
69380
|
+
context.out(`${join12(pluginFolderOf({ context }), LAZE_PLUGIN)}
|
|
69301
69381
|
`);
|
|
69302
69382
|
return 0;
|
|
69303
69383
|
}
|
|
@@ -69434,10 +69514,32 @@ async function pushInbox({
|
|
|
69434
69514
|
}
|
|
69435
69515
|
|
|
69436
69516
|
// src/services/plugin-tip.service.ts
|
|
69437
|
-
import { mkdir as mkdir12, readFile as
|
|
69517
|
+
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile12 } from "node:fs/promises";
|
|
69438
69518
|
import { dirname as dirname12 } from "node:path";
|
|
69439
69519
|
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
69520
|
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.";
|
|
69521
|
+
function monitorsRunHere({ context }) {
|
|
69522
|
+
const entrypoint = context.environment.inherited.CLAUDE_CODE_ENTRYPOINT;
|
|
69523
|
+
return entrypoint === void 0 || entrypoint === "cli";
|
|
69524
|
+
}
|
|
69525
|
+
function pluginLinesOf({
|
|
69526
|
+
context,
|
|
69527
|
+
registered
|
|
69528
|
+
}) {
|
|
69529
|
+
if (registered === void 0) return [];
|
|
69530
|
+
if (!registered)
|
|
69531
|
+
return ["Claude Code did not take the Laze plugin; the hooks deliver on their own."];
|
|
69532
|
+
if (!monitorsRunHere({ context })) {
|
|
69533
|
+
return [
|
|
69534
|
+
"The Laze plugin is installed in Claude Code. This session runs headless (claude -p), where",
|
|
69535
|
+
"Claude Code starts no plugin monitors, so the hooks deliver here; nothing to type or restart."
|
|
69536
|
+
];
|
|
69537
|
+
}
|
|
69538
|
+
return [
|
|
69539
|
+
"The Laze plugin is installed in Claude Code: from the next start or resume it delivers too.",
|
|
69540
|
+
LINK_RELOAD_TIP
|
|
69541
|
+
];
|
|
69542
|
+
}
|
|
69441
69543
|
function toldPathOf({ context, session }) {
|
|
69442
69544
|
return statePathOf({ context, kind: "told", profile: `plugin-${sessionKeyOf({ session })}` });
|
|
69443
69545
|
}
|
|
@@ -69454,8 +69556,9 @@ async function reloadTipOnce({
|
|
|
69454
69556
|
context,
|
|
69455
69557
|
session
|
|
69456
69558
|
}) {
|
|
69457
|
-
if (!session || !
|
|
69458
|
-
|
|
69559
|
+
if (!session || !monitorsRunHere({ context })) return void 0;
|
|
69560
|
+
if (!await pluginRegistered({ context })) return void 0;
|
|
69561
|
+
const told = await readFile11(toldPathOf({ context, session }), "utf8").then(
|
|
69459
69562
|
() => true,
|
|
69460
69563
|
() => false
|
|
69461
69564
|
);
|
|
@@ -69521,9 +69624,9 @@ async function installHooks({
|
|
|
69521
69624
|
directory,
|
|
69522
69625
|
profile
|
|
69523
69626
|
}) {
|
|
69524
|
-
const folder =
|
|
69525
|
-
const path =
|
|
69526
|
-
const current2 = await
|
|
69627
|
+
const folder = join13(directory, ".claude");
|
|
69628
|
+
const path = join13(folder, "settings.local.json");
|
|
69629
|
+
const current2 = await readFile12(path, "utf8").then(
|
|
69527
69630
|
(text2) => JSON.parse(text2),
|
|
69528
69631
|
() => ({})
|
|
69529
69632
|
);
|
|
@@ -69559,14 +69662,6 @@ async function registerMcp({
|
|
|
69559
69662
|
done.abort();
|
|
69560
69663
|
return code === 0;
|
|
69561
69664
|
}
|
|
69562
|
-
function pluginLinesOf({ plugin: plugin2 }) {
|
|
69563
|
-
if (plugin2 === void 0) return [];
|
|
69564
|
-
if (!plugin2) return ["Claude Code did not take the Laze plugin; the hooks deliver on their own."];
|
|
69565
|
-
return [
|
|
69566
|
-
"The Laze plugin is installed in Claude Code: from the next start or resume it delivers too.",
|
|
69567
|
-
LINK_RELOAD_TIP
|
|
69568
|
-
];
|
|
69569
|
-
}
|
|
69570
69665
|
function mcpLinesOf({
|
|
69571
69666
|
mcp: mcp2,
|
|
69572
69667
|
mcpAdd: mcpAdd2,
|
|
@@ -69595,7 +69690,7 @@ function claudeStepsOf({
|
|
|
69595
69690
|
"Answer each with",
|
|
69596
69691
|
` ${laze} reply <message-id> "<answer>" --profile ${profile}`,
|
|
69597
69692
|
"Nothing else needs to keep running.",
|
|
69598
|
-
...
|
|
69693
|
+
...plugin2,
|
|
69599
69694
|
...mcpLinesOf({ mcp: mcp2, mcpAdd: mcpAdd2, directory })
|
|
69600
69695
|
].join("\n");
|
|
69601
69696
|
}
|
|
@@ -69724,14 +69819,15 @@ async function nextStepsFor({
|
|
|
69724
69819
|
}
|
|
69725
69820
|
const mcp2 = args.flags.mcp ? await registerMcp({ context, directory, profile }) : void 0;
|
|
69726
69821
|
const mcpAdd2 = mcpAddCommandOf({ context, profile });
|
|
69727
|
-
|
|
69822
|
+
const lines = pluginLinesOf({ context, registered: plugin2?.registered });
|
|
69823
|
+
return claudeStepsOf({ profile, laze, directory, mcp: mcp2, mcpAdd: mcpAdd2, plugin: lines });
|
|
69728
69824
|
}
|
|
69729
69825
|
async function reportTranscript({
|
|
69730
69826
|
client,
|
|
69731
69827
|
input: input2
|
|
69732
69828
|
}) {
|
|
69733
69829
|
if (!input2.transcript_path || !input2.session_id) return;
|
|
69734
|
-
const lines = (await
|
|
69830
|
+
const lines = (await readFile12(input2.transcript_path, "utf8")).split("\n");
|
|
69735
69831
|
const context = readTranscript({ lines });
|
|
69736
69832
|
await client.post("/api/agents/me/activity", {
|
|
69737
69833
|
sessionId: input2.session_id,
|
|
@@ -69748,21 +69844,23 @@ async function handOver({ context, args }) {
|
|
|
69748
69844
|
const raw = await context.readStdin();
|
|
69749
69845
|
const input2 = raw.trim() ? JSON.parse(raw) : {};
|
|
69750
69846
|
const session = sessionOf({ context, harness: "claude-code", sessionId: input2.session_id });
|
|
69751
|
-
const
|
|
69847
|
+
const claudePid = await claudePidOf({ context });
|
|
69848
|
+
const asked = await pluginHookArgs({ context, args, session, claudePid });
|
|
69849
|
+
if (!asked) return;
|
|
69850
|
+
const named = await sessionProfileArgs({ context, args: asked, session });
|
|
69752
69851
|
const { client, name: agent2 } = await signedIn({ context, args: named });
|
|
69753
69852
|
await reportTranscript({ client, input: input2 }).catch(
|
|
69754
69853
|
(error62) => context.err(`laze: could not report context: ${String(error62)}
|
|
69755
69854
|
`)
|
|
69756
69855
|
);
|
|
69757
69856
|
if (input2.stop_hook_active) return;
|
|
69758
|
-
const claudePid = await claudePidOf({ context });
|
|
69759
69857
|
if (await monitorServes({ context, profile: agent2, claudePid })) {
|
|
69760
69858
|
return turnEnded({ context, client, agent: agent2 });
|
|
69761
69859
|
}
|
|
69762
69860
|
const kept = await dueFromSpool({
|
|
69763
69861
|
context,
|
|
69764
69862
|
profile: agent2,
|
|
69765
|
-
seen: () => input2.transcript_path ?
|
|
69863
|
+
seen: () => input2.transcript_path ? readFile12(input2.transcript_path, "utf8") : Promise.resolve(""),
|
|
69766
69864
|
pushedToo: false
|
|
69767
69865
|
});
|
|
69768
69866
|
const claim3 = forSession({ client, session });
|
|
@@ -69796,8 +69894,8 @@ async function addSessionStartWaiter({ context, args }) {
|
|
|
69796
69894
|
const directory = context.environment.inherited.CLAUDE_PROJECT_DIR;
|
|
69797
69895
|
const profile = flagText({ args, name: "profile" });
|
|
69798
69896
|
if (!directory || !profile) return;
|
|
69799
|
-
const path =
|
|
69800
|
-
const settings2 = await
|
|
69897
|
+
const path = join13(directory, ".claude", "settings.local.json");
|
|
69898
|
+
const settings2 = await readFile12(path, "utf8").then(
|
|
69801
69899
|
(text2) => JSON.parse(text2),
|
|
69802
69900
|
() => void 0
|
|
69803
69901
|
);
|
|
@@ -69806,7 +69904,7 @@ async function addSessionStartWaiter({ context, args }) {
|
|
|
69806
69904
|
}
|
|
69807
69905
|
async function refreshPlugin({ context }) {
|
|
69808
69906
|
if (await pluginIsCurrent({ context })) return;
|
|
69809
|
-
const logPath =
|
|
69907
|
+
const logPath = join13(pluginFolderOf({ context }), "install.log");
|
|
69810
69908
|
context.processes.spawnDetached({ argv: [...context.program, "plugin", "install"], logPath });
|
|
69811
69909
|
}
|
|
69812
69910
|
async function stopHook({ context, args }) {
|
|
@@ -69824,7 +69922,7 @@ async function stopHook({ context, args }) {
|
|
|
69824
69922
|
}
|
|
69825
69923
|
|
|
69826
69924
|
// src/services/agent-manage-commands.service.ts
|
|
69827
|
-
import { readFile as
|
|
69925
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
69828
69926
|
import { extname, resolve as resolve5 } from "node:path";
|
|
69829
69927
|
|
|
69830
69928
|
// src/rules/login-format.rules.ts
|
|
@@ -69953,7 +70051,7 @@ async function avatarOf({
|
|
|
69953
70051
|
}) {
|
|
69954
70052
|
const path = flagText({ args, name: "avatar" });
|
|
69955
70053
|
if (!path) return void 0;
|
|
69956
|
-
const bytes = await
|
|
70054
|
+
const bytes = await readFile13(resolve5(context.cwd, path)).catch(() => {
|
|
69957
70055
|
throw new CliUsageError(`laze: cannot read the avatar file ${path}.`);
|
|
69958
70056
|
});
|
|
69959
70057
|
const uploaded = await client.post("/api/agents/avatars", {
|
|
@@ -70643,8 +70741,8 @@ async function requestAgent({ context, args }) {
|
|
|
70643
70741
|
}
|
|
70644
70742
|
|
|
70645
70743
|
// src/services/app-commands.service.ts
|
|
70646
|
-
import { mkdir as mkdir14, readdir as readdir5, readFile as
|
|
70647
|
-
import { dirname as dirname13, join as
|
|
70744
|
+
import { mkdir as mkdir14, readdir as readdir5, readFile as readFile14, writeFile as writeFile15 } from "node:fs/promises";
|
|
70745
|
+
import { dirname as dirname13, join as join15, relative as relative3, resolve as resolve6, sep as sep2 } from "node:path";
|
|
70648
70746
|
|
|
70649
70747
|
// ../../modules/app/contract/src/app.connections.ts
|
|
70650
70748
|
var appFunctionNameSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/);
|
|
@@ -73037,7 +73135,7 @@ async function appPinsCommand({
|
|
|
73037
73135
|
import { execFile } from "node:child_process";
|
|
73038
73136
|
import { mkdtemp, rm as rm8, writeFile as writeFile14 } from "node:fs/promises";
|
|
73039
73137
|
import { tmpdir } from "node:os";
|
|
73040
|
-
import { join as
|
|
73138
|
+
import { join as join14 } from "node:path";
|
|
73041
73139
|
import { promisify } from "node:util";
|
|
73042
73140
|
var run2 = promisify(execFile);
|
|
73043
73141
|
var MODULE_SYNTAX = /^\s*(import|export)\s/m;
|
|
@@ -73066,11 +73164,11 @@ async function scriptErrorsOf({
|
|
|
73066
73164
|
const unknown2 = unknownCollectionsOf({ files: files2, collections });
|
|
73067
73165
|
const scripts = files2.flatMap(scriptsOf);
|
|
73068
73166
|
if (scripts.length === 0) return unknown2;
|
|
73069
|
-
const dir = await mkdtemp(
|
|
73167
|
+
const dir = await mkdtemp(join14(tmpdir(), "laze-app-check-"));
|
|
73070
73168
|
try {
|
|
73071
73169
|
const errors = await Promise.all(
|
|
73072
73170
|
scripts.map(async (script, index) => {
|
|
73073
|
-
const file3 =
|
|
73171
|
+
const file3 = join14(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
|
|
73074
73172
|
await writeFile14(file3, script.code);
|
|
73075
73173
|
try {
|
|
73076
73174
|
await run2(process.execPath, ["--check", file3]);
|
|
@@ -73220,7 +73318,7 @@ async function turnTokenOf({
|
|
|
73220
73318
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
73221
73319
|
if (pinned) return pinned;
|
|
73222
73320
|
if (env.LAZE_TURN_FILE) {
|
|
73223
|
-
return
|
|
73321
|
+
return readFile14(env.LAZE_TURN_FILE, "utf8").then(
|
|
73224
73322
|
(text2) => text2.trim(),
|
|
73225
73323
|
() => ""
|
|
73226
73324
|
);
|
|
@@ -73246,7 +73344,7 @@ function folderOf({ context, word: word3 }) {
|
|
|
73246
73344
|
return resolve6(context.cwd, word3 ?? ".");
|
|
73247
73345
|
}
|
|
73248
73346
|
async function readManifest(folder) {
|
|
73249
|
-
const text2 = await
|
|
73347
|
+
const text2 = await readFile14(join15(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
|
|
73250
73348
|
if (text2 === void 0) return void 0;
|
|
73251
73349
|
const parsed = appManifestSchema.safeParse(JSON.parse(text2));
|
|
73252
73350
|
if (!parsed.success) {
|
|
@@ -73281,7 +73379,7 @@ async function jsonFlag({
|
|
|
73281
73379
|
}) {
|
|
73282
73380
|
const raw = flagText({ args, name: name2 });
|
|
73283
73381
|
if (!raw) return void 0;
|
|
73284
|
-
const text2 = raw.startsWith("@") ? await
|
|
73382
|
+
const text2 = raw.startsWith("@") ? await readFile14(resolve6(context.cwd, raw.slice(1)), "utf8") : raw;
|
|
73285
73383
|
try {
|
|
73286
73384
|
return JSON.parse(text2);
|
|
73287
73385
|
} catch {
|
|
@@ -73294,7 +73392,7 @@ async function listFiles(folder) {
|
|
|
73294
73392
|
while (pending.length > 0 && found.length <= MAX_FILES) {
|
|
73295
73393
|
const current2 = pending.pop() ?? folder;
|
|
73296
73394
|
for (const entry of await readdir5(current2, { withFileTypes: true })) {
|
|
73297
|
-
const path =
|
|
73395
|
+
const path = join15(current2, entry.name);
|
|
73298
73396
|
const rel = relative3(folder, path).split(sep2).join("/");
|
|
73299
73397
|
if (isSkippedPath({ path: rel })) continue;
|
|
73300
73398
|
if (entry.isDirectory()) pending.push(path);
|
|
@@ -73338,8 +73436,8 @@ var appCreate = async ({ context, args }) => {
|
|
|
73338
73436
|
await mkdir14(folder, { recursive: true });
|
|
73339
73437
|
const files2 = template ? templateFiles({ template, name: name2 }) : {};
|
|
73340
73438
|
for (const [path, content] of Object.entries(files2)) {
|
|
73341
|
-
await mkdir14(dirname13(
|
|
73342
|
-
await writeFile15(
|
|
73439
|
+
await mkdir14(dirname13(join15(folder, path)), { recursive: true });
|
|
73440
|
+
await writeFile15(join15(folder, path), content);
|
|
73343
73441
|
}
|
|
73344
73442
|
const manifest = {
|
|
73345
73443
|
app: { id: app2.id, name: app2.name, slug: app2.slug },
|
|
@@ -73347,7 +73445,7 @@ var appCreate = async ({ context, args }) => {
|
|
|
73347
73445
|
views: template?.views ? [...template.views] : [],
|
|
73348
73446
|
seed: template ? { ...template.seed } : {}
|
|
73349
73447
|
};
|
|
73350
|
-
await writeFile15(
|
|
73448
|
+
await writeFile15(join15(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
73351
73449
|
`);
|
|
73352
73450
|
print5({
|
|
73353
73451
|
context,
|
|
@@ -73384,7 +73482,7 @@ var appPush = async ({ context, args }) => {
|
|
|
73384
73482
|
paths.map(
|
|
73385
73483
|
async (path) => buildFileOf({
|
|
73386
73484
|
path: relative3(folder, path).split(sep2).join("/"),
|
|
73387
|
-
bytes: await
|
|
73485
|
+
bytes: await readFile14(path)
|
|
73388
73486
|
})
|
|
73389
73487
|
)
|
|
73390
73488
|
);
|
|
@@ -73767,7 +73865,7 @@ var appImport = async ({ context, args }) => {
|
|
|
73767
73865
|
const words = args.words.slice(2);
|
|
73768
73866
|
const [named, collection, file3] = words.length >= 3 ? words : [void 0, ...words];
|
|
73769
73867
|
if (!collection || !file3) throw new CliUsageError(USAGE5);
|
|
73770
|
-
const csv = await
|
|
73868
|
+
const csv = await readFile14(resolve6(context.cwd, file3), "utf8").catch(() => {
|
|
73771
73869
|
throw new CliUsageError(`Cannot read ${file3}`);
|
|
73772
73870
|
});
|
|
73773
73871
|
const scoped = named ? { ...args, flags: { ...args.flags, app: named } } : args;
|
|
@@ -74333,8 +74431,8 @@ async function billing({ context, args }) {
|
|
|
74333
74431
|
|
|
74334
74432
|
// src/services/browser-commands.service.ts
|
|
74335
74433
|
import { randomBytes } from "node:crypto";
|
|
74336
|
-
import { mkdir as mkdir15, readFile as
|
|
74337
|
-
import { dirname as dirname14, join as
|
|
74434
|
+
import { mkdir as mkdir15, readFile as readFile15, writeFile as writeFile16 } from "node:fs/promises";
|
|
74435
|
+
import { dirname as dirname14, join as join16 } from "node:path";
|
|
74338
74436
|
|
|
74339
74437
|
// src/services/browser-tab-commands.service.ts
|
|
74340
74438
|
var BROWSER_TAB_PATHS = {
|
|
@@ -74880,7 +74978,7 @@ async function turnTokenOf2({ context }) {
|
|
|
74880
74978
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
74881
74979
|
if (pinned) return pinned;
|
|
74882
74980
|
if (!env.LAZE_TURN_FILE) return "";
|
|
74883
|
-
return
|
|
74981
|
+
return readFile15(env.LAZE_TURN_FILE, "utf8").then(
|
|
74884
74982
|
(text2) => text2.trim(),
|
|
74885
74983
|
() => ""
|
|
74886
74984
|
);
|
|
@@ -74954,7 +75052,7 @@ async function cdp({ context, args }) {
|
|
|
74954
75052
|
}
|
|
74955
75053
|
function bridgeStatePath({ context, machine: machine2 }) {
|
|
74956
75054
|
const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74957
|
-
return
|
|
75055
|
+
return join16(dirname14(context.environment.configPath), "bridges", `${safe}.json`);
|
|
74958
75056
|
}
|
|
74959
75057
|
async function bridgePort({
|
|
74960
75058
|
context,
|
|
@@ -74962,7 +75060,7 @@ async function bridgePort({
|
|
|
74962
75060
|
access
|
|
74963
75061
|
}) {
|
|
74964
75062
|
const path = bridgeStatePath({ context, machine: machine2 });
|
|
74965
|
-
const live = await
|
|
75063
|
+
const live = await readFile15(path, "utf8").then(
|
|
74966
75064
|
(text2) => JSON.parse(text2),
|
|
74967
75065
|
() => void 0
|
|
74968
75066
|
);
|
|
@@ -75620,7 +75718,7 @@ async function channelSettings({ context, args }) {
|
|
|
75620
75718
|
}
|
|
75621
75719
|
|
|
75622
75720
|
// src/services/chat-actions-commands.service.ts
|
|
75623
|
-
import { readFile as
|
|
75721
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
75624
75722
|
import { basename as basename2, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve7 } from "node:path";
|
|
75625
75723
|
|
|
75626
75724
|
// src/services/file-upload.service.ts
|
|
@@ -75925,7 +76023,7 @@ function uploadNameOf({ cwd, path }) {
|
|
|
75925
76023
|
}
|
|
75926
76024
|
var fileUpload = async ({ context, args, client }) => {
|
|
75927
76025
|
const path = resolve7(context.cwd, wordAt(args, 3));
|
|
75928
|
-
const bytes = new Uint8Array(await
|
|
76026
|
+
const bytes = new Uint8Array(await readFile16(path));
|
|
75929
76027
|
const answer4 = await uploadFile({
|
|
75930
76028
|
context,
|
|
75931
76029
|
client,
|
|
@@ -76090,26 +76188,9 @@ async function chatActions({
|
|
|
76090
76188
|
}
|
|
76091
76189
|
|
|
76092
76190
|
// src/services/claude-monitor.service.ts
|
|
76093
|
-
import { readFile as
|
|
76191
|
+
import { readFile as readFile17, rm as rm9 } from "node:fs/promises";
|
|
76094
76192
|
var MONITOR_IDLE_MS = 3e4;
|
|
76095
76193
|
var MONITOR_OUTRANKED_MS = 3e3;
|
|
76096
|
-
async function agentProfileHere({
|
|
76097
|
-
context,
|
|
76098
|
-
args,
|
|
76099
|
-
session,
|
|
76100
|
-
claudePid
|
|
76101
|
-
}) {
|
|
76102
|
-
const config2 = await context.store.read();
|
|
76103
|
-
const cwd = (claudePid ? await context.processes.cwdOf(claudePid) : void 0) ?? context.cwd;
|
|
76104
|
-
const folder = boundProfileOf({ bindings: config2.bindings, cwd });
|
|
76105
|
-
if (!folder && !session) return void 0;
|
|
76106
|
-
const asked = { ...args, flags: { ...args.flags, ...folder ? { profile: folder } : {} } };
|
|
76107
|
-
const name2 = flagText({
|
|
76108
|
-
args: await sessionProfileArgs({ context, args: asked, session }),
|
|
76109
|
-
name: "profile"
|
|
76110
|
-
});
|
|
76111
|
-
return name2 && config2.profiles[name2]?.kind === "agent" ? name2 : void 0;
|
|
76112
|
-
}
|
|
76113
76194
|
async function deliverOnce({
|
|
76114
76195
|
context,
|
|
76115
76196
|
args,
|
|
@@ -76196,7 +76277,7 @@ async function monitorSessionOf({
|
|
|
76196
76277
|
const fromEnv = sessionOf({ context, harness: "claude-code", sessionId });
|
|
76197
76278
|
if (fromEnv || !claudePid) return fromEnv;
|
|
76198
76279
|
const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
|
|
76199
|
-
return
|
|
76280
|
+
return readFile17(path, "utf8").then(
|
|
76200
76281
|
(text2) => JSON.parse(text2),
|
|
76201
76282
|
() => void 0
|
|
76202
76283
|
);
|
|
@@ -77683,10 +77764,10 @@ async function computer({ context, args }) {
|
|
|
77683
77764
|
}
|
|
77684
77765
|
|
|
77685
77766
|
// src/services/connect-commands.service.ts
|
|
77686
|
-
import { readFile as
|
|
77767
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
77687
77768
|
|
|
77688
77769
|
// src/services/mcp-gateway.service.ts
|
|
77689
|
-
import { readFile as
|
|
77770
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
77690
77771
|
import { createInterface as createInterface3 } from "node:readline";
|
|
77691
77772
|
var TURN_HEADER = "x-laze-turn";
|
|
77692
77773
|
function serveMcpGateway({
|
|
@@ -77729,7 +77810,7 @@ async function relayMcpLines({
|
|
|
77729
77810
|
const github3 = env.LAZE_GITHUB_CONNECTION;
|
|
77730
77811
|
const url2 = `${profile.url.replace(/\/+$/, "")}/api/connectors/mcp/${encodeURIComponent(profile.agentId)}${github3 ? `?github=${encodeURIComponent(github3)}` : ""}`;
|
|
77731
77812
|
const turnFile = env.LAZE_TURN_FILE;
|
|
77732
|
-
const readTurn = () =>
|
|
77813
|
+
const readTurn = () => readFile18(turnFile, "utf8").then(
|
|
77733
77814
|
(text2) => text2.trim(),
|
|
77734
77815
|
() => ""
|
|
77735
77816
|
);
|
|
@@ -77819,7 +77900,7 @@ async function turnOf({ context }) {
|
|
|
77819
77900
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
77820
77901
|
if (pinned) return pinned;
|
|
77821
77902
|
const file3 = env.LAZE_TURN_FILE;
|
|
77822
|
-
const turn = file3 ? await
|
|
77903
|
+
const turn = file3 ? await readFile19(file3, "utf8").then(
|
|
77823
77904
|
(text2) => text2.trim(),
|
|
77824
77905
|
() => ""
|
|
77825
77906
|
) : "";
|
|
@@ -77877,11 +77958,11 @@ async function connect({
|
|
|
77877
77958
|
}
|
|
77878
77959
|
|
|
77879
77960
|
// src/services/connector-commands.service.ts
|
|
77880
|
-
import { readFile as
|
|
77961
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
77881
77962
|
import { resolve as resolve8 } from "node:path";
|
|
77882
77963
|
|
|
77883
77964
|
// src/services/vault-keychain-commands.service.ts
|
|
77884
|
-
import { readFile as
|
|
77965
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
77885
77966
|
|
|
77886
77967
|
// src/rules/vault-input.rules.ts
|
|
77887
77968
|
function secondsOf(text2) {
|
|
@@ -78192,7 +78273,7 @@ async function secretText({ context, args }) {
|
|
|
78192
78273
|
);
|
|
78193
78274
|
}
|
|
78194
78275
|
const file3 = flagText({ args, name: "from-file" });
|
|
78195
|
-
const text2 = file3 ? await
|
|
78276
|
+
const text2 = file3 ? await readFile20(file3, "utf8") : await context.readStdin();
|
|
78196
78277
|
const trimmed = text2.replace(/\r?\n$/, "");
|
|
78197
78278
|
if (!trimmed.trim()) throw new CliUsageError("No value: pipe it on stdin or use --from-file.");
|
|
78198
78279
|
return trimmed;
|
|
@@ -78390,7 +78471,7 @@ async function keyText({ context, args }) {
|
|
|
78390
78471
|
throw new CliUsageError("A key never goes in a flag: pipe it on stdin or use --from-file.");
|
|
78391
78472
|
}
|
|
78392
78473
|
const file3 = flagText({ args, name: "from-file" });
|
|
78393
|
-
const text2 = file3 ? await
|
|
78474
|
+
const text2 = file3 ? await readFile21(resolve8(context.cwd, file3), "utf8") : await context.readStdin();
|
|
78394
78475
|
const trimmed = text2.trim();
|
|
78395
78476
|
if (!trimmed) throw new CliUsageError("No key: pipe it on stdin or use --from-file.");
|
|
78396
78477
|
return trimmed;
|
|
@@ -78776,8 +78857,8 @@ var DOMAINS_USAGE = `Usage:
|
|
|
78776
78857
|
var printJson4 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
|
|
78777
78858
|
`);
|
|
78778
78859
|
function printDomain(context, row) {
|
|
78779
|
-
const
|
|
78780
|
-
context.out(`${row.domain} ${
|
|
78860
|
+
const join20 = row.autoJoin ? "auto-join on" : "auto-join off";
|
|
78861
|
+
context.out(`${row.domain} ${join20}${row.enforced ? " single sign-on enforced" : ""}
|
|
78781
78862
|
`);
|
|
78782
78863
|
}
|
|
78783
78864
|
async function list4({ context, args }) {
|
|
@@ -78809,7 +78890,7 @@ async function domains({ context, args }) {
|
|
|
78809
78890
|
}
|
|
78810
78891
|
|
|
78811
78892
|
// src/services/feed-commands.service.ts
|
|
78812
|
-
import { readFile as
|
|
78893
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
78813
78894
|
import { resolve as resolve10 } from "node:path";
|
|
78814
78895
|
|
|
78815
78896
|
// src/rules/feed-input.rules.ts
|
|
@@ -78934,7 +79015,7 @@ function feedFlagsOf({ args }) {
|
|
|
78934
79015
|
}
|
|
78935
79016
|
|
|
78936
79017
|
// src/services/feed-files.service.ts
|
|
78937
|
-
import { readFile as
|
|
79018
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
78938
79019
|
import { basename as basename3, resolve as resolve9 } from "node:path";
|
|
78939
79020
|
|
|
78940
79021
|
// ../../modules/feed/contract/src/feed.ts
|
|
@@ -79527,7 +79608,7 @@ async function local({ context, path }) {
|
|
|
79527
79608
|
return {
|
|
79528
79609
|
fileName,
|
|
79529
79610
|
contentType: contentTypeOf(fileName),
|
|
79530
|
-
bytes: new Uint8Array(await
|
|
79611
|
+
bytes: new Uint8Array(await readFile22(full))
|
|
79531
79612
|
};
|
|
79532
79613
|
}
|
|
79533
79614
|
async function directWith({ client, to }) {
|
|
@@ -79605,7 +79686,7 @@ async function bodyOf2({
|
|
|
79605
79686
|
flags: flags2
|
|
79606
79687
|
}) {
|
|
79607
79688
|
const body = { ...flags2.fields };
|
|
79608
|
-
const read3 = (source) => "file" in source ?
|
|
79689
|
+
const read3 = (source) => "file" in source ? readFile23(resolve10(context.cwd, source.file), "utf8") : source.text;
|
|
79609
79690
|
for (const [field, source] of Object.entries(flags2.texts)) body[field] = await read3(source);
|
|
79610
79691
|
if (flags2.rich) {
|
|
79611
79692
|
const text2 = await read3(flags2.rich.source);
|
|
@@ -79767,7 +79848,7 @@ async function textFlag({
|
|
|
79767
79848
|
}) {
|
|
79768
79849
|
const value = flagText({ args, name: name2 });
|
|
79769
79850
|
if (!value.startsWith("@")) return value;
|
|
79770
|
-
return
|
|
79851
|
+
return readFile23(resolve10(context.cwd, value.slice(1)), "utf8");
|
|
79771
79852
|
}
|
|
79772
79853
|
async function feedList({ context, args }) {
|
|
79773
79854
|
const { client } = await signedIn({ context, args });
|
|
@@ -79877,7 +79958,7 @@ async function feed({ context, args }) {
|
|
|
79877
79958
|
}
|
|
79878
79959
|
|
|
79879
79960
|
// src/services/github-commands.service.ts
|
|
79880
|
-
import { readFile as
|
|
79961
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
79881
79962
|
|
|
79882
79963
|
// src/rules/github-signature.rules.ts
|
|
79883
79964
|
var TURN_SEPARATOR = "~";
|
|
@@ -79947,7 +80028,7 @@ var REAL_GH = "/usr/bin/gh";
|
|
|
79947
80028
|
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>`.";
|
|
79948
80029
|
async function turnFileToken({ env }) {
|
|
79949
80030
|
if (!env.LAZE_TURN_FILE) return "";
|
|
79950
|
-
return
|
|
80031
|
+
return readFile24(env.LAZE_TURN_FILE, "utf8").then(
|
|
79951
80032
|
(text2) => text2.trim(),
|
|
79952
80033
|
() => ""
|
|
79953
80034
|
);
|
|
@@ -79981,7 +80062,7 @@ async function githubGh({
|
|
|
79981
80062
|
args: args.rest,
|
|
79982
80063
|
agentName: profile.name ?? "An agent",
|
|
79983
80064
|
threadUrl: threadUrlOf({ env, workspaceId: profile.workspaceId }),
|
|
79984
|
-
readBodyFile: (path) => path === "-" ? context.readStdin() :
|
|
80065
|
+
readBodyFile: (path) => path === "-" ? context.readStdin() : readFile24(path, "utf8")
|
|
79985
80066
|
});
|
|
79986
80067
|
return context.runCommand({
|
|
79987
80068
|
command: [REAL_GH, ...ghArgs],
|
|
@@ -80080,7 +80161,7 @@ async function setAgentGithub({
|
|
|
80080
80161
|
}
|
|
80081
80162
|
|
|
80082
80163
|
// src/services/history-commands.service.ts
|
|
80083
|
-
import { readFile as
|
|
80164
|
+
import { readFile as readFile25 } from "node:fs/promises";
|
|
80084
80165
|
|
|
80085
80166
|
// src/rules/history-format.rules.ts
|
|
80086
80167
|
function timeOf2(iso) {
|
|
@@ -80176,7 +80257,7 @@ async function turnTokenOf3({ context }) {
|
|
|
80176
80257
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
80177
80258
|
if (pinned) return pinned;
|
|
80178
80259
|
if (!env.LAZE_TURN_FILE) return "";
|
|
80179
|
-
return
|
|
80260
|
+
return readFile25(env.LAZE_TURN_FILE, "utf8").then(
|
|
80180
80261
|
(text2) => text2.trim(),
|
|
80181
80262
|
() => ""
|
|
80182
80263
|
);
|
|
@@ -80368,19 +80449,19 @@ async function ip({ context, args }) {
|
|
|
80368
80449
|
}
|
|
80369
80450
|
|
|
80370
80451
|
// src/services/join-commands.service.ts
|
|
80371
|
-
import { mkdir as mkdir16, readFile as
|
|
80372
|
-
import { dirname as dirname15, join as
|
|
80452
|
+
import { mkdir as mkdir16, readFile as readFile26, rename as rename5, rm as rm10, writeFile as writeFile17 } from "node:fs/promises";
|
|
80453
|
+
import { dirname as dirname15, join as join17 } from "node:path";
|
|
80373
80454
|
var DEFAULT_WAIT_SECONDS2 = 100;
|
|
80374
80455
|
var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
|
|
80375
80456
|
function pendingPathOf({ context }) {
|
|
80376
|
-
return
|
|
80457
|
+
return join17(dirname15(context.environment.configPath), "join", "pending.json");
|
|
80377
80458
|
}
|
|
80378
80459
|
async function readPending({
|
|
80379
80460
|
context,
|
|
80380
80461
|
url: url2,
|
|
80381
80462
|
args
|
|
80382
80463
|
}) {
|
|
80383
|
-
const pending = await
|
|
80464
|
+
const pending = await readFile26(pendingPathOf({ context }), "utf8").then(
|
|
80384
80465
|
(text2) => JSON.parse(text2),
|
|
80385
80466
|
() => void 0
|
|
80386
80467
|
);
|
|
@@ -80710,9 +80791,9 @@ function machineAccessCommand(name2) {
|
|
|
80710
80791
|
|
|
80711
80792
|
// src/services/vault-commands.service.ts
|
|
80712
80793
|
import { createHash as createHash2 } from "node:crypto";
|
|
80713
|
-
import { mkdir as mkdir17, readFile as
|
|
80794
|
+
import { mkdir as mkdir17, readFile as readFile27, rm as rm11, writeFile as writeFile18 } from "node:fs/promises";
|
|
80714
80795
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
80715
|
-
import { dirname as dirname16, join as
|
|
80796
|
+
import { dirname as dirname16, join as join18 } from "node:path";
|
|
80716
80797
|
var USAGE10 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
|
|
80717
80798
|
Runs the command with the connection's values in its environment, on a Laze agent's computer
|
|
80718
80799
|
or on a machine it runs on.`;
|
|
@@ -80751,7 +80832,7 @@ async function turnTokenOf4({
|
|
|
80751
80832
|
if (pinned) return pinned;
|
|
80752
80833
|
if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80753
80834
|
try {
|
|
80754
|
-
return (await
|
|
80835
|
+
return (await readFile27(turnFile, "utf8")).trim();
|
|
80755
80836
|
} catch {
|
|
80756
80837
|
throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80757
80838
|
}
|
|
@@ -80761,11 +80842,11 @@ function runKeyPathOf({
|
|
|
80761
80842
|
connection
|
|
80762
80843
|
}) {
|
|
80763
80844
|
const name2 = createHash2("sha256").update(connection).digest("hex");
|
|
80764
|
-
const base = turnFile ? dirname16(turnFile) :
|
|
80765
|
-
return
|
|
80845
|
+
const base = turnFile ? dirname16(turnFile) : join18(tmpdir2(), "laze-vault");
|
|
80846
|
+
return join18(base, "vault-run-keys", `${name2}.json`);
|
|
80766
80847
|
}
|
|
80767
80848
|
async function runKeyAt({ path }) {
|
|
80768
|
-
const saved3 = await
|
|
80849
|
+
const saved3 = await readFile27(path, "utf8").then(
|
|
80769
80850
|
(text2) => JSON.parse(text2),
|
|
80770
80851
|
() => void 0
|
|
80771
80852
|
);
|
|
@@ -81447,14 +81528,14 @@ async function serveMcp({
|
|
|
81447
81528
|
}
|
|
81448
81529
|
|
|
81449
81530
|
// src/services/mount-files.service.ts
|
|
81450
|
-
import { mkdir as mkdir18, readFile as
|
|
81531
|
+
import { mkdir as mkdir18, readFile as readFile28, rm as rm12, writeFile as writeFile19 } from "node:fs/promises";
|
|
81451
81532
|
import { dirname as dirname17, relative as relative5, resolve as resolve11 } from "node:path";
|
|
81452
81533
|
async function textArgument({
|
|
81453
81534
|
context,
|
|
81454
81535
|
value
|
|
81455
81536
|
}) {
|
|
81456
81537
|
if (value === "-") return context.readStdin();
|
|
81457
|
-
if (value.startsWith("@")) return
|
|
81538
|
+
if (value.startsWith("@")) return readFile28(resolve11(context.cwd, value.slice(1)), "utf8");
|
|
81458
81539
|
return value;
|
|
81459
81540
|
}
|
|
81460
81541
|
function turnChannel({ context, args }) {
|
|
@@ -82352,8 +82433,8 @@ async function schedule({ context, args }) {
|
|
|
82352
82433
|
}
|
|
82353
82434
|
|
|
82354
82435
|
// src/services/skill-commands.service.ts
|
|
82355
|
-
import { readdir as readdir6, readFile as
|
|
82356
|
-
import { join as
|
|
82436
|
+
import { readdir as readdir6, readFile as readFile29 } from "node:fs/promises";
|
|
82437
|
+
import { join as join19, relative as relative6, resolve as resolve12 } from "node:path";
|
|
82357
82438
|
var USAGE16 = `Usage:
|
|
82358
82439
|
laze skill list [--agent <agentId>]
|
|
82359
82440
|
laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
|
|
@@ -82374,8 +82455,8 @@ async function folderFiles({ root }) {
|
|
|
82374
82455
|
const files2 = [];
|
|
82375
82456
|
for (const entry of entries) {
|
|
82376
82457
|
if (!entry.isFile()) continue;
|
|
82377
|
-
const full =
|
|
82378
|
-
files2.push({ path: relative6(root, full), content: await
|
|
82458
|
+
const full = join19(entry.parentPath, entry.name);
|
|
82459
|
+
files2.push({ path: relative6(root, full), content: await readFile29(full, "utf8") });
|
|
82379
82460
|
}
|
|
82380
82461
|
return files2.toSorted((a, b) => a.path.localeCompare(b.path));
|
|
82381
82462
|
}
|
|
@@ -82473,7 +82554,7 @@ async function skillUpdate({ context, args }) {
|
|
|
82473
82554
|
if (!name2 || !newName && description === void 0 && !skillMdFile) {
|
|
82474
82555
|
throw new CliUsageError(USAGE16);
|
|
82475
82556
|
}
|
|
82476
|
-
const skillMd = skillMdFile ? await
|
|
82557
|
+
const skillMd = skillMdFile ? await readFile29(resolve12(context.cwd, skillMdFile), "utf8") : void 0;
|
|
82477
82558
|
const { client } = await signedIn({ context, args });
|
|
82478
82559
|
const updated = await client.post("/api/skills/update", {
|
|
82479
82560
|
name: name2,
|
|
@@ -82519,7 +82600,7 @@ async function skill({ context, args }) {
|
|
|
82519
82600
|
}
|
|
82520
82601
|
|
|
82521
82602
|
// src/services/slack-commands.service.ts
|
|
82522
|
-
import { readFile as
|
|
82603
|
+
import { readFile as readFile30 } from "node:fs/promises";
|
|
82523
82604
|
import { resolve as resolve13 } from "node:path";
|
|
82524
82605
|
var SLACK_USAGE = `Usage (a person's key; Slack stays the source, the bot joins no channel by itself):
|
|
82525
82606
|
laze slack overview connected Slack workspaces, mirrors, your link
|
|
@@ -82567,7 +82648,7 @@ async function secretLines({ context, args }) {
|
|
|
82567
82648
|
throw new CliUsageError("A secret never goes in a flag: pipe it on stdin or use --from-file.");
|
|
82568
82649
|
}
|
|
82569
82650
|
const file3 = flagText({ args, name: "from-file" });
|
|
82570
|
-
const text2 = file3 ? await
|
|
82651
|
+
const text2 = file3 ? await readFile30(resolve13(context.cwd, file3), "utf8") : await context.readStdin();
|
|
82571
82652
|
return text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
82572
82653
|
}
|
|
82573
82654
|
async function secretsOf({
|
|
@@ -82871,7 +82952,7 @@ async function slack({
|
|
|
82871
82952
|
}
|
|
82872
82953
|
|
|
82873
82954
|
// src/services/sso-commands.service.ts
|
|
82874
|
-
import { readFile as
|
|
82955
|
+
import { readFile as readFile31 } from "node:fs/promises";
|
|
82875
82956
|
var SSO_USAGE = `Usage:
|
|
82876
82957
|
laze sso domains claimed domains and how each signs in (admins)
|
|
82877
82958
|
laze sso claim <domain> the TXT record that proves the domain
|
|
@@ -82958,7 +83039,7 @@ function refuseSecretFlags({ args }) {
|
|
|
82958
83039
|
}
|
|
82959
83040
|
async function clientSecretOf({ context, args }) {
|
|
82960
83041
|
const file3 = flagText({ args, name: "from-file" });
|
|
82961
|
-
const text2 = file3 ? await
|
|
83042
|
+
const text2 = file3 ? await readFile31(file3, "utf8") : await context.readStdin();
|
|
82962
83043
|
const secret = text2.trim();
|
|
82963
83044
|
if (!secret) throw new CliUsageError("No client secret: pipe it on stdin or use --from-file.");
|
|
82964
83045
|
return secret;
|
|
@@ -83291,7 +83372,7 @@ async function vaultScrub({ context, args }) {
|
|
|
83291
83372
|
}
|
|
83292
83373
|
|
|
83293
83374
|
// src/services/whatsapp-business-commands.service.ts
|
|
83294
|
-
import { readFile as
|
|
83375
|
+
import { readFile as readFile32 } from "node:fs/promises";
|
|
83295
83376
|
import { resolve as resolve14 } from "node:path";
|
|
83296
83377
|
|
|
83297
83378
|
// ../../modules/whatsapp-business/contract/src/whatsapp-business.prices.ts
|
|
@@ -83711,7 +83792,7 @@ async function secretsOf2({ context, args }) {
|
|
|
83711
83792
|
const fromConnection = flagText({ args, name: "from-vault" });
|
|
83712
83793
|
if (fromConnection) return { fromConnection };
|
|
83713
83794
|
const file3 = flagText({ args, name: "from-file" });
|
|
83714
|
-
const text2 = file3 ? await
|
|
83795
|
+
const text2 = file3 ? await readFile32(resolve14(context.cwd, file3), "utf8") : await context.readStdin();
|
|
83715
83796
|
const lines = text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
83716
83797
|
if (lines.length !== 2) {
|
|
83717
83798
|
throw new CliUsageError(
|
|
@@ -84292,7 +84373,7 @@ async function flags({ context, args }) {
|
|
|
84292
84373
|
}
|
|
84293
84374
|
|
|
84294
84375
|
// src/services/workspace-commands.service.ts
|
|
84295
|
-
import { readFile as
|
|
84376
|
+
import { readFile as readFile33 } from "node:fs/promises";
|
|
84296
84377
|
import { resolve as resolve16 } from "node:path";
|
|
84297
84378
|
var ROLE_NAMES2 = {
|
|
84298
84379
|
OWNER: "Owner",
|
|
@@ -84475,7 +84556,7 @@ var LOGO_USAGE = "Usage: laze workspace logo set <file.png|jpg|webp> | laze work
|
|
|
84475
84556
|
async function readLogo({ context, file: file3 }) {
|
|
84476
84557
|
let bytes;
|
|
84477
84558
|
try {
|
|
84478
|
-
bytes = new Uint8Array(await
|
|
84559
|
+
bytes = new Uint8Array(await readFile33(resolve16(context.cwd, file3)));
|
|
84479
84560
|
} catch {
|
|
84480
84561
|
throw new CliUsageError(`No file to read at ${file3}.`);
|
|
84481
84562
|
}
|
|
@@ -85136,7 +85217,7 @@ async function runCli({
|
|
|
85136
85217
|
// src/services/processes.service.ts
|
|
85137
85218
|
import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
|
|
85138
85219
|
import { mkdirSync, openSync } from "node:fs";
|
|
85139
|
-
import { readFile as
|
|
85220
|
+
import { readFile as readFile34, readlink } from "node:fs/promises";
|
|
85140
85221
|
import { dirname as dirname18 } from "node:path";
|
|
85141
85222
|
import { promisify as promisify2 } from "node:util";
|
|
85142
85223
|
var run3 = promisify2(execFile2);
|
|
@@ -85150,14 +85231,14 @@ function alive(pid) {
|
|
|
85150
85231
|
}
|
|
85151
85232
|
}
|
|
85152
85233
|
async function argsOf(pid) {
|
|
85153
|
-
const raw = await
|
|
85234
|
+
const raw = await readFile34(`/proc/${pid}/cmdline`, "utf8").catch(() => void 0);
|
|
85154
85235
|
if (raw) return raw.split("\0").filter(Boolean);
|
|
85155
85236
|
const listed = await run3("ps", ["-o", "args=", "-p", String(pid)]).catch(() => void 0);
|
|
85156
85237
|
const line = listed?.stdout.trim();
|
|
85157
85238
|
return line ? line.split(/\s+/) : void 0;
|
|
85158
85239
|
}
|
|
85159
85240
|
async function parentOf(pid) {
|
|
85160
|
-
const stat3 = await
|
|
85241
|
+
const stat3 = await readFile34(`/proc/${pid}/stat`, "utf8").catch(() => void 0);
|
|
85161
85242
|
const fromStat = stat3 ? Number(stat3.slice(stat3.lastIndexOf(")") + 2).split(" ")[1]) : NaN;
|
|
85162
85243
|
if (fromStat > 0) return fromStat;
|
|
85163
85244
|
const listed = await run3("ps", ["-o", "ppid=", "-p", String(pid)]).catch(() => void 0);
|