@autohq/cli 0.1.418 → 0.1.420
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/agent-bridge.js +557 -58
- package/dist/index.js +630 -131
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -652,8 +652,8 @@ var require_common = __commonJS({
|
|
|
652
652
|
}
|
|
653
653
|
return debug12;
|
|
654
654
|
}
|
|
655
|
-
function extend2(namespace,
|
|
656
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
655
|
+
function extend2(namespace, delimiter2) {
|
|
656
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
|
|
657
657
|
newDebug.log = this.log;
|
|
658
658
|
return newDebug;
|
|
659
659
|
}
|
|
@@ -13853,8 +13853,8 @@ function emoji() {
|
|
|
13853
13853
|
}
|
|
13854
13854
|
var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
13855
13855
|
var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
13856
|
-
var mac = (
|
|
13857
|
-
const escapedDelim = escapeRegex(
|
|
13856
|
+
var mac = (delimiter2) => {
|
|
13857
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
13858
13858
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
13859
13859
|
};
|
|
13860
13860
|
var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -30820,7 +30820,7 @@ Object.assign(lookup, {
|
|
|
30820
30820
|
// package.json
|
|
30821
30821
|
var package_default = {
|
|
30822
30822
|
name: "@autohq/cli",
|
|
30823
|
-
version: "0.1.
|
|
30823
|
+
version: "0.1.420",
|
|
30824
30824
|
license: "SEE LICENSE IN README.md",
|
|
30825
30825
|
publishConfig: {
|
|
30826
30826
|
access: "public"
|
|
@@ -34000,6 +34000,11 @@ var TRIGGER_BINDING_TARGET_TYPES = [
|
|
|
34000
34000
|
"linear.issue",
|
|
34001
34001
|
"auto.session"
|
|
34002
34002
|
];
|
|
34003
|
+
var OBSERVED_TARGET_EVENT_KEYS = [
|
|
34004
|
+
"auto.session.binding.bound",
|
|
34005
|
+
"auto.session.binding.updated",
|
|
34006
|
+
"auto.session.binding.unbound"
|
|
34007
|
+
];
|
|
34003
34008
|
var SESSION_BINDING_SOURCES = [
|
|
34004
34009
|
"trigger_spawn",
|
|
34005
34010
|
"agent_tool",
|
|
@@ -34022,6 +34027,7 @@ var BINDING_TRANSITION_CAUSES = [
|
|
|
34022
34027
|
"manual_update",
|
|
34023
34028
|
"attributed_event",
|
|
34024
34029
|
"mention",
|
|
34030
|
+
"observed_binding_event",
|
|
34025
34031
|
"session_spawn",
|
|
34026
34032
|
"trigger_spawn",
|
|
34027
34033
|
"chat_send",
|
|
@@ -34284,6 +34290,17 @@ var TriggerReleaseSchema = external_exports.union([
|
|
|
34284
34290
|
external_exports.literal(true).transform(() => ({ context: null })),
|
|
34285
34291
|
external_exports.object({ context: JsonObjectSchema.nullable().default(null) }).strict()
|
|
34286
34292
|
]);
|
|
34293
|
+
var ObservedTargetActionSchema = external_exports.discriminatedUnion("action", [
|
|
34294
|
+
external_exports.object({
|
|
34295
|
+
action: external_exports.literal("bind"),
|
|
34296
|
+
context: JsonObjectSchema.nullable().default(null),
|
|
34297
|
+
eventContext: JsonObjectSchema.nullable().default(null)
|
|
34298
|
+
}).strict(),
|
|
34299
|
+
external_exports.object({
|
|
34300
|
+
action: external_exports.literal("unbind"),
|
|
34301
|
+
eventContext: JsonObjectSchema.nullable().default(null)
|
|
34302
|
+
}).strict()
|
|
34303
|
+
]);
|
|
34287
34304
|
var CanonicalTriggerRoutingSchema = external_exports.discriminatedUnion("kind", [
|
|
34288
34305
|
external_exports.object({
|
|
34289
34306
|
kind: external_exports.literal("spawn"),
|
|
@@ -34312,7 +34329,17 @@ var CanonicalTriggerRoutingSchema = external_exports.discriminatedUnion("kind",
|
|
|
34312
34329
|
// routing completes. No-op when no active binding exists. `agent.singleton`
|
|
34313
34330
|
// is rejected at apply time (singleton slots are pool-membership state
|
|
34314
34331
|
// owned by the reconciler).
|
|
34315
|
-
release: TriggerReleaseSchema.default(false)
|
|
34332
|
+
release: TriggerReleaseSchema.default(false),
|
|
34333
|
+
// Observed-target lifecycle action: after the router delivers a matching
|
|
34334
|
+
// binding-transition event to the observer session this trigger's
|
|
34335
|
+
// `auto.session` target resolved, the platform binds or unbinds that
|
|
34336
|
+
// session to/from the target carried by the observed event. Apply-time
|
|
34337
|
+
// validation restricts this to `target: auto.session` triggers on the
|
|
34338
|
+
// `auto.session.binding.bound|updated|unbound` event keys; the target type
|
|
34339
|
+
// is authorized at runtime against the observer agent's own bindable
|
|
34340
|
+
// targets. Distinct from `release` above, which releases this route's own
|
|
34341
|
+
// `auto.session` observation binding.
|
|
34342
|
+
observedTarget: ObservedTargetActionSchema.optional()
|
|
34316
34343
|
})
|
|
34317
34344
|
]);
|
|
34318
34345
|
var LegacySingletonRouteBySchema = external_exports.object({
|
|
@@ -34812,6 +34839,7 @@ var AgentApplySpecSchema = AgentSpecFieldsSchema.extend({
|
|
|
34812
34839
|
validateConcurrencyConfig(spec, context);
|
|
34813
34840
|
validateBindingsConfig(spec, context);
|
|
34814
34841
|
validateTriggerReleaseConfig(spec, context);
|
|
34842
|
+
validateTriggerObservedTargetConfig(spec, context);
|
|
34815
34843
|
});
|
|
34816
34844
|
function validateConcurrencyConfig(spec, context) {
|
|
34817
34845
|
if (spec.concurrency === void 0 && spec.replace !== void 0) {
|
|
@@ -34913,6 +34941,28 @@ function validateTriggerReleaseConfig(spec, context) {
|
|
|
34913
34941
|
}
|
|
34914
34942
|
}
|
|
34915
34943
|
}
|
|
34944
|
+
function validateTriggerObservedTargetConfig(spec, context) {
|
|
34945
|
+
const legalEvents = new Set(OBSERVED_TARGET_EVENT_KEYS);
|
|
34946
|
+
for (const [index, trigger] of spec.triggers.entries()) {
|
|
34947
|
+
if (trigger.routing.kind !== "bind" || !trigger.routing.observedTarget) {
|
|
34948
|
+
continue;
|
|
34949
|
+
}
|
|
34950
|
+
if (trigger.routing.target !== "auto.session") {
|
|
34951
|
+
context.addIssue({
|
|
34952
|
+
code: external_exports.ZodIssueCode.custom,
|
|
34953
|
+
path: ["triggers", index, "routing", "observedTarget"],
|
|
34954
|
+
message: "`observedTarget` requires `target: auto.session`: only the observed child-session relationship may drive an observed-target action"
|
|
34955
|
+
});
|
|
34956
|
+
}
|
|
34957
|
+
if (!trigger.event || !legalEvents.has(trigger.event)) {
|
|
34958
|
+
context.addIssue({
|
|
34959
|
+
code: external_exports.ZodIssueCode.custom,
|
|
34960
|
+
path: ["triggers", index, "routing", "observedTarget"],
|
|
34961
|
+
message: `\`observedTarget\` requires an \`event\` in [${OBSERVED_TARGET_EVENT_KEYS.join(", ")}]: the binding lifecycle transitions are the events that carry the target to act on`
|
|
34962
|
+
});
|
|
34963
|
+
}
|
|
34964
|
+
}
|
|
34965
|
+
}
|
|
34916
34966
|
var AgentStatusSchema = external_exports.object({
|
|
34917
34967
|
runCount: external_exports.number().int().nonnegative().default(0),
|
|
34918
34968
|
lastActivityAt: external_exports.string().datetime().nullable().default(null)
|
|
@@ -61465,6 +61515,233 @@ function uiChunk(chunk) {
|
|
|
61465
61515
|
};
|
|
61466
61516
|
}
|
|
61467
61517
|
|
|
61518
|
+
// src/commands/agent-bridge/harness/claude-code/read-state.ts
|
|
61519
|
+
import {
|
|
61520
|
+
existsSync as existsSync2,
|
|
61521
|
+
mkdirSync as mkdirSync2,
|
|
61522
|
+
readFileSync as readFileSync2,
|
|
61523
|
+
statSync,
|
|
61524
|
+
writeFileSync as writeFileSync2
|
|
61525
|
+
} from "fs";
|
|
61526
|
+
import { dirname as dirname2 } from "path";
|
|
61527
|
+
|
|
61528
|
+
// src/commands/agent-bridge/harness/claude-code/resume-store.ts
|
|
61529
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
61530
|
+
import { dirname } from "path";
|
|
61531
|
+
var AGENT_BRIDGE_RUNTIME_DIR = "/tmp/auto-bridge-runtime";
|
|
61532
|
+
var CLAUDE_SESSION_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-session-id`;
|
|
61533
|
+
function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
61534
|
+
return {
|
|
61535
|
+
read(sessionId) {
|
|
61536
|
+
if (!existsSync(path2)) {
|
|
61537
|
+
return null;
|
|
61538
|
+
}
|
|
61539
|
+
const record2 = parseResumeRecord(readFileSync(path2, "utf8"));
|
|
61540
|
+
if (!record2 || record2.sessionId !== sessionId) {
|
|
61541
|
+
return null;
|
|
61542
|
+
}
|
|
61543
|
+
return record2.agentId;
|
|
61544
|
+
},
|
|
61545
|
+
write(record2) {
|
|
61546
|
+
mkdirSync(dirname(path2), { recursive: true });
|
|
61547
|
+
writeFileSync(path2, `${JSON.stringify(record2)}
|
|
61548
|
+
`, "utf8");
|
|
61549
|
+
}
|
|
61550
|
+
};
|
|
61551
|
+
}
|
|
61552
|
+
function parseResumeRecord(raw) {
|
|
61553
|
+
try {
|
|
61554
|
+
const value2 = JSON.parse(raw);
|
|
61555
|
+
if (value2 !== null && typeof value2 === "object" && "sessionId" in value2 && "agentId" in value2 && typeof value2.sessionId === "string" && typeof value2.agentId === "string" && value2.agentId.length > 0) {
|
|
61556
|
+
return { sessionId: value2.sessionId, agentId: value2.agentId };
|
|
61557
|
+
}
|
|
61558
|
+
return null;
|
|
61559
|
+
} catch {
|
|
61560
|
+
return null;
|
|
61561
|
+
}
|
|
61562
|
+
}
|
|
61563
|
+
|
|
61564
|
+
// src/commands/agent-bridge/harness/claude-code/read-state.ts
|
|
61565
|
+
var CLAUDE_READ_STATE_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-read-state`;
|
|
61566
|
+
var CLAUDE_READ_STATE_MAX_ENTRIES = 256;
|
|
61567
|
+
var ClaudeReadStateTracker = class {
|
|
61568
|
+
constructor(store) {
|
|
61569
|
+
this.store = store;
|
|
61570
|
+
}
|
|
61571
|
+
store;
|
|
61572
|
+
// Most-recently-observed entries last (Map preserves insertion order, and
|
|
61573
|
+
// touches re-insert), so eviction drops the stalest observation first.
|
|
61574
|
+
entriesByPath = /* @__PURE__ */ new Map();
|
|
61575
|
+
// tool_use ids of in-flight file-tool calls, mapped to the file they target.
|
|
61576
|
+
// Cleared at each turn's terminal result so interrupted calls cannot leak.
|
|
61577
|
+
pendingFileToolUses = /* @__PURE__ */ new Map();
|
|
61578
|
+
loadedForSessionId = null;
|
|
61579
|
+
// Feed every live SDK message through here. Successful Read/Write/Edit
|
|
61580
|
+
// results commit a path+mtime observation; everything else is ignored.
|
|
61581
|
+
observe(sessionId, message) {
|
|
61582
|
+
this.ensureLoaded(sessionId);
|
|
61583
|
+
if (message.type === "result") {
|
|
61584
|
+
this.pendingFileToolUses.clear();
|
|
61585
|
+
return;
|
|
61586
|
+
}
|
|
61587
|
+
if (message.type === "assistant" && message.parent_tool_use_id === null) {
|
|
61588
|
+
for (const block of contentBlocks(message.message.content)) {
|
|
61589
|
+
const use = fileToolUse(block);
|
|
61590
|
+
if (use) {
|
|
61591
|
+
this.pendingFileToolUses.set(use.toolUseId, use.path);
|
|
61592
|
+
}
|
|
61593
|
+
}
|
|
61594
|
+
return;
|
|
61595
|
+
}
|
|
61596
|
+
if (message.type !== "user" || message.parent_tool_use_id !== null) {
|
|
61597
|
+
return;
|
|
61598
|
+
}
|
|
61599
|
+
if ("isReplay" in message && message.isReplay === true) {
|
|
61600
|
+
return;
|
|
61601
|
+
}
|
|
61602
|
+
for (const block of contentBlocks(message.message.content)) {
|
|
61603
|
+
if (block.type !== "tool_result") {
|
|
61604
|
+
continue;
|
|
61605
|
+
}
|
|
61606
|
+
const toolUseId = typeof block.tool_use_id === "string" ? block.tool_use_id : null;
|
|
61607
|
+
if (toolUseId === null) {
|
|
61608
|
+
continue;
|
|
61609
|
+
}
|
|
61610
|
+
const path2 = this.pendingFileToolUses.get(toolUseId);
|
|
61611
|
+
this.pendingFileToolUses.delete(toolUseId);
|
|
61612
|
+
if (path2 !== void 0 && block.is_error !== true) {
|
|
61613
|
+
this.commit(sessionId, path2);
|
|
61614
|
+
}
|
|
61615
|
+
}
|
|
61616
|
+
}
|
|
61617
|
+
// The seeds to replay into a fresh CLI process, stalest observation first so
|
|
61618
|
+
// the most recent reads survive any CLI-side eviction.
|
|
61619
|
+
seeds(sessionId) {
|
|
61620
|
+
this.ensureLoaded(sessionId);
|
|
61621
|
+
return [...this.entriesByPath].map(([path2, mtime]) => ({ path: path2, mtime }));
|
|
61622
|
+
}
|
|
61623
|
+
// A conversation-lineage break: the next CLI session starts with no prior
|
|
61624
|
+
// context, so nothing the model "remembers reading" exists anymore.
|
|
61625
|
+
clear(sessionId) {
|
|
61626
|
+
this.ensureLoaded(sessionId);
|
|
61627
|
+
if (this.entriesByPath.size === 0) {
|
|
61628
|
+
return;
|
|
61629
|
+
}
|
|
61630
|
+
this.entriesByPath.clear();
|
|
61631
|
+
this.persist(sessionId);
|
|
61632
|
+
}
|
|
61633
|
+
ensureLoaded(sessionId) {
|
|
61634
|
+
if (this.loadedForSessionId === sessionId) {
|
|
61635
|
+
return;
|
|
61636
|
+
}
|
|
61637
|
+
this.loadedForSessionId = sessionId;
|
|
61638
|
+
this.entriesByPath.clear();
|
|
61639
|
+
this.pendingFileToolUses.clear();
|
|
61640
|
+
for (const entry of this.store.read(sessionId) ?? []) {
|
|
61641
|
+
this.entriesByPath.set(entry.path, entry.mtime);
|
|
61642
|
+
}
|
|
61643
|
+
}
|
|
61644
|
+
commit(sessionId, path2) {
|
|
61645
|
+
let mtime;
|
|
61646
|
+
try {
|
|
61647
|
+
mtime = Math.floor(statSync(path2).mtimeMs);
|
|
61648
|
+
} catch {
|
|
61649
|
+
if (this.entriesByPath.delete(path2)) {
|
|
61650
|
+
this.persist(sessionId);
|
|
61651
|
+
}
|
|
61652
|
+
return;
|
|
61653
|
+
}
|
|
61654
|
+
this.entriesByPath.delete(path2);
|
|
61655
|
+
this.entriesByPath.set(path2, mtime);
|
|
61656
|
+
while (this.entriesByPath.size > CLAUDE_READ_STATE_MAX_ENTRIES) {
|
|
61657
|
+
const oldest = this.entriesByPath.keys().next().value;
|
|
61658
|
+
if (oldest === void 0) {
|
|
61659
|
+
break;
|
|
61660
|
+
}
|
|
61661
|
+
this.entriesByPath.delete(oldest);
|
|
61662
|
+
}
|
|
61663
|
+
this.persist(sessionId);
|
|
61664
|
+
}
|
|
61665
|
+
persist(sessionId) {
|
|
61666
|
+
this.store.write({ sessionId, entries: this.seeds(sessionId) });
|
|
61667
|
+
}
|
|
61668
|
+
};
|
|
61669
|
+
function fileClaudeReadStateStore(path2 = CLAUDE_READ_STATE_PATH) {
|
|
61670
|
+
return {
|
|
61671
|
+
read(sessionId) {
|
|
61672
|
+
if (!existsSync2(path2)) {
|
|
61673
|
+
return null;
|
|
61674
|
+
}
|
|
61675
|
+
const record2 = parseReadStateRecord(readFileSync2(path2, "utf8"));
|
|
61676
|
+
if (!record2 || record2.sessionId !== sessionId) {
|
|
61677
|
+
return null;
|
|
61678
|
+
}
|
|
61679
|
+
return record2.entries;
|
|
61680
|
+
},
|
|
61681
|
+
write(record2) {
|
|
61682
|
+
mkdirSync2(dirname2(path2), { recursive: true });
|
|
61683
|
+
writeFileSync2(path2, `${JSON.stringify(record2)}
|
|
61684
|
+
`, "utf8");
|
|
61685
|
+
}
|
|
61686
|
+
};
|
|
61687
|
+
}
|
|
61688
|
+
function fileToolUse(block) {
|
|
61689
|
+
if (block.type !== "tool_use" || typeof block.id !== "string") {
|
|
61690
|
+
return null;
|
|
61691
|
+
}
|
|
61692
|
+
const input = block.input;
|
|
61693
|
+
if (typeof input !== "object" || input === null) {
|
|
61694
|
+
return null;
|
|
61695
|
+
}
|
|
61696
|
+
const filePath = input.file_path;
|
|
61697
|
+
if (typeof filePath !== "string" || filePath.length === 0) {
|
|
61698
|
+
return null;
|
|
61699
|
+
}
|
|
61700
|
+
switch (block.name) {
|
|
61701
|
+
case "Read": {
|
|
61702
|
+
const { offset, limit } = input;
|
|
61703
|
+
if (offset !== void 0 || limit !== void 0) {
|
|
61704
|
+
return null;
|
|
61705
|
+
}
|
|
61706
|
+
return { toolUseId: block.id, path: filePath };
|
|
61707
|
+
}
|
|
61708
|
+
case "Write":
|
|
61709
|
+
case "Edit":
|
|
61710
|
+
return { toolUseId: block.id, path: filePath };
|
|
61711
|
+
default:
|
|
61712
|
+
return null;
|
|
61713
|
+
}
|
|
61714
|
+
}
|
|
61715
|
+
function contentBlocks(content) {
|
|
61716
|
+
if (!Array.isArray(content)) {
|
|
61717
|
+
return [];
|
|
61718
|
+
}
|
|
61719
|
+
return content.filter(
|
|
61720
|
+
(block) => typeof block === "object" && block !== null
|
|
61721
|
+
);
|
|
61722
|
+
}
|
|
61723
|
+
function parseReadStateRecord(raw) {
|
|
61724
|
+
try {
|
|
61725
|
+
const value2 = JSON.parse(raw);
|
|
61726
|
+
if (value2 === null || typeof value2 !== "object" || !("sessionId" in value2) || !("entries" in value2) || typeof value2.sessionId !== "string" || !Array.isArray(value2.entries)) {
|
|
61727
|
+
return null;
|
|
61728
|
+
}
|
|
61729
|
+
const entries = [];
|
|
61730
|
+
for (const entry of value2.entries) {
|
|
61731
|
+
if (entry === null || typeof entry !== "object" || typeof entry.path !== "string" || typeof entry.mtime !== "number") {
|
|
61732
|
+
return null;
|
|
61733
|
+
}
|
|
61734
|
+
entries.push({
|
|
61735
|
+
path: entry.path,
|
|
61736
|
+
mtime: entry.mtime
|
|
61737
|
+
});
|
|
61738
|
+
}
|
|
61739
|
+
return { sessionId: value2.sessionId, entries };
|
|
61740
|
+
} catch {
|
|
61741
|
+
return null;
|
|
61742
|
+
}
|
|
61743
|
+
}
|
|
61744
|
+
|
|
61468
61745
|
// ../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
61469
61746
|
import { createRequire as i_ } from "module";
|
|
61470
61747
|
import { execFile as v6$ } from "child_process";
|
|
@@ -81236,6 +81513,7 @@ var CLAUDE_INTERRUPT_SETTLE_TIMEOUT_MS = 1e4;
|
|
|
81236
81513
|
var CLAUDE_INTERRUPT_ACK_TIMEOUT_MS = 1e4;
|
|
81237
81514
|
var CLAUDE_MCP_REGISTRATION_TIMEOUT_MS = 3e3;
|
|
81238
81515
|
var CLAUDE_MCP_REGISTRATION_POLL_INTERVAL_MS = 100;
|
|
81516
|
+
var CLAUDE_READ_STATE_SEED_FAILURE_LIMIT = 3;
|
|
81239
81517
|
var CLAUDE_STARTUP_PROFILE_HOOK_EVENTS = [
|
|
81240
81518
|
"Setup",
|
|
81241
81519
|
"SessionStart",
|
|
@@ -81452,6 +81730,32 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
81452
81730
|
}
|
|
81453
81731
|
);
|
|
81454
81732
|
}
|
|
81733
|
+
async seedReadState(seeds) {
|
|
81734
|
+
if (seeds.length === 0 || this.state.kind !== "running") {
|
|
81735
|
+
return;
|
|
81736
|
+
}
|
|
81737
|
+
const query = this.state.query;
|
|
81738
|
+
const startedAt = Date.now();
|
|
81739
|
+
let seeded = 0;
|
|
81740
|
+
let failed = 0;
|
|
81741
|
+
for (const seed of seeds) {
|
|
81742
|
+
try {
|
|
81743
|
+
await query.seedReadState(seed.path, seed.mtime);
|
|
81744
|
+
seeded += 1;
|
|
81745
|
+
} catch (error51) {
|
|
81746
|
+
failed += 1;
|
|
81747
|
+
this.input.writeOutput?.(
|
|
81748
|
+
`agent_bridge_claude_read_state_seed_failed path=${seed.path} error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
81749
|
+
);
|
|
81750
|
+
if (failed >= CLAUDE_READ_STATE_SEED_FAILURE_LIMIT) {
|
|
81751
|
+
break;
|
|
81752
|
+
}
|
|
81753
|
+
}
|
|
81754
|
+
}
|
|
81755
|
+
this.input.writeOutput?.(
|
|
81756
|
+
`agent_bridge_claude_read_state_seeded seeded=${seeded} total=${seeds.length} duration_ms=${Date.now() - startedAt}`
|
|
81757
|
+
);
|
|
81758
|
+
}
|
|
81455
81759
|
close() {
|
|
81456
81760
|
const previousState = this.state;
|
|
81457
81761
|
if (previousState.kind === "closed") {
|
|
@@ -81513,6 +81817,7 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
81513
81817
|
this.input.writeOutput?.(
|
|
81514
81818
|
`agent_bridge_claude_resume_fallback session_id=${resume}`
|
|
81515
81819
|
);
|
|
81820
|
+
this.input.onResumeFallback?.();
|
|
81516
81821
|
this.state = { kind: "idle" };
|
|
81517
81822
|
return this.startSdkSession();
|
|
81518
81823
|
}
|
|
@@ -82117,7 +82422,7 @@ function isClaudeAgentTurnResult(message) {
|
|
|
82117
82422
|
}
|
|
82118
82423
|
function toolUseIds(message) {
|
|
82119
82424
|
if (message.type === "assistant") {
|
|
82120
|
-
return
|
|
82425
|
+
return contentBlocks2(message.message.content).flatMap(
|
|
82121
82426
|
(block2) => block2.type === "tool_use" && typeof block2.id === "string" ? [block2.id] : []
|
|
82122
82427
|
);
|
|
82123
82428
|
}
|
|
@@ -82135,11 +82440,11 @@ function toolResultIds(message) {
|
|
|
82135
82440
|
if (message.type !== "user") {
|
|
82136
82441
|
return [];
|
|
82137
82442
|
}
|
|
82138
|
-
return
|
|
82443
|
+
return contentBlocks2(message.message.content).flatMap(
|
|
82139
82444
|
(block) => block.type === "tool_result" && typeof block.tool_use_id === "string" ? [block.tool_use_id] : []
|
|
82140
82445
|
);
|
|
82141
82446
|
}
|
|
82142
|
-
function
|
|
82447
|
+
function contentBlocks2(content) {
|
|
82143
82448
|
if (!Array.isArray(content)) {
|
|
82144
82449
|
return [];
|
|
82145
82450
|
}
|
|
@@ -82148,42 +82453,6 @@ function contentBlocks(content) {
|
|
|
82148
82453
|
);
|
|
82149
82454
|
}
|
|
82150
82455
|
|
|
82151
|
-
// src/commands/agent-bridge/harness/claude-code/resume-store.ts
|
|
82152
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
82153
|
-
import { dirname } from "path";
|
|
82154
|
-
var AGENT_BRIDGE_RUNTIME_DIR = "/tmp/auto-bridge-runtime";
|
|
82155
|
-
var CLAUDE_SESSION_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-session-id`;
|
|
82156
|
-
function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
82157
|
-
return {
|
|
82158
|
-
read(sessionId) {
|
|
82159
|
-
if (!existsSync2(path2)) {
|
|
82160
|
-
return null;
|
|
82161
|
-
}
|
|
82162
|
-
const record2 = parseResumeRecord(readFileSync2(path2, "utf8"));
|
|
82163
|
-
if (!record2 || record2.sessionId !== sessionId) {
|
|
82164
|
-
return null;
|
|
82165
|
-
}
|
|
82166
|
-
return record2.agentId;
|
|
82167
|
-
},
|
|
82168
|
-
write(record2) {
|
|
82169
|
-
mkdirSync2(dirname(path2), { recursive: true });
|
|
82170
|
-
writeFileSync(path2, `${JSON.stringify(record2)}
|
|
82171
|
-
`, "utf8");
|
|
82172
|
-
}
|
|
82173
|
-
};
|
|
82174
|
-
}
|
|
82175
|
-
function parseResumeRecord(raw) {
|
|
82176
|
-
try {
|
|
82177
|
-
const value2 = JSON.parse(raw);
|
|
82178
|
-
if (value2 !== null && typeof value2 === "object" && "sessionId" in value2 && "agentId" in value2 && typeof value2.sessionId === "string" && typeof value2.agentId === "string" && value2.agentId.length > 0) {
|
|
82179
|
-
return { sessionId: value2.sessionId, agentId: value2.agentId };
|
|
82180
|
-
}
|
|
82181
|
-
return null;
|
|
82182
|
-
} catch {
|
|
82183
|
-
return null;
|
|
82184
|
-
}
|
|
82185
|
-
}
|
|
82186
|
-
|
|
82187
82456
|
// src/commands/agent-bridge/harness/claude-code/index.ts
|
|
82188
82457
|
function createClaudeCodeCommandHandler(input) {
|
|
82189
82458
|
return new ClaudeCodeCommandHandler(input);
|
|
@@ -82193,6 +82462,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
82193
82462
|
this.input = input;
|
|
82194
82463
|
this.claudeConfig = input.claude;
|
|
82195
82464
|
this.outputBuffer = new AgentBridgeOutputBuffer(input);
|
|
82465
|
+
this.readState = input.readState ? new ClaudeReadStateTracker(input.readState) : null;
|
|
82196
82466
|
}
|
|
82197
82467
|
input;
|
|
82198
82468
|
context = null;
|
|
@@ -82214,6 +82484,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
82214
82484
|
pendingQuestions = /* @__PURE__ */ new Map();
|
|
82215
82485
|
outputBuffer;
|
|
82216
82486
|
projector = new ClaudeCodeProjector();
|
|
82487
|
+
readState;
|
|
82217
82488
|
livenessTicker = null;
|
|
82218
82489
|
// -----------------------------------------------------------------------------
|
|
82219
82490
|
// Lifecycle (public API)
|
|
@@ -82590,6 +82861,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
82590
82861
|
return;
|
|
82591
82862
|
}
|
|
82592
82863
|
this.persistAgentId(activeContext, message);
|
|
82864
|
+
this.trackReadState(activeContext, message);
|
|
82593
82865
|
let projections;
|
|
82594
82866
|
try {
|
|
82595
82867
|
projections = this.projector.project(message);
|
|
@@ -82653,6 +82925,31 @@ var ClaudeCodeCommandHandler = class {
|
|
|
82653
82925
|
);
|
|
82654
82926
|
}
|
|
82655
82927
|
}
|
|
82928
|
+
// Observes file-tool results into the read-state tracker and replays the
|
|
82929
|
+
// tracked seeds whenever a fresh CLI cache appears: a new process's `init`
|
|
82930
|
+
// (runtime restart, selection change, CLI-internal fork — all resume the
|
|
82931
|
+
// conversation but start with an empty readFileState) and compaction
|
|
82932
|
+
// boundaries (which can evict prior reads). Seeding is fire-and-forget:
|
|
82933
|
+
// a failed seed degrades to today's behavior, a fresh Read before writing.
|
|
82934
|
+
trackReadState(activeContext, message) {
|
|
82935
|
+
const tracker = this.readState;
|
|
82936
|
+
if (!tracker) {
|
|
82937
|
+
return;
|
|
82938
|
+
}
|
|
82939
|
+
if (message.type === "system" && (message.subtype === "init" || message.subtype === "compact_boundary")) {
|
|
82940
|
+
const seeds = tracker.seeds(activeContext.sessionId);
|
|
82941
|
+
if (seeds.length === 0) {
|
|
82942
|
+
return;
|
|
82943
|
+
}
|
|
82944
|
+
this.agentSession?.seedReadState(seeds).catch((error51) => {
|
|
82945
|
+
this.input.writeOutput?.(
|
|
82946
|
+
`agent_bridge_claude_read_state_seed_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
82947
|
+
);
|
|
82948
|
+
});
|
|
82949
|
+
return;
|
|
82950
|
+
}
|
|
82951
|
+
tracker.observe(activeContext.sessionId, message);
|
|
82952
|
+
}
|
|
82656
82953
|
storedResumeAgentId() {
|
|
82657
82954
|
const store = this.input.sessionResume;
|
|
82658
82955
|
const activeContext = this.context;
|
|
@@ -82682,10 +82979,18 @@ var ClaudeCodeCommandHandler = class {
|
|
|
82682
82979
|
"Cannot restart Claude Code for a model/effort selection change without a session id to resume"
|
|
82683
82980
|
);
|
|
82684
82981
|
}
|
|
82982
|
+
if (!resumeAgentId && this.context) {
|
|
82983
|
+
this.readState?.clear(this.context.sessionId);
|
|
82984
|
+
}
|
|
82685
82985
|
const session = claudeAgentBridgeRuntime.start({
|
|
82686
82986
|
claude: this.claudeConfig,
|
|
82687
82987
|
resumeAgentId,
|
|
82688
82988
|
...resumeRequired ? { allowResumeFallback: false } : {},
|
|
82989
|
+
onResumeFallback: () => {
|
|
82990
|
+
if (this.context) {
|
|
82991
|
+
this.readState?.clear(this.context.sessionId);
|
|
82992
|
+
}
|
|
82993
|
+
},
|
|
82689
82994
|
canUseTool: this.canUseTool,
|
|
82690
82995
|
onMessage: (message, meta3) => this.handleAgentMessage(message, meta3),
|
|
82691
82996
|
onError: (error51) => this.handleAgentError(error51),
|
|
@@ -83098,25 +83403,25 @@ function normalizeChunk(chunk) {
|
|
|
83098
83403
|
}
|
|
83099
83404
|
|
|
83100
83405
|
// src/commands/agent-bridge/harness/codex/resume-store.ts
|
|
83101
|
-
import { existsSync as
|
|
83102
|
-
import { dirname as
|
|
83406
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
83407
|
+
import { dirname as dirname3 } from "path";
|
|
83103
83408
|
var AGENT_BRIDGE_RUNTIME_DIR2 = "/tmp/auto-bridge-runtime";
|
|
83104
83409
|
var CODEX_THREAD_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR2}/codex-thread-id`;
|
|
83105
83410
|
function fileCodexThreadResumeStore(path2 = CODEX_THREAD_RESUME_PATH) {
|
|
83106
83411
|
return {
|
|
83107
83412
|
read(sessionId) {
|
|
83108
|
-
if (!
|
|
83413
|
+
if (!existsSync4(path2)) {
|
|
83109
83414
|
return null;
|
|
83110
83415
|
}
|
|
83111
|
-
const record2 = parseResumeRecord2(
|
|
83416
|
+
const record2 = parseResumeRecord2(readFileSync4(path2, "utf8"));
|
|
83112
83417
|
if (!record2 || record2.sessionId !== sessionId) {
|
|
83113
83418
|
return null;
|
|
83114
83419
|
}
|
|
83115
83420
|
return record2.threadId;
|
|
83116
83421
|
},
|
|
83117
83422
|
write(record2) {
|
|
83118
|
-
|
|
83119
|
-
|
|
83423
|
+
mkdirSync4(dirname3(path2), { recursive: true });
|
|
83424
|
+
writeFileSync3(path2, `${JSON.stringify(record2)}
|
|
83120
83425
|
`, "utf8");
|
|
83121
83426
|
}
|
|
83122
83427
|
};
|
|
@@ -83135,8 +83440,26 @@ function parseResumeRecord2(raw) {
|
|
|
83135
83440
|
|
|
83136
83441
|
// src/commands/agent-bridge/harness/codex/session.ts
|
|
83137
83442
|
import { spawn } from "child_process";
|
|
83138
|
-
import { mkdirSync as
|
|
83139
|
-
import { join as
|
|
83443
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
83444
|
+
import { join as join3 } from "path";
|
|
83445
|
+
|
|
83446
|
+
// src/commands/agent-bridge/harness/codex/edit-capability.ts
|
|
83447
|
+
import { execFileSync } from "child_process";
|
|
83448
|
+
import {
|
|
83449
|
+
constants,
|
|
83450
|
+
accessSync,
|
|
83451
|
+
existsSync as existsSync5,
|
|
83452
|
+
lstatSync as lstatSync2,
|
|
83453
|
+
mkdtempSync,
|
|
83454
|
+
readFileSync as readFileSync5,
|
|
83455
|
+
realpathSync as realpathSync2,
|
|
83456
|
+
rmSync as rmSync2,
|
|
83457
|
+
symlinkSync as symlinkSync2,
|
|
83458
|
+
unlinkSync as unlinkSync2,
|
|
83459
|
+
writeFileSync as writeFileSync4
|
|
83460
|
+
} from "fs";
|
|
83461
|
+
import { tmpdir } from "os";
|
|
83462
|
+
import { delimiter, dirname as dirname4, join as join2 } from "path";
|
|
83140
83463
|
|
|
83141
83464
|
// src/commands/agent-bridge/harness/codex/options.ts
|
|
83142
83465
|
import { join } from "path";
|
|
@@ -83278,6 +83601,172 @@ function tomlString(value2) {
|
|
|
83278
83601
|
return `"${value2.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
83279
83602
|
}
|
|
83280
83603
|
|
|
83604
|
+
// src/commands/agent-bridge/harness/codex/edit-capability.ts
|
|
83605
|
+
var CODEX_APPLY_PATCH_ALIAS = "apply_patch";
|
|
83606
|
+
var CODEX_EDIT_PROBE = {
|
|
83607
|
+
fileName: "probe.txt",
|
|
83608
|
+
before: "codex-edit-probe\n",
|
|
83609
|
+
after: "codex-edit-probe-ok\n",
|
|
83610
|
+
patch: [
|
|
83611
|
+
"*** Begin Patch",
|
|
83612
|
+
"*** Update File: probe.txt",
|
|
83613
|
+
"@@",
|
|
83614
|
+
"-codex-edit-probe",
|
|
83615
|
+
"+codex-edit-probe-ok",
|
|
83616
|
+
"*** End Patch"
|
|
83617
|
+
].join("\n")
|
|
83618
|
+
};
|
|
83619
|
+
var PROBE_TIMEOUT_MS = 15e3;
|
|
83620
|
+
var MAX_EVIDENCE_LENGTH = 300;
|
|
83621
|
+
var CODEX_PLATFORM_VENDOR_TARGETS = {
|
|
83622
|
+
linux: {
|
|
83623
|
+
x64: "x86_64-unknown-linux-musl",
|
|
83624
|
+
arm64: "aarch64-unknown-linux-musl"
|
|
83625
|
+
},
|
|
83626
|
+
darwin: {
|
|
83627
|
+
x64: "x86_64-apple-darwin",
|
|
83628
|
+
arm64: "aarch64-apple-darwin"
|
|
83629
|
+
}
|
|
83630
|
+
};
|
|
83631
|
+
function ensureCodexEditCapability(input) {
|
|
83632
|
+
if (input.command !== CODEX_EXECUTABLE_PATH) {
|
|
83633
|
+
input.writeOutput?.(
|
|
83634
|
+
"agent_bridge_codex_edit_capability status=skipped reason=command_override"
|
|
83635
|
+
);
|
|
83636
|
+
return;
|
|
83637
|
+
}
|
|
83638
|
+
const startedAt = Date.now();
|
|
83639
|
+
const layout = runStep(input, "resolve", () => resolveCodexVendorLayout());
|
|
83640
|
+
const status = runStep(
|
|
83641
|
+
input,
|
|
83642
|
+
"provision",
|
|
83643
|
+
() => provisionApplyPatchAlias(layout)
|
|
83644
|
+
);
|
|
83645
|
+
const alias = join2(layout.codexPathDir, CODEX_APPLY_PATCH_ALIAS);
|
|
83646
|
+
runStep(input, "verify", () => verifyApplyPatchAlias(alias));
|
|
83647
|
+
input.writeOutput?.(
|
|
83648
|
+
`agent_bridge_codex_edit_capability status=${status} alias=${alias} duration_ms=${Date.now() - startedAt}`
|
|
83649
|
+
);
|
|
83650
|
+
}
|
|
83651
|
+
function codexEditFallthroughMarker(item) {
|
|
83652
|
+
if (item.type !== "commandExecution" || item.exitCode !== 127) {
|
|
83653
|
+
return null;
|
|
83654
|
+
}
|
|
83655
|
+
const output = item.aggregatedOutput ?? "";
|
|
83656
|
+
if (!/apply_patch: (command )?not found/.test(output)) {
|
|
83657
|
+
return null;
|
|
83658
|
+
}
|
|
83659
|
+
return `agent_bridge_codex_edit_fallthrough item_id=${item.id} exit_code=127`;
|
|
83660
|
+
}
|
|
83661
|
+
function resolveCodexVendorLayout() {
|
|
83662
|
+
const wrapper = whichOnPath(CODEX_EXECUTABLE_PATH);
|
|
83663
|
+
if (!wrapper) {
|
|
83664
|
+
throw new Error("codex executable not found on PATH");
|
|
83665
|
+
}
|
|
83666
|
+
const target = CODEX_PLATFORM_VENDOR_TARGETS[process.platform]?.[process.arch];
|
|
83667
|
+
if (!target) {
|
|
83668
|
+
throw new Error(
|
|
83669
|
+
`unsupported platform for codex vendor layout: ${process.platform}/${process.arch}`
|
|
83670
|
+
);
|
|
83671
|
+
}
|
|
83672
|
+
const packageRoot = join2(dirname4(realpathSync2(wrapper)), "..");
|
|
83673
|
+
const platformPackage = `@openai/codex-${platformPackageSuffix()}`;
|
|
83674
|
+
const candidates = [
|
|
83675
|
+
join2(packageRoot, "node_modules", platformPackage, "vendor", target),
|
|
83676
|
+
join2(packageRoot, "vendor", target)
|
|
83677
|
+
];
|
|
83678
|
+
for (const vendorDir of candidates) {
|
|
83679
|
+
const binary = join2(vendorDir, "bin", "codex");
|
|
83680
|
+
const codexPathDir = join2(vendorDir, "codex-path");
|
|
83681
|
+
if (existsSync5(binary) && existsSync5(codexPathDir)) {
|
|
83682
|
+
return { binary, codexPathDir };
|
|
83683
|
+
}
|
|
83684
|
+
}
|
|
83685
|
+
throw new Error(
|
|
83686
|
+
`codex vendor layout not found (wrapper=${wrapper} candidates=${candidates.join(",")})`
|
|
83687
|
+
);
|
|
83688
|
+
}
|
|
83689
|
+
function platformPackageSuffix() {
|
|
83690
|
+
const os = process.platform === "darwin" ? "darwin" : "linux";
|
|
83691
|
+
return `${os}-${process.arch}`;
|
|
83692
|
+
}
|
|
83693
|
+
function whichOnPath(command) {
|
|
83694
|
+
for (const dir of (process.env.PATH ?? "").split(delimiter)) {
|
|
83695
|
+
if (!dir) {
|
|
83696
|
+
continue;
|
|
83697
|
+
}
|
|
83698
|
+
const candidate = join2(dir, command);
|
|
83699
|
+
try {
|
|
83700
|
+
accessSync(candidate, constants.X_OK);
|
|
83701
|
+
return candidate;
|
|
83702
|
+
} catch {
|
|
83703
|
+
}
|
|
83704
|
+
}
|
|
83705
|
+
return null;
|
|
83706
|
+
}
|
|
83707
|
+
function provisionApplyPatchAlias(layout) {
|
|
83708
|
+
const alias = join2(layout.codexPathDir, CODEX_APPLY_PATCH_ALIAS);
|
|
83709
|
+
if (aliasResolvesToBinary(alias, layout.binary)) {
|
|
83710
|
+
return "present";
|
|
83711
|
+
}
|
|
83712
|
+
if (lstatExists(alias)) {
|
|
83713
|
+
unlinkSync2(alias);
|
|
83714
|
+
}
|
|
83715
|
+
symlinkSync2(layout.binary, alias);
|
|
83716
|
+
return "provisioned";
|
|
83717
|
+
}
|
|
83718
|
+
function aliasResolvesToBinary(alias, binary) {
|
|
83719
|
+
try {
|
|
83720
|
+
return realpathSync2(alias) === realpathSync2(binary);
|
|
83721
|
+
} catch {
|
|
83722
|
+
return false;
|
|
83723
|
+
}
|
|
83724
|
+
}
|
|
83725
|
+
function lstatExists(path2) {
|
|
83726
|
+
try {
|
|
83727
|
+
lstatSync2(path2);
|
|
83728
|
+
return true;
|
|
83729
|
+
} catch {
|
|
83730
|
+
return false;
|
|
83731
|
+
}
|
|
83732
|
+
}
|
|
83733
|
+
function verifyApplyPatchAlias(alias) {
|
|
83734
|
+
const scratch = mkdtempSync(join2(tmpdir(), "codex-edit-probe-"));
|
|
83735
|
+
try {
|
|
83736
|
+
const probeFile = join2(scratch, CODEX_EDIT_PROBE.fileName);
|
|
83737
|
+
writeFileSync4(probeFile, CODEX_EDIT_PROBE.before);
|
|
83738
|
+
execFileSync(alias, [CODEX_EDIT_PROBE.patch], {
|
|
83739
|
+
cwd: scratch,
|
|
83740
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
83741
|
+
timeout: PROBE_TIMEOUT_MS
|
|
83742
|
+
});
|
|
83743
|
+
const applied = readFileSync5(probeFile, "utf8");
|
|
83744
|
+
if (applied !== CODEX_EDIT_PROBE.after) {
|
|
83745
|
+
throw new Error("probe patch did not apply the expected content");
|
|
83746
|
+
}
|
|
83747
|
+
} finally {
|
|
83748
|
+
rmSync2(scratch, { recursive: true, force: true });
|
|
83749
|
+
}
|
|
83750
|
+
}
|
|
83751
|
+
function runStep(input, step, action) {
|
|
83752
|
+
try {
|
|
83753
|
+
return action();
|
|
83754
|
+
} catch (error51) {
|
|
83755
|
+
const detail = boundedEvidence(error51);
|
|
83756
|
+
input.writeOutput?.(
|
|
83757
|
+
`agent_bridge_codex_edit_capability status=failed step=${step} error=${detail}`
|
|
83758
|
+
);
|
|
83759
|
+
throw new Error(
|
|
83760
|
+
`Codex edit capability unavailable at ${step}: ${detail}. Codex 0.141.0 declares no apply_patch tool; without the codex-path alias, exec invocations the interceptor does not recognize fail with command-not-found (codex-runtime-tool-loss-diagnostics).`
|
|
83761
|
+
);
|
|
83762
|
+
}
|
|
83763
|
+
}
|
|
83764
|
+
function boundedEvidence(error51) {
|
|
83765
|
+
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
83766
|
+
const flattened = message.replace(/\s+/g, " ").trim();
|
|
83767
|
+
return flattened.length > MAX_EVIDENCE_LENGTH ? `${flattened.slice(0, MAX_EVIDENCE_LENGTH)}\u2026` : flattened;
|
|
83768
|
+
}
|
|
83769
|
+
|
|
83281
83770
|
// src/commands/agent-bridge/harness/codex/turn-retry.ts
|
|
83282
83771
|
var MAX_CODEX_TURN_RETRY_ATTEMPTS = 3;
|
|
83283
83772
|
var MAX_CODEX_TURN_RETRY_TOTAL_DELAY_MS = 3e4;
|
|
@@ -83511,12 +84000,16 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
83511
84000
|
}
|
|
83512
84001
|
async start() {
|
|
83513
84002
|
const options = codexLaunchOptions(this.input.codex);
|
|
83514
|
-
|
|
83515
|
-
|
|
84003
|
+
mkdirSync5(options.codexHome, { recursive: true });
|
|
84004
|
+
writeFileSync5(join3(options.codexHome, "config.toml"), options.configToml);
|
|
83516
84005
|
const startedAt = Date.now();
|
|
83517
84006
|
this.input.writeOutput?.(
|
|
83518
84007
|
`agent_bridge_codex_startup_started codex_home=${options.codexHome}`
|
|
83519
84008
|
);
|
|
84009
|
+
ensureCodexEditCapability({
|
|
84010
|
+
command: options.command,
|
|
84011
|
+
...this.input.writeOutput ? { writeOutput: this.input.writeOutput } : {}
|
|
84012
|
+
});
|
|
83520
84013
|
const proc = spawn(options.command, options.args, {
|
|
83521
84014
|
env: options.env,
|
|
83522
84015
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -83916,12 +84409,17 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
83916
84409
|
this.pendingToolItemIds.add(notification.item.id);
|
|
83917
84410
|
}
|
|
83918
84411
|
return;
|
|
83919
|
-
case "itemCompleted":
|
|
84412
|
+
case "itemCompleted": {
|
|
84413
|
+
const fallthrough = codexEditFallthroughMarker(notification.item);
|
|
84414
|
+
if (fallthrough) {
|
|
84415
|
+
this.input.writeOutput?.(fallthrough);
|
|
84416
|
+
}
|
|
83920
84417
|
this.pendingToolItemIds.delete(notification.item.id);
|
|
83921
84418
|
if (this.pendingToolItemIds.size === 0) {
|
|
83922
84419
|
this.resolveSettlement();
|
|
83923
84420
|
}
|
|
83924
84421
|
return;
|
|
84422
|
+
}
|
|
83925
84423
|
default:
|
|
83926
84424
|
return;
|
|
83927
84425
|
}
|
|
@@ -84406,6 +84904,7 @@ function createHarnessCommandHandler(input) {
|
|
|
84406
84904
|
return createClaudeCodeCommandHandler({
|
|
84407
84905
|
...base,
|
|
84408
84906
|
claude,
|
|
84907
|
+
readState: fileClaudeReadStateStore(),
|
|
84409
84908
|
sessionResume: fileClaudeSessionResumeStore()
|
|
84410
84909
|
});
|
|
84411
84910
|
}
|
|
@@ -84627,7 +85126,7 @@ function bridgeUrlHost(bridgeUrl) {
|
|
|
84627
85126
|
}
|
|
84628
85127
|
|
|
84629
85128
|
// src/lib/entrypoint.ts
|
|
84630
|
-
import { realpathSync as
|
|
85129
|
+
import { realpathSync as realpathSync3 } from "fs";
|
|
84631
85130
|
import { pathToFileURL } from "url";
|
|
84632
85131
|
function isCliEntrypoint(input) {
|
|
84633
85132
|
if (input.entrypoint.kind === "missing") {
|
|
@@ -84635,7 +85134,7 @@ function isCliEntrypoint(input) {
|
|
|
84635
85134
|
}
|
|
84636
85135
|
let resolvedEntrypoint;
|
|
84637
85136
|
try {
|
|
84638
|
-
resolvedEntrypoint =
|
|
85137
|
+
resolvedEntrypoint = realpathSync3(input.entrypoint.path);
|
|
84639
85138
|
} catch {
|
|
84640
85139
|
return false;
|
|
84641
85140
|
}
|