flavor-code 1.3.4 → 1.3.6
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/{app-EHB3XAQY.js → app-CJSBYZAD.js} +1 -1
- package/dist/{chunk-YKSMZDUZ.js → chunk-BR3CWUYR.js} +158 -70
- package/dist/{chunk-RDBTC35M.js → chunk-ZCEUFSHA.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/desktop/main.js +178 -90
- package/dist/hooks/bus.d.ts +7 -0
- package/dist/sdk/index.js +2 -2
- package/dist/tools/ask-user-question.d.ts +4 -1
- package/dist/tools/types.d.ts +2 -0
- package/package.json +2 -2
|
@@ -5006,7 +5006,7 @@ async function ensureOnce(options) {
|
|
|
5006
5006
|
|
|
5007
5007
|
// src/production.ts
|
|
5008
5008
|
import { readFile as readFile22 } from "fs/promises";
|
|
5009
|
-
import { createHash as createHash17, randomUUID as
|
|
5009
|
+
import { createHash as createHash17, randomUUID as randomUUID19 } from "crypto";
|
|
5010
5010
|
import { homedir as homedir2, release as osRelease, tmpdir as tmpdir3, version as osVersion } from "os";
|
|
5011
5011
|
import { basename as basename6, join as join24, relative as relative20, resolve as resolve27, sep as sep20 } from "path";
|
|
5012
5012
|
|
|
@@ -7484,11 +7484,18 @@ var DEFAULT_TOOL_OUTPUT_LIMITS = Object.freeze({
|
|
|
7484
7484
|
perTurnChars: 2e5
|
|
7485
7485
|
});
|
|
7486
7486
|
var PreToolUsePayload = z9.object({
|
|
7487
|
+
// Optional for backwards-compatible hook updatedInput payloads; runtime
|
|
7488
|
+
// emissions always populate it.
|
|
7489
|
+
toolCallId: z9.string().optional(),
|
|
7487
7490
|
tool: z9.string(),
|
|
7488
7491
|
input: z9.unknown(),
|
|
7489
7492
|
agent: z9.enum(["main", "subagent"])
|
|
7490
7493
|
});
|
|
7491
|
-
var PermissionRequestPayload = PreToolUsePayload.extend({
|
|
7494
|
+
var PermissionRequestPayload = PreToolUsePayload.extend({
|
|
7495
|
+
reason: z9.string().optional(),
|
|
7496
|
+
toolCategory: z9.string(),
|
|
7497
|
+
allowAlways: z9.boolean()
|
|
7498
|
+
});
|
|
7492
7499
|
var PostToolUsePayload = PreToolUsePayload.extend({ output: z9.unknown() });
|
|
7493
7500
|
var PostToolUseFailurePayload = PreToolUsePayload.extend({
|
|
7494
7501
|
error: z9.object({ code: z9.string(), message: z9.string() })
|
|
@@ -7605,30 +7612,31 @@ var ToolRuntime = class {
|
|
|
7605
7612
|
const tool = this.#tools.get(call.name);
|
|
7606
7613
|
if (tool === void 0) return { ok: false, error: { code: "unknown_tool", message: `Unknown tool: ${call.name}` } };
|
|
7607
7614
|
const signal = context.signal ?? new AbortController().signal;
|
|
7615
|
+
const toolCallId = call.id ?? randomUUID7();
|
|
7608
7616
|
const validation = this.validate(call);
|
|
7609
7617
|
if (!validation.ok) {
|
|
7610
|
-
return this.#fail(call.name, call.input, context.agent, validation.error.code, validation.error.message);
|
|
7618
|
+
return this.#fail(toolCallId, call.name, call.input, context.agent, validation.error.code, validation.error.message);
|
|
7611
7619
|
}
|
|
7612
7620
|
let input = validation.input;
|
|
7613
7621
|
try {
|
|
7614
7622
|
const pre = await this.#hooks.emit({
|
|
7615
7623
|
version: 1,
|
|
7616
7624
|
type: "PreToolUse",
|
|
7617
|
-
payload: { tool: tool.name, input, agent: context.agent }
|
|
7625
|
+
payload: { toolCallId, tool: tool.name, input, agent: context.agent }
|
|
7618
7626
|
});
|
|
7619
7627
|
if (pre.updatedInput !== void 0) {
|
|
7620
7628
|
const payload = PreToolUsePayload.parse(pre.updatedInput);
|
|
7621
7629
|
if (payload.tool !== tool.name || payload.agent !== context.agent) {
|
|
7622
|
-
return this.#fail(tool.name, input, context.agent, "invalid_input", "PreToolUse cannot change the tool or agent");
|
|
7630
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "invalid_input", "PreToolUse cannot change the tool or agent");
|
|
7623
7631
|
}
|
|
7624
7632
|
try {
|
|
7625
7633
|
input = tool.inputSchema.parse(payload.input);
|
|
7626
7634
|
} catch (error) {
|
|
7627
|
-
return this.#fail(tool.name, payload.input, context.agent, "invalid_input", message(error));
|
|
7635
|
+
return this.#fail(toolCallId, tool.name, payload.input, context.agent, "invalid_input", message(error));
|
|
7628
7636
|
}
|
|
7629
7637
|
}
|
|
7630
7638
|
if (pre.decision === "deny") {
|
|
7631
|
-
return this.#fail(tool.name, input, context.agent, "hook_denied", pre.reason ?? "Tool use denied by hook");
|
|
7639
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "hook_denied", pre.reason ?? "Tool use denied by hook");
|
|
7632
7640
|
}
|
|
7633
7641
|
const request = {
|
|
7634
7642
|
agent: context.agent,
|
|
@@ -7639,13 +7647,13 @@ var ToolRuntime = class {
|
|
|
7639
7647
|
let permission = this.#permissions.decide(request);
|
|
7640
7648
|
const nonCacheableApproval = request.allowAlways === false || permission.allowAlways === false;
|
|
7641
7649
|
if (permission.decision === "deny") {
|
|
7642
|
-
return this.#fail(tool.name, input, context.agent, "permission_denied", permission.reason ?? "Tool use denied");
|
|
7650
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "permission_denied", permission.reason ?? "Tool use denied");
|
|
7643
7651
|
}
|
|
7644
7652
|
if (permission.decision === "ask" && context.agent === "main" && !nonCacheableApproval && this.#permissions.mode === "auto" && this.#permissions.profile === "standard" && this.#classify !== void 0) {
|
|
7645
7653
|
try {
|
|
7646
7654
|
const classified = await this.#classify(request, signal);
|
|
7647
7655
|
if (classified.decision === "deny") {
|
|
7648
|
-
return this.#fail(tool.name, input, context.agent, "permission_denied", classified.reason ?? "Auto classifier denied tool use");
|
|
7656
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "permission_denied", classified.reason ?? "Auto classifier denied tool use");
|
|
7649
7657
|
}
|
|
7650
7658
|
if (classified.decision === "allow") permission = classified;
|
|
7651
7659
|
else {
|
|
@@ -7662,13 +7670,21 @@ var ToolRuntime = class {
|
|
|
7662
7670
|
const requestDecision = await this.#hooks.emit({
|
|
7663
7671
|
version: 1,
|
|
7664
7672
|
type: "PermissionRequest",
|
|
7665
|
-
payload: {
|
|
7673
|
+
payload: {
|
|
7674
|
+
toolCallId,
|
|
7675
|
+
tool: tool.name,
|
|
7676
|
+
input: tool.permissionInput?.(input) ?? input,
|
|
7677
|
+
agent: context.agent,
|
|
7678
|
+
reason,
|
|
7679
|
+
toolCategory: getToolCategory(tool.name),
|
|
7680
|
+
allowAlways
|
|
7681
|
+
}
|
|
7666
7682
|
});
|
|
7667
7683
|
if (requestDecision.decision === "deny") {
|
|
7668
|
-
return this.#fail(tool.name, input, context.agent, "permission_denied", requestDecision.reason ?? "Permission request denied");
|
|
7684
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "permission_denied", requestDecision.reason ?? "Permission request denied");
|
|
7669
7685
|
}
|
|
7670
7686
|
if (requestDecision.updatedInput !== void 0) {
|
|
7671
|
-
return this.#fail(tool.name, input, context.agent, "invalid_input", "PermissionRequest cannot modify an already-authorized tool call");
|
|
7687
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "invalid_input", "PermissionRequest cannot modify an already-authorized tool call");
|
|
7672
7688
|
}
|
|
7673
7689
|
if (this.#hooks.hasListeners("PermissionRequest") && requestDecision.decision === "allow") {
|
|
7674
7690
|
const ctx = requestDecision.additionalContext ?? "";
|
|
@@ -7677,18 +7693,18 @@ var ToolRuntime = class {
|
|
|
7677
7693
|
if (allowAlways && category !== "destructive") this.#alwaysAllowed.add(category);
|
|
7678
7694
|
}
|
|
7679
7695
|
} else if (context.agent !== "main" && this.#permissions.mode !== "bubble") {
|
|
7680
|
-
return this.#fail(tool.name, input, context.agent, "approval_required", reason);
|
|
7696
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "approval_required", reason);
|
|
7681
7697
|
} else if (signal.aborted) {
|
|
7682
7698
|
throw signal.reason;
|
|
7683
7699
|
} else {
|
|
7684
7700
|
const category = getToolCategory(tool.name);
|
|
7685
7701
|
if (allowAlways && this.#alwaysAllowed.has(category)) {
|
|
7686
7702
|
} else if (this.#approve === void 0) {
|
|
7687
|
-
return this.#fail(tool.name, input, context.agent, "permission_denied", reason);
|
|
7703
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "permission_denied", reason);
|
|
7688
7704
|
} else {
|
|
7689
7705
|
const decision = await this.#approve({ ...request, reason, ...allowAlways ? {} : { allowAlways: false } }, signal);
|
|
7690
7706
|
if (decision === "deny") {
|
|
7691
|
-
return this.#fail(tool.name, input, context.agent, "user_denied", reason);
|
|
7707
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "user_denied", reason);
|
|
7692
7708
|
}
|
|
7693
7709
|
if (decision === "always" && allowAlways && category !== "destructive") {
|
|
7694
7710
|
this.#alwaysAllowed.add(category);
|
|
@@ -7702,7 +7718,7 @@ var ToolRuntime = class {
|
|
|
7702
7718
|
try {
|
|
7703
7719
|
rawOutput = tool.outputSchema === void 0 ? executed : tool.outputSchema.parse(executed);
|
|
7704
7720
|
} catch (error) {
|
|
7705
|
-
return this.#fail(tool.name, input, context.agent, "invalid_output", message(error));
|
|
7721
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "invalid_output", message(error));
|
|
7706
7722
|
}
|
|
7707
7723
|
const declaredPresentation = tool.presentResult?.(rawOutput, input);
|
|
7708
7724
|
const presentation = declaredPresentation ?? getToolPresentation(rawOutput);
|
|
@@ -7713,7 +7729,7 @@ var ToolRuntime = class {
|
|
|
7713
7729
|
await this.#hooks.emit({
|
|
7714
7730
|
version: 1,
|
|
7715
7731
|
type: "PostToolUse",
|
|
7716
|
-
payload: { tool: tool.name, input, agent: context.agent, output }
|
|
7732
|
+
payload: { toolCallId, tool: tool.name, input, agent: context.agent, output }
|
|
7717
7733
|
});
|
|
7718
7734
|
return {
|
|
7719
7735
|
ok: true,
|
|
@@ -7723,7 +7739,7 @@ var ToolRuntime = class {
|
|
|
7723
7739
|
...additionalContext === void 0 || additionalContext.length === 0 ? {} : { additionalContext }
|
|
7724
7740
|
};
|
|
7725
7741
|
} catch (error) {
|
|
7726
|
-
return this.#fail(tool.name, input, context.agent, "tool_error", message(error));
|
|
7742
|
+
return this.#fail(toolCallId, tool.name, input, context.agent, "tool_error", message(error));
|
|
7727
7743
|
}
|
|
7728
7744
|
}
|
|
7729
7745
|
async #limitOutput(tool, output) {
|
|
@@ -7771,13 +7787,13 @@ var ToolRuntime = class {
|
|
|
7771
7787
|
const limited = await this.#limitOutput(tool, content);
|
|
7772
7788
|
return typeof limited === "string" ? limited : serializeToolOutput(limited);
|
|
7773
7789
|
}
|
|
7774
|
-
async #fail(tool, input, agent, code, errorMessage2) {
|
|
7790
|
+
async #fail(toolCallId, tool, input, agent, code, errorMessage2) {
|
|
7775
7791
|
const result = { ok: false, error: { code, message: errorMessage2 } };
|
|
7776
7792
|
try {
|
|
7777
7793
|
await this.#hooks.emit({
|
|
7778
7794
|
version: 1,
|
|
7779
7795
|
type: "PostToolUseFailure",
|
|
7780
|
-
payload: { tool, input, agent, error: result.error }
|
|
7796
|
+
payload: { toolCallId, tool, input, agent, error: result.error }
|
|
7781
7797
|
});
|
|
7782
7798
|
} catch {
|
|
7783
7799
|
}
|
|
@@ -8398,6 +8414,7 @@ function isWithin2(root, target) {
|
|
|
8398
8414
|
|
|
8399
8415
|
// src/hooks/bus.ts
|
|
8400
8416
|
import { spawn as spawn4 } from "child_process";
|
|
8417
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
8401
8418
|
|
|
8402
8419
|
// src/hooks/types.ts
|
|
8403
8420
|
import { z as z11 } from "zod";
|
|
@@ -8464,6 +8481,11 @@ var DEFAULT_MAX_OUTPUT_BYTES = 1048576;
|
|
|
8464
8481
|
var HookBus = class {
|
|
8465
8482
|
#handlers = /* @__PURE__ */ new Map();
|
|
8466
8483
|
#payloadSchemas = /* @__PURE__ */ new Map();
|
|
8484
|
+
#options;
|
|
8485
|
+
#sequence = 0;
|
|
8486
|
+
constructor(options = {}) {
|
|
8487
|
+
this.#options = options;
|
|
8488
|
+
}
|
|
8467
8489
|
registerPayloadSchema(type, schema) {
|
|
8468
8490
|
const registrations = this.#payloadSchemas.get(type) ?? [];
|
|
8469
8491
|
const registration = { schema };
|
|
@@ -8500,7 +8522,9 @@ var HookBus = class {
|
|
|
8500
8522
|
async emit(rawEvent, externalSignal) {
|
|
8501
8523
|
externalSignal?.throwIfAborted();
|
|
8502
8524
|
let event = HookEventSchema.parse(rawEvent);
|
|
8503
|
-
|
|
8525
|
+
const validatedPayload = this.#validatePayload(event.type, event.payload);
|
|
8526
|
+
const envelope = this.#eventEnvelope();
|
|
8527
|
+
event = { ...event, payload: decoratePayload(validatedPayload, envelope) };
|
|
8504
8528
|
let aggregate2 = { decision: "allow" };
|
|
8505
8529
|
for (const registered of this.#handlers.get(event.type) ?? []) {
|
|
8506
8530
|
externalSignal?.throwIfAborted();
|
|
@@ -8515,8 +8539,8 @@ var HookBus = class {
|
|
|
8515
8539
|
externalSignal?.throwIfAborted();
|
|
8516
8540
|
if (decision.updatedInput !== void 0) {
|
|
8517
8541
|
const payload = this.#validatePayload(event.type, decision.updatedInput);
|
|
8518
|
-
event = HookEventSchema.parse({ ...event, payload });
|
|
8519
|
-
aggregate2 = { ...aggregate2, updatedInput:
|
|
8542
|
+
event = HookEventSchema.parse({ ...event, payload: decoratePayload(payload, envelope) });
|
|
8543
|
+
aggregate2 = { ...aggregate2, updatedInput: payload };
|
|
8520
8544
|
}
|
|
8521
8545
|
if (decision.additionalContext !== void 0) {
|
|
8522
8546
|
aggregate2 = {
|
|
@@ -8533,6 +8557,15 @@ var HookBus = class {
|
|
|
8533
8557
|
const schema = this.#payloadSchemas.get(type)?.at(-1)?.schema;
|
|
8534
8558
|
return schema ? schema.parse(payload) : zodRecord(payload);
|
|
8535
8559
|
}
|
|
8560
|
+
#eventEnvelope() {
|
|
8561
|
+
if (this.#options.eventContext === void 0) return void 0;
|
|
8562
|
+
return {
|
|
8563
|
+
...this.#options.eventContext(),
|
|
8564
|
+
eventId: (this.#options.eventId ?? randomUUID9)(),
|
|
8565
|
+
sequence: ++this.#sequence,
|
|
8566
|
+
timestamp: (this.#options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))()
|
|
8567
|
+
};
|
|
8568
|
+
}
|
|
8536
8569
|
async #invoke(registered, event, externalSignal) {
|
|
8537
8570
|
const timeoutSignal = AbortSignal.timeout(registered.timeoutMs);
|
|
8538
8571
|
const signal = externalSignal === void 0 ? timeoutSignal : AbortSignal.any([timeoutSignal, externalSignal]);
|
|
@@ -8544,6 +8577,9 @@ var HookBus = class {
|
|
|
8544
8577
|
return HookDecisionSchema.parse(await Promise.race([invocation, timeout]));
|
|
8545
8578
|
}
|
|
8546
8579
|
};
|
|
8580
|
+
function decoratePayload(payload, envelope) {
|
|
8581
|
+
return envelope === void 0 ? payload : { ...payload, ...envelope };
|
|
8582
|
+
}
|
|
8547
8583
|
function runShellHandler(descriptor, event, signal) {
|
|
8548
8584
|
return new Promise((resolve28, reject) => {
|
|
8549
8585
|
const child = spawn4(descriptor.command, [...descriptor.args ?? []], {
|
|
@@ -11421,7 +11457,7 @@ function formatPriorGaps(gaps) {
|
|
|
11421
11457
|
|
|
11422
11458
|
// src/goal/store.ts
|
|
11423
11459
|
import { constants as constants2 } from "fs";
|
|
11424
|
-
import { randomUUID as
|
|
11460
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
11425
11461
|
import { lstat as lstat6, mkdir as mkdir11, open as open6, rename as rename4, rm as rm4 } from "fs/promises";
|
|
11426
11462
|
import { dirname as dirname12, join as join14, relative as relative9, resolve as resolve11, sep as sep9 } from "path";
|
|
11427
11463
|
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
@@ -11445,7 +11481,7 @@ var GoalStore = class {
|
|
|
11445
11481
|
if (Buffer.byteLength(body) > this.#maxBytes) {
|
|
11446
11482
|
throw new Error(`Goal state exceeds maximum size of ${this.#maxBytes} bytes`);
|
|
11447
11483
|
}
|
|
11448
|
-
const temporary = join14(this.#root, `.${state.id}.${process.pid}.${
|
|
11484
|
+
const temporary = join14(this.#root, `.${state.id}.${process.pid}.${randomUUID10()}.tmp`);
|
|
11449
11485
|
let handle;
|
|
11450
11486
|
try {
|
|
11451
11487
|
handle = await open6(temporary, constants2.O_CREAT | constants2.O_EXCL | constants2.O_WRONLY, 384);
|
|
@@ -11558,7 +11594,7 @@ async function ensureWorktreeDirectoryIgnored(root) {
|
|
|
11558
11594
|
import { constants as constants3 } from "fs";
|
|
11559
11595
|
import { lstat as lstat7, mkdir as mkdir13, open as open7, readFile as readFile11, realpath as realpath5, rename as rename5, rm as rm5, stat as stat5 } from "fs/promises";
|
|
11560
11596
|
import { dirname as dirname13, join as join16, relative as relative10, resolve as resolve13, sep as sep10 } from "path";
|
|
11561
|
-
import { randomUUID as
|
|
11597
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
11562
11598
|
var LOOP_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
11563
11599
|
var DEFAULT_MAX_BYTES2 = 5 * 1024 * 1024;
|
|
11564
11600
|
var LoopStore = class {
|
|
@@ -11589,7 +11625,7 @@ var LoopStore = class {
|
|
|
11589
11625
|
const body = `${JSON.stringify(state, null, 2)}
|
|
11590
11626
|
`;
|
|
11591
11627
|
if (Buffer.byteLength(body) > this.#maxBytes) throw new Error(`Loop state exceeds maximum size of ${this.#maxBytes} bytes`);
|
|
11592
|
-
const temporary = join16(directory, `.state.${process.pid}.${
|
|
11628
|
+
const temporary = join16(directory, `.state.${process.pid}.${randomUUID11()}.tmp`);
|
|
11593
11629
|
let handle;
|
|
11594
11630
|
try {
|
|
11595
11631
|
handle = await open7(temporary, constants3.O_CREAT | constants3.O_EXCL | constants3.O_WRONLY, 384);
|
|
@@ -11615,7 +11651,7 @@ var LoopStore = class {
|
|
|
11615
11651
|
return state;
|
|
11616
11652
|
} catch (error) {
|
|
11617
11653
|
if (isCode4(error, "ENOENT")) throw new Error(`Loop "${loopId}" was not found`);
|
|
11618
|
-
const quarantine = `${target}.corrupt-${Date.now()}-${
|
|
11654
|
+
const quarantine = `${target}.corrupt-${Date.now()}-${randomUUID11().slice(0, 8)}`;
|
|
11619
11655
|
await rename5(target, quarantine).catch(() => void 0);
|
|
11620
11656
|
throw new Error(`Loop "${loopId}" is corrupt and was quarantined: ${message(error)}`);
|
|
11621
11657
|
}
|
|
@@ -14383,7 +14419,7 @@ function createSkillResourceTool(registry) {
|
|
|
14383
14419
|
import { constants as constants5 } from "fs";
|
|
14384
14420
|
import { lstat as lstat9, mkdir as mkdir14, open as open8, readFile as readFile16, readdir as readdir6, realpath as realpath7, rename as rename6, rm as rm6, stat as stat6 } from "fs/promises";
|
|
14385
14421
|
import { basename as basename3, dirname as dirname15, join as join19, relative as relative13, resolve as resolve18, sep as sep13 } from "path";
|
|
14386
|
-
import { randomUUID as
|
|
14422
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
14387
14423
|
import { z as z22 } from "zod";
|
|
14388
14424
|
var SESSION_VERSION = 4;
|
|
14389
14425
|
var DEFAULT_MAX_SESSION_BYTES = 5 * 1024 * 1024;
|
|
@@ -14541,7 +14577,7 @@ var SessionStore = class {
|
|
|
14541
14577
|
const body = `${lines.join("\n")}
|
|
14542
14578
|
`;
|
|
14543
14579
|
if (Buffer.byteLength(body) > this.#maxBytes) throw new Error(`Session exceeds maximum size of ${this.#maxBytes} bytes`);
|
|
14544
|
-
const temporary = join19(this.#sessions, `.${document.sessionId}.${process.pid}.${
|
|
14580
|
+
const temporary = join19(this.#sessions, `.${document.sessionId}.${process.pid}.${randomUUID12()}.tmp`);
|
|
14545
14581
|
let handle;
|
|
14546
14582
|
try {
|
|
14547
14583
|
handle = await open8(temporary, constants5.O_CREAT | constants5.O_EXCL | constants5.O_WRONLY, 384);
|
|
@@ -14697,7 +14733,7 @@ var SessionStore = class {
|
|
|
14697
14733
|
if (!isWithin5(canonicalRoot, canonicalSessions)) throw new Error("Session directory escapes the workspace");
|
|
14698
14734
|
}
|
|
14699
14735
|
async #quarantine(path) {
|
|
14700
|
-
const target = `${path}.corrupt-${Date.now()}-${
|
|
14736
|
+
const target = `${path}.corrupt-${Date.now()}-${randomUUID12().slice(0, 8)}`;
|
|
14701
14737
|
await rename6(path, target);
|
|
14702
14738
|
return target;
|
|
14703
14739
|
}
|
|
@@ -14917,7 +14953,7 @@ function sanitize2(input, seen = /* @__PURE__ */ new WeakSet()) {
|
|
|
14917
14953
|
|
|
14918
14954
|
// src/sleep/organizer.ts
|
|
14919
14955
|
import { constants as constants6 } from "fs";
|
|
14920
|
-
import { randomUUID as
|
|
14956
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
14921
14957
|
import { lstat as lstat10, mkdir as mkdir15, open as open9, readdir as readdir7, realpath as realpath8, rename as rename7, rm as rm7 } from "fs/promises";
|
|
14922
14958
|
import { isAbsolute as isAbsolute8, join as join20, relative as relative14, resolve as resolve19, sep as sep14 } from "path";
|
|
14923
14959
|
import { z as z23 } from "zod";
|
|
@@ -15074,7 +15110,7 @@ Previous output was invalid. Repair it and return strict JSON only.`;
|
|
|
15074
15110
|
return (await readdir7(this.#sleepDirectory, { withFileTypes: true })).some((entry2) => entry2.isFile() && entry2.name.startsWith(prefix) && entry2.name.endsWith(".md"));
|
|
15075
15111
|
}
|
|
15076
15112
|
async #atomicWrite(path, content) {
|
|
15077
|
-
const temporary = join20(this.#sleepDirectory, `.${
|
|
15113
|
+
const temporary = join20(this.#sleepDirectory, `.${randomUUID13()}.tmp`);
|
|
15078
15114
|
let handle;
|
|
15079
15115
|
try {
|
|
15080
15116
|
handle = await open9(temporary, constants6.O_CREAT | constants6.O_EXCL | constants6.O_WRONLY, 384);
|
|
@@ -15450,7 +15486,7 @@ function computeSessionStats(documents) {
|
|
|
15450
15486
|
import { constants as constants7 } from "fs";
|
|
15451
15487
|
import { mkdir as mkdir16, open as open10, readFile as readFile17, realpath as realpath9, rename as rename8, rm as rm8, stat as stat7 } from "fs/promises";
|
|
15452
15488
|
import { dirname as dirname16, isAbsolute as isAbsolute9, relative as relative15, resolve as resolve20, sep as sep15 } from "path";
|
|
15453
|
-
import { randomUUID as
|
|
15489
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
15454
15490
|
import { z as z24 } from "zod";
|
|
15455
15491
|
|
|
15456
15492
|
// src/tools/file-diff.ts
|
|
@@ -15803,7 +15839,7 @@ function createPathGuard(workspace) {
|
|
|
15803
15839
|
async function atomicWrite(path, content, signal, expectedVersion) {
|
|
15804
15840
|
abortIfNeeded(signal);
|
|
15805
15841
|
await mkdir16(dirname16(path), { recursive: true });
|
|
15806
|
-
const temporary = `${path}.${
|
|
15842
|
+
const temporary = `${path}.${randomUUID14()}.tmp`;
|
|
15807
15843
|
try {
|
|
15808
15844
|
const handle = await open10(temporary, constants7.O_CREAT | constants7.O_EXCL | constants7.O_WRONLY, 384);
|
|
15809
15845
|
try {
|
|
@@ -17200,18 +17236,40 @@ function hookAnswersFromUpdatedInput(updatedInput, questions) {
|
|
|
17200
17236
|
var QuestionBridge = class {
|
|
17201
17237
|
#pending;
|
|
17202
17238
|
#onChange;
|
|
17203
|
-
|
|
17239
|
+
#relay;
|
|
17240
|
+
#active = false;
|
|
17241
|
+
constructor(onChange, relay) {
|
|
17204
17242
|
this.#onChange = onChange;
|
|
17243
|
+
this.#relay = relay;
|
|
17205
17244
|
}
|
|
17206
17245
|
get pending() {
|
|
17207
17246
|
return this.#pending?.questions;
|
|
17208
17247
|
}
|
|
17209
17248
|
ask(questions, signal) {
|
|
17210
|
-
if (this.#
|
|
17249
|
+
if (this.#active) return Promise.reject(new Error("A question is already pending"));
|
|
17211
17250
|
if (signal.aborted) return Promise.reject(signal.reason);
|
|
17251
|
+
this.#active = true;
|
|
17252
|
+
if (this.#relay !== void 0) return this.#askRelayed(questions, signal);
|
|
17253
|
+
return this.#askLocally(questions, signal);
|
|
17254
|
+
}
|
|
17255
|
+
async #askRelayed(questions, signal) {
|
|
17256
|
+
try {
|
|
17257
|
+
const answers = await this.#relay(questions, signal);
|
|
17258
|
+
if (answers !== void 0) {
|
|
17259
|
+
this.#active = false;
|
|
17260
|
+
return answers;
|
|
17261
|
+
}
|
|
17262
|
+
return await this.#askLocally(questions, signal);
|
|
17263
|
+
} catch (error) {
|
|
17264
|
+
this.#active = false;
|
|
17265
|
+
throw error;
|
|
17266
|
+
}
|
|
17267
|
+
}
|
|
17268
|
+
#askLocally(questions, signal) {
|
|
17212
17269
|
return new Promise((resolve28, reject) => {
|
|
17213
17270
|
const onAbort = () => {
|
|
17214
17271
|
this.#pending = void 0;
|
|
17272
|
+
this.#active = false;
|
|
17215
17273
|
reject(signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason)));
|
|
17216
17274
|
};
|
|
17217
17275
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -17220,12 +17278,14 @@ var QuestionBridge = class {
|
|
|
17220
17278
|
resolve: (answers) => {
|
|
17221
17279
|
signal.removeEventListener("abort", onAbort);
|
|
17222
17280
|
this.#pending = void 0;
|
|
17281
|
+
this.#active = false;
|
|
17223
17282
|
this.#onChange?.();
|
|
17224
17283
|
resolve28(answers);
|
|
17225
17284
|
},
|
|
17226
17285
|
reject: (error) => {
|
|
17227
17286
|
signal.removeEventListener("abort", onAbort);
|
|
17228
17287
|
this.#pending = void 0;
|
|
17288
|
+
this.#active = false;
|
|
17229
17289
|
this.#onChange?.();
|
|
17230
17290
|
reject(error);
|
|
17231
17291
|
}
|
|
@@ -17311,7 +17371,7 @@ function createTodoWriteTool() {
|
|
|
17311
17371
|
}
|
|
17312
17372
|
|
|
17313
17373
|
// src/tools/managed.ts
|
|
17314
|
-
import { randomUUID as
|
|
17374
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
17315
17375
|
import { link as link2, lstat as lstat11, mkdir as mkdir17, readFile as readFile19, readdir as readdir8, unlink as unlink4, writeFile as writeFile10 } from "fs/promises";
|
|
17316
17376
|
import { dirname as dirname18, join as join21, resolve as resolve22 } from "path";
|
|
17317
17377
|
import { z as z31 } from "zod";
|
|
@@ -17598,7 +17658,7 @@ ${sourceUrl}`
|
|
|
17598
17658
|
}
|
|
17599
17659
|
async function writeExclusive(path, content) {
|
|
17600
17660
|
await mkdir17(dirname18(path), { recursive: true });
|
|
17601
|
-
const temporary = `${path}.${
|
|
17661
|
+
const temporary = `${path}.${randomUUID15()}.tmp`;
|
|
17602
17662
|
try {
|
|
17603
17663
|
await writeFile10(temporary, content, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
17604
17664
|
await link2(temporary, path);
|
|
@@ -19385,7 +19445,7 @@ function relativeDisplay(workspace, filePath) {
|
|
|
19385
19445
|
}
|
|
19386
19446
|
|
|
19387
19447
|
// src/jobs/registry.ts
|
|
19388
|
-
import { randomUUID as
|
|
19448
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
19389
19449
|
var JobRegistry = class {
|
|
19390
19450
|
#jobs = /* @__PURE__ */ new Map();
|
|
19391
19451
|
#maxOutputChars;
|
|
@@ -19399,7 +19459,7 @@ var JobRegistry = class {
|
|
|
19399
19459
|
}
|
|
19400
19460
|
create(input) {
|
|
19401
19461
|
this.#pruneCompleted();
|
|
19402
|
-
const id = `job-${
|
|
19462
|
+
const id = `job-${randomUUID16().slice(0, 12)}`;
|
|
19403
19463
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19404
19464
|
let settle;
|
|
19405
19465
|
const done = new Promise((resolve28) => {
|
|
@@ -19525,7 +19585,7 @@ function snapshot2(job) {
|
|
|
19525
19585
|
}
|
|
19526
19586
|
|
|
19527
19587
|
// src/terminal/service.ts
|
|
19528
|
-
import { randomUUID as
|
|
19588
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
19529
19589
|
import { createRequire as nodeCreateRequire } from "module";
|
|
19530
19590
|
import { isAbsolute as isAbsolute11, relative as relative19, resolve as resolve25, sep as sep19 } from "path";
|
|
19531
19591
|
var TerminalService = class {
|
|
@@ -19543,7 +19603,7 @@ var TerminalService = class {
|
|
|
19543
19603
|
open(input) {
|
|
19544
19604
|
const cwd = workspacePath(this.#root, input.cwd ?? ".");
|
|
19545
19605
|
const shell = input.shell ?? defaultShell();
|
|
19546
|
-
const id = `term-${
|
|
19606
|
+
const id = `term-${randomUUID17().slice(0, 12)}`;
|
|
19547
19607
|
const pty = this.#factory(shell, input.args ?? [], {
|
|
19548
19608
|
cwd,
|
|
19549
19609
|
cols: input.columns ?? 100,
|
|
@@ -19769,7 +19829,7 @@ function palSocketAddress(options) {
|
|
|
19769
19829
|
}
|
|
19770
19830
|
|
|
19771
19831
|
// src/pals/client.ts
|
|
19772
|
-
import { randomUUID as
|
|
19832
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
19773
19833
|
import { Socket as Socket3 } from "net";
|
|
19774
19834
|
var DEFAULT_REQUEST_TIMEOUT_MS = 5e3;
|
|
19775
19835
|
var DEFAULT_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -19845,7 +19905,7 @@ var PalClient = class {
|
|
|
19845
19905
|
return this.starting;
|
|
19846
19906
|
}
|
|
19847
19907
|
async list() {
|
|
19848
|
-
const data2 = await this.request({ version: 1, type: "list", requestId:
|
|
19908
|
+
const data2 = await this.request({ version: 1, type: "list", requestId: randomUUID18() });
|
|
19849
19909
|
return PalPresenceListSchema.parse(data2);
|
|
19850
19910
|
}
|
|
19851
19911
|
async rename(alias) {
|
|
@@ -19858,38 +19918,38 @@ var PalClient = class {
|
|
|
19858
19918
|
throw error;
|
|
19859
19919
|
}
|
|
19860
19920
|
}
|
|
19861
|
-
async sendTask(target, message2, messageId =
|
|
19862
|
-
const data2 = await this.request({ version: 1, type: "task", requestId:
|
|
19921
|
+
async sendTask(target, message2, messageId = randomUUID18()) {
|
|
19922
|
+
const data2 = await this.request({ version: 1, type: "task", requestId: randomUUID18(), messageId, target, goal: message2 });
|
|
19863
19923
|
return DeliveryReceiptSchema.parse(data2);
|
|
19864
19924
|
}
|
|
19865
|
-
async sendChat(target, message2, messageId =
|
|
19866
|
-
const data2 = await this.request({ version: 1, type: "chat", requestId:
|
|
19925
|
+
async sendChat(target, message2, messageId = randomUUID18()) {
|
|
19926
|
+
const data2 = await this.request({ version: 1, type: "chat", requestId: randomUUID18(), messageId, target, message: message2 });
|
|
19867
19927
|
return DeliveryReceiptSchema.parse(data2);
|
|
19868
19928
|
}
|
|
19869
19929
|
async startCoWork(input) {
|
|
19870
19930
|
const data2 = await this.request({
|
|
19871
19931
|
version: 1,
|
|
19872
19932
|
type: "cowork-propose",
|
|
19873
|
-
requestId:
|
|
19874
|
-
coWorkId: input.coWorkId ??
|
|
19933
|
+
requestId: randomUUID18(),
|
|
19934
|
+
coWorkId: input.coWorkId ?? randomUUID18(),
|
|
19875
19935
|
goal: input.goal,
|
|
19876
19936
|
participants: input.participants
|
|
19877
19937
|
});
|
|
19878
19938
|
return CoWorkSnapshotSchema.parse(data2);
|
|
19879
19939
|
}
|
|
19880
19940
|
async coWorkAction(action) {
|
|
19881
|
-
const request = { version: 1, requestId:
|
|
19941
|
+
const request = { version: 1, requestId: randomUUID18(), ...action };
|
|
19882
19942
|
return CoWorkSnapshotSchema.parse(await this.request(request));
|
|
19883
19943
|
}
|
|
19884
19944
|
async coWorkStatus(coWorkId) {
|
|
19885
|
-
const data2 = await this.request({ version: 1, type: "cowork-get", requestId:
|
|
19945
|
+
const data2 = await this.request({ version: 1, type: "cowork-get", requestId: randomUUID18(), coWorkId });
|
|
19886
19946
|
return CoWorkSnapshotSchema.parse(data2);
|
|
19887
19947
|
}
|
|
19888
19948
|
async integrateCoWork(input) {
|
|
19889
19949
|
return this.coWorkAction({ type: "cowork-integration", ...input });
|
|
19890
19950
|
}
|
|
19891
19951
|
async cancelCoWork(coWorkId, reason) {
|
|
19892
|
-
const data2 = await this.request({ version: 1, type: "cowork-cancel", requestId:
|
|
19952
|
+
const data2 = await this.request({ version: 1, type: "cowork-cancel", requestId: randomUUID18(), coWorkId, reason });
|
|
19893
19953
|
return CoWorkSnapshotSchema.parse(data2);
|
|
19894
19954
|
}
|
|
19895
19955
|
subscribe(listener) {
|
|
@@ -19901,7 +19961,7 @@ var PalClient = class {
|
|
|
19901
19961
|
if (this.registered && this.socket !== void 0) {
|
|
19902
19962
|
let disconnectTimer;
|
|
19903
19963
|
await Promise.race([
|
|
19904
|
-
this.request({ version: 1, type: "disconnect", requestId:
|
|
19964
|
+
this.request({ version: 1, type: "disconnect", requestId: randomUUID18() }).catch(() => void 0),
|
|
19905
19965
|
new Promise((resolve28) => {
|
|
19906
19966
|
disconnectTimer = setTimeout(resolve28, Math.min(this.requestTimeoutMs, 250));
|
|
19907
19967
|
})
|
|
@@ -19992,7 +20052,7 @@ var PalClient = class {
|
|
|
19992
20052
|
const data2 = await this.request({
|
|
19993
20053
|
version: 1,
|
|
19994
20054
|
type: "register",
|
|
19995
|
-
requestId:
|
|
20055
|
+
requestId: randomUUID18(),
|
|
19996
20056
|
authToken: this.authToken,
|
|
19997
20057
|
presence: { version: 1, ...this.registration, connectedAt: now, lastSeenAt: now }
|
|
19998
20058
|
});
|
|
@@ -20104,7 +20164,7 @@ var PalClient = class {
|
|
|
20104
20164
|
if (!this.registered) return;
|
|
20105
20165
|
if (this.heartbeatPending) return;
|
|
20106
20166
|
this.heartbeatPending = true;
|
|
20107
|
-
void this.request({ version: 1, type: "heartbeat", requestId:
|
|
20167
|
+
void this.request({ version: 1, type: "heartbeat", requestId: randomUUID18() }).catch(() => void 0).finally(() => {
|
|
20108
20168
|
this.heartbeatPending = false;
|
|
20109
20169
|
});
|
|
20110
20170
|
}, this.heartbeatIntervalMs);
|
|
@@ -20391,7 +20451,7 @@ var ApprovalBridge = class {
|
|
|
20391
20451
|
request(request, signal = new AbortController().signal) {
|
|
20392
20452
|
if (this.#settle !== void 0) return Promise.resolve("deny");
|
|
20393
20453
|
if (signal.aborted) return Promise.resolve("deny");
|
|
20394
|
-
this.#pending = { id:
|
|
20454
|
+
this.#pending = { id: randomUUID19(), ...request };
|
|
20395
20455
|
this.#onChange?.();
|
|
20396
20456
|
return new Promise((resolvePromise) => {
|
|
20397
20457
|
this.#settle = resolvePromise;
|
|
@@ -20510,7 +20570,14 @@ async function createProductionRuntime(options) {
|
|
|
20510
20570
|
environment.OPENAI_API_KEY,
|
|
20511
20571
|
environment.ANTHROPIC_API_KEY
|
|
20512
20572
|
].filter((value) => typeof value === "string" && value.length > 0);
|
|
20513
|
-
|
|
20573
|
+
let hookSessionId;
|
|
20574
|
+
const hooks = new HookBus({
|
|
20575
|
+
eventContext: () => ({
|
|
20576
|
+
protocolVersion: 2,
|
|
20577
|
+
workspace,
|
|
20578
|
+
...hookSessionId === void 0 ? {} : { sessionId: hookSessionId }
|
|
20579
|
+
})
|
|
20580
|
+
});
|
|
20514
20581
|
hooks.on(
|
|
20515
20582
|
"PostToolUseFailure",
|
|
20516
20583
|
createIncidentReporter({
|
|
@@ -20530,8 +20597,7 @@ async function createProductionRuntime(options) {
|
|
|
20530
20597
|
diagnostics.push(...permissionPolicy.diagnostics);
|
|
20531
20598
|
const approvals = new ApprovalBridge(options.onApprovalChange);
|
|
20532
20599
|
const resolveToolApproval = options.approvalPolicy === "deny" && options.rpcToolApprovals !== true ? () => "deny" : (request, signal) => approvals.request(request, signal);
|
|
20533
|
-
const
|
|
20534
|
-
const askUserQuestionHandler = async (qs, signal) => {
|
|
20600
|
+
const relayQuestions = async (qs, signal) => {
|
|
20535
20601
|
if (options.approvalPolicy === "deny") throw new Error("AskUserQuestion is not available in non-interactive mode");
|
|
20536
20602
|
if (hooks.hasListeners("PermissionRequest")) {
|
|
20537
20603
|
let decision;
|
|
@@ -20549,8 +20615,10 @@ async function createProductionRuntime(options) {
|
|
|
20549
20615
|
const hookAnswers = hookAnswersFromUpdatedInput(decision.updatedInput, qs);
|
|
20550
20616
|
if (hookAnswers !== void 0) return hookAnswers;
|
|
20551
20617
|
}
|
|
20552
|
-
return
|
|
20618
|
+
return void 0;
|
|
20553
20619
|
};
|
|
20620
|
+
const questions = new QuestionBridge(options.onApprovalChange, relayQuestions);
|
|
20621
|
+
const askUserQuestionHandler = (qs, signal) => questions.ask(qs, signal);
|
|
20554
20622
|
const executionEnvironment = createExecutionEnvironment(workspace, config.execution);
|
|
20555
20623
|
const jobs = new JobRegistry();
|
|
20556
20624
|
const terminals = new TerminalService(workspace, { jobs });
|
|
@@ -20874,7 +20942,8 @@ async function createProductionRuntime(options) {
|
|
|
20874
20942
|
let taskResults = { ...recovered?.tasks.results ?? {} };
|
|
20875
20943
|
const subagentStartedAt = {};
|
|
20876
20944
|
const subagentElapsedMs = {};
|
|
20877
|
-
let sessionId = recovered?.sessionId ?? `session-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${
|
|
20945
|
+
let sessionId = recovered?.sessionId ?? `session-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${randomUUID19().slice(0, 8)}`;
|
|
20946
|
+
hookSessionId = sessionId;
|
|
20878
20947
|
let harnessJournal = new HarnessJournal({ workspace, sessionId });
|
|
20879
20948
|
const harnessRecovery = harnessJournal.recover();
|
|
20880
20949
|
if (harnessRecovery.queue.length > 0 || harnessRecovery.incompleteTools.length > 0 || harnessRecovery.incompleteModelIds.length > 0 || harnessRecovery.interruptedTurnIds.length > 0) {
|
|
@@ -20958,7 +21027,13 @@ async function createProductionRuntime(options) {
|
|
|
20958
21027
|
const publishTaskState = async () => {
|
|
20959
21028
|
harness.main.context.updateTaskState(serializedTaskState());
|
|
20960
21029
|
await persist();
|
|
20961
|
-
|
|
21030
|
+
const snapshot4 = taskSnapshot();
|
|
21031
|
+
emitOutput({ type: "tasks", snapshot: snapshot4 });
|
|
21032
|
+
await hooks.emit({
|
|
21033
|
+
version: 1,
|
|
21034
|
+
type: "Notification",
|
|
21035
|
+
payload: { kind: "task_snapshot", taskSnapshot: snapshot4 }
|
|
21036
|
+
}).catch(() => void 0);
|
|
20962
21037
|
};
|
|
20963
21038
|
for (const tool of createTaskPlanTools({
|
|
20964
21039
|
getPlan: () => taskPlan,
|
|
@@ -21516,7 +21591,7 @@ async function createProductionRuntime(options) {
|
|
|
21516
21591
|
return answers[0] === "Continue" ? "approved" : "rejected";
|
|
21517
21592
|
},
|
|
21518
21593
|
fingerprint: workspaceFingerprint,
|
|
21519
|
-
idFactory: () => `loop-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${
|
|
21594
|
+
idFactory: () => `loop-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${randomUUID19().slice(0, 8)}`
|
|
21520
21595
|
});
|
|
21521
21596
|
const goalStore = new GoalStore({ workspace });
|
|
21522
21597
|
const goalOrchestrator = new GoalOrchestrator({
|
|
@@ -21535,7 +21610,7 @@ async function createProductionRuntime(options) {
|
|
|
21535
21610
|
executionEnvironment
|
|
21536
21611
|
),
|
|
21537
21612
|
now: () => (/* @__PURE__ */ new Date()).toISOString(),
|
|
21538
|
-
idFactory: () => `goal-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${
|
|
21613
|
+
idFactory: () => `goal-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${randomUUID19().slice(0, 8)}`,
|
|
21539
21614
|
runWorker: ({ workspace: goalWorkspace, prompt, signal }) => runLoopWorker({ workspace: goalWorkspace, prompt, signal })
|
|
21540
21615
|
});
|
|
21541
21616
|
let sessionHistory = await SessionHistory.open({
|
|
@@ -21648,7 +21723,7 @@ async function createProductionRuntime(options) {
|
|
|
21648
21723
|
runExplicitSkill(harness, skills, skill, prompt, signal, selectedModels.mainError),
|
|
21649
21724
|
persist
|
|
21650
21725
|
),
|
|
21651
|
-
runLoop: (goal, signal) => runLoopSession(loopOrchestrator, goal, signal),
|
|
21726
|
+
runLoop: (goal, signal) => runLoopSession(loopOrchestrator, hooks, goal, signal),
|
|
21652
21727
|
runGoal: (goal, signal) => persistEach(runGoalSession(goalOrchestrator, goal, signal), persist),
|
|
21653
21728
|
mcp: async (command, signal) => {
|
|
21654
21729
|
signal.throwIfAborted();
|
|
@@ -21806,7 +21881,8 @@ ${summary2}`;
|
|
|
21806
21881
|
for (const key of Object.keys(subagentStartedAt)) delete subagentStartedAt[key];
|
|
21807
21882
|
for (const key of Object.keys(subagentElapsedMs)) delete subagentElapsedMs[key];
|
|
21808
21883
|
const previousIdeSessionId = ideSessionId;
|
|
21809
|
-
sessionId = `session-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${
|
|
21884
|
+
sessionId = `session-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "").slice(0, 17)}-${randomUUID19().slice(0, 8)}`;
|
|
21885
|
+
hookSessionId = sessionId;
|
|
21810
21886
|
harnessJournal = new HarnessJournal({ workspace, sessionId });
|
|
21811
21887
|
setUsageSession(sessionId);
|
|
21812
21888
|
ideSessionId = sessionId;
|
|
@@ -22105,9 +22181,10 @@ function formatMcpReconnect(server) {
|
|
|
22105
22181
|
if (server.status === "disabled") return `MCP server "${server.name}" is disabled. Enable it before reconnecting.`;
|
|
22106
22182
|
return `Failed to reconnect MCP server "${server.name}": ${server.error ?? "unknown error"}`;
|
|
22107
22183
|
}
|
|
22108
|
-
async function* runLoopSession(orchestrator, goal, signal) {
|
|
22184
|
+
async function* runLoopSession(orchestrator, hooks, goal, signal) {
|
|
22109
22185
|
let totalInputTokens = 0;
|
|
22110
22186
|
let totalOutputTokens = 0;
|
|
22187
|
+
let latestVerification;
|
|
22111
22188
|
for await (const event of orchestrator.run({ goal, signal })) {
|
|
22112
22189
|
if (event.type === "worker-event") {
|
|
22113
22190
|
if (event.event.type === "usage") {
|
|
@@ -22121,8 +22198,19 @@ async function* runLoopSession(orchestrator, goal, signal) {
|
|
|
22121
22198
|
} else if (event.event.type !== "done") yield event.event;
|
|
22122
22199
|
continue;
|
|
22123
22200
|
}
|
|
22201
|
+
if (event.type === "loop-verification") latestVerification = event.evidence;
|
|
22124
22202
|
yield loopProgressEvent(event);
|
|
22125
22203
|
if (event.type === "loop-terminal") {
|
|
22204
|
+
await hooks.emit({
|
|
22205
|
+
version: 1,
|
|
22206
|
+
type: "LoopEnd",
|
|
22207
|
+
payload: {
|
|
22208
|
+
loopId: event.loopId,
|
|
22209
|
+
outcome: event.status,
|
|
22210
|
+
reason: event.reason,
|
|
22211
|
+
verification: latestVerification ?? null
|
|
22212
|
+
}
|
|
22213
|
+
}).catch(() => void 0);
|
|
22126
22214
|
yield { type: "done", usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens } };
|
|
22127
22215
|
}
|
|
22128
22216
|
}
|
|
@@ -22836,7 +22924,7 @@ function memoryTranscriptHash(messages) {
|
|
|
22836
22924
|
return createHash17("sha256").update(visible, "utf8").digest("hex");
|
|
22837
22925
|
}
|
|
22838
22926
|
function createMemoryTaskId() {
|
|
22839
|
-
return `memory-${
|
|
22927
|
+
return `memory-${randomUUID19()}`;
|
|
22840
22928
|
}
|
|
22841
22929
|
|
|
22842
22930
|
export {
|