overlord-cli 0.2608131824.0 → 0.2608132027.0
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/index.js +111 -23
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -63,6 +63,10 @@ var init_redact_secrets = __esm({
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
// src/errors.ts
|
|
66
|
+
function isUnlinkableExecutionRequestError(error) {
|
|
67
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
68
|
+
return message.includes("invalid_execution_request_transition");
|
|
69
|
+
}
|
|
66
70
|
function formatCliError(error) {
|
|
67
71
|
if (error instanceof CliError) {
|
|
68
72
|
return redactSecrets(error.message);
|
|
@@ -16527,6 +16531,31 @@ var init_dist2 = __esm({
|
|
|
16527
16531
|
}
|
|
16528
16532
|
});
|
|
16529
16533
|
|
|
16534
|
+
// ../packages/core/dist/service/latch-environment.js
|
|
16535
|
+
function isUtf8Locale(value) {
|
|
16536
|
+
return typeof value === "string" && UTF8_LOCALE_PATTERN.test(value);
|
|
16537
|
+
}
|
|
16538
|
+
function latchChildEnvironment({ baseEnv = process.env, platform: platform2 = process.platform } = {}) {
|
|
16539
|
+
const effective = baseEnv.LC_ALL ?? baseEnv.LC_CTYPE ?? baseEnv.LANG;
|
|
16540
|
+
if (isUtf8Locale(effective))
|
|
16541
|
+
return { ...baseEnv };
|
|
16542
|
+
const env = {
|
|
16543
|
+
...baseEnv,
|
|
16544
|
+
// macOS ships the bare `UTF-8` locale; glibc systems ship `C.UTF-8`.
|
|
16545
|
+
LC_CTYPE: platform2 === "darwin" ? "UTF-8" : "C.UTF-8"
|
|
16546
|
+
};
|
|
16547
|
+
if (env.LC_ALL !== void 0 && !isUtf8Locale(env.LC_ALL))
|
|
16548
|
+
delete env.LC_ALL;
|
|
16549
|
+
return env;
|
|
16550
|
+
}
|
|
16551
|
+
var UTF8_LOCALE_PATTERN;
|
|
16552
|
+
var init_latch_environment = __esm({
|
|
16553
|
+
"../packages/core/dist/service/latch-environment.js"() {
|
|
16554
|
+
"use strict";
|
|
16555
|
+
UTF8_LOCALE_PATTERN = /utf-?8/i;
|
|
16556
|
+
}
|
|
16557
|
+
});
|
|
16558
|
+
|
|
16530
16559
|
// ../packages/core/dist/service/latch-launch.js
|
|
16531
16560
|
function trimmed(value) {
|
|
16532
16561
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
@@ -16553,7 +16582,7 @@ function buildLatchCreateManifest({ commandString, shell = process.env.SHELL?.tr
|
|
|
16553
16582
|
return {
|
|
16554
16583
|
format_version: LATCH_MANIFEST_FORMAT_VERSION,
|
|
16555
16584
|
launch: {
|
|
16556
|
-
argv: [shellPath, "-
|
|
16585
|
+
argv: [shellPath, "-ilc", commandString],
|
|
16557
16586
|
cwd,
|
|
16558
16587
|
env: cleanedEnv,
|
|
16559
16588
|
inherit_env: true,
|
|
@@ -16658,7 +16687,8 @@ function runLatchJson({ executable, args }) {
|
|
|
16658
16687
|
encoding: "utf8",
|
|
16659
16688
|
shell: false,
|
|
16660
16689
|
timeout: 1e4,
|
|
16661
|
-
maxBuffer: 1024 * 1024
|
|
16690
|
+
maxBuffer: 1024 * 1024,
|
|
16691
|
+
env: latchChildEnvironment()
|
|
16662
16692
|
});
|
|
16663
16693
|
if (result.error) {
|
|
16664
16694
|
throw new LatchSessionCommandError(result.error.message);
|
|
@@ -16738,6 +16768,7 @@ var LatchSessionCommandError;
|
|
|
16738
16768
|
var init_latch_session = __esm({
|
|
16739
16769
|
"../packages/core/dist/service/latch-session.js"() {
|
|
16740
16770
|
"use strict";
|
|
16771
|
+
init_latch_environment();
|
|
16741
16772
|
init_latch_launch();
|
|
16742
16773
|
LatchSessionCommandError = class extends Error {
|
|
16743
16774
|
constructor(message) {
|
|
@@ -16838,7 +16869,8 @@ async function collectLatchEvents({ executable = "latch", providerSessionId, fro
|
|
|
16838
16869
|
const bin = trimmed3(executable) ?? "latch";
|
|
16839
16870
|
return new Promise((resolve, reject) => {
|
|
16840
16871
|
const child = spawn3(bin, ["events", sessionId, "--json", "--from", String(fromCursor)], {
|
|
16841
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
16872
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
16873
|
+
env: latchChildEnvironment()
|
|
16842
16874
|
});
|
|
16843
16875
|
let stdout = "";
|
|
16844
16876
|
let stderr = "";
|
|
@@ -16894,7 +16926,7 @@ async function collectLatchEvents({ executable = "latch", providerSessionId, fro
|
|
|
16894
16926
|
finish({ ended: true, error: new LatchSessionCommandError(detail) });
|
|
16895
16927
|
return;
|
|
16896
16928
|
}
|
|
16897
|
-
finish({ ended: signal
|
|
16929
|
+
finish({ ended: signal === null && (code === 0 || code === null) });
|
|
16898
16930
|
});
|
|
16899
16931
|
});
|
|
16900
16932
|
}
|
|
@@ -16902,6 +16934,7 @@ var HARNESS_EVENT_TYPES;
|
|
|
16902
16934
|
var init_latch_events = __esm({
|
|
16903
16935
|
"../packages/core/dist/service/latch-events.js"() {
|
|
16904
16936
|
"use strict";
|
|
16937
|
+
init_latch_environment();
|
|
16905
16938
|
init_latch_session();
|
|
16906
16939
|
HARNESS_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
16907
16940
|
"user_message",
|
|
@@ -17547,6 +17580,7 @@ var SUPPORTED_LATCH_PROTOCOL_VERSION, REQUIRED_LATCH_CAPABILITIES, LATCH_STANDAL
|
|
|
17547
17580
|
var init_latch_discovery = __esm({
|
|
17548
17581
|
"../packages/core/dist/service/latch-discovery.js"() {
|
|
17549
17582
|
"use strict";
|
|
17583
|
+
init_latch_environment();
|
|
17550
17584
|
init_terminal_profile_types2();
|
|
17551
17585
|
SUPPORTED_LATCH_PROTOCOL_VERSION = 1;
|
|
17552
17586
|
REQUIRED_LATCH_CAPABILITIES = ["create"];
|
|
@@ -17557,7 +17591,8 @@ var init_latch_discovery = __esm({
|
|
|
17557
17591
|
const stdout = execFileSync3(executable, argv, {
|
|
17558
17592
|
encoding: "utf8",
|
|
17559
17593
|
stdio: ["ignore", "pipe", "pipe"],
|
|
17560
|
-
timeout: 5e3
|
|
17594
|
+
timeout: 5e3,
|
|
17595
|
+
env: latchChildEnvironment()
|
|
17561
17596
|
});
|
|
17562
17597
|
return { status: 0, stdout: String(stdout), stderr: "" };
|
|
17563
17598
|
} catch (error) {
|
|
@@ -17594,7 +17629,8 @@ function probeLatchInteractionCapabilities({ executable = "latch", providerSessi
|
|
|
17594
17629
|
const help = spawnSync3(bin, ["send", "--help"], {
|
|
17595
17630
|
encoding: "utf8",
|
|
17596
17631
|
shell: false,
|
|
17597
|
-
timeout: 5e3
|
|
17632
|
+
timeout: 5e3,
|
|
17633
|
+
env: latchChildEnvironment()
|
|
17598
17634
|
});
|
|
17599
17635
|
if (help.error || help.status !== 0) {
|
|
17600
17636
|
const detail = (help.stderr || help.stdout || help.error?.message || "latch send is unavailable").trim().slice(0, 200);
|
|
@@ -17637,7 +17673,8 @@ function resolveLatchInput({ executable = "latch", providerSessionId, requestId,
|
|
|
17637
17673
|
encoding: "utf8",
|
|
17638
17674
|
shell: false,
|
|
17639
17675
|
timeout: 1e4,
|
|
17640
|
-
maxBuffer: 1024 * 1024
|
|
17676
|
+
maxBuffer: 1024 * 1024,
|
|
17677
|
+
env: latchChildEnvironment()
|
|
17641
17678
|
});
|
|
17642
17679
|
if (result.error)
|
|
17643
17680
|
throw new LatchSessionCommandError(result.error.message);
|
|
@@ -17655,6 +17692,7 @@ function resolveLatchInput({ executable = "latch", providerSessionId, requestId,
|
|
|
17655
17692
|
var init_latch_send = __esm({
|
|
17656
17693
|
"../packages/core/dist/service/latch-send.js"() {
|
|
17657
17694
|
"use strict";
|
|
17695
|
+
init_latch_environment();
|
|
17658
17696
|
init_latch_session();
|
|
17659
17697
|
}
|
|
17660
17698
|
});
|
|
@@ -19089,7 +19127,7 @@ function spawnLatchJson({
|
|
|
19089
19127
|
const result = spawnSync4(executable, args, {
|
|
19090
19128
|
encoding: "utf8",
|
|
19091
19129
|
input: stdin,
|
|
19092
|
-
env:
|
|
19130
|
+
env: latchChildEnvironment(),
|
|
19093
19131
|
maxBuffer: 2 * 1024 * 1024
|
|
19094
19132
|
});
|
|
19095
19133
|
return {
|
|
@@ -19176,6 +19214,7 @@ function openLatchViewer({
|
|
|
19176
19214
|
var init_latch_launch2 = __esm({
|
|
19177
19215
|
"src/latch-launch.ts"() {
|
|
19178
19216
|
"use strict";
|
|
19217
|
+
init_latch_environment();
|
|
19179
19218
|
init_latch_launch();
|
|
19180
19219
|
init_terminal_profile_types2();
|
|
19181
19220
|
}
|
|
@@ -19884,7 +19923,7 @@ async function launchAgent({
|
|
|
19884
19923
|
}) : null;
|
|
19885
19924
|
if (existingProviderSession && plan.latchCommandString) {
|
|
19886
19925
|
const shell = process.env.SHELL?.trim() || "/bin/bash";
|
|
19887
|
-
const result2 = spawnSync5(shell, ["-
|
|
19926
|
+
const result2 = spawnSync5(shell, ["-ilc", plan.latchCommandString], {
|
|
19888
19927
|
cwd: options.workingDirectory,
|
|
19889
19928
|
env,
|
|
19890
19929
|
stdio: "inherit"
|
|
@@ -19894,7 +19933,7 @@ async function launchAgent({
|
|
|
19894
19933
|
...plan,
|
|
19895
19934
|
execution: {
|
|
19896
19935
|
command: shell,
|
|
19897
|
-
args: ["-
|
|
19936
|
+
args: ["-ilc", plan.latchCommandString],
|
|
19898
19937
|
useShell: false,
|
|
19899
19938
|
terminal: null,
|
|
19900
19939
|
display: `Latch session ${existingProviderSession.providerSessionId} (inline) \u203A ${plan.latchCommandString}`
|
|
@@ -21400,6 +21439,11 @@ var init_vcs = __esm({
|
|
|
21400
21439
|
// src/record-touched.ts
|
|
21401
21440
|
import { readFileSync as readFileSync20 } from "node:fs";
|
|
21402
21441
|
import path29 from "node:path";
|
|
21442
|
+
function firstNonEmptyString(value) {
|
|
21443
|
+
if (typeof value !== "string") return null;
|
|
21444
|
+
const trimmed7 = value.trim();
|
|
21445
|
+
return trimmed7 ? trimmed7 : null;
|
|
21446
|
+
}
|
|
21403
21447
|
function collectCandidates(toolInput) {
|
|
21404
21448
|
const counts = /* @__PURE__ */ new Map();
|
|
21405
21449
|
const order = [];
|
|
@@ -21411,22 +21455,43 @@ function collectCandidates(toolInput) {
|
|
|
21411
21455
|
counts.set(trimmed7, (counts.get(trimmed7) ?? 0) + amount);
|
|
21412
21456
|
};
|
|
21413
21457
|
bump(toolInput.file_path, 1);
|
|
21458
|
+
bump(toolInput.filePath, 1);
|
|
21459
|
+
bump(toolInput.path, 1);
|
|
21414
21460
|
bump(toolInput.notebook_path, 1);
|
|
21415
21461
|
const edits = toolInput.edits;
|
|
21416
21462
|
if (Array.isArray(edits)) {
|
|
21417
|
-
const topLevelPath = toolInput.file_path;
|
|
21418
|
-
if (
|
|
21419
|
-
counts.set(topLevelPath
|
|
21463
|
+
const topLevelPath = firstNonEmptyString(toolInput.file_path) ?? firstNonEmptyString(toolInput.filePath) ?? firstNonEmptyString(toolInput.path);
|
|
21464
|
+
if (topLevelPath) {
|
|
21465
|
+
counts.set(topLevelPath, (counts.get(topLevelPath) ?? 0) - 1);
|
|
21420
21466
|
}
|
|
21421
21467
|
for (const edit of edits) {
|
|
21422
21468
|
if (edit && typeof edit === "object") {
|
|
21423
|
-
const
|
|
21469
|
+
const record = edit;
|
|
21470
|
+
const value = record.file_path ?? record.filePath ?? record.path ?? topLevelPath;
|
|
21424
21471
|
bump(value, 1);
|
|
21425
21472
|
}
|
|
21426
21473
|
}
|
|
21427
21474
|
}
|
|
21428
21475
|
return order.map((filePath) => ({ filePath, editCount: Math.max(counts.get(filePath) ?? 1, 1) }));
|
|
21429
21476
|
}
|
|
21477
|
+
function resolveHookWorkingDirectory({
|
|
21478
|
+
payload,
|
|
21479
|
+
fallbackCwd,
|
|
21480
|
+
env
|
|
21481
|
+
}) {
|
|
21482
|
+
const fromCwd = firstNonEmptyString(payload.cwd);
|
|
21483
|
+
if (fromCwd) return path29.resolve(fromCwd);
|
|
21484
|
+
const roots = payload.workspace_roots;
|
|
21485
|
+
if (Array.isArray(roots)) {
|
|
21486
|
+
const fromRoots = firstNonEmptyString(roots[0]);
|
|
21487
|
+
if (fromRoots) return path29.resolve(fromRoots);
|
|
21488
|
+
}
|
|
21489
|
+
for (const key of PROJECT_DIR_ENV_KEYS) {
|
|
21490
|
+
const fromEnv = firstNonEmptyString(env[key]);
|
|
21491
|
+
if (fromEnv) return path29.resolve(fromEnv);
|
|
21492
|
+
}
|
|
21493
|
+
return path29.resolve(fallbackCwd);
|
|
21494
|
+
}
|
|
21430
21495
|
function compact(value, limit = 500) {
|
|
21431
21496
|
if (typeof value !== "string") return null;
|
|
21432
21497
|
const text = value.split(/\s+/).filter(Boolean).join(" ");
|
|
@@ -21486,7 +21551,8 @@ function recentAssistantContext(transcriptPath) {
|
|
|
21486
21551
|
function recordTouchedFromPayload({
|
|
21487
21552
|
rawPayload,
|
|
21488
21553
|
missionOverride,
|
|
21489
|
-
fallbackCwd
|
|
21554
|
+
fallbackCwd,
|
|
21555
|
+
env = process.env
|
|
21490
21556
|
}) {
|
|
21491
21557
|
let payload;
|
|
21492
21558
|
try {
|
|
@@ -21497,8 +21563,7 @@ function recordTouchedFromPayload({
|
|
|
21497
21563
|
const toolInputRaw = payload.tool_input;
|
|
21498
21564
|
const toolInput = toolInputRaw && typeof toolInputRaw === "object" ? toolInputRaw : {};
|
|
21499
21565
|
const toolName = typeof payload.tool_name === "string" && payload.tool_name.trim() ? payload.tool_name.trim() : "file edit";
|
|
21500
|
-
const
|
|
21501
|
-
const workingDirectory = path29.resolve(cwd);
|
|
21566
|
+
const workingDirectory = resolveHookWorkingDirectory({ payload, fallbackCwd, env });
|
|
21502
21567
|
const trimmedOverride = missionOverride?.trim();
|
|
21503
21568
|
let missionId;
|
|
21504
21569
|
let ambiguous = false;
|
|
@@ -21507,7 +21572,10 @@ function recordTouchedFromPayload({
|
|
|
21507
21572
|
} else {
|
|
21508
21573
|
const resolved = resolveActiveMissionForCwd(workingDirectory);
|
|
21509
21574
|
if (!resolved) {
|
|
21510
|
-
return {
|
|
21575
|
+
return {
|
|
21576
|
+
recorded: false,
|
|
21577
|
+
reason: `no active session manifest entry for this cwd (${workingDirectory})`
|
|
21578
|
+
};
|
|
21511
21579
|
}
|
|
21512
21580
|
missionId = resolved.missionId;
|
|
21513
21581
|
ambiguous = resolved.ambiguous;
|
|
@@ -21538,11 +21606,17 @@ function recordTouchedFromPayload({
|
|
|
21538
21606
|
});
|
|
21539
21607
|
return { recorded: true, missionId, ambiguous, files: candidates.length };
|
|
21540
21608
|
}
|
|
21609
|
+
var PROJECT_DIR_ENV_KEYS;
|
|
21541
21610
|
var init_record_touched = __esm({
|
|
21542
21611
|
"src/record-touched.ts"() {
|
|
21543
21612
|
"use strict";
|
|
21544
21613
|
init_vcs();
|
|
21545
21614
|
init_vcs_sessions();
|
|
21615
|
+
PROJECT_DIR_ENV_KEYS = [
|
|
21616
|
+
"CURSOR_PROJECT_DIR",
|
|
21617
|
+
"CLAUDE_PROJECT_DIR",
|
|
21618
|
+
"CLAUDE_PROJECT_ROOT"
|
|
21619
|
+
];
|
|
21546
21620
|
}
|
|
21547
21621
|
});
|
|
21548
21622
|
|
|
@@ -22711,10 +22785,24 @@ async function runProtocolCommand({
|
|
|
22711
22785
|
workingDirectory
|
|
22712
22786
|
})
|
|
22713
22787
|
};
|
|
22714
|
-
const
|
|
22715
|
-
|
|
22716
|
-
|
|
22717
|
-
|
|
22788
|
+
const protocolPath = `/api/protocol/${encodeURIComponent(subcommand)}`;
|
|
22789
|
+
let result;
|
|
22790
|
+
try {
|
|
22791
|
+
result = await runtime.backend.post({
|
|
22792
|
+
path: protocolPath,
|
|
22793
|
+
body: protocolBody
|
|
22794
|
+
});
|
|
22795
|
+
} catch (error) {
|
|
22796
|
+
if (subcommand === "attach" && typeof flags["--execution-request-id"] === "string" && isUnlinkableExecutionRequestError(error)) {
|
|
22797
|
+
delete flags["--execution-request-id"];
|
|
22798
|
+
result = await runtime.backend.post({
|
|
22799
|
+
path: protocolPath,
|
|
22800
|
+
body: { ...protocolBody, flags }
|
|
22801
|
+
});
|
|
22802
|
+
} else {
|
|
22803
|
+
throw error;
|
|
22804
|
+
}
|
|
22805
|
+
}
|
|
22718
22806
|
if ((subcommand === "attach" || subcommand === "resume-follow-up") && missionId) {
|
|
22719
22807
|
writeBaseline({
|
|
22720
22808
|
workingDirectory,
|
|
@@ -22768,7 +22856,7 @@ async function runProtocolCommand({
|
|
|
22768
22856
|
)
|
|
22769
22857
|
);
|
|
22770
22858
|
if (connectorInstallsEditHook && !hasTouchedFilesLog({ workingDirectory, missionId }) && readChangedFiles(workingDirectory).length > 0) {
|
|
22771
|
-
const warning = `[overlord] warning: no touched-files log found at deliver for mission ${missionId} in ${workingDirectory}, even though this connector installs a PostToolUse edit hook. Deliver is falling back to baseline-only attribution, which can misattribute concurrent sessions' edits. Check ~/.ovld/logs/post-tool-use-hook.log for why the hook did not record any touched files.`;
|
|
22859
|
+
const warning = `[overlord] warning: no touched-files log found at deliver for mission ${missionId} in ${workingDirectory}, even though this connector installs a PostToolUse edit hook. Deliver is falling back to baseline-only attribution, which can misattribute concurrent sessions' edits. Check ~/.ovld/logs/cursor-post-tool-use-hook.log and ~/.ovld/logs/post-tool-use-hook.log for why the hook did not record any touched files.`;
|
|
22772
22860
|
console.error(warning);
|
|
22773
22861
|
const sessionKeyForAlert = typeof flags["--session-key"] === "string" ? flags["--session-key"] : void 0;
|
|
22774
22862
|
if (sessionKeyForAlert) {
|