@bastani/atomic 0.9.63 → 0.9.64

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.
@@ -558,6 +558,502 @@ var init_store_backend = __esm(() => {
558
558
  };
559
559
  });
560
560
 
561
+ // dist/builtin/workflows/src/runs/shared/prompt-callsite.ts
562
+ import { fileURLToPath } from "node:url";
563
+ function normalizeSlashes(path) {
564
+ return path.replace(/\\/g, "/");
565
+ }
566
+ function normalizeStackPath(framePath) {
567
+ let normalized = framePath;
568
+ if (normalized.startsWith("file://")) {
569
+ try {
570
+ normalized = fileURLToPath(normalized);
571
+ } catch {
572
+ try {
573
+ normalized = decodeURIComponent(new URL(normalized).pathname);
574
+ } catch {}
575
+ }
576
+ }
577
+ normalized = normalizeSlashes(normalized).replace(/^\/([A-Za-z]:\/)/, "$1");
578
+ return normalized;
579
+ }
580
+ function currentModuleRuntimeRoot() {
581
+ const modulePath = normalizeStackPath(fileURLToPath(import.meta.url));
582
+ const markers = ["packages/workflows/src/", ...PACKAGED_WORKFLOW_RUNTIME_ROOTS.map((root) => root.slice(1))];
583
+ for (const marker of markers) {
584
+ const index = modulePath.indexOf(marker);
585
+ if (index >= 0)
586
+ return modulePath.slice(0, index + marker.length);
587
+ }
588
+ return;
589
+ }
590
+ function isWorkflowRuntimeFrame(normalizedPath) {
591
+ const path = normalizeSlashes(normalizedPath);
592
+ if (path.startsWith("packages/workflows/src/"))
593
+ return true;
594
+ if (CURRENT_WORKFLOW_RUNTIME_ROOT !== undefined && path.startsWith(CURRENT_WORKFLOW_RUNTIME_ROOT)) {
595
+ return true;
596
+ }
597
+ const comparable = path.startsWith("/") ? path : `/${path}`;
598
+ return PACKAGED_WORKFLOW_RUNTIME_ROOTS.some((runtimeRoot) => comparable.includes(runtimeRoot));
599
+ }
600
+ function parsePromptStackFrame(stackLine) {
601
+ const line = stackLine.trim();
602
+ if (line.length === 0)
603
+ return;
604
+ if (line.includes("node:internal") || line.includes("bun:") || line.includes("(native:"))
605
+ return;
606
+ const match = line.match(/(\S+):(\d+):(\d+)\)?$/);
607
+ if (!match)
608
+ return;
609
+ const [, rawFramePath, lineNumber, columnNumber] = match;
610
+ if (rawFramePath === undefined || lineNumber === undefined || columnNumber === undefined)
611
+ return;
612
+ const normalizedPath = normalizeStackPath(rawFramePath.replace(/^\(/, ""));
613
+ return { normalizedPath, lineNumber, columnNumber };
614
+ }
615
+ function normalizedPromptCallsiteFrame(stackLine) {
616
+ const frame = parsePromptStackFrame(stackLine);
617
+ if (frame === undefined)
618
+ return;
619
+ if (isWorkflowRuntimeFrame(frame.normalizedPath))
620
+ return;
621
+ return `${frame.normalizedPath}:${frame.lineNumber}:${frame.columnNumber}`;
622
+ }
623
+ function selectPromptCallsiteFrame(stack) {
624
+ return stack.split(`
625
+ `).slice(1).map(normalizedPromptCallsiteFrame).find((candidate) => candidate !== undefined);
626
+ }
627
+ var PACKAGED_WORKFLOW_RUNTIME_ROOTS, CURRENT_WORKFLOW_RUNTIME_ROOT;
628
+ var init_prompt_callsite = __esm(() => {
629
+ PACKAGED_WORKFLOW_RUNTIME_ROOTS = ["/dist/builtin/workflows/src/"];
630
+ CURRENT_WORKFLOW_RUNTIME_ROOT = currentModuleRuntimeRoot();
631
+ });
632
+
633
+ // dist/builtin/workflows/src/shared/workflow-source.ts
634
+ function isWorkflowRuntimeModule(path) {
635
+ const normalized = normalizeStackPath(path);
636
+ return normalized === OWN_MODULE_PATH || isWorkflowRuntimeFrame(normalized);
637
+ }
638
+ function recordWorkflowSource(definition, path) {
639
+ WORKFLOW_SOURCES.set(definition, path);
640
+ }
641
+ function workflowSource(definition) {
642
+ return WORKFLOW_SOURCES.get(definition);
643
+ }
644
+ var WORKFLOW_SOURCES, OWN_MODULE_PATH;
645
+ var init_workflow_source = __esm(() => {
646
+ init_prompt_callsite();
647
+ WORKFLOW_SOURCES = new WeakMap;
648
+ OWN_MODULE_PATH = normalizeStackPath(import.meta.url);
649
+ });
650
+
651
+ // dist/builtin/workflows/src/engine/run-rejection-boundary.ts
652
+ import { AsyncLocalStorage } from "node:async_hooks";
653
+ import { inspect } from "node:util";
654
+ import { isStaleExtensionContextError } from "@bastani/atomic";
655
+ function boundaryBag() {
656
+ return globalThis;
657
+ }
658
+ function sharedBoundary() {
659
+ const bag = boundaryBag();
660
+ const existing = bag[BOUNDARY_KEY];
661
+ if (existing !== undefined && existing.version === 5)
662
+ return existing;
663
+ const created = {
664
+ version: 5,
665
+ store: new AsyncLocalStorage,
666
+ owners: new WeakMap,
667
+ promises: new WeakMap,
668
+ scopes: new Set,
669
+ runs: new Map,
670
+ ended: new Map,
671
+ stops: new Set,
672
+ listener: undefined
673
+ };
674
+ bag[BOUNDARY_KEY] = created;
675
+ return created;
676
+ }
677
+ function isObject(value2) {
678
+ return typeof value2 === "object" && value2 !== null || typeof value2 === "function";
679
+ }
680
+ function isPrimitive(value2) {
681
+ return !isObject(value2);
682
+ }
683
+ function safeField(value2, key) {
684
+ try {
685
+ return value2[key];
686
+ } catch {
687
+ return;
688
+ }
689
+ }
690
+ function strongerEffect(left, right) {
691
+ return left === "fail-run" || right === "fail-run" ? "fail-run" : "ignore";
692
+ }
693
+ function addAttribution(into, scope, effect) {
694
+ into.set(scope, strongerEffect(into.get(scope), effect));
695
+ }
696
+ function recordedOwners(boundary, reason) {
697
+ const owners = new Map;
698
+ let stopped = false;
699
+ const seen = new Set;
700
+ const pending = [{ value: reason, depth: 0 }];
701
+ while (pending.length > 0) {
702
+ const { value: value2, depth } = pending.pop();
703
+ if (depth > MAX_CAUSE_DEPTH)
704
+ continue;
705
+ if (isPrimitive(value2)) {
706
+ if (depth === 0 || value2 !== undefined && value2 !== null) {
707
+ for (const scope of boundary.scopes) {
708
+ const entry = scope.primitives.get(value2);
709
+ if (entry !== undefined)
710
+ addAttribution(owners, scope, entry.effect);
711
+ }
712
+ if (typeof value2 === "string" && boundary.stops.has(value2))
713
+ stopped = true;
714
+ }
715
+ continue;
716
+ }
717
+ if (seen.has(value2))
718
+ continue;
719
+ seen.add(value2);
720
+ for (const [scope, effect] of boundary.owners.get(value2) ?? [])
721
+ addAttribution(owners, scope, effect);
722
+ pending.push({ value: safeField(value2, "cause"), depth: depth + 1 });
723
+ const errors = safeField(value2, "errors");
724
+ if (Array.isArray(errors))
725
+ for (const entry of errors)
726
+ pending.push({ value: entry, depth: depth + 1 });
727
+ }
728
+ return { owners, stopped };
729
+ }
730
+ function pruneEndedSources(boundary) {
731
+ const now = Date.now();
732
+ for (const [source, trees] of boundary.ended) {
733
+ for (const [rootRunId, endedAt] of trees)
734
+ if (now - endedAt > ENDED_RUN_GRACE_MS)
735
+ trees.delete(rootRunId);
736
+ if (trees.size === 0)
737
+ boundary.ended.delete(source);
738
+ }
739
+ }
740
+ function recordEndedRun(boundary, scope) {
741
+ if (scope.source === undefined)
742
+ return;
743
+ const trees = boundary.ended.get(scope.source) ?? new Map;
744
+ trees.set(scope.rootRunId, Date.now());
745
+ boundary.ended.set(scope.source, trees);
746
+ }
747
+ function endedInAnotherRunTree(boundary, source, live) {
748
+ for (const endedRoot of boundary.ended.get(source)?.keys() ?? [])
749
+ if (endedRoot !== live.rootRunId)
750
+ return true;
751
+ return false;
752
+ }
753
+ function recognizedSources(boundary) {
754
+ pruneEndedSources(boundary);
755
+ const sources = new Set(boundary.ended.keys());
756
+ for (const scope of boundary.scopes)
757
+ if (scope.live && scope.source !== undefined)
758
+ sources.add(scope.source);
759
+ return sources;
760
+ }
761
+ function authoringSource(reason, sources) {
762
+ if (sources.size === 0 || !isObject(reason))
763
+ return;
764
+ const stack = safeField(reason, "stack");
765
+ if (typeof stack !== "string")
766
+ return;
767
+ for (const line of stack.split(`
768
+ `)) {
769
+ if (!line.trimStart().startsWith("at "))
770
+ continue;
771
+ const path = parsePromptStackFrame(line)?.normalizedPath;
772
+ if (path === undefined)
773
+ continue;
774
+ if (isWorkflowRuntimeModule(path))
775
+ return;
776
+ if (/\/node_modules\//.test(path))
777
+ continue;
778
+ if (sources.has(path))
779
+ return path;
780
+ }
781
+ return;
782
+ }
783
+ function hasAncestorIn(scope, candidates) {
784
+ for (let ancestor = scope.parent;ancestor !== undefined; ancestor = ancestor.parent) {
785
+ if (candidates.has(ancestor))
786
+ return true;
787
+ }
788
+ return false;
789
+ }
790
+ function outermostLiveRuns(boundary, source) {
791
+ const matching = new Set;
792
+ for (const scope of boundary.scopes)
793
+ if (scope.live && scope.source === source)
794
+ matching.add(scope);
795
+ const outermost = new Set;
796
+ for (const scope of matching)
797
+ if (!hasAncestorIn(scope, matching))
798
+ outermost.add(scope);
799
+ return outermost;
800
+ }
801
+ function runOfSource(boundary, source) {
802
+ const [only, ...others] = outermostLiveRuns(boundary, source);
803
+ if (only === undefined)
804
+ return new Map;
805
+ if (others.length > 0 || only.sharedSource)
806
+ return;
807
+ if (endedInAnotherRunTree(boundary, source, only))
808
+ return;
809
+ return new Map([[only, "fail-run"]]);
810
+ }
811
+ function markSharedSource(boundary, source) {
812
+ const runs = outermostLiveRuns(boundary, source);
813
+ if (runs.size > 1)
814
+ for (const run of runs)
815
+ run.sharedSource = true;
816
+ }
817
+ function rejectingRun(boundary, recorded, promise, scoped) {
818
+ const tracked = promise === undefined ? undefined : boundary.promises.get(promise);
819
+ if (tracked !== undefined && recorded.has(tracked))
820
+ return tracked;
821
+ if (scoped !== undefined && recorded.has(scoped))
822
+ return scoped;
823
+ return;
824
+ }
825
+ function attribute(boundary, reason, promise) {
826
+ const { owners: recorded, stopped } = recordedOwners(boundary, reason);
827
+ const scoped = boundary.store.getStore();
828
+ if (recorded.size > 1) {
829
+ const rejecting = rejectingRun(boundary, recorded, promise, scoped);
830
+ if (rejecting !== undefined)
831
+ return new Map([[rejecting, recorded.get(rejecting) ?? "fail-run"]]);
832
+ }
833
+ if (recorded.size > 0)
834
+ return recorded;
835
+ if (stopped)
836
+ return new Map;
837
+ if (scoped !== undefined && boundary.scopes.has(scoped))
838
+ return new Map([[scoped, "fail-run"]]);
839
+ const origin = authoringSource(reason, recognizedSources(boundary));
840
+ if (origin === undefined)
841
+ return;
842
+ if (scoped !== undefined)
843
+ return new Map([[scoped, "ignore"]]);
844
+ return runOfSource(boundary, origin);
845
+ }
846
+ function unhandledRejectionError(reason) {
847
+ return Object.assign(new Error("This error originated either by throwing inside of an async function without a catch block, " + `or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "${inspect(reason)}".`), { code: "ERR_UNHANDLED_REJECTION" });
848
+ }
849
+ function unhandledRejectionsMode() {
850
+ const args = [...(process.env.NODE_OPTIONS ?? "").split(/\s+/), ...process.execArgv];
851
+ let mode = "throw";
852
+ for (let index = 0;index < args.length; index += 1) {
853
+ const arg = args[index] ?? "";
854
+ if (arg.startsWith(`${FLAG}=`))
855
+ mode = arg.slice(FLAG.length + 1);
856
+ else if (arg === FLAG && args[index + 1] !== undefined)
857
+ mode = args[index + 1] ?? mode;
858
+ }
859
+ return mode;
860
+ }
861
+ function surfaceNatively(boundary, reason) {
862
+ const listener = boundary.listener;
863
+ if (listener === undefined || process.listenerCount(EVENT) > 1)
864
+ return;
865
+ if (!NATIVE_REPORTING_MODES.has(unhandledRejectionsMode()))
866
+ return;
867
+ process.nextTick(() => {
868
+ process.removeListener(EVENT, listener);
869
+ Promise.reject(reason);
870
+ setImmediate(() => {
871
+ if (!process.listeners(EVENT).includes(listener))
872
+ process.on(EVENT, listener);
873
+ });
874
+ });
875
+ }
876
+ function onUnhandledRejection(reason, promise) {
877
+ const boundary = sharedBoundary();
878
+ const owners = attribute(boundary, reason, promise);
879
+ if (owners === undefined) {
880
+ surfaceNatively(boundary, reason);
881
+ return;
882
+ }
883
+ const error = isObject(reason) ? reason : unhandledRejectionError(reason);
884
+ const staleExtensionContext = isStaleExtensionContextError(error);
885
+ for (const [scope, effect] of owners) {
886
+ if (effect !== "fail-run" || !scope.live)
887
+ continue;
888
+ if (staleExtensionContext) {
889
+ console.error(`atomic-workflows: run ${scope.runId} ignored a stale extension-context rejection`, error);
890
+ continue;
891
+ }
892
+ try {
893
+ scope.fail(error);
894
+ } catch {}
895
+ }
896
+ }
897
+ function ensureInstalled(boundary) {
898
+ if (boundary.listener !== undefined)
899
+ return;
900
+ boundary.listener = onUnhandledRejection;
901
+ process.on(EVENT, onUnhandledRejection);
902
+ }
903
+ function record(boundary, scope, reason, effect) {
904
+ if (isPrimitive(reason)) {
905
+ recordPrimitive(scope, reason, effect);
906
+ return;
907
+ }
908
+ const owners = boundary.owners.get(reason);
909
+ if (owners === undefined)
910
+ boundary.owners.set(reason, new Map([[scope, effect]]));
911
+ else
912
+ addAttribution(owners, scope, effect);
913
+ }
914
+ function recordStop(boundary, reason) {
915
+ boundary.stops.delete(reason);
916
+ boundary.stops.add(reason);
917
+ if (boundary.stops.size <= MAX_STOP_STRINGS)
918
+ return;
919
+ const oldest = boundary.stops.values().next();
920
+ if (!oldest.done)
921
+ boundary.stops.delete(oldest.value);
922
+ }
923
+ function recordPrimitive(scope, reason, effect) {
924
+ if (!scope.live)
925
+ return;
926
+ if (scope.primitives.size >= MAX_PRIMITIVES_PER_RUN && !scope.primitives.has(reason)) {
927
+ const oldest = scope.primitives.keys().next();
928
+ if (!oldest.done)
929
+ scope.primitives.delete(oldest.value);
930
+ }
931
+ scope.generation += 1;
932
+ const generation = scope.generation;
933
+ scope.primitives.set(reason, { effect: strongerEffect(scope.primitives.get(reason)?.effect, effect), generation });
934
+ afterPendingRejectionReports().then(() => {
935
+ if (scope.primitives.get(reason)?.generation === generation)
936
+ scope.primitives.delete(reason);
937
+ });
938
+ }
939
+ function discardFailure() {}
940
+ function afterPendingRejectionReports() {
941
+ return new Promise((resolve) => {
942
+ const { port1, port2 } = new MessageChannel;
943
+ port1.onmessage = () => {
944
+ port1.close();
945
+ port2.close();
946
+ resolve();
947
+ };
948
+ port2.postMessage(undefined);
949
+ });
950
+ }
951
+ function currentRunConsole() {
952
+ return sharedBoundary().store.getStore()?.console;
953
+ }
954
+ function openRunRejectionScope(options) {
955
+ const boundary = sharedBoundary();
956
+ ensureInstalled(boundary);
957
+ pruneEndedSources(boundary);
958
+ const parent = options.parentRunId === undefined ? undefined : boundary.runs.get(options.parentRunId);
959
+ const rootRunId = parent?.rootRunId ?? options.runId;
960
+ const scope = {
961
+ runId: options.runId,
962
+ rootRunId,
963
+ source: options.source === undefined ? undefined : normalizeStackPath(options.source),
964
+ parent,
965
+ fail: options.fail,
966
+ primitives: new Map,
967
+ generation: 0,
968
+ live: true,
969
+ sharedSource: false,
970
+ console: parent !== undefined ? parent.console : options.consoleLog === true ? { rootRunId, bytes: 0, capped: false, announced: false } : undefined
971
+ };
972
+ boundary.scopes.add(scope);
973
+ boundary.runs.set(scope.runId, scope);
974
+ if (scope.source !== undefined)
975
+ markSharedSource(boundary, scope.source);
976
+ return {
977
+ run: (callback) => boundary.store.run(scope, callback),
978
+ contain: (promise, effect = "fail-run") => {
979
+ boundary.promises.set(promise, scope);
980
+ promise.then(undefined, (reason) => record(boundary, scope, reason, effect));
981
+ return promise;
982
+ },
983
+ watch: (promise) => {
984
+ const watched = promise.then(undefined, (reason) => {
985
+ record(boundary, scope, reason, "fail-run");
986
+ throw reason;
987
+ });
988
+ boundary.promises.set(watched, scope);
989
+ return watched;
990
+ },
991
+ ignore: (reason) => {
992
+ if (typeof reason === "string")
993
+ recordStop(boundary, reason);
994
+ else
995
+ record(boundary, scope, reason, "ignore");
996
+ },
997
+ settle: afterPendingRejectionReports,
998
+ close: () => {
999
+ scope.live = false;
1000
+ scope.fail = discardFailure;
1001
+ recordEndedRun(boundary, scope);
1002
+ afterPendingRejectionReports().then(() => {
1003
+ scope.primitives.clear();
1004
+ scope.parent = undefined;
1005
+ boundary.scopes.delete(scope);
1006
+ if (boundary.runs.get(scope.runId) === scope)
1007
+ boundary.runs.delete(scope.runId);
1008
+ });
1009
+ }
1010
+ };
1011
+ }
1012
+ function containStageRejections(stage, scope) {
1013
+ const contained = Object.create(stage);
1014
+ const descriptors = {};
1015
+ for (const name of WATCHED_STAGE_METHODS) {
1016
+ descriptors[name] = {
1017
+ value: (...args) => {
1018
+ const result = Reflect.apply(stage[name], stage, args);
1019
+ return result instanceof Promise ? scope.watch(result) : result;
1020
+ }
1021
+ };
1022
+ }
1023
+ Object.defineProperties(contained, descriptors);
1024
+ return contained;
1025
+ }
1026
+ function containUiRejections(ui, scope) {
1027
+ return {
1028
+ input: (prompt) => scope.watch(ui.input(prompt)),
1029
+ confirm: (message) => scope.watch(ui.confirm(message)),
1030
+ select: (message, options) => scope.watch(ui.select(message, options)),
1031
+ editor: (initial) => scope.watch(ui.editor(initial)),
1032
+ custom: (factory, options) => scope.watch(ui.custom(factory, options))
1033
+ };
1034
+ }
1035
+ var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections", MAX_CAUSE_DEPTH = 8, MAX_PRIMITIVES_PER_RUN = 64, MAX_STOP_STRINGS = 64, ENDED_RUN_GRACE_MS = 30000, NATIVE_REPORTING_MODES, WATCHED_STAGE_METHODS;
1036
+ var init_run_rejection_boundary = __esm(() => {
1037
+ init_prompt_callsite();
1038
+ init_workflow_source();
1039
+ BOUNDARY_KEY = Symbol.for("atomic-workflows/run-rejection-boundary@5");
1040
+ NATIVE_REPORTING_MODES = new Set(["throw", "warn-with-error-code"]);
1041
+ WATCHED_STAGE_METHODS = [
1042
+ "prompt",
1043
+ "complete",
1044
+ "sendUserMessage",
1045
+ "steer",
1046
+ "followUp",
1047
+ "setModel",
1048
+ "setThinkingLevel",
1049
+ "cycleModel",
1050
+ "cycleThinkingLevel",
1051
+ "navigateTree",
1052
+ "compact",
1053
+ "abort"
1054
+ ];
1055
+ });
1056
+
561
1057
  // dist/builtin/workflows/src/shared/flat-string.ts
562
1058
  function flattenTruncatedString(value2) {
563
1059
  return value2.split("").join("");
@@ -5419,32 +5915,36 @@ var init_workflow_tool_abort = __esm(() => {
5419
5915
  });
5420
5916
 
5421
5917
  // dist/builtin/workflows/src/engine/run-tool-control-registry.ts
5918
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
5422
5919
  function createToolControlRegistry() {
5423
5920
  const byRun = new Map;
5424
5921
  const admissionByRun = new Map;
5425
5922
  const runControls = new Map;
5426
- const makeHandle = (registration) => ({
5427
- runId: registration.runId,
5428
- nodeId: registration.nodeId,
5429
- name: registration.name,
5430
- settled: registration.settled,
5431
- get aborted() {
5432
- return registration.controller.signal.aborted;
5433
- },
5434
- abort(scope) {
5435
- const existing = registration.controller.signal.reason;
5436
- if (registration.controller.signal.aborted && existing instanceof WorkflowToolAbortError)
5437
- return existing;
5438
- const reason = new WorkflowToolAbortError({
5439
- runId: registration.runId,
5440
- nodeId: registration.nodeId,
5441
- toolName: registration.name,
5442
- scope
5443
- });
5444
- registration.controller.abort(reason);
5445
- return reason;
5446
- }
5447
- });
5923
+ const makeHandle = (registration) => {
5924
+ const inRegisteringContext = AsyncLocalStorage2.snapshot();
5925
+ return {
5926
+ runId: registration.runId,
5927
+ nodeId: registration.nodeId,
5928
+ name: registration.name,
5929
+ settled: registration.settled,
5930
+ get aborted() {
5931
+ return registration.controller.signal.aborted;
5932
+ },
5933
+ abort(scope) {
5934
+ const existing = registration.controller.signal.reason;
5935
+ if (registration.controller.signal.aborted && existing instanceof WorkflowToolAbortError)
5936
+ return existing;
5937
+ const reason = new WorkflowToolAbortError({
5938
+ runId: registration.runId,
5939
+ nodeId: registration.nodeId,
5940
+ toolName: registration.name,
5941
+ scope
5942
+ });
5943
+ inRegisteringContext(() => registration.controller.abort(reason));
5944
+ return reason;
5945
+ }
5946
+ };
5947
+ };
5448
5948
  return {
5449
5949
  register(registration) {
5450
5950
  let runMap = byRun.get(registration.runId);
@@ -5956,11 +6456,11 @@ function canonicalJsonString(value2) {
5956
6456
  var init_durable_hash = () => {};
5957
6457
 
5958
6458
  // dist/builtin/workflows/src/durable/backend.ts
5959
- import { closeSync, openSync, readSync } from "node:fs";
6459
+ import { closeSync as closeSync2, openSync as openSync2, readSync } from "node:fs";
5960
6460
  function readSessionHeaderId(sessionFile) {
5961
6461
  let fd;
5962
6462
  try {
5963
- fd = openSync(sessionFile, "r");
6463
+ fd = openSync2(sessionFile, "r");
5964
6464
  } catch {
5965
6465
  return;
5966
6466
  }
@@ -5974,7 +6474,7 @@ function readSessionHeaderId(sessionFile) {
5974
6474
  } catch {
5975
6475
  return;
5976
6476
  } finally {
5977
- closeSync(fd);
6477
+ closeSync2(fd);
5978
6478
  }
5979
6479
  }
5980
6480
  function migrateStageSessionCheckpoint(checkpoint) {
@@ -6740,96 +7240,6 @@ function resolve_budget(layers) {
6740
7240
  // dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts
6741
7241
  var DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15, WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
6742
7242
 
6743
- // dist/builtin/workflows/src/runs/shared/prompt-callsite.ts
6744
- import { fileURLToPath } from "node:url";
6745
- function normalizeSlashes(path) {
6746
- return path.replace(/\\/g, "/");
6747
- }
6748
- function normalizeStackPath(framePath) {
6749
- let normalized = framePath;
6750
- if (normalized.startsWith("file://")) {
6751
- try {
6752
- normalized = fileURLToPath(normalized);
6753
- } catch {
6754
- try {
6755
- normalized = decodeURIComponent(new URL(normalized).pathname);
6756
- } catch {}
6757
- }
6758
- }
6759
- normalized = normalizeSlashes(normalized).replace(/^\/([A-Za-z]:\/)/, "$1");
6760
- return normalized;
6761
- }
6762
- function currentModuleRuntimeRoot() {
6763
- const modulePath = normalizeStackPath(fileURLToPath(import.meta.url));
6764
- const markers = ["packages/workflows/src/", ...PACKAGED_WORKFLOW_RUNTIME_ROOTS.map((root) => root.slice(1))];
6765
- for (const marker of markers) {
6766
- const index = modulePath.indexOf(marker);
6767
- if (index >= 0)
6768
- return modulePath.slice(0, index + marker.length);
6769
- }
6770
- return;
6771
- }
6772
- function isWorkflowRuntimeFrame(normalizedPath) {
6773
- const path = normalizeSlashes(normalizedPath);
6774
- if (path.startsWith("packages/workflows/src/"))
6775
- return true;
6776
- if (CURRENT_WORKFLOW_RUNTIME_ROOT !== undefined && path.startsWith(CURRENT_WORKFLOW_RUNTIME_ROOT)) {
6777
- return true;
6778
- }
6779
- const comparable = path.startsWith("/") ? path : `/${path}`;
6780
- return PACKAGED_WORKFLOW_RUNTIME_ROOTS.some((runtimeRoot) => comparable.includes(runtimeRoot));
6781
- }
6782
- function parsePromptStackFrame(stackLine) {
6783
- const line = stackLine.trim();
6784
- if (line.length === 0)
6785
- return;
6786
- if (line.includes("node:internal") || line.includes("bun:") || line.includes("(native:"))
6787
- return;
6788
- const match = line.match(/(\S+):(\d+):(\d+)\)?$/);
6789
- if (!match)
6790
- return;
6791
- const [, rawFramePath, lineNumber, columnNumber] = match;
6792
- if (rawFramePath === undefined || lineNumber === undefined || columnNumber === undefined)
6793
- return;
6794
- const normalizedPath = normalizeStackPath(rawFramePath.replace(/^\(/, ""));
6795
- return { normalizedPath, lineNumber, columnNumber };
6796
- }
6797
- function normalizedPromptCallsiteFrame(stackLine) {
6798
- const frame = parsePromptStackFrame(stackLine);
6799
- if (frame === undefined)
6800
- return;
6801
- if (isWorkflowRuntimeFrame(frame.normalizedPath))
6802
- return;
6803
- return `${frame.normalizedPath}:${frame.lineNumber}:${frame.columnNumber}`;
6804
- }
6805
- function selectPromptCallsiteFrame(stack) {
6806
- return stack.split(`
6807
- `).slice(1).map(normalizedPromptCallsiteFrame).find((candidate) => candidate !== undefined);
6808
- }
6809
- var PACKAGED_WORKFLOW_RUNTIME_ROOTS, CURRENT_WORKFLOW_RUNTIME_ROOT;
6810
- var init_prompt_callsite = __esm(() => {
6811
- PACKAGED_WORKFLOW_RUNTIME_ROOTS = ["/dist/builtin/workflows/src/"];
6812
- CURRENT_WORKFLOW_RUNTIME_ROOT = currentModuleRuntimeRoot();
6813
- });
6814
-
6815
- // dist/builtin/workflows/src/shared/workflow-source.ts
6816
- function isWorkflowRuntimeModule(path) {
6817
- const normalized = normalizeStackPath(path);
6818
- return normalized === OWN_MODULE_PATH || isWorkflowRuntimeFrame(normalized);
6819
- }
6820
- function recordWorkflowSource(definition, path) {
6821
- WORKFLOW_SOURCES.set(definition, path);
6822
- }
6823
- function workflowSource(definition) {
6824
- return WORKFLOW_SOURCES.get(definition);
6825
- }
6826
- var WORKFLOW_SOURCES, OWN_MODULE_PATH;
6827
- var init_workflow_source = __esm(() => {
6828
- init_prompt_callsite();
6829
- WORKFLOW_SOURCES = new WeakMap;
6830
- OWN_MODULE_PATH = normalizeStackPath(import.meta.url);
6831
- });
6832
-
6833
7243
  // dist/builtin/workflows/src/workflows/identity.ts
6834
7244
  function normalizeWorkflowName(name) {
6835
7245
  if (!name || typeof name !== "string") {
@@ -7879,7 +8289,7 @@ var init_legacy_journal_tables = __esm(() => {
7879
8289
  });
7880
8290
 
7881
8291
  // dist/builtin/workflows/src/durable/journal/sql-run-journal.ts
7882
- import { AsyncLocalStorage } from "node:async_hooks";
8292
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
7883
8293
  import {
7884
8294
  assertStorageSchemaVersion,
7885
8295
  renderStorageIdentifiers as renderStorageIdentifiers2,
@@ -7905,7 +8315,7 @@ class SqlRunJournal {
7905
8315
  database;
7906
8316
  tables;
7907
8317
  legacy;
7908
- appendGuard = new AsyncLocalStorage;
8318
+ appendGuard = new AsyncLocalStorage3;
7909
8319
  constructor(database, tables, legacy) {
7910
8320
  this.database = database;
7911
8321
  this.tables = tables;
@@ -8395,7 +8805,7 @@ var init_sql_run_journal = __esm(() => {
8395
8805
  });
8396
8806
 
8397
8807
  // dist/builtin/workflows/src/durable/journal/resolution.ts
8398
- import { dirname as dirname2, isAbsolute, join } from "node:path";
8808
+ import { dirname as dirname2, isAbsolute, join as join2 } from "node:path";
8399
8809
  import { getAgentDir, selectProcessStorage } from "@bastani/atomic";
8400
8810
  import {
8401
8811
  StorageConfigError,
@@ -8407,7 +8817,7 @@ function provideRunJournalHostModules(modules) {
8407
8817
  }
8408
8818
  function selectRunJournal(options = {}) {
8409
8819
  const agentDir = options.agentDir ?? getAgentDir();
8410
- const defaultPath = join(dirname2(agentDir), "workflows", "journal.sqlite");
8820
+ const defaultPath = join2(dirname2(agentDir), "workflows", "journal.sqlite");
8411
8821
  if (options.journal !== undefined) {
8412
8822
  if (options.journal !== null && typeof options.journal === "object" && "createRun" in options.journal) {
8413
8823
  const journal = options.journal;
@@ -8444,8 +8854,8 @@ function selectRunJournal(options = {}) {
8444
8854
  const value2 = journal !== undefined ? journal : options.settings?.storage;
8445
8855
  if (value2 === undefined)
8446
8856
  return { kind: "sqlite", path: defaultPath };
8447
- const selection = selectStorage(value2, "settings", journal !== undefined ? "workflows.journal" : "storage", journal !== undefined ? defaultPath : join(dirname2(agentDir), "storage.sqlite"));
8448
- const resolved = selection.kind === "sqlite" && !isAbsolute(selection.path) ? { ...selection, path: join(dirname2(agentDir), selection.path) } : selection;
8857
+ const selection = selectStorage(value2, "settings", journal !== undefined ? "workflows.journal" : "storage", journal !== undefined ? defaultPath : join2(dirname2(agentDir), "storage.sqlite"));
8858
+ const resolved = selection.kind === "sqlite" && !isAbsolute(selection.path) ? { ...selection, path: join2(dirname2(agentDir), selection.path) } : selection;
8449
8859
  origins.set(resolved, { source: "settings" });
8450
8860
  return resolved;
8451
8861
  }
@@ -8496,11 +8906,11 @@ var init_resolution = __esm(() => {
8496
8906
  });
8497
8907
 
8498
8908
  // dist/builtin/workflows/src/durable/journal/sqlite-run-journal.ts
8499
- import { dirname as dirname3, join as join2 } from "node:path";
8909
+ import { dirname as dirname3, join as join3 } from "node:path";
8500
8910
  import { getAgentDir as getAgentDir2, openNodeSqliteDatabase, validateStoragePrefix, wrapNodeSqliteDatabase } from "@bastani/atomic";
8501
8911
  function workflowJournalPath() {
8502
8912
  const override = process.env.ATOMIC_WORKFLOW_JOURNAL_PATH;
8503
- return override !== undefined && override.length > 0 ? override : join2(dirname3(getAgentDir2()), "workflows", "journal.sqlite");
8913
+ return override !== undefined && override.length > 0 ? override : join3(dirname3(getAgentDir2()), "workflows", "journal.sqlite");
8504
8914
  }
8505
8915
  async function openSqlRunJournal(source = workflowJournalPath(), options = {}) {
8506
8916
  validateStoragePrefix(options.prefix);
@@ -8629,7 +9039,7 @@ function asRecord(value2) {
8629
9039
  function field(value2, key) {
8630
9040
  return asRecord(value2)?.[key];
8631
9041
  }
8632
- function safeField(value2, key) {
9042
+ function safeField2(value2, key) {
8633
9043
  try {
8634
9044
  return field(value2, key);
8635
9045
  } catch {
@@ -8655,26 +9065,26 @@ function findProcessFailureError(value2, seen, depth) {
8655
9065
  if (value2 === null || typeof value2 !== "object" || depth >= 8 || seen.has(value2))
8656
9066
  return;
8657
9067
  seen.add(value2);
8658
- if (nonZeroExitCode(safeField(value2, "exitCode")))
9068
+ if (nonZeroExitCode(safeField2(value2, "exitCode")))
8659
9069
  return value2;
8660
- if (nonEmptyProcessOutput(safeField(value2, "stdout")))
9070
+ if (nonEmptyProcessOutput(safeField2(value2, "stdout")))
8661
9071
  return value2;
8662
- if (nonEmptyProcessOutput(safeField(value2, "stderr")))
9072
+ if (nonEmptyProcessOutput(safeField2(value2, "stderr")))
8663
9073
  return value2;
8664
9074
  for (const key of ["cause", "error", "response", "body"]) {
8665
- const selected = findProcessFailureError(safeField(value2, key), seen, depth + 1);
9075
+ const selected = findProcessFailureError(safeField2(value2, key), seen, depth + 1);
8666
9076
  if (selected !== undefined)
8667
9077
  return selected;
8668
9078
  }
8669
- const diagnostics = safeField(value2, "diagnostics");
9079
+ const diagnostics = safeField2(value2, "diagnostics");
8670
9080
  if (Array.isArray(diagnostics)) {
8671
9081
  for (const diagnostic of diagnostics) {
8672
- const selected = findProcessFailureError(safeField(diagnostic, "error") ?? diagnostic, seen, depth + 1);
9082
+ const selected = findProcessFailureError(safeField2(diagnostic, "error") ?? diagnostic, seen, depth + 1);
8673
9083
  if (selected !== undefined)
8674
9084
  return selected;
8675
9085
  }
8676
9086
  }
8677
- const errors = safeField(value2, "errors");
9087
+ const errors = safeField2(value2, "errors");
8678
9088
  if (!Array.isArray(errors))
8679
9089
  return;
8680
9090
  for (const error of errors) {
@@ -8880,7 +9290,7 @@ function isInfrastructureError(value2) {
8880
9290
  }
8881
9291
  function isRetryableWorkflowError(error) {
8882
9292
  let current = error;
8883
- for (let depth = 0;depth < MAX_CAUSE_DEPTH && current !== undefined && current !== null; depth++) {
9293
+ for (let depth = 0;depth < MAX_CAUSE_DEPTH3 && current !== undefined && current !== null; depth++) {
8884
9294
  if (isInfrastructureError(current))
8885
9295
  return true;
8886
9296
  current = current instanceof Error ? current.cause : undefined;
@@ -8907,7 +9317,7 @@ function failedOnInfrastructureFault(result) {
8907
9317
  return true;
8908
9318
  return Array.isArray(result.stages) && result.stages.some((stage) => stage?.status === "failed" && (names(stage.failureCode) || names(stage.error)));
8909
9319
  }
8910
- var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError", WORKFLOW_INFRASTRUCTURE_FAULTS, MAX_CAUSE_DEPTH = 8, FAULT_PATTERNS, WorkflowInfrastructureError;
9320
+ var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError", WORKFLOW_INFRASTRUCTURE_FAULTS, MAX_CAUSE_DEPTH3 = 8, FAULT_PATTERNS, WorkflowInfrastructureError;
8911
9321
  var init_workflow_infrastructure_error = __esm(() => {
8912
9322
  WORKFLOW_INFRASTRUCTURE_FAULTS = new Set([
8913
9323
  "worker_lost",
@@ -10055,9 +10465,9 @@ var init_workflow_human_input = __esm(() => {
10055
10465
  });
10056
10466
 
10057
10467
  // dist/builtin/workflows/src/extension/wiring.ts
10058
- import { join as join3 } from "node:path";
10468
+ import { join as join4 } from "node:path";
10059
10469
  import {
10060
- isStaleExtensionContextError as isStaleExtensionContextError5,
10470
+ isStaleExtensionContextError as isStaleExtensionContextError6,
10061
10471
  ModelRuntime,
10062
10472
  noOpUIContext,
10063
10473
  resolveRestoredModelReference
@@ -10202,7 +10612,7 @@ function emitLateIntercomRoute(pi, meta, messages, options, batch) {
10202
10612
  try {
10203
10613
  pi.events.emit(LATE_STAGE_MESSAGE_EVENT2, event);
10204
10614
  } catch (error) {
10205
- if (!isStaleExtensionContextError5(error))
10615
+ if (!isStaleExtensionContextError6(error))
10206
10616
  throw error;
10207
10617
  return Promise.reject(error);
10208
10618
  }
@@ -10214,7 +10624,7 @@ function routeThroughStaleContextGuard(route) {
10214
10624
  try {
10215
10625
  return route();
10216
10626
  } catch (error) {
10217
- if (!isStaleExtensionContextError5(error))
10627
+ if (!isStaleExtensionContextError6(error))
10218
10628
  throw error;
10219
10629
  return Promise.reject(error);
10220
10630
  }
@@ -10484,8 +10894,8 @@ function createAgentSessionAdapter(baseOptions = {}, stageUiBroker) {
10484
10894
  async createAgentSession(options, prepareOptions) {
10485
10895
  if (options && !options.modelRuntime && typeof options.model === "string") {
10486
10896
  options.modelRuntime = await ModelRuntime.create({
10487
- authPath: options.agentDir ? join3(options.agentDir, "auth.json") : undefined,
10488
- modelsPath: options.agentDir ? join3(options.agentDir, "models.json") : undefined
10897
+ authPath: options.agentDir ? join4(options.agentDir, "auth.json") : undefined,
10898
+ modelsPath: options.agentDir ? join4(options.agentDir, "models.json") : undefined
10489
10899
  });
10490
10900
  await resolveStageModel(options, false);
10491
10901
  }
@@ -10986,7 +11396,7 @@ var init_executor_abort = __esm(() => {
10986
11396
  });
10987
11397
 
10988
11398
  // dist/builtin/workflows/src/shared/prompt-callsite-context.ts
10989
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
11399
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
10990
11400
  function withPromptCallerStack(stack, delegate) {
10991
11401
  if (stack === undefined)
10992
11402
  return delegate();
@@ -10997,7 +11407,7 @@ function currentPromptCallerStack() {
10997
11407
  }
10998
11408
  var promptCallerStacks;
10999
11409
  var init_prompt_callsite_context = __esm(() => {
11000
- promptCallerStacks = new AsyncLocalStorage2;
11410
+ promptCallerStacks = new AsyncLocalStorage4;
11001
11411
  });
11002
11412
 
11003
11413
  // dist/builtin/workflows/src/workers/pooled-prompt-limits.ts
@@ -12291,7 +12701,7 @@ function sleepOrAbort(ms, signal) {
12291
12701
  var init_retry = () => {};
12292
12702
 
12293
12703
  // dist/builtin/workflows/src/durable/tool-outcome.ts
12294
- function safeField2(error, key) {
12704
+ function safeField3(error, key) {
12295
12705
  try {
12296
12706
  return field(error, key);
12297
12707
  } catch {
@@ -12299,7 +12709,7 @@ function safeField2(error, key) {
12299
12709
  }
12300
12710
  }
12301
12711
  function exposedText(error, key) {
12302
- const value2 = safeField2(error, key);
12712
+ const value2 = safeField3(error, key);
12303
12713
  if (typeof value2 === "string")
12304
12714
  return value2;
12305
12715
  try {
@@ -12340,7 +12750,7 @@ function safeErrorText(error) {
12340
12750
  }
12341
12751
  function normalizeWorkflowToolError(error) {
12342
12752
  error = selectProcessFailureError(error);
12343
- const exitCode = safeField2(error, "exitCode");
12753
+ const exitCode = safeField3(error, "exitCode");
12344
12754
  const stdout = exposedText(error, "stdout");
12345
12755
  const stderr = exposedText(error, "stderr");
12346
12756
  let message;
@@ -13865,7 +14275,7 @@ class PromptReservationState {
13865
14275
  }
13866
14276
 
13867
14277
  // dist/builtin/workflows/src/durable/journal/journal-backend.ts
13868
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
14278
+ import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
13869
14279
  import { randomUUID as randomUUID5 } from "node:crypto";
13870
14280
  import { setImmediate as setImmediate2 } from "node:timers";
13871
14281
  import { StorageError } from "@bastani/atomic/storage";
@@ -13921,7 +14331,7 @@ function createTurnSlicer(threshold, budgetMs = TURN_BUDGET_MS) {
13921
14331
  turnStart();
13922
14332
  if (queue.length === 0 && !draining && waiting() < threshold)
13923
14333
  return run();
13924
- const inCallerContext = AsyncLocalStorage3.snapshot();
14334
+ const inCallerContext = AsyncLocalStorage5.snapshot();
13925
14335
  return new Promise((resolve, reject) => {
13926
14336
  queue.push(() => {
13927
14337
  let result;
@@ -13998,7 +14408,7 @@ class JournalDurableBackend {
13998
14408
  catalogToken;
13999
14409
  leases = new Map;
14000
14410
  executions = new Map;
14001
- executionContext = new AsyncLocalStorage3;
14411
+ executionContext = new AsyncLocalStorage5;
14002
14412
  pending = new Map;
14003
14413
  waitingOperations = 0;
14004
14414
  reconciledPendingStages = new Map;
@@ -14010,7 +14420,7 @@ class JournalDurableBackend {
14010
14420
  state = "open";
14011
14421
  closing;
14012
14422
  renewing = new Map;
14013
- mutationContext = new AsyncLocalStorage3;
14423
+ mutationContext = new AsyncLocalStorage5;
14014
14424
  processExitCleanup;
14015
14425
  unregisterExecutionStorages = registerExecutionStorages(this.executionContext, this.mutationContext);
14016
14426
  constructor(journal, holderId = `${PROCESS_HOLDER_ID}:${randomUUID5()}`, ownsJournal = true) {
@@ -14493,7 +14903,7 @@ class JournalDurableBackend {
14493
14903
  event,
14494
14904
  ...key === undefined ? {} : { key },
14495
14905
  ...requiresRegisteredRun ? { requiresRegisteredRun } : {},
14496
- context: AsyncLocalStorage3.snapshot(),
14906
+ context: AsyncLocalStorage5.snapshot(),
14497
14907
  resolve,
14498
14908
  reject
14499
14909
  });
@@ -15416,23 +15826,23 @@ var init_workflow_artifact_env = __esm(() => {
15416
15826
  import { randomUUID as randomUUID6 } from "node:crypto";
15417
15827
  import { existsSync } from "node:fs";
15418
15828
  import { mkdir, readdir, rm, stat } from "node:fs/promises";
15419
- import { dirname as dirname4, join as join4 } from "node:path";
15829
+ import { dirname as dirname4, join as join5 } from "node:path";
15420
15830
  import { getAgentDir as getAgentDir4, getEnvValue } from "@bastani/atomic";
15421
15831
  function workflowArtifactRoot() {
15422
15832
  const override = getEnvValue(ENV_WORKFLOW_ARTIFACT_DIR);
15423
15833
  if (override !== undefined && override.length > 0)
15424
15834
  return override;
15425
- return join4(dirname4(getAgentDir4()), "workflows");
15835
+ return join5(dirname4(getAgentDir4()), "workflows");
15426
15836
  }
15427
15837
  function workflowArtifactRunsRoot() {
15428
- return join4(workflowArtifactRoot(), "runs");
15838
+ return join5(workflowArtifactRoot(), "runs");
15429
15839
  }
15430
15840
  function safeRunId(runId) {
15431
15841
  const safe = runId.replace(/[^A-Za-z0-9._-]/g, "_");
15432
15842
  return safe.length > 0 ? safe : "run";
15433
15843
  }
15434
15844
  function workflowArtifactRunPath(runId) {
15435
- return join4(workflowArtifactRunsRoot(), safeRunId(runId));
15845
+ return join5(workflowArtifactRunsRoot(), safeRunId(runId));
15436
15846
  }
15437
15847
  function normalizeSerializedPath(value2) {
15438
15848
  return value2.replaceAll("\\", "/").replace(/\/{2,}/g, "/");
@@ -15568,7 +15978,7 @@ async function pruneWorkflowArtifactRuns(root = workflowArtifactRunsRoot(), now
15568
15978
  for (const entry of entries) {
15569
15979
  if (!entry.isDirectory())
15570
15980
  continue;
15571
- const entryPath = join4(root, entry.name);
15981
+ const entryPath = join5(root, entry.name);
15572
15982
  let metadata;
15573
15983
  try {
15574
15984
  metadata = await stat(entryPath);
@@ -15623,7 +16033,7 @@ async function ensureWorkflowArtifactRunDirectory(runId) {
15623
16033
  }
15624
16034
  function workflowArtifactDirectoryPath(runId) {
15625
16035
  const effectiveRunId = runId ?? randomUUID6();
15626
- return join4(workflowArtifactRunPath(effectiveRunId), `artifact-${randomUUID6()}`);
16036
+ return join5(workflowArtifactRunPath(effectiveRunId), `artifact-${randomUUID6()}`);
15627
16037
  }
15628
16038
  async function ensureWorkflowArtifactDirectory(directory) {
15629
16039
  await pruneArtifactRootIfDue(workflowArtifactRunsRoot(), Date.now());
@@ -17378,7 +17788,7 @@ function taskWithSharedDefaults(taskOptions, options) {
17378
17788
  var init_executor_task_prompts = () => {};
17379
17789
 
17380
17790
  // dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts
17381
- import { isAbsolute as isAbsolute8, join as join12, resolve as resolve10 } from "node:path";
17791
+ import { isAbsolute as isAbsolute8, join as join13, resolve as resolve10 } from "node:path";
17382
17792
  import { CONFIG_DIR_NAME } from "@bastani/atomic";
17383
17793
  function positiveConcurrency(value2) {
17384
17794
  if (typeof value2 !== "number" || !Number.isFinite(value2) || value2 < 1)
@@ -17534,7 +17944,7 @@ function resolvedTaskCwd(cwd, workflowInvocationCwd) {
17534
17944
  return isAbsolute8(cwd) ? cwd : resolve10(workflowInvocationCwd, cwd);
17535
17945
  }
17536
17946
  function taskWorktreeOutputsRoot(runId) {
17537
- return join12(workflowArtifactRunPath(runId), "task-outputs");
17947
+ return join13(workflowArtifactRunPath(runId), "task-outputs");
17538
17948
  }
17539
17949
  function prepareTaskWorktrees(tasks, options, runId, scope, workflowInvocationCwd = process.cwd(), symlinkDirectories) {
17540
17950
  if (options.worktree !== true && !tasks.some((task) => task.worktree === true)) {
@@ -17559,9 +17969,9 @@ function prepareTaskWorktrees(tasks, options, runId, scope, workflowInvocationCw
17559
17969
  tasks: tasks.map((task, index) => ({ ...task, cwd: setup.worktrees[index].agentCwd })),
17560
17970
  setup,
17561
17971
  agents,
17562
- diffsDir: join12(setup.cwd, CONFIG_DIR_NAME, "workflows", "worktree-diffs", runId, scope),
17972
+ diffsDir: join13(setup.cwd, CONFIG_DIR_NAME, "workflows", "worktree-diffs", runId, scope),
17563
17973
  outputIsolations: tasks.map((_, index) => ({
17564
- baseDir: join12(trustedRoot, runId, scope, String(index)),
17974
+ baseDir: join13(trustedRoot, runId, scope, String(index)),
17565
17975
  trustedRoot
17566
17976
  }))
17567
17977
  };
@@ -19004,7 +19414,7 @@ function raceAbort2(operation, signal) {
19004
19414
 
19005
19415
  // dist/builtin/workflows/src/shared/possible-stages.ts
19006
19416
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
19007
- import { dirname as dirname11, join as join13, resolve as resolve11 } from "node:path";
19417
+ import { dirname as dirname11, join as join14, resolve as resolve11 } from "node:path";
19008
19418
  import { fileURLToPath as fileURLToPath3 } from "node:url";
19009
19419
  function scanPossibleStagesFromSource(entrySourcePath, options = {}) {
19010
19420
  const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
@@ -19020,7 +19430,7 @@ function resolveBuiltinDefinitionSource(name) {
19020
19430
  const builtinDir = fileURLToPath3(new URL("../../builtin/", import.meta.url));
19021
19431
  for (const stem of [name, kebabCase(name)]) {
19022
19432
  for (const extension of [".ts", ".js"]) {
19023
- const candidate = join13(builtinDir, `${stem}${extension}`);
19433
+ const candidate = join14(builtinDir, `${stem}${extension}`);
19024
19434
  if (isFileSync(candidate))
19025
19435
  return candidate;
19026
19436
  }
@@ -20463,9 +20873,9 @@ function resolveRelativeSpecifier(specifier, importingFile) {
20463
20873
  return;
20464
20874
  const candidates = [];
20465
20875
  if (specifier.endsWith(".js")) {
20466
- candidates.push(join13(dirname11(importingFile), `${specifier.slice(0, -3)}.ts`));
20876
+ candidates.push(join14(dirname11(importingFile), `${specifier.slice(0, -3)}.ts`));
20467
20877
  }
20468
- candidates.push(join13(dirname11(importingFile), specifier), join13(dirname11(importingFile), `${specifier}.ts`), join13(dirname11(importingFile), `${specifier}.js`), join13(dirname11(importingFile), specifier, "index.ts"), join13(dirname11(importingFile), specifier, "index.js"));
20878
+ candidates.push(join14(dirname11(importingFile), specifier), join14(dirname11(importingFile), `${specifier}.ts`), join14(dirname11(importingFile), `${specifier}.js`), join14(dirname11(importingFile), specifier, "index.ts"), join14(dirname11(importingFile), specifier, "index.js"));
20469
20879
  return candidates.find((candidate) => isFileSync(candidate));
20470
20880
  }
20471
20881
  function isFileSync(path) {
@@ -20500,7 +20910,7 @@ var init_possible_stages = __esm(() => {
20500
20910
 
20501
20911
  // dist/builtin/workflows/src/workers/admission-host.ts
20502
20912
  import { execFile, execFileSync } from "node:child_process";
20503
- import { readdirSync as readdirSync4, readFileSync as readFileSync5 } from "node:fs";
20913
+ import { readdirSync as readdirSync5, readFileSync as readFileSync5 } from "node:fs";
20504
20914
  import { readFile } from "node:fs/promises";
20505
20915
  import { hostname } from "node:os";
20506
20916
  function admissionBootIdentity() {
@@ -20551,7 +20961,7 @@ function scanProcessGroup(group) {
20551
20961
  let complete = true;
20552
20962
  let entries;
20553
20963
  try {
20554
- entries = readdirSync4("/proc");
20964
+ entries = readdirSync5("/proc");
20555
20965
  } catch {
20556
20966
  return { members, complete: false };
20557
20967
  }
@@ -57360,10 +57770,10 @@ var init_verification_prompts = __esm(() => {
57360
57770
  // dist/builtin/workflows/builtin/pattern-artifact-root.ts
57361
57771
  import { randomUUID as randomUUID9 } from "node:crypto";
57362
57772
  import { mkdir as mkdir2 } from "node:fs/promises";
57363
- import { join as join14 } from "node:path";
57773
+ import { join as join15 } from "node:path";
57364
57774
  async function stableArtifactRoot(ctx, workflowName) {
57365
57775
  const cwd = ctx.cwd ?? process.cwd();
57366
- const artifactDir = await ctx.tool("artifact-root", { workflow: workflowName }, async () => join14(cwd, ".atomic", "workflows", "runs", `${workflowName}-${randomUUID9()}`));
57776
+ const artifactDir = await ctx.tool("artifact-root", { workflow: workflowName }, async () => join15(cwd, ".atomic", "workflows", "runs", `${workflowName}-${randomUUID9()}`));
57367
57777
  await mkdir2(artifactDir, { recursive: true });
57368
57778
  return artifactDir;
57369
57779
  }
@@ -57403,7 +57813,7 @@ function fold_usage(results) {
57403
57813
 
57404
57814
  // dist/builtin/workflows/builtin/adversarial-verification-runner.ts
57405
57815
  import { readFile as readFile2, writeFile } from "node:fs/promises";
57406
- import { join as join15 } from "node:path";
57816
+ import { join as join16 } from "node:path";
57407
57817
  import { Type as Type4 } from "typebox";
57408
57818
  function isRecord3(value2) {
57409
57819
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -57498,8 +57908,8 @@ async function writeInvalid(path, stage) {
57498
57908
  }
57499
57909
  async function runAdversarialVerification(ctx) {
57500
57910
  const root = await stableArtifactRoot(ctx, "adversarial-verification");
57501
- const criteriaPath = join15(root, "criteria.md");
57502
- const candidatePath = join15(root, "candidate.md");
57911
+ const criteriaPath = join16(root, "criteria.md");
57912
+ const candidatePath = join16(root, "candidate.md");
57503
57913
  const resolvedCriteria = resolveCriteria(ctx.inputs.criteria);
57504
57914
  await writeFile(criteriaPath, renderCriteriaMarkdown(resolvedCriteria));
57505
57915
  await ctx.task("worker", { prompt: renderWorkerPrompt(ctx.inputs.task), context: "fresh", output: candidatePath, outputMode: "file-only" });
@@ -57531,7 +57941,7 @@ async function runAdversarialVerification(ctx) {
57531
57941
  criterion,
57532
57942
  verifierIndex: index + 1,
57533
57943
  name,
57534
- artifactPath: join15(root, `verification-${round}-${criterion.id}-${index + 1}.json`)
57944
+ artifactPath: join16(root, `verification-${round}-${criterion.id}-${index + 1}.json`)
57535
57945
  });
57536
57946
  }
57537
57947
  }
@@ -57584,8 +57994,8 @@ async function runAdversarialVerification(ctx) {
57584
57994
  const decision = decide_verification(roundResult, { acceptMean, quorumFraction: QUORUM_FRACTION });
57585
57995
  finalDecision = decision;
57586
57996
  finalMean = meanScore(scoreReports);
57587
- scoreTablePath = join15(root, `verification-summary-${round}.json`);
57588
- reviewReportPath = join15(root, `review-${round}.json`);
57997
+ scoreTablePath = join16(root, `verification-summary-${round}.json`);
57998
+ reviewReportPath = join16(root, `review-${round}.json`);
57589
57999
  const summary = {
57590
58000
  scores: scoreReports,
57591
58001
  mean: finalMean,
@@ -57766,7 +58176,7 @@ var GROUNDED_REPORTING2 = "Before reporting progress, audit each claim against a
57766
58176
 
57767
58177
  // dist/builtin/workflows/builtin/classify-and-act-runner.ts
57768
58178
  import { writeFile as writeFile2 } from "node:fs/promises";
57769
- import { join as join16 } from "node:path";
58179
+ import { join as join17 } from "node:path";
57770
58180
  import { Type as Type6 } from "typebox";
57771
58181
  function safeName(value2) {
57772
58182
  const normalized = value2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -57806,7 +58216,7 @@ async function runClassifyAndAct(ctx) {
57806
58216
  const needsFallback = exactCategory === undefined || confidence < ctx.inputs.confidence_threshold;
57807
58217
  const fallback = needsFallback ? await resolveFallbackCategory(ctx, exactCategory) : undefined;
57808
58218
  const category = fallback?.category ?? exactCategory;
57809
- const classificationPath = join16(artifactDir, "classification.json");
58219
+ const classificationPath = join17(artifactDir, "classification.json");
57810
58220
  await writeFile2(classificationPath, JSON.stringify({
57811
58221
  proposed_category: proposedCategory,
57812
58222
  selected_category: category,
@@ -57816,7 +58226,7 @@ async function runClassifyAndAct(ctx) {
57816
58226
  fallback_used: needsFallback,
57817
58227
  fallback_mode: fallback?.fallbackMode ?? "none"
57818
58228
  }, null, 2));
57819
- const actionPath = join16(artifactDir, `action-${safeName(category)}.md`);
58229
+ const actionPath = join17(artifactDir, `action-${safeName(category)}.md`);
57820
58230
  const action = await ctx.task(`action-${safeName(category)}`, {
57821
58231
  tools: actionTools(category),
57822
58232
  prompt: actionPrompt({ prompt: ctx.inputs.prompt, category, classificationPath }),
@@ -57956,7 +58366,7 @@ var GROUNDED_REPORTING3 = "Before reporting progress, audit each claim against a
57956
58366
 
57957
58367
  // dist/builtin/workflows/builtin/fan-out-and-synthesize-runner.ts
57958
58368
  import { writeFile as writeFile3 } from "node:fs/promises";
57959
- import { join as join17 } from "node:path";
58369
+ import { join as join18 } from "node:path";
57960
58370
  import { Type as Type8 } from "typebox";
57961
58371
  function safeName2(value2, index) {
57962
58372
  const normalized = value2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -57987,9 +58397,9 @@ async function runFanOutAndSynthesize(ctx) {
57987
58397
  context: "fresh"
57988
58398
  });
57989
58399
  const partitions = parsedPartitions(plan.structured, ctx.inputs.max_branches, ctx.inputs.prompt);
57990
- const partitionPath = join17(artifactDir, "partition-plan.json");
58400
+ const partitionPath = join18(artifactDir, "partition-plan.json");
57991
58401
  await writeFile3(partitionPath, JSON.stringify({ task: ctx.inputs.prompt, partitions }, null, 2));
57992
- const branchPaths = partitions.map((partition, index) => join17(artifactDir, `branch-${safeName2(partition.label, index)}.md`));
58402
+ const branchPaths = partitions.map((partition, index) => join18(artifactDir, `branch-${safeName2(partition.label, index)}.md`));
57993
58403
  const steps = partitions.map((partition, index) => ({
57994
58404
  name: `branch-${safeName2(partition.label, index)}`,
57995
58405
  prompt: branchPrompt({ prompt: ctx.inputs.prompt, ...partition }),
@@ -57999,13 +58409,13 @@ async function runFanOutAndSynthesize(ctx) {
57999
58409
  outputMode: "file-only"
58000
58410
  }));
58001
58411
  await ctx.parallel(steps, { concurrency: Math.min(ctx.inputs.max_concurrency, partitions.length), failFast: false });
58002
- const manifestPath = join17(artifactDir, "manifest.json");
58412
+ const manifestPath = join18(artifactDir, "manifest.json");
58003
58413
  await writeFile3(manifestPath, JSON.stringify({
58004
58414
  task: ctx.inputs.prompt,
58005
58415
  partition_plan: partitionPath,
58006
58416
  branches: partitions.map((partition, index) => ({ ...partition, artifact_path: branchPaths[index] }))
58007
58417
  }, null, 2));
58008
- const synthesisPath = join17(artifactDir, "synthesis.md");
58418
+ const synthesisPath = join18(artifactDir, "synthesis.md");
58009
58419
  const synthesis = await ctx.task("synthesize", {
58010
58420
  prompt: synthesisPrompt(ctx.inputs.prompt, manifestPath),
58011
58421
  context: "fresh",
@@ -58170,7 +58580,7 @@ var init_generate_and_filter_prompts = __esm(() => {
58170
58580
 
58171
58581
  // dist/builtin/workflows/builtin/generate-and-filter-runner.ts
58172
58582
  import { readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
58173
- import { join as join18 } from "node:path";
58583
+ import { join as join19 } from "node:path";
58174
58584
  import { Type as Type10 } from "typebox";
58175
58585
  function isRecord4(value2) {
58176
58586
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -58189,7 +58599,7 @@ function judgeDecision(value2) {
58189
58599
  }
58190
58600
  async function runGenerateAndFilter(ctx) {
58191
58601
  const root = await stableArtifactRoot(ctx, "generate-and-filter");
58192
- const candidatePaths = Array.from({ length: ctx.inputs.num_candidates }, (_, index) => join18(root, `candidate-${index + 1}.md`));
58602
+ const candidatePaths = Array.from({ length: ctx.inputs.num_candidates }, (_, index) => join19(root, `candidate-${index + 1}.md`));
58193
58603
  const shortlistLimit = Math.min(ctx.inputs.shortlist_size, ctx.inputs.num_candidates);
58194
58604
  await ctx.parallel(candidatePaths.map((path, index) => ({
58195
58605
  name: `generate-${index + 1}`,
@@ -58198,9 +58608,9 @@ async function runGenerateAndFilter(ctx) {
58198
58608
  output: path,
58199
58609
  outputMode: "file-only"
58200
58610
  })), { concurrency: ctx.inputs.max_concurrency, failFast: false });
58201
- const manifestPath = join18(root, "manifest.json");
58611
+ const manifestPath = join19(root, "manifest.json");
58202
58612
  await writeFile4(manifestPath, JSON.stringify({ task: ctx.inputs.prompt, candidate_artifact_paths: candidatePaths }, null, 2));
58203
- const filterPath = join18(root, "filter.json");
58613
+ const filterPath = join19(root, "filter.json");
58204
58614
  const filtered = await ctx.task("dedupe-and-filter", {
58205
58615
  prompt: renderFilterPrompt(ctx.inputs.prompt, candidatePaths, shortlistLimit),
58206
58616
  context: "fresh",
@@ -58217,7 +58627,7 @@ async function runGenerateAndFilter(ctx) {
58217
58627
  let judgePath = null;
58218
58628
  let decisionPath = filterPath;
58219
58629
  if (ctx.inputs.use_judge) {
58220
- judgePath = join18(root, "judge.json");
58630
+ judgePath = join19(root, "judge.json");
58221
58631
  const judgeCandidates = await Promise.all(shortlist.map(async (path) => ({ path, body: await readFile3(path, "utf8") })));
58222
58632
  const judgePrompt = renderJudgePrompt(ctx.inputs.prompt, filterPath, shortlistLimit, judgeCandidates);
58223
58633
  const judged = await ctx.task("judge", {
@@ -58233,7 +58643,7 @@ async function runGenerateAndFilter(ctx) {
58233
58643
  shortlist = judgedShortlist.length > 0 ? judgedShortlist : shortlist;
58234
58644
  decisionPath = judgePath;
58235
58645
  }
58236
- const finalPath = join18(root, "shortlist.md");
58646
+ const finalPath = join19(root, "shortlist.md");
58237
58647
  const finalShortlist = await ctx.task("final-shortlist", {
58238
58648
  prompt: renderFinalShortlistPrompt(ctx.inputs.prompt, decisionPath),
58239
58649
  context: "fresh",
@@ -58762,7 +59172,7 @@ var init_review_convergence = __esm(() => {
58762
59172
 
58763
59173
  // dist/builtin/workflows/builtin/goal-artifacts.ts
58764
59174
  import { writeFile as writeFile5 } from "node:fs/promises";
58765
- import { join as join19 } from "node:path";
59175
+ import { join as join20 } from "node:path";
58766
59176
  function artifactSafeName(value2) {
58767
59177
  const safe = value2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
58768
59178
  return safe.length > 0 ? safe : "artifact";
@@ -58773,7 +59183,7 @@ function withoutTurn(value2) {
58773
59183
  return copy;
58774
59184
  }
58775
59185
  async function writeReviewArtifact(artifactDir, reviewer, decision, rawText, convergenceDecision) {
58776
- const artifactPath = join19(artifactDir, `review-${artifactSafeName(reviewer)}.json`);
59186
+ const artifactPath = join20(artifactDir, `review-${artifactSafeName(reviewer)}.json`);
58777
59187
  await writeFile5(artifactPath, `${JSON.stringify({ reviewer, decision, convergence_decision: convergenceDecision, raw_text: rawText }, null, 2)}
58778
59188
  `, { encoding: "utf8" });
58779
59189
  return artifactPath;
@@ -58782,7 +59192,7 @@ async function writeReviewRoundArtifact(artifactDir, reviews, consolidatedFindin
58782
59192
  reviewer: review.reviewer,
58783
59193
  findings: review.findings
58784
59194
  }))), reverification = []) {
58785
- const artifactPath = join19(artifactDir, "review-round-latest.json");
59195
+ const artifactPath = join20(artifactDir, "review-round-latest.json");
58786
59196
  const visibleReviews = reviews.map(withoutTurn);
58787
59197
  await writeFile5(artifactPath, `${JSON.stringify({ reviews: visibleReviews, consolidated_findings: consolidatedFindings, reverification }, null, 2)}
58788
59198
  `, { encoding: "utf8" });
@@ -59012,7 +59422,7 @@ var init_goal_review = __esm(() => {
59012
59422
  // dist/builtin/workflows/builtin/goal-ledger.ts
59013
59423
  import { randomUUID as randomUUID10 } from "node:crypto";
59014
59424
  import { readFile as readFile4, rename, rm as rm2, writeFile as writeFile6 } from "node:fs/promises";
59015
- import { dirname as dirname12, join as join20 } from "node:path";
59425
+ import { dirname as dirname12, join as join21 } from "node:path";
59016
59426
  import { isDeepStrictEqual } from "node:util";
59017
59427
  function withoutTurn2(value2) {
59018
59428
  const copy = { ...value2 };
@@ -59037,7 +59447,7 @@ function modelVisibleLedger(ledger) {
59037
59447
  };
59038
59448
  }
59039
59449
  function goalLedgerStatePath(ledgerPath) {
59040
- return join20(dirname12(ledgerPath), LEDGER_STATE_FILENAME);
59450
+ return join21(dirname12(ledgerPath), LEDGER_STATE_FILENAME);
59041
59451
  }
59042
59452
  function appendLifecycleEvent(ledger, event, summary, turn = ledger.turns) {
59043
59453
  ledger.lifecycle.push({
@@ -59113,7 +59523,7 @@ function recoverLegacyExecutionInterruption(ledger) {
59113
59523
  return true;
59114
59524
  }
59115
59525
  async function createGoalLedger(objective, acceptanceCriteria, artifactDir) {
59116
- const ledgerPath = join20(artifactDir, LEDGER_FILENAME);
59526
+ const ledgerPath = join21(artifactDir, LEDGER_FILENAME);
59117
59527
  const existing = await readExistingGoalLedger(ledgerPath);
59118
59528
  if (existing !== undefined) {
59119
59529
  if (recoverLegacyExecutionInterruption(existing))
@@ -59620,7 +60030,7 @@ var init_goal_orchestrator_prompts = __esm(() => {
59620
60030
  });
59621
60031
 
59622
60032
  // dist/builtin/workflows/builtin/goal-runner.ts
59623
- import { join as join21 } from "node:path";
60033
+ import { join as join22 } from "node:path";
59624
60034
  function positiveInteger(value2, fallback) {
59625
60035
  if (typeof value2 !== "number" || !Number.isFinite(value2) || value2 <= 0) {
59626
60036
  return fallback;
@@ -59671,7 +60081,7 @@ async function runGoalWorkflow(ctx, options) {
59671
60081
  appendLifecycleEvent(ledger, "work_turn_started", "Orchestrator started.", turn);
59672
60082
  await writeGoalLedger(ledgerPath, ledger);
59673
60083
  }
59674
- const orchestratorReceiptPath = join21(artifactDir, "orchestrator-receipt.md");
60084
+ const orchestratorReceiptPath = join22(artifactDir, "orchestrator-receipt.md");
59675
60085
  const orchestratorForkOptions = forkContinuationOptions(previousOrchestratorSessionId);
59676
60086
  const orchestratorPrompt = orchestratorForkOptions.forkFromSessionId === undefined ? renderGoalOrchestratorPrompt({
59677
60087
  ledger,
@@ -59742,7 +60152,7 @@ async function runGoalWorkflow(ctx, options) {
59742
60152
  const reviewerName = result.name ?? result.stageName;
59743
60153
  const normalizedReviewerName = reviewerName.replace(/-\d+$/u, "");
59744
60154
  const parsed = reviewerContractError === undefined ? parsedReviewDecisionFromResult(result, reviewerName) : { decision: reviewerErrorDecision(reviewerContractError.message), parsed: false, diagnostics: [reviewerContractError.message] };
59745
- const reviewArtifactPath = join21(artifactDir, `review-${artifactSafeName(normalizedReviewerName)}.json`);
60155
+ const reviewArtifactPath = join22(artifactDir, `review-${artifactSafeName(normalizedReviewerName)}.json`);
59746
60156
  const record = reviewDecisionToRecord({
59747
60157
  turn,
59748
60158
  reviewer: normalizedReviewerName,
@@ -60063,7 +60473,7 @@ var GROUNDED_REPORTING5 = "Before reporting progress, audit each claim against a
60063
60473
 
60064
60474
  // dist/builtin/workflows/builtin/loop-until-done-runner.ts
60065
60475
  import { mkdir as mkdir3, writeFile as writeFile7 } from "node:fs/promises";
60066
- import { join as join22 } from "node:path";
60476
+ import { join as join23 } from "node:path";
60067
60477
  import { Type as Type16 } from "typebox";
60068
60478
  function progressCurve(entries) {
60069
60479
  return entries.flatMap((entry) => entry.progress === undefined ? [] : [entry.progress.score]);
@@ -60146,18 +60556,18 @@ async function writeLedger(path, task, maxIterations, status, entries) {
60146
60556
  }
60147
60557
  async function runLoopUntilDone(ctx) {
60148
60558
  const artifactDir = await stableArtifactRoot(ctx, "loop-until-done");
60149
- const iterationsDir = join22(artifactDir, "iterations");
60150
- const evaluationsDir = join22(artifactDir, "evaluations");
60559
+ const iterationsDir = join23(artifactDir, "iterations");
60560
+ const evaluationsDir = join23(artifactDir, "evaluations");
60151
60561
  await mkdir3(iterationsDir, { recursive: true });
60152
60562
  await mkdir3(evaluationsDir, { recursive: true });
60153
- const ledgerPath = join22(artifactDir, "progress-ledger.json");
60563
+ const ledgerPath = join23(artifactDir, "progress-ledger.json");
60154
60564
  const entries = [];
60155
60565
  const iterationArtifactPaths = [];
60156
60566
  const evaluationArtifactPaths = [];
60157
60567
  await writeLedger(ledgerPath, ctx.inputs.prompt, ctx.inputs.max_iterations, "active", entries);
60158
60568
  for (let iteration = 1;iteration <= ctx.inputs.max_iterations; iteration += 1) {
60159
- const iterationPath = join22(iterationsDir, `iteration-${iteration}.md`);
60160
- const evaluationPath = join22(evaluationsDir, `evaluation-${iteration}.json`);
60569
+ const iterationPath = join23(iterationsDir, `iteration-${iteration}.md`);
60570
+ const evaluationPath = join23(evaluationsDir, `evaluation-${iteration}.json`);
60161
60571
  iterationArtifactPaths.push(iterationPath);
60162
60572
  evaluationArtifactPaths.push(evaluationPath);
60163
60573
  await ctx.task(`iteration-${iteration}`, {
@@ -60206,7 +60616,7 @@ async function runLoopUntilDone(ctx) {
60206
60616
  await writeLedger(ledgerPath, ctx.inputs.prompt, ctx.inputs.max_iterations, decision.done ? "complete" : "active", entries);
60207
60617
  if (decision.done) {
60208
60618
  const report = progressReport(entries);
60209
- const resultPath = join22(artifactDir, "result.md");
60619
+ const resultPath = join23(artifactDir, "result.md");
60210
60620
  const final = await ctx.task("completion-summary", {
60211
60621
  prompt: renderCompletionPrompt({ task: ctx.inputs.prompt, ledgerPath, iterationPath }),
60212
60622
  context: "fresh",
@@ -60323,9 +60733,9 @@ var init_loop_until_done = __esm(() => {
60323
60733
 
60324
60734
  // dist/builtin/workflows/builtin/open-claude-design-utils.ts
60325
60735
  import { spawnSync as spawnSync3 } from "node:child_process";
60326
- import { mkdirSync as mkdirSync6 } from "node:fs";
60736
+ import { mkdirSync as mkdirSync7 } from "node:fs";
60327
60737
  import { tmpdir, userInfo } from "node:os";
60328
- import { join as join23 } from "node:path";
60738
+ import { join as join24 } from "node:path";
60329
60739
  import { Type as Type18 } from "typebox";
60330
60740
  import { createChildProcessEnvironment as createChildProcessEnvironment3 } from "@bastani/atomic";
60331
60741
  function taggedPrompt3(sections) {
@@ -60368,32 +60778,32 @@ function tmpArtifactBase() {
60368
60778
  try {
60369
60779
  user = userInfo().username.replace(/[^A-Za-z0-9._-]/g, "_") || "default";
60370
60780
  } catch {}
60371
- return join23(tmpdir(), `open-claude-design-${user}`);
60781
+ return join24(tmpdir(), `open-claude-design-${user}`);
60372
60782
  }
60373
60783
  function prepareArtifactDir(cwd = process.cwd()) {
60374
60784
  const runId = `${new Date().toISOString().replace(/[:.]/g, "-")}-${Math.random().toString(36).slice(2, 8)}`;
60375
60785
  const tmpCandidates = [
60376
- join23(tmpArtifactBase(), runId),
60377
- join23(tmpdir(), "open-claude-design", runId)
60786
+ join24(tmpArtifactBase(), runId),
60787
+ join24(tmpdir(), "open-claude-design", runId)
60378
60788
  ];
60379
- const candidates = process.env.NODE_ENV === "test" ? tmpCandidates : [join23(cwd, "specs", "design", runId), ...tmpCandidates];
60789
+ const candidates = process.env.NODE_ENV === "test" ? tmpCandidates : [join24(cwd, "specs", "design", runId), ...tmpCandidates];
60380
60790
  for (const candidate of candidates) {
60381
60791
  try {
60382
- mkdirSync6(candidate, { recursive: true });
60792
+ mkdirSync7(candidate, { recursive: true });
60383
60793
  return {
60384
60794
  runId,
60385
60795
  artifactDir: candidate,
60386
- previewPath: join23(candidate, "preview.html"),
60387
- specPath: join23(candidate, "spec.html")
60796
+ previewPath: join24(candidate, "preview.html"),
60797
+ specPath: join24(candidate, "spec.html")
60388
60798
  };
60389
60799
  } catch {}
60390
60800
  }
60391
- const fallback = join23(tmpArtifactBase(), runId);
60801
+ const fallback = join24(tmpArtifactBase(), runId);
60392
60802
  return {
60393
60803
  runId,
60394
60804
  artifactDir: fallback,
60395
- previewPath: join23(fallback, "preview.html"),
60396
- specPath: join23(fallback, "spec.html")
60805
+ previewPath: join24(fallback, "preview.html"),
60806
+ specPath: join24(fallback, "spec.html")
60397
60807
  };
60398
60808
  }
60399
60809
  function ensureAgentBrowser() {
@@ -60727,8 +61137,8 @@ var init_open_claude_design_live_protocol = __esm(() => {
60727
61137
  });
60728
61138
 
60729
61139
  // dist/builtin/workflows/builtin/open-claude-design-setup.ts
60730
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync4 } from "node:fs";
60731
- import { join as join24 } from "node:path";
61140
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync4 } from "node:fs";
61141
+ import { join as join25 } from "node:path";
60732
61142
  function renderDiscoveryContext(discovery) {
60733
61143
  return [
60734
61144
  `Confirmed design brief: ${discovery.brief}`,
@@ -60793,10 +61203,10 @@ async function runDiscoveryAndInit(args) {
60793
61203
  };
60794
61204
  }
60795
61205
  function designContextPath(artifactDir) {
60796
- return join24(artifactDir, DESIGN_CONTEXT_FILENAME);
61206
+ return join25(artifactDir, DESIGN_CONTEXT_FILENAME);
60797
61207
  }
60798
61208
  function referencesBriefPath(artifactDir) {
60799
- return join24(artifactDir, REFERENCES_BRIEF_FILENAME);
61209
+ return join25(artifactDir, REFERENCES_BRIEF_FILENAME);
60800
61210
  }
60801
61211
  function buildReferenceDiscoveryPrompt(args) {
60802
61212
  const siteList = REFERENCE_DESIGN_SITES.map((site, index) => `${index + 1}. ${site.name} — ${site.url}`).join(`
@@ -60822,8 +61232,8 @@ function buildReferenceDiscoveryPrompt(args) {
60822
61232
  [
60823
61233
  "Use the agent-browser skill to open each gallery; if `agent-browser` reports a missing browser executable, follow the bootstrap rules and retry once.",
60824
61234
  "From each gallery, choose 1-3 fitting designs and CLICK INTO each actual live or project-detail page; do not capture only the grid or thumbnail.",
60825
- `Capture motion across the entire page: start \`agent-browser record start ${join24(args.artifactDir, "ref-<site>-<n>.webm")}\`, scroll smoothly in small increments with waits (using repeated \`agent-browser scroll down 600\` or \`agent-browser mouse wheel 600\`) so animations fire and lazy content loads, then run \`agent-browser record stop\`.`,
60826
- `Also run \`agent-browser screenshot ${join24(args.artifactDir, "ref-<site>-<n>.png")} --full\`; this still is the minimum when video is unavailable.`,
61235
+ `Capture motion across the entire page: start \`agent-browser record start ${join25(args.artifactDir, "ref-<site>-<n>.webm")}\`, scroll smoothly in small increments with waits (using repeated \`agent-browser scroll down 600\` or \`agent-browser mouse wheel 600\`) so animations fire and lazy content loads, then run \`agent-browser record stop\`.`,
61236
+ `Also run \`agent-browser screenshot ${join25(args.artifactDir, "ref-<site>-<n>.png")} --full\`; this still is the minimum when video is unavailable.`,
60827
61237
  "Record the actual destination URL, title, and author. For each reference, cite observed layout, typography, color, spacing, and motion traits rather than inferred traits.",
60828
61238
  "Assess fit against DESIGN.md, PRODUCT.md, and the ds-* discovery evidence in the design-context file; prefer on-brand references and flag departures.",
60829
61239
  "Use ask_user_question to ask which reference direction they prefer, offering 2-4 strongest options plus `None of these fit`. If none fit, ask them to provide a reference image, screenshot, URL, or local file path and record the answer.",
@@ -60848,7 +61258,7 @@ function buildReferenceDiscoveryPrompt(args) {
60848
61258
  }
60849
61259
  function writeRequiredContextArtifact(artifactDir, filePath, content, label) {
60850
61260
  try {
60851
- mkdirSync7(artifactDir, { recursive: true });
61261
+ mkdirSync8(artifactDir, { recursive: true });
60852
61262
  writeFileSync4(filePath, `${content}
60853
61263
  `);
60854
61264
  } catch (error) {
@@ -61400,7 +61810,7 @@ var init_ralph_review_gate = __esm(() => {
61400
61810
 
61401
61811
  // dist/builtin/workflows/builtin/ralph-core.ts
61402
61812
  import { mkdir as mkdir4, writeFile as writeFile8 } from "node:fs/promises";
61403
- import { dirname as dirname13, join as join25 } from "node:path";
61813
+ import { dirname as dirname13, join as join26 } from "node:path";
61404
61814
  import { Type as Type20 } from "typebox";
61405
61815
  function taggedPrompt4(sections) {
61406
61816
  return sections.map(([tag, content]) => {
@@ -61440,11 +61850,11 @@ function slugifyResearchTopic(prompt) {
61440
61850
  }
61441
61851
  function defaultResearchPath(prompt, now = new Date) {
61442
61852
  const date = now.toISOString().slice(0, 10);
61443
- return join25(DEFAULT_RESEARCH_DIR, `${date}-${slugifyResearchTopic(prompt)}.md`);
61853
+ return join26(DEFAULT_RESEARCH_DIR, `${date}-${slugifyResearchTopic(prompt)}.md`);
61444
61854
  }
61445
61855
  async function createImplementationNotesFile(prompt, runId) {
61446
61856
  const notesDir = await createWorkflowArtifactDirectory(runId);
61447
- const notesPath = join25(notesDir, IMPLEMENTATION_NOTES_FILENAME);
61857
+ const notesPath = join26(notesDir, IMPLEMENTATION_NOTES_FILENAME);
61448
61858
  const initialNotes = [
61449
61859
  "# Implementation Notes",
61450
61860
  "",
@@ -61465,7 +61875,7 @@ async function createImplementationNotesFile(prompt, runId) {
61465
61875
  }
61466
61876
  async function createQaEvidenceVideoPath(runId) {
61467
61877
  const qaDir = await createWorkflowArtifactDirectory(runId);
61468
- return join25(qaDir, QA_E2E_VIDEO_FILENAME);
61878
+ return join26(qaDir, QA_E2E_VIDEO_FILENAME);
61469
61879
  }
61470
61880
  function renderQaE2eVideoGuidance(qaVideoPath) {
61471
61881
  return [
@@ -61869,7 +62279,7 @@ var init_ralph_models = __esm(() => {
61869
62279
 
61870
62280
  // dist/builtin/workflows/builtin/ralph-runner.ts
61871
62281
  import { existsSync as existsSync6 } from "node:fs";
61872
- import { join as join26, resolve as resolve12 } from "node:path";
62282
+ import { join as join27, resolve as resolve12 } from "node:path";
61873
62283
  async function runRalphWorkflow(ctx, options) {
61874
62284
  const { prompt, acceptanceCriteria, maxLoops, comparisonBaseBranch, workflowStartCwd, createPr, runId } = options;
61875
62285
  let latestReviewReportPath;
@@ -61930,7 +62340,7 @@ async function runRalphWorkflow(ctx, options) {
61930
62340
  const researchPath = workflowResearchPath;
61931
62341
  finalResearchPath = researchPath;
61932
62342
  finalPlanPath = researchPath;
61933
- const orchestratorReportPath = join26(artifactDir, "orchestrator-report.md");
62343
+ const orchestratorReportPath = join27(artifactDir, "orchestrator-report.md");
61934
62344
  const orchestratorForkOptions = forkContinuationOptions3(previousOrchestratorSessionId);
61935
62345
  const orchestratorPrompt = orchestratorForkOptions.forkFromSessionId === undefined ? taggedPrompt4([
61936
62346
  ["acceptance_criteria", keepContext(acceptanceCriteria)],
@@ -62066,7 +62476,7 @@ Read it before implementation or delegation because it is the primary current im
62066
62476
  diagnostics: parsed.diagnostics,
62067
62477
  allowFinalActionRemaining: createPr
62068
62478
  });
62069
- const artifactPath = join26(artifactDir, `review-${artifactSafeName2(reviewer)}.json`);
62479
+ const artifactPath = join27(artifactDir, `review-${artifactSafeName2(reviewer)}.json`);
62070
62480
  await writeJsonArtifact(artifactPath, {
62071
62481
  reviewer,
62072
62482
  decision: parsed.decision,
@@ -62122,7 +62532,7 @@ Read it before implementation or delegation because it is the primary current im
62122
62532
  usage: fold_usage([orchestrator, ...reviews, ...reverifyResults])
62123
62533
  }));
62124
62534
  }
62125
- latestReviewReportPath = await writeJsonArtifact(join26(artifactDir, "review-round-latest.json"), {
62535
+ latestReviewReportPath = await writeJsonArtifact(join27(artifactDir, "review-round-latest.json"), {
62126
62536
  convergence_decision: roundConvergenceDecision,
62127
62537
  convergence: convergenceEntries,
62128
62538
  consolidated_findings: reverified.batch,
@@ -62491,7 +62901,7 @@ var init_tournament_prompts = __esm(() => {
62491
62901
 
62492
62902
  // dist/builtin/workflows/builtin/tournament-runner.ts
62493
62903
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile9 } from "node:fs/promises";
62494
- import { join as join27, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve13 } from "node:path";
62904
+ import { join as join28, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve13 } from "node:path";
62495
62905
  import { Type as Type22 } from "typebox";
62496
62906
  function serializableObject3(value2) {
62497
62907
  if (value2 === null || Array.isArray(value2) || typeof value2 !== "object")
@@ -62580,16 +62990,16 @@ function combineUsage(totals) {
62580
62990
  }
62581
62991
  async function runTournament(ctx) {
62582
62992
  const artifactDir = await stableArtifactRoot(ctx, "tournament");
62583
- const attemptsDir = join27(artifactDir, "attempts");
62993
+ const attemptsDir = join28(artifactDir, "attempts");
62584
62994
  const numAttempts = ctx.inputs.num_attempts ?? 4;
62585
62995
  const maxConcurrency = ctx.inputs.max_concurrency ?? 4;
62586
62996
  const nEvaluations = ctx.inputs.n_evaluations ?? 2;
62587
62997
  const pivotCount = ctx.inputs.pivots ?? 1;
62588
62998
  const seed = ctx.inputs.seed ?? 0;
62589
- const judgesDir = join27(artifactDir, "judges");
62999
+ const judgesDir = join28(artifactDir, "judges");
62590
63000
  await mkdir5(attemptsDir, { recursive: true });
62591
63001
  await mkdir5(judgesDir, { recursive: true });
62592
- const attemptArtifactPaths = Array.from({ length: numAttempts }, (_, index) => join27(attemptsDir, `attempt-${index + 1}.md`));
63002
+ const attemptArtifactPaths = Array.from({ length: numAttempts }, (_, index) => join28(attemptsDir, `attempt-${index + 1}.md`));
62593
63003
  const models = ctx.inputs.models;
62594
63004
  const attemptResults = await ctx.parallel(attemptArtifactPaths.map((path, index) => ({
62595
63005
  name: `attempt-${index + 1}`,
@@ -62754,7 +63164,7 @@ The previous report was invalid. Return the required JSON schema exactly once.`,
62754
63164
  const outputRanking = ranking.map(({ label, meanPreference }) => ({ label, meanPreference }));
62755
63165
  const budgetPivots = Math.min(pivotCount, entrants.length);
62756
63166
  const comparisonBudget = (entrants.length + budgetPivots * (entrants.length - budgetPivots) + budgetPivots * (budgetPivots - 1) / 2) * criteria.length * nEvaluations;
62757
- const comparisonPath = join27(artifactDir, "comparisons.json");
63167
+ const comparisonPath = join28(artifactDir, "comparisons.json");
62758
63168
  const assignment = modelAssignment(entrants, models);
62759
63169
  const phaseUsage = {
62760
63170
  attempts: fold_usage(attemptResults),
@@ -62790,7 +63200,7 @@ The previous report was invalid. Return the required JSON schema exactly once.`,
62790
63200
  await writeLedger(fold_usage([]));
62791
63201
  const winner = ranking[0];
62792
63202
  const winnerEntrant = entrants[winner.index];
62793
- const resultPath = join27(artifactDir, "winner.md");
63203
+ const resultPath = join28(artifactDir, "winner.md");
62794
63204
  const reducer = await ctx.task("comparisons-reducer", {
62795
63205
  prompt: renderComparisonsReducerPrompt({
62796
63206
  task: ctx.inputs.prompt,
@@ -64224,13 +64634,13 @@ var init_sql_pool_queue = __esm(() => {
64224
64634
  });
64225
64635
 
64226
64636
  // dist/builtin/workflows/src/engine/session-closed-error.ts
64227
- import { isStaleExtensionContextError as isStaleExtensionContextError6 } from "@bastani/atomic";
64637
+ import { isStaleExtensionContextError as isStaleExtensionContextError7 } from "@bastani/atomic";
64228
64638
  function reportsClosedSession(error) {
64229
- return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError6(error);
64639
+ return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError7(error);
64230
64640
  }
64231
64641
  function isSessionClosedError(error) {
64232
64642
  let current = error;
64233
- for (let depth = 0;depth < MAX_CAUSE_DEPTH2 && current !== undefined; depth++) {
64643
+ for (let depth = 0;depth < MAX_CAUSE_DEPTH4 && current !== undefined; depth++) {
64234
64644
  try {
64235
64645
  if (reportsClosedSession(current))
64236
64646
  return true;
@@ -64241,7 +64651,7 @@ function isSessionClosedError(error) {
64241
64651
  }
64242
64652
  return false;
64243
64653
  }
64244
- var MAX_CAUSE_DEPTH2 = 8;
64654
+ var MAX_CAUSE_DEPTH4 = 8;
64245
64655
  var init_session_closed_error = () => {};
64246
64656
 
64247
64657
  // dist/builtin/workflows/src/shared/external-run-routes.ts
@@ -65732,24 +66142,24 @@ function createMessageReader(onMessage, onError) {
65732
66142
  }
65733
66143
 
65734
66144
  // dist/builtin/intercom/broker/broker-status.ts
65735
- function isObject(value2) {
66145
+ function isObject2(value2) {
65736
66146
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
65737
66147
  }
65738
66148
  function isOptionalString2(value2) {
65739
66149
  return value2 === undefined || typeof value2 === "string";
65740
66150
  }
65741
66151
  function isBrokerStatusReport(value2) {
65742
- if (!isObject(value2) || typeof value2.pid !== "number" || typeof value2.sessions !== "number")
66152
+ if (!isObject2(value2) || typeof value2.pid !== "number" || typeof value2.sessions !== "number")
65743
66153
  return false;
65744
66154
  const { storage, multiNode } = value2;
65745
- if (storage !== undefined && (!isObject(storage) || typeof storage.digest !== "string" || storage.source !== "env" && storage.source !== "settings"))
66155
+ if (storage !== undefined && (!isObject2(storage) || typeof storage.digest !== "string" || storage.source !== "env" && storage.source !== "settings"))
65746
66156
  return false;
65747
- return isObject(multiNode) && (multiNode.status === "off" || multiNode.status === "starting" || multiNode.status === "on" || multiNode.status === "unavailable") && isOptionalString2(multiNode.reason) && isOptionalString2(multiNode.adapter) && isOptionalString2(multiNode.prefix) && (multiNode.peers === undefined || Array.isArray(multiNode.peers) && multiNode.peers.every((peer) => typeof peer === "string"));
66157
+ return isObject2(multiNode) && (multiNode.status === "off" || multiNode.status === "starting" || multiNode.status === "on" || multiNode.status === "unavailable") && isOptionalString2(multiNode.reason) && isOptionalString2(multiNode.adapter) && isOptionalString2(multiNode.prefix) && (multiNode.peers === undefined || Array.isArray(multiNode.peers) && multiNode.peers.every((peer) => typeof peer === "string"));
65748
66158
  }
65749
66159
 
65750
66160
  // dist/builtin/intercom/broker/paths.ts
65751
66161
  import { homedir as homedir2 } from "os";
65752
- import { join as join28 } from "path";
66162
+ import { join as join29 } from "path";
65753
66163
  function getHomeDir() {
65754
66164
  if (process.platform === "win32") {
65755
66165
  if (process.env.USERPROFILE)
@@ -65766,7 +66176,7 @@ function expandTildePath(path) {
65766
66176
  if (path === "~")
65767
66177
  return getHomeDir();
65768
66178
  if (path.startsWith("~/") || process.platform === "win32" && path.startsWith("~\\")) {
65769
- return join28(getHomeDir(), path.slice(2));
66179
+ return join29(getHomeDir(), path.slice(2));
65770
66180
  }
65771
66181
  return path;
65772
66182
  }
@@ -65777,31 +66187,31 @@ function getAgentDir5() {
65777
66187
  const piAgentDir = process.env.PI_CODING_AGENT_DIR;
65778
66188
  if (piAgentDir)
65779
66189
  return expandTildePath(piAgentDir);
65780
- return join28(getHomeDir(), ".atomic", "agent");
66190
+ return join29(getHomeDir(), ".atomic", "agent");
65781
66191
  }
65782
66192
  function sanitizePipeSegment(value2) {
65783
66193
  return value2.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "default";
65784
66194
  }
65785
66195
  function getIntercomDirPath(agentDir = getAgentDir5()) {
65786
- return join28(agentDir, "intercom");
66196
+ return join29(agentDir, "intercom");
65787
66197
  }
65788
66198
  function getBrokerPidPath(agentDir = getAgentDir5()) {
65789
- return join28(getIntercomDirPath(agentDir), "broker.pid");
66199
+ return join29(getIntercomDirPath(agentDir), "broker.pid");
65790
66200
  }
65791
66201
  function getBrokerSpawnLockPath(agentDir = getAgentDir5()) {
65792
- return join28(getIntercomDirPath(agentDir), "broker.spawn.lock");
66202
+ return join29(getIntercomDirPath(agentDir), "broker.spawn.lock");
65793
66203
  }
65794
66204
  function getBrokerLogPath(agentDir = getAgentDir5()) {
65795
- return join28(getIntercomDirPath(agentDir), "broker.log");
66205
+ return join29(getIntercomDirPath(agentDir), "broker.log");
65796
66206
  }
65797
66207
  function getBrokerStartAnnouncementPath(agentDir = getAgentDir5()) {
65798
- return join28(getIntercomDirPath(agentDir), "broker.starting");
66208
+ return join29(getIntercomDirPath(agentDir), "broker.starting");
65799
66209
  }
65800
66210
  function getBrokerSocketPath(platform = process.platform, agentDir = getAgentDir5()) {
65801
66211
  if (platform === "win32") {
65802
66212
  return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(agentDir)}`;
65803
66213
  }
65804
- return join28(getIntercomDirPath(agentDir), "broker.sock");
66214
+ return join29(getIntercomDirPath(agentDir), "broker.sock");
65805
66215
  }
65806
66216
  var BROKER_STORAGE_ENV = "ATOMIC_STORAGE";
65807
66217
  var init_paths = () => {};
@@ -67508,26 +67918,26 @@ var init_start_announcement = () => {};
67508
67918
  // dist/builtin/intercom/broker/spawn.ts
67509
67919
  import { spawn } from "child_process";
67510
67920
  import { randomUUID as randomUUID15 } from "crypto";
67511
- import { appendFileSync, chmodSync, closeSync as closeSync3, existsSync as existsSync7, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync7, readSync as readSync2, statSync as statSync5, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "fs";
67512
- import { join as join29, dirname as dirname14 } from "path";
67921
+ import { appendFileSync, chmodSync, closeSync as closeSync4, existsSync as existsSync7, mkdirSync as mkdirSync9, openSync as openSync4, readFileSync as readFileSync7, readSync as readSync2, statSync as statSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "fs";
67922
+ import { join as join30, dirname as dirname14 } from "path";
67513
67923
  import { fileURLToPath as fileURLToPath5 } from "url";
67514
67924
  import { createRequire as createRequire3 } from "module";
67515
67925
  import { createChildProcessEnvironment as createChildProcessEnvironment4, isBunBinary, processSharedStorageSelection } from "@bastani/atomic";
67516
67926
  function isIntercomPackageRoot(dir) {
67517
- return existsSync7(join29(dir, "package.json")) && existsSync7(join29(dir, "broker"));
67927
+ return existsSync7(join30(dir, "package.json")) && existsSync7(join30(dir, "broker"));
67518
67928
  }
67519
67929
  function resolveIntercomPackageRoot(moduleHref) {
67520
67930
  const here = dirname14(fileURLToPath5(moduleHref));
67521
67931
  if (isIntercomPackageRoot(here))
67522
67932
  return here;
67523
- return join29(here, "..");
67933
+ return join30(here, "..");
67524
67934
  }
67525
67935
  function resolveBrokerEntrypoint(packageRoot) {
67526
- const bundled = join29(packageRoot, "broker", "broker.bundle.mjs");
67527
- return existsSync7(bundled) ? bundled : join29(packageRoot, "broker", "broker.ts");
67936
+ const bundled = join30(packageRoot, "broker", "broker.bundle.mjs");
67937
+ return existsSync7(bundled) ? bundled : join30(packageRoot, "broker", "broker.ts");
67528
67938
  }
67529
67939
  function ensurePrivateDirectory(path) {
67530
- mkdirSync8(path, { recursive: true, mode: 448 });
67940
+ mkdirSync9(path, { recursive: true, mode: 448 });
67531
67941
  if (process.platform !== "win32")
67532
67942
  chmodSync(path, 448);
67533
67943
  }
@@ -67540,14 +67950,14 @@ function getCurrentBrokerRuntime() {
67540
67950
  return isBunBinary ? "bun-binary" : "bun-source";
67541
67951
  }
67542
67952
  function requireFromExtensionDir(extensionDir) {
67543
- return createRequire3(join29(extensionDir, "package.json"));
67953
+ return createRequire3(join30(extensionDir, "package.json"));
67544
67954
  }
67545
67955
  function getJitiCliPath(extensionDir = EXTENSION_DIR) {
67546
67956
  try {
67547
67957
  const jitiPackage = requireFromExtensionDir(extensionDir).resolve("jiti/package.json");
67548
- return join29(dirname14(jitiPackage), "lib", "jiti-cli.mjs");
67958
+ return join30(dirname14(jitiPackage), "lib", "jiti-cli.mjs");
67549
67959
  } catch {
67550
- return join29(extensionDir, "node_modules", "jiti", "lib", "jiti-cli.mjs");
67960
+ return join30(extensionDir, "node_modules", "jiti", "lib", "jiti-cli.mjs");
67551
67961
  }
67552
67962
  }
67553
67963
  function getDefaultBrokerRunnerPath(extensionDir) {
@@ -67569,7 +67979,7 @@ function quoteWindowsArg(value2) {
67569
67979
  return `"${value2.replace(/"/g, '""')}"`;
67570
67980
  }
67571
67981
  function getWindowsHiddenLauncherPath(intercomDir = INTERCOM_DIR) {
67572
- return join29(intercomDir, "broker-launch.vbs");
67982
+ return join30(intercomDir, "broker-launch.vbs");
67573
67983
  }
67574
67984
  function usesDefaultBrokerCommand(brokerCommand, brokerArgs) {
67575
67985
  return brokerCommand === "npx" && brokerArgs.length === 2 && brokerArgs[0] === "--no-install" && brokerArgs[1] === "tsx";
@@ -67643,7 +68053,7 @@ function resetBrokerLog(logPath = BROKER_LOG) {
67643
68053
  ensurePrivateDirectory(dirname14(logPath));
67644
68054
  try {
67645
68055
  const previous = readBrokerLogTail(logPath);
67646
- closeSync3(openSync3(logPath, "w"));
68056
+ closeSync4(openSync4(logPath, "w"));
67647
68057
  if (previous.length > 0) {
67648
68058
  try {
67649
68059
  const previousPath = `${logPath}.previous`;
@@ -67672,8 +68082,8 @@ async function resetBrokerLogOnceReleased() {
67672
68082
  function readBrokerLogTail(logPath = BROKER_LOG, maxBytes = BROKER_LOG_TAIL_BYTES) {
67673
68083
  let fd;
67674
68084
  try {
67675
- fd = openSync3(logPath, "r");
67676
- const size = statSync5(logPath).size;
68085
+ fd = openSync4(logPath, "r");
68086
+ const size = statSync6(logPath).size;
67677
68087
  const length = Math.min(size, maxBytes);
67678
68088
  if (length <= 0)
67679
68089
  return "";
@@ -67685,7 +68095,7 @@ function readBrokerLogTail(logPath = BROKER_LOG, maxBytes = BROKER_LOG_TAIL_BYTE
67685
68095
  } finally {
67686
68096
  if (fd !== undefined) {
67687
68097
  try {
67688
- closeSync3(fd);
68098
+ closeSync4(fd);
67689
68099
  } catch {}
67690
68100
  }
67691
68101
  }
@@ -67731,13 +68141,13 @@ async function spawnBrokerIfNeeded(brokerCommand, brokerArgs, readyTimeoutMs = B
67731
68141
  await waitForBroker(readyTimeoutMs);
67732
68142
  return;
67733
68143
  }
67734
- const logFd = launch.kind === "direct" ? openSync3(BROKER_LOG, "a") : undefined;
68144
+ const logFd = launch.kind === "direct" ? openSync4(BROKER_LOG, "a") : undefined;
67735
68145
  let child;
67736
68146
  try {
67737
68147
  child = spawn(launch.command, launch.args, getBrokerSpawnOptions(extensionDir, logFd ?? "ignore", announcement));
67738
68148
  } finally {
67739
68149
  if (logFd !== undefined)
67740
- closeSync3(logFd);
68150
+ closeSync4(logFd);
67741
68151
  }
67742
68152
  child.unref();
67743
68153
  await new Promise((resolve, reject) => {
@@ -68550,12 +68960,12 @@ var init_sql_pool_usage = __esm(() => {
68550
68960
 
68551
68961
  // dist/builtin/workflows/src/workers/pooled-watch-trace.ts
68552
68962
  import { appendFileSync as appendFileSync2 } from "node:fs";
68553
- import { dirname as dirname15, join as join30, resolve as resolve14 } from "node:path";
68963
+ import { dirname as dirname15, join as join31, resolve as resolve14 } from "node:path";
68554
68964
  function configurePooledWatchTrace(journalPath, processRole) {
68555
68965
  if (setting === undefined || setting === "" || setting === "0")
68556
68966
  return;
68557
68967
  role = processRole;
68558
- file = setting === "1" ? join30(dirname15(resolve14(journalPath)), "pooled-watch-trace.jsonl") : resolve14(setting);
68968
+ file = setting === "1" ? join31(dirname15(resolve14(journalPath)), "pooled-watch-trace.jsonl") : resolve14(setting);
68559
68969
  }
68560
68970
  function tracePooledWatch(step, detail) {
68561
68971
  if (file === undefined)
@@ -68749,7 +69159,7 @@ import { fork } from "node:child_process";
68749
69159
  import { randomUUID as randomUUID17 } from "node:crypto";
68750
69160
  import { createWriteStream } from "node:fs";
68751
69161
  import { appendFile, mkdir as mkdir6, rm as rm3, rmdir } from "node:fs/promises";
68752
- import { dirname as dirname16, join as join31, resolve as resolve15 } from "node:path";
69162
+ import { dirname as dirname16, join as join32, resolve as resolve15 } from "node:path";
68753
69163
  import { setTimeout as delay2 } from "node:timers/promises";
68754
69164
  function isRootLeaseLost(error) {
68755
69165
  return error instanceof StaleLeaseError || error.message.startsWith("Stale lease for run ");
@@ -68758,7 +69168,7 @@ function unconfirmedCleanup(groups) {
68758
69168
  return new Error(`Local worker process cleanup unconfirmed; ${groups.length > 0 ? `process groups ${groups.join(", ")} still running after SIGKILL; ` : ""}permits quarantined`);
68759
69169
  }
68760
69170
  function workerLogDirectory(journalPath, root) {
68761
- return join31(dirname16(resolve15(journalPath)), "worker-logs", encodeURIComponent(root).replaceAll(".", "%2E"));
69171
+ return join32(dirname16(resolve15(journalPath)), "worker-logs", encodeURIComponent(root).replaceAll(".", "%2E"));
68762
69172
  }
68763
69173
  function token(work) {
68764
69174
  return {
@@ -69690,7 +70100,7 @@ class PoolCoordinator {
69690
70100
  this.slots.add(slot);
69691
70101
  let ready = false;
69692
70102
  let serial = Promise.resolve();
69693
- const logPath = join31(this.logDirectory, `${worker}.log`);
70103
+ const logPath = join32(this.logDirectory, `${worker}.log`);
69694
70104
  this.logs.set(child, logPath);
69695
70105
  let logFailure;
69696
70106
  const log = createWriteStream(logPath, { flags: "a" });
@@ -74404,7 +74814,7 @@ function describeErrorWithCauses(error) {
74404
74814
  const messages = [];
74405
74815
  const visited = new Set;
74406
74816
  let current = error;
74407
- for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH3 && !visited.has(current); depth++) {
74817
+ for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH5 && !visited.has(current); depth++) {
74408
74818
  visited.add(current);
74409
74819
  const message = current instanceof Error ? current.message : String(current);
74410
74820
  if (!messages.includes(message))
@@ -74413,7 +74823,7 @@ function describeErrorWithCauses(error) {
74413
74823
  }
74414
74824
  return messages.join(": ");
74415
74825
  }
74416
- var MAX_CAUSE_DEPTH3 = 5;
74826
+ var MAX_CAUSE_DEPTH5 = 5;
74417
74827
 
74418
74828
  // dist/builtin/workflows/src/engine/run-durable-finalize.ts
74419
74829
  async function finalizeDurableTerminalStatus(input) {
@@ -74877,407 +75287,6 @@ function deferStageUntilRunRelease(input) {
74877
75287
  };
74878
75288
  }
74879
75289
 
74880
- // dist/builtin/workflows/src/engine/run-rejection-boundary.ts
74881
- import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
74882
- import { inspect } from "node:util";
74883
- import { isStaleExtensionContextError as isStaleExtensionContextError7 } from "@bastani/atomic";
74884
- function boundaryBag() {
74885
- return globalThis;
74886
- }
74887
- function sharedBoundary() {
74888
- const bag = boundaryBag();
74889
- const existing = bag[BOUNDARY_KEY];
74890
- if (existing !== undefined && existing.version === 5)
74891
- return existing;
74892
- const created = {
74893
- version: 5,
74894
- store: new AsyncLocalStorage4,
74895
- owners: new WeakMap,
74896
- promises: new WeakMap,
74897
- scopes: new Set,
74898
- runs: new Map,
74899
- ended: new Map,
74900
- stops: new Set,
74901
- listener: undefined
74902
- };
74903
- bag[BOUNDARY_KEY] = created;
74904
- return created;
74905
- }
74906
- function isObject2(value2) {
74907
- return typeof value2 === "object" && value2 !== null || typeof value2 === "function";
74908
- }
74909
- function isPrimitive(value2) {
74910
- return !isObject2(value2);
74911
- }
74912
- function safeField3(value2, key) {
74913
- try {
74914
- return value2[key];
74915
- } catch {
74916
- return;
74917
- }
74918
- }
74919
- function strongerEffect(left, right) {
74920
- return left === "fail-run" || right === "fail-run" ? "fail-run" : "ignore";
74921
- }
74922
- function addAttribution(into, scope, effect) {
74923
- into.set(scope, strongerEffect(into.get(scope), effect));
74924
- }
74925
- function recordedOwners(boundary, reason) {
74926
- const owners = new Map;
74927
- let stopped = false;
74928
- const seen = new Set;
74929
- const pending = [{ value: reason, depth: 0 }];
74930
- while (pending.length > 0) {
74931
- const { value: value2, depth } = pending.pop();
74932
- if (depth > MAX_CAUSE_DEPTH4)
74933
- continue;
74934
- if (isPrimitive(value2)) {
74935
- if (depth === 0 || value2 !== undefined && value2 !== null) {
74936
- for (const scope of boundary.scopes) {
74937
- const entry = scope.primitives.get(value2);
74938
- if (entry !== undefined)
74939
- addAttribution(owners, scope, entry.effect);
74940
- }
74941
- if (typeof value2 === "string" && boundary.stops.has(value2))
74942
- stopped = true;
74943
- }
74944
- continue;
74945
- }
74946
- if (seen.has(value2))
74947
- continue;
74948
- seen.add(value2);
74949
- for (const [scope, effect] of boundary.owners.get(value2) ?? [])
74950
- addAttribution(owners, scope, effect);
74951
- pending.push({ value: safeField3(value2, "cause"), depth: depth + 1 });
74952
- const errors = safeField3(value2, "errors");
74953
- if (Array.isArray(errors))
74954
- for (const entry of errors)
74955
- pending.push({ value: entry, depth: depth + 1 });
74956
- }
74957
- return { owners, stopped };
74958
- }
74959
- function pruneEndedSources(boundary) {
74960
- const now = Date.now();
74961
- for (const [source, trees] of boundary.ended) {
74962
- for (const [rootRunId, endedAt] of trees)
74963
- if (now - endedAt > ENDED_RUN_GRACE_MS)
74964
- trees.delete(rootRunId);
74965
- if (trees.size === 0)
74966
- boundary.ended.delete(source);
74967
- }
74968
- }
74969
- function recordEndedRun(boundary, scope) {
74970
- if (scope.source === undefined)
74971
- return;
74972
- const trees = boundary.ended.get(scope.source) ?? new Map;
74973
- trees.set(scope.rootRunId, Date.now());
74974
- boundary.ended.set(scope.source, trees);
74975
- }
74976
- function endedInAnotherRunTree(boundary, source, live) {
74977
- for (const endedRoot of boundary.ended.get(source)?.keys() ?? [])
74978
- if (endedRoot !== live.rootRunId)
74979
- return true;
74980
- return false;
74981
- }
74982
- function recognizedSources(boundary) {
74983
- pruneEndedSources(boundary);
74984
- const sources = new Set(boundary.ended.keys());
74985
- for (const scope of boundary.scopes)
74986
- if (scope.live && scope.source !== undefined)
74987
- sources.add(scope.source);
74988
- return sources;
74989
- }
74990
- function authoringSource(reason, sources) {
74991
- if (sources.size === 0 || !isObject2(reason))
74992
- return;
74993
- const stack = safeField3(reason, "stack");
74994
- if (typeof stack !== "string")
74995
- return;
74996
- for (const line of stack.split(`
74997
- `)) {
74998
- if (!line.trimStart().startsWith("at "))
74999
- continue;
75000
- const path = parsePromptStackFrame(line)?.normalizedPath;
75001
- if (path === undefined)
75002
- continue;
75003
- if (isWorkflowRuntimeModule(path))
75004
- return;
75005
- if (/\/node_modules\//.test(path))
75006
- continue;
75007
- if (sources.has(path))
75008
- return path;
75009
- }
75010
- return;
75011
- }
75012
- function hasAncestorIn(scope, candidates) {
75013
- for (let ancestor = scope.parent;ancestor !== undefined; ancestor = ancestor.parent) {
75014
- if (candidates.has(ancestor))
75015
- return true;
75016
- }
75017
- return false;
75018
- }
75019
- function outermostLiveRuns(boundary, source) {
75020
- const matching = new Set;
75021
- for (const scope of boundary.scopes)
75022
- if (scope.live && scope.source === source)
75023
- matching.add(scope);
75024
- const outermost = new Set;
75025
- for (const scope of matching)
75026
- if (!hasAncestorIn(scope, matching))
75027
- outermost.add(scope);
75028
- return outermost;
75029
- }
75030
- function runOfSource(boundary, source) {
75031
- const [only, ...others] = outermostLiveRuns(boundary, source);
75032
- if (only === undefined)
75033
- return new Map;
75034
- if (others.length > 0 || only.sharedSource)
75035
- return;
75036
- if (endedInAnotherRunTree(boundary, source, only))
75037
- return;
75038
- return new Map([[only, "fail-run"]]);
75039
- }
75040
- function markSharedSource(boundary, source) {
75041
- const runs = outermostLiveRuns(boundary, source);
75042
- if (runs.size > 1)
75043
- for (const run of runs)
75044
- run.sharedSource = true;
75045
- }
75046
- function rejectingRun(boundary, recorded, promise, scoped) {
75047
- const tracked = promise === undefined ? undefined : boundary.promises.get(promise);
75048
- if (tracked !== undefined && recorded.has(tracked))
75049
- return tracked;
75050
- if (scoped !== undefined && recorded.has(scoped))
75051
- return scoped;
75052
- return;
75053
- }
75054
- function attribute(boundary, reason, promise) {
75055
- const { owners: recorded, stopped } = recordedOwners(boundary, reason);
75056
- const scoped = boundary.store.getStore();
75057
- if (recorded.size > 1) {
75058
- const rejecting = rejectingRun(boundary, recorded, promise, scoped);
75059
- if (rejecting !== undefined)
75060
- return new Map([[rejecting, recorded.get(rejecting) ?? "fail-run"]]);
75061
- }
75062
- if (recorded.size > 0)
75063
- return recorded;
75064
- if (stopped)
75065
- return new Map;
75066
- if (scoped !== undefined && boundary.scopes.has(scoped))
75067
- return new Map([[scoped, "fail-run"]]);
75068
- const origin = authoringSource(reason, recognizedSources(boundary));
75069
- if (origin === undefined)
75070
- return;
75071
- if (scoped !== undefined)
75072
- return new Map([[scoped, "ignore"]]);
75073
- return runOfSource(boundary, origin);
75074
- }
75075
- function unhandledRejectionError(reason) {
75076
- return Object.assign(new Error("This error originated either by throwing inside of an async function without a catch block, " + `or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "${inspect(reason)}".`), { code: "ERR_UNHANDLED_REJECTION" });
75077
- }
75078
- function unhandledRejectionsMode() {
75079
- const args = [...(process.env.NODE_OPTIONS ?? "").split(/\s+/), ...process.execArgv];
75080
- let mode = "throw";
75081
- for (let index = 0;index < args.length; index += 1) {
75082
- const arg = args[index] ?? "";
75083
- if (arg.startsWith(`${FLAG}=`))
75084
- mode = arg.slice(FLAG.length + 1);
75085
- else if (arg === FLAG && args[index + 1] !== undefined)
75086
- mode = args[index + 1] ?? mode;
75087
- }
75088
- return mode;
75089
- }
75090
- function surfaceNatively(boundary, reason) {
75091
- const listener = boundary.listener;
75092
- if (listener === undefined || process.listenerCount(EVENT) > 1)
75093
- return;
75094
- if (!NATIVE_REPORTING_MODES.has(unhandledRejectionsMode()))
75095
- return;
75096
- process.nextTick(() => {
75097
- process.removeListener(EVENT, listener);
75098
- Promise.reject(reason);
75099
- setImmediate(() => {
75100
- if (!process.listeners(EVENT).includes(listener))
75101
- process.on(EVENT, listener);
75102
- });
75103
- });
75104
- }
75105
- function onUnhandledRejection(reason, promise) {
75106
- const boundary = sharedBoundary();
75107
- const owners = attribute(boundary, reason, promise);
75108
- if (owners === undefined) {
75109
- surfaceNatively(boundary, reason);
75110
- return;
75111
- }
75112
- const error = isObject2(reason) ? reason : unhandledRejectionError(reason);
75113
- const staleExtensionContext = isStaleExtensionContextError7(error);
75114
- for (const [scope, effect] of owners) {
75115
- if (effect !== "fail-run" || !scope.live)
75116
- continue;
75117
- if (staleExtensionContext) {
75118
- console.error(`atomic-workflows: run ${scope.runId} ignored a stale extension-context rejection`, error);
75119
- continue;
75120
- }
75121
- try {
75122
- scope.fail(error);
75123
- } catch {}
75124
- }
75125
- }
75126
- function ensureInstalled(boundary) {
75127
- if (boundary.listener !== undefined)
75128
- return;
75129
- boundary.listener = onUnhandledRejection;
75130
- process.on(EVENT, onUnhandledRejection);
75131
- }
75132
- function record(boundary, scope, reason, effect) {
75133
- if (isPrimitive(reason)) {
75134
- recordPrimitive(scope, reason, effect);
75135
- return;
75136
- }
75137
- const owners = boundary.owners.get(reason);
75138
- if (owners === undefined)
75139
- boundary.owners.set(reason, new Map([[scope, effect]]));
75140
- else
75141
- addAttribution(owners, scope, effect);
75142
- }
75143
- function recordStop(boundary, reason) {
75144
- boundary.stops.delete(reason);
75145
- boundary.stops.add(reason);
75146
- if (boundary.stops.size <= MAX_STOP_STRINGS)
75147
- return;
75148
- const oldest = boundary.stops.values().next();
75149
- if (!oldest.done)
75150
- boundary.stops.delete(oldest.value);
75151
- }
75152
- function recordPrimitive(scope, reason, effect) {
75153
- if (!scope.live)
75154
- return;
75155
- if (scope.primitives.size >= MAX_PRIMITIVES_PER_RUN && !scope.primitives.has(reason)) {
75156
- const oldest = scope.primitives.keys().next();
75157
- if (!oldest.done)
75158
- scope.primitives.delete(oldest.value);
75159
- }
75160
- scope.generation += 1;
75161
- const generation = scope.generation;
75162
- scope.primitives.set(reason, { effect: strongerEffect(scope.primitives.get(reason)?.effect, effect), generation });
75163
- afterPendingRejectionReports().then(() => {
75164
- if (scope.primitives.get(reason)?.generation === generation)
75165
- scope.primitives.delete(reason);
75166
- });
75167
- }
75168
- function discardFailure() {}
75169
- function afterPendingRejectionReports() {
75170
- return new Promise((resolve) => {
75171
- const { port1, port2 } = new MessageChannel;
75172
- port1.onmessage = () => {
75173
- port1.close();
75174
- port2.close();
75175
- resolve();
75176
- };
75177
- port2.postMessage(undefined);
75178
- });
75179
- }
75180
- function openRunRejectionScope(options) {
75181
- const boundary = sharedBoundary();
75182
- ensureInstalled(boundary);
75183
- pruneEndedSources(boundary);
75184
- const parent = options.parentRunId === undefined ? undefined : boundary.runs.get(options.parentRunId);
75185
- const scope = {
75186
- runId: options.runId,
75187
- rootRunId: parent?.rootRunId ?? options.runId,
75188
- source: options.source === undefined ? undefined : normalizeStackPath(options.source),
75189
- parent,
75190
- fail: options.fail,
75191
- primitives: new Map,
75192
- generation: 0,
75193
- live: true,
75194
- sharedSource: false
75195
- };
75196
- boundary.scopes.add(scope);
75197
- boundary.runs.set(scope.runId, scope);
75198
- if (scope.source !== undefined)
75199
- markSharedSource(boundary, scope.source);
75200
- return {
75201
- run: (callback) => boundary.store.run(scope, callback),
75202
- contain: (promise, effect = "fail-run") => {
75203
- boundary.promises.set(promise, scope);
75204
- promise.then(undefined, (reason) => record(boundary, scope, reason, effect));
75205
- return promise;
75206
- },
75207
- watch: (promise) => {
75208
- const watched = promise.then(undefined, (reason) => {
75209
- record(boundary, scope, reason, "fail-run");
75210
- throw reason;
75211
- });
75212
- boundary.promises.set(watched, scope);
75213
- return watched;
75214
- },
75215
- ignore: (reason) => {
75216
- if (typeof reason === "string")
75217
- recordStop(boundary, reason);
75218
- else
75219
- record(boundary, scope, reason, "ignore");
75220
- },
75221
- settle: afterPendingRejectionReports,
75222
- close: () => {
75223
- scope.live = false;
75224
- scope.fail = discardFailure;
75225
- recordEndedRun(boundary, scope);
75226
- afterPendingRejectionReports().then(() => {
75227
- scope.primitives.clear();
75228
- scope.parent = undefined;
75229
- boundary.scopes.delete(scope);
75230
- if (boundary.runs.get(scope.runId) === scope)
75231
- boundary.runs.delete(scope.runId);
75232
- });
75233
- }
75234
- };
75235
- }
75236
- function containStageRejections(stage, scope) {
75237
- const contained = Object.create(stage);
75238
- const descriptors = {};
75239
- for (const name of WATCHED_STAGE_METHODS) {
75240
- descriptors[name] = {
75241
- value: (...args) => {
75242
- const result = Reflect.apply(stage[name], stage, args);
75243
- return result instanceof Promise ? scope.watch(result) : result;
75244
- }
75245
- };
75246
- }
75247
- Object.defineProperties(contained, descriptors);
75248
- return contained;
75249
- }
75250
- function containUiRejections(ui, scope) {
75251
- return {
75252
- input: (prompt) => scope.watch(ui.input(prompt)),
75253
- confirm: (message) => scope.watch(ui.confirm(message)),
75254
- select: (message, options) => scope.watch(ui.select(message, options)),
75255
- editor: (initial) => scope.watch(ui.editor(initial)),
75256
- custom: (factory, options) => scope.watch(ui.custom(factory, options))
75257
- };
75258
- }
75259
- var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections", MAX_CAUSE_DEPTH4 = 8, MAX_PRIMITIVES_PER_RUN = 64, MAX_STOP_STRINGS = 64, ENDED_RUN_GRACE_MS = 30000, NATIVE_REPORTING_MODES, WATCHED_STAGE_METHODS;
75260
- var init_run_rejection_boundary = __esm(() => {
75261
- init_prompt_callsite();
75262
- init_workflow_source();
75263
- BOUNDARY_KEY = Symbol.for("atomic-workflows/run-rejection-boundary@5");
75264
- NATIVE_REPORTING_MODES = new Set(["throw", "warn-with-error-code"]);
75265
- WATCHED_STAGE_METHODS = [
75266
- "prompt",
75267
- "complete",
75268
- "sendUserMessage",
75269
- "steer",
75270
- "followUp",
75271
- "setModel",
75272
- "setThinkingLevel",
75273
- "cycleModel",
75274
- "cycleThinkingLevel",
75275
- "navigateTree",
75276
- "compact",
75277
- "abort"
75278
- ];
75279
- });
75280
-
75281
75290
  // dist/builtin/workflows/src/engine/run-returned-status.ts
75282
75291
  function classifyReturnedRunStatus(result, runSnapshot) {
75283
75292
  const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
@@ -80076,7 +80085,7 @@ var init_stage_runner_controller = __esm(() => {
80076
80085
  // dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts
80077
80086
  import { createHash as createHash5 } from "node:crypto";
80078
80087
  import { mkdir as mkdir7, writeFile as writeFile10 } from "node:fs/promises";
80079
- import { basename as basename5, dirname as dirname17, isAbsolute as isAbsolute11, join as join32, resolve as resolve18 } from "node:path";
80088
+ import { basename as basename5, dirname as dirname17, isAbsolute as isAbsolute11, join as join33, resolve as resolve18 } from "node:path";
80080
80089
  function normalizeMaxOutput2(maxOutput) {
80081
80090
  return {
80082
80091
  bytes: maxOutput?.bytes ?? DEFAULT_MAX_OUTPUT_BYTES,
@@ -80139,7 +80148,7 @@ function formatByteSize(bytes) {
80139
80148
  }
80140
80149
  function transcriptPath(runId, outputPath) {
80141
80150
  const digest = createHash5("sha256").update(outputPath).digest("hex").slice(0, 16);
80142
- return join32(workflowArtifactRunPath(runId), "transcripts", `${digest}-${basename5(outputPath)}.transcript.md`);
80151
+ return join33(workflowArtifactRunPath(runId), "transcripts", `${digest}-${basename5(outputPath)}.transcript.md`);
80143
80152
  }
80144
80153
  function appendContent(lines, content) {
80145
80154
  if (typeof content === "string") {
@@ -81815,6 +81824,7 @@ async function executeRun(def, resolvedInputs, opts) {
81815
81824
  runId,
81816
81825
  ...opts.parentRun !== undefined ? { parentRunId: opts.parentRun.runId } : {},
81817
81826
  ...authoredIn !== undefined ? { source: authoredIn } : {},
81827
+ ...opts.routeConsoleToLog === true ? { consoleLog: true } : {},
81818
81828
  fail: (error) => {
81819
81829
  if (findWorkflowGracefulQuit(error) !== undefined)
81820
81830
  return;
@@ -81823,6 +81833,8 @@ async function executeRun(def, resolvedInputs, opts) {
81823
81833
  ownController.abort(selected.error);
81824
81834
  }
81825
81835
  });
81836
+ const abortOutsideRunScope = ownController.abort.bind(ownController);
81837
+ ownController.abort = (reason) => rejectionScope.run(() => abortOutsideRunScope(reason));
81826
81838
  ownController.signal.addEventListener("abort", () => rejectionScope.ignore(ownController.signal.reason), {
81827
81839
  once: true
81828
81840
  });
@@ -82496,8 +82508,8 @@ var init_workflows_host_module = __esm(() => {
82496
82508
 
82497
82509
  // dist/builtin/workflows/src/workers/pool-journal.ts
82498
82510
  import { createHash as createHash6, randomUUID as randomUUID22 } from "node:crypto";
82499
- import { existsSync as existsSync9, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
82500
- import { basename as basename6, dirname as dirname18, join as join33, resolve as resolve19 } from "node:path";
82511
+ import { existsSync as existsSync9, mkdirSync as mkdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
82512
+ import { basename as basename6, dirname as dirname18, join as join34, resolve as resolve19 } from "node:path";
82501
82513
  import { storageSelectionKey as storageSelectionKey2 } from "@bastani/atomic/storage";
82502
82514
  function encodeOption(value2) {
82503
82515
  if (typeof value2 === "bigint")
@@ -82551,7 +82563,7 @@ function openDurableJournal(durable) {
82551
82563
  return openSelectedRunJournal(decodeSelection(durable.selection), durable.agentDir);
82552
82564
  }
82553
82565
  function poolStateDirectory(agentDir) {
82554
- return join33(dirname18(agentDir), "workflows", "pool");
82566
+ return join34(dirname18(agentDir), "workflows", "pool");
82555
82567
  }
82556
82568
  function databaseIdentity(selection, agentDir) {
82557
82569
  return storageSelectionKey2(selection.kind === "adapter" ? { ...selection, secrets: undefined } : selection, agentDir);
@@ -82559,7 +82571,7 @@ function databaseIdentity(selection, agentDir) {
82559
82571
  function coordinationPath(durable) {
82560
82572
  const selection = decodeSelection(durable.selection);
82561
82573
  const identity = createHash6("sha256").update(databaseIdentity(selection, durable.agentDir)).digest("hex");
82562
- return join33(poolStateDirectory(durable.agentDir), `${identity.slice(0, 24)}.sqlite`);
82574
+ return join34(poolStateDirectory(durable.agentDir), `${identity.slice(0, 24)}.sqlite`);
82563
82575
  }
82564
82576
  function coordinationDatabase(durable) {
82565
82577
  return basename6(coordinationPath(durable), ".sqlite");
@@ -82568,7 +82580,7 @@ function openCoordinationJournal(path) {
82568
82580
  const file = resolve19(path);
82569
82581
  let opened = coordinationJournals.get(file);
82570
82582
  if (opened === undefined) {
82571
- mkdirSync9(dirname18(file), { recursive: true });
82583
+ mkdirSync10(dirname18(file), { recursive: true });
82572
82584
  opened = resolveRunJournal({ journal: { path: file } });
82573
82585
  coordinationJournals.set(file, opened);
82574
82586
  opened.catch(() => {
@@ -82585,13 +82597,13 @@ function poolJournalFor(journal) {
82585
82597
  return coordinations.get(journal) ?? journal;
82586
82598
  }
82587
82599
  function poolHostId(agentDir) {
82588
- const file = join33(poolStateDirectory(agentDir), "host-id");
82600
+ const file = join34(poolStateDirectory(agentDir), "host-id");
82589
82601
  try {
82590
82602
  const existing = readFileSync9(file, "utf8").trim();
82591
82603
  if (existing !== "")
82592
82604
  return existing;
82593
82605
  } catch {}
82594
- mkdirSync9(dirname18(file), { recursive: true });
82606
+ mkdirSync10(dirname18(file), { recursive: true });
82595
82607
  const id = randomUUID22();
82596
82608
  try {
82597
82609
  writeFileSync7(file, `${id}
@@ -82679,18 +82691,18 @@ class CheckpointCatalogIndex {
82679
82691
  stages.push(checkpoint);
82680
82692
  const key = durableStageGroupKey(checkpoint);
82681
82693
  this.groupKeys.set(checkpoint, key);
82682
- append(this.groups, key, checkpoint);
82694
+ append2(this.groups, key, checkpoint);
82683
82695
  const runId = checkpoint.topology?.run?.runId;
82684
82696
  if (runId !== undefined)
82685
- append(this.stagesByRunId, runId, checkpoint);
82697
+ append2(this.stagesByRunId, runId, checkpoint);
82686
82698
  if (checkpoint.output !== undefined)
82687
- append(this.outputsByReplayKey, checkpoint.replayKey, checkpoint);
82699
+ append2(this.outputsByReplayKey, checkpoint.replayKey, checkpoint);
82688
82700
  const boundary = checkpoint.topology?.boundary;
82689
82701
  if (boundary === undefined)
82690
82702
  return;
82691
- append(this.boundariesByReplayKey, checkpoint.replayKey, checkpoint);
82692
- append(this.boundariesByStageId, checkpoint.topology.stageId, checkpoint);
82693
- append(this.boundariesByChildRunId, boundary.child.runId, checkpoint);
82703
+ append2(this.boundariesByReplayKey, checkpoint.replayKey, checkpoint);
82704
+ append2(this.boundariesByStageId, checkpoint.topology.stageId, checkpoint);
82705
+ append2(this.boundariesByChildRunId, boundary.child.runId, checkpoint);
82694
82706
  });
82695
82707
  this.stages = stages;
82696
82708
  }
@@ -82754,7 +82766,7 @@ function hasPrefix(sorted, prefix) {
82754
82766
  function compareCodeUnits(left, right) {
82755
82767
  return left < right ? -1 : left > right ? 1 : 0;
82756
82768
  }
82757
- function append(map, key, value2) {
82769
+ function append2(map, key, value2) {
82758
82770
  const list = map.get(key);
82759
82771
  if (list === undefined)
82760
82772
  map.set(key, [value2]);
@@ -84487,10 +84499,180 @@ __export(exports_builtin, {
84487
84499
 
84488
84500
  // dist/builtin/workflows/src/extension/extension-factory.ts
84489
84501
  init_store_backend();
84490
- import { registerExtensionContextRetirementEffect as registerExtensionContextRetirementEffect3 } from "@bastani/atomic";
84502
+ import { join as join39 } from "node:path";
84503
+ import { getAgentDir as getAgentDir8, registerExtensionContextRetirementEffect as registerExtensionContextRetirementEffect3 } from "@bastani/atomic";
84504
+
84505
+ // dist/builtin/workflows/src/engine/run-console.ts
84506
+ init_run_rejection_boundary();
84507
+ import { closeSync, mkdirSync, openSync, readdirSync, rmSync, statSync, writeSync } from "node:fs";
84508
+ import { join } from "node:path";
84509
+ import { format } from "node:util";
84510
+ var METHODS = ["log", "info", "debug", "warn", "error"];
84511
+ var ROUTER_KEY = Symbol.for("atomic-workflows/run-console@4");
84512
+ var MAX_RUN_CONSOLE_BYTES = 8 * 1024 * 1024;
84513
+ var MAX_PROCESS_CONSOLE_LOG_BYTES = 64 * 1024 * 1024;
84514
+ var CONSOLE_LOG_RETENTION_MS = 14 * 24 * 60 * 60 * 1000;
84515
+ var MAX_CONSOLE_LOG_DIRECTORY_BYTES = 1024 * 1024 * 1024;
84516
+ var MAX_CAUSE_DEPTH2 = 8;
84517
+ var LOG_NAME = /^(\d+)-\d+\.log$/;
84518
+ function routerBag() {
84519
+ return globalThis;
84520
+ }
84521
+ function isAbortCancellation(value2, depth = 0) {
84522
+ try {
84523
+ if (!(value2 instanceof Error) || depth > MAX_CAUSE_DEPTH2)
84524
+ return false;
84525
+ if (value2.name === "AbortError")
84526
+ return true;
84527
+ const cause = value2.cause;
84528
+ return cause !== value2 && isAbortCancellation(cause, depth + 1);
84529
+ } catch {
84530
+ return false;
84531
+ }
84532
+ }
84533
+ function writeAll(fd, text) {
84534
+ const buffer = Buffer.from(text);
84535
+ let offset = 0;
84536
+ while (offset < buffer.length) {
84537
+ const written = writeSync(fd, buffer, offset, buffer.length - offset);
84538
+ if (written <= 0)
84539
+ throw new Error(`wrote ${offset} of ${buffer.length} bytes`);
84540
+ offset += written;
84541
+ }
84542
+ return buffer.length;
84543
+ }
84544
+ function processLog(state, directory) {
84545
+ if (state.log !== undefined)
84546
+ return state.log;
84547
+ const path = join(directory, `${process.pid}-${Date.now()}.log`);
84548
+ const fd = openSync(path, "wx");
84549
+ state.log = { path, fd, bytes: 0, capped: false };
84550
+ return state.log;
84551
+ }
84552
+ function append(log, run, method, args) {
84553
+ if (log.capped || run.capped)
84554
+ return false;
84555
+ const stamp = new Date().toISOString();
84556
+ const processMarker = `${stamp} log limit reached; later workflow console output is dropped
84557
+ `;
84558
+ const fits = (text) => log.bytes + Buffer.byteLength(text) + Buffer.byteLength(processMarker) <= MAX_PROCESS_CONSOLE_LOG_BYTES;
84559
+ const capProcess = () => {
84560
+ log.capped = true;
84561
+ log.bytes += writeAll(log.fd, processMarker);
84562
+ return false;
84563
+ };
84564
+ const line = `${stamp} ${run.rootRunId} ${method} ${format(...args)}
84565
+ `;
84566
+ const size = Buffer.byteLength(line);
84567
+ if (run.bytes + size > MAX_RUN_CONSOLE_BYTES) {
84568
+ run.capped = true;
84569
+ const runMarker = `${stamp} ${run.rootRunId} run log limit reached; its later output is dropped
84570
+ `;
84571
+ if (!fits(runMarker))
84572
+ return capProcess();
84573
+ log.bytes += writeAll(log.fd, runMarker);
84574
+ return false;
84575
+ }
84576
+ if (!fits(line))
84577
+ return capProcess();
84578
+ log.bytes += writeAll(log.fd, line);
84579
+ run.bytes += size;
84580
+ return true;
84581
+ }
84582
+ function write(state, method, args, run, directory) {
84583
+ if (state.failed)
84584
+ return;
84585
+ let log;
84586
+ let written;
84587
+ try {
84588
+ log = processLog(state, directory);
84589
+ written = append(log, run, method, args);
84590
+ } catch (error) {
84591
+ state.failed = true;
84592
+ const path = state.log?.path ?? directory;
84593
+ if (state.log !== undefined) {
84594
+ try {
84595
+ closeSync(state.log.fd);
84596
+ } catch {}
84597
+ state.log = undefined;
84598
+ }
84599
+ const cause = error instanceof Error ? error.message : String(error);
84600
+ state.originals.warn(`atomic-workflows: workflow console output could not be written to ${path} (${cause}); later workflow console output is dropped`);
84601
+ return;
84602
+ }
84603
+ if (written && !run.announced && !args.some((arg) => isAbortCancellation(arg))) {
84604
+ run.announced = true;
84605
+ state.originals.warn(`atomic-workflows: run ${run.rootRunId} console output is in ${log.path}`);
84606
+ }
84607
+ }
84608
+ function routed(state, method) {
84609
+ return (...args) => {
84610
+ const directory = state.logDirectory;
84611
+ const run = directory === undefined ? undefined : currentRunConsole();
84612
+ if (directory === undefined || run === undefined)
84613
+ state.originals[method](...args);
84614
+ else
84615
+ write(state, method, args, run, directory);
84616
+ };
84617
+ }
84618
+ function installedRouter() {
84619
+ const bag = routerBag();
84620
+ const existing = bag[ROUTER_KEY];
84621
+ if (existing !== undefined)
84622
+ return existing;
84623
+ const originals = Object.fromEntries(METHODS.map((method) => [method, console[method].bind(console)]));
84624
+ const state = { logDirectory: undefined, log: undefined, failed: false, originals };
84625
+ for (const method of METHODS)
84626
+ console[method] = routed(state, method);
84627
+ bag[ROUTER_KEY] = state;
84628
+ return state;
84629
+ }
84630
+ function processAlive(pid) {
84631
+ if (pid === process.pid)
84632
+ return true;
84633
+ try {
84634
+ process.kill(pid, 0);
84635
+ return true;
84636
+ } catch (error) {
84637
+ return error.code === "EPERM";
84638
+ }
84639
+ }
84640
+ function pruneLogs(directory, now) {
84641
+ const logs = readdirSync(directory).flatMap((name) => {
84642
+ const pid = LOG_NAME.exec(name)?.[1];
84643
+ if (pid === undefined)
84644
+ return [];
84645
+ const path = join(directory, name);
84646
+ try {
84647
+ const { mtimeMs, size } = statSync(path);
84648
+ return [{ path, mtimeMs, size, live: processAlive(Number(pid)) }];
84649
+ } catch {
84650
+ return [];
84651
+ }
84652
+ });
84653
+ let total = logs.reduce((sum, log) => sum + log.size, 0);
84654
+ for (const log of logs.filter(({ live }) => !live).sort((left, right) => left.mtimeMs - right.mtimeMs)) {
84655
+ if (now - log.mtimeMs < CONSOLE_LOG_RETENTION_MS && total <= MAX_CONSOLE_LOG_DIRECTORY_BYTES)
84656
+ break;
84657
+ try {
84658
+ rmSync(log.path, { force: true });
84659
+ total -= log.size;
84660
+ } catch {}
84661
+ }
84662
+ }
84663
+ function routeWorkflowConsoleOutput(logDirectory, now = Date.now()) {
84664
+ const state = installedRouter();
84665
+ if (state.logDirectory === logDirectory)
84666
+ return;
84667
+ try {
84668
+ mkdirSync(logDirectory, { recursive: true });
84669
+ pruneLogs(logDirectory, now);
84670
+ } catch {}
84671
+ state.logDirectory = logDirectory;
84672
+ }
84491
84673
 
84492
84674
  // dist/builtin/workflows/src/intercom/intercom-routing.ts
84493
- import { isStaleExtensionContextError } from "@bastani/atomic";
84675
+ import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
84494
84676
  function toNoticeLevel(raw) {
84495
84677
  if (raw === "warning" || raw === "error")
84496
84678
  return raw;
@@ -84522,7 +84704,7 @@ function buildIntercomCallbacks(deps) {
84522
84704
  accepted
84523
84705
  });
84524
84706
  } catch (error) {
84525
- if (!isStaleExtensionContextError(error))
84707
+ if (!isStaleExtensionContextError2(error))
84526
84708
  throw error;
84527
84709
  }
84528
84710
  store.ackNotice(noticeId);
@@ -84551,7 +84733,7 @@ function buildIntercomCallbacks(deps) {
84551
84733
  }
84552
84734
 
84553
84735
  // dist/builtin/workflows/src/intercom/result-intercom.ts
84554
- import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
84736
+ import { isStaleExtensionContextError as isStaleExtensionContextError3 } from "@bastani/atomic";
84555
84737
  function subscribeIntercomControl(pi, callbacks) {
84556
84738
  if (typeof pi.events?.on !== "function")
84557
84739
  return null;
@@ -84580,7 +84762,7 @@ function subscribeIntercomControl(pi, callbacks) {
84580
84762
  try {
84581
84763
  unsubscribe = pi.events.on("subagent:control-intercom", handler);
84582
84764
  } catch (error) {
84583
- if (!isStaleExtensionContextError2(error))
84765
+ if (!isStaleExtensionContextError3(error))
84584
84766
  throw error;
84585
84767
  return null;
84586
84768
  }
@@ -84590,7 +84772,7 @@ function subscribeIntercomControl(pi, callbacks) {
84590
84772
  if (typeof unsubscribe === "function")
84591
84773
  unsubscribe();
84592
84774
  } catch (error) {
84593
- if (!isStaleExtensionContextError2(error))
84775
+ if (!isStaleExtensionContextError3(error))
84594
84776
  throw error;
84595
84777
  }
84596
84778
  };
@@ -86501,7 +86683,7 @@ function deriveGraphThemeFromPiTheme(theme) {
86501
86683
  }
86502
86684
 
86503
86685
  // dist/builtin/workflows/src/tui/inline-form-overlay.ts
86504
- import { isStaleExtensionContextError as isStaleExtensionContextError3 } from "@bastani/atomic";
86686
+ import { isStaleExtensionContextError as isStaleExtensionContextError4 } from "@bastani/atomic";
86505
86687
 
86506
86688
  // dist/builtin/workflows/src/tui/header.ts
86507
86689
  function pillFor(run, theme) {
@@ -88219,7 +88401,7 @@ async function openInlineInputsForm(pi, ctx, opts) {
88219
88401
  try {
88220
88402
  return getEditor.call(ctx.ui) === installedFactory;
88221
88403
  } catch (err) {
88222
- if (isStaleExtensionContextError3(err)) {
88404
+ if (isStaleExtensionContextError4(err)) {
88223
88405
  return false;
88224
88406
  }
88225
88407
  return true;
@@ -94960,7 +95142,7 @@ function buildGraphOverlayAdapter(pi, store, buildOpts = {}) {
94960
95142
  import {
94961
95143
  decideReactiveWidgetAction,
94962
95144
  installReactiveWidget,
94963
- isStaleExtensionContextError as isStaleExtensionContextError4
95145
+ isStaleExtensionContextError as isStaleExtensionContextError5
94964
95146
  } from "@bastani/atomic";
94965
95147
 
94966
95148
  // dist/builtin/workflows/src/tui/widget.ts
@@ -95816,7 +95998,7 @@ function installStoreWidget(pi, storeInstance, timers = defaultTimerApi, clock =
95816
95998
  render: (snap, { theme, width, now }) => buildThemedWidgetLines(snap, theme, width, now, layout),
95817
95999
  getNextRefreshDelayMs: (snap, now) => nextWidgetRefreshDelayMs(snap, now),
95818
96000
  requestRenderOnStateNoop: false,
95819
- isStaleError: isStaleExtensionContextError4,
96001
+ isStaleError: isStaleExtensionContextError5,
95820
96002
  onMountError: (error) => {
95821
96003
  reportWidgetFailure(ui, `Workflow progress widget could not mount: ${error.message}`);
95822
96004
  }
@@ -97672,7 +97854,7 @@ function installCompactionHook(api, store) {
97672
97854
  });
97673
97855
  }
97674
97856
  // dist/builtin/workflows/src/extension/config-loader.ts
97675
- import { isAbsolute as isAbsolute12, join as join34 } from "node:path";
97857
+ import { isAbsolute as isAbsolute12, join as join35 } from "node:path";
97676
97858
  import { CONFIG_DIR_NAME as CONFIG_DIR_NAME2, getAgentDir as getAgentDir6 } from "@bastani/atomic";
97677
97859
  // dist/builtin/workflows/src/extension/lifecycle-notifications.ts
97678
97860
  init_returned_run_status();
@@ -98589,7 +98771,7 @@ function resolveWorkflowPaths(workflows, baseDir) {
98589
98771
  }
98590
98772
  return Object.fromEntries(Object.entries(workflows).map(([name, entry]) => [
98591
98773
  name,
98592
- isAbsolute12(entry.path) ? entry.path : join34(baseDir, entry.path)
98774
+ isAbsolute12(entry.path) ? entry.path : join35(baseDir, entry.path)
98593
98775
  ]));
98594
98776
  }
98595
98777
  function workflowAgentDirs(opts) {
@@ -98597,12 +98779,12 @@ function workflowAgentDirs(opts) {
98597
98779
  return opts.agentDirs;
98598
98780
  if (opts.homeDir !== undefined) {
98599
98781
  const homeDir = opts.homeDir;
98600
- return [join34(homeDir, CONFIG_DIR_NAME2, "agent")];
98782
+ return [join35(homeDir, CONFIG_DIR_NAME2, "agent")];
98601
98783
  }
98602
98784
  return [getAgentDir6()];
98603
98785
  }
98604
98786
  function toScopedDiscoveryConfig(globalConfig, projectConfig, opts) {
98605
- const globalBase = opts.agentDir ?? (opts.homeDir === undefined ? getAgentDir6() : join34(opts.homeDir, CONFIG_DIR_NAME2, "agent"));
98787
+ const globalBase = opts.agentDir ?? (opts.homeDir === undefined ? getAgentDir6() : join35(opts.homeDir, CONFIG_DIR_NAME2, "agent"));
98606
98788
  const projectBase = opts.projectRoot;
98607
98789
  const result = {};
98608
98790
  const projectWorkflows = resolveWorkflowPaths(projectConfig?.workflows, projectBase);
@@ -98612,7 +98794,7 @@ function toScopedDiscoveryConfig(globalConfig, projectConfig, opts) {
98612
98794
  if (hasWorkflows(globalConfig)) {
98613
98795
  const projectKeys = new Set(Object.keys(projectWorkflows ?? {}));
98614
98796
  const globalEntries = Object.entries(globalConfig.workflows).filter(([name]) => !projectKeys.has(name)).map(([name, entry]) => {
98615
- return [name, isAbsolute12(entry.path) ? entry.path : join34(globalBase, entry.path)];
98797
+ return [name, isAbsolute12(entry.path) ? entry.path : join35(globalBase, entry.path)];
98616
98798
  });
98617
98799
  if (globalEntries.length > 0) {
98618
98800
  result.globalWorkflows = Object.fromEntries(globalEntries);
@@ -98623,8 +98805,8 @@ function toScopedDiscoveryConfig(globalConfig, projectConfig, opts) {
98623
98805
  async function loadWorkflowConfig(opts = {}) {
98624
98806
  const projectRoot = opts.projectRoot ?? process.cwd();
98625
98807
  const diagnostics = [];
98626
- const globalCandidates = workflowAgentDirs(opts).map((agentDir) => join34(agentDir, "extensions", "workflow", "config.json"));
98627
- const projectCandidates = [join34(projectRoot, CONFIG_DIR_NAME2, "extensions", "workflow", "config.json")];
98808
+ const globalCandidates = workflowAgentDirs(opts).map((agentDir) => join35(agentDir, "extensions", "workflow", "config.json"));
98809
+ const projectCandidates = [join35(projectRoot, CONFIG_DIR_NAME2, "extensions", "workflow", "config.json")];
98628
98810
  let globalConfig = null;
98629
98811
  for (let i = globalCandidates.length - 1;i >= 0; i--) {
98630
98812
  const globalPath = globalCandidates[i];
@@ -100316,7 +100498,7 @@ init_possible_stages();
100316
100498
  import { registerExtensionContextRetirementEffect as registerExtensionContextRetirementEffect2 } from "@bastani/atomic";
100317
100499
 
100318
100500
  // dist/builtin/workflows/src/extension/discovery.ts
100319
- import { join as join36 } from "node:path";
100501
+ import { join as join37 } from "node:path";
100320
100502
  import { CONFIG_DIR_NAME as CONFIG_DIR_NAME3, getAgentDir as getAgentDir7 } from "@bastani/atomic";
100321
100503
 
100322
100504
  // dist/builtin/workflows/builtin/index.ts
@@ -100337,12 +100519,12 @@ init_registry();
100337
100519
  // dist/builtin/workflows/src/extension/discovery-loaders.ts
100338
100520
  init_workflow_module_loader();
100339
100521
  import { readdir as readdir2, stat as stat2 } from "node:fs/promises";
100340
- import { extname, isAbsolute as isAbsolute13, join as join35, resolve as resolve21 } from "node:path";
100522
+ import { extname, isAbsolute as isAbsolute13, join as join36, resolve as resolve21 } from "node:path";
100341
100523
  async function scanWorkflowDir(dir) {
100342
100524
  try {
100343
100525
  const entries = await readdir2(dir, { withFileTypes: true });
100344
100526
  const WORKFLOW_EXTS = new Set([".ts", ".js", ".mjs", ".cjs"]);
100345
- return entries.filter((e) => e.isFile() && WORKFLOW_EXTS.has(extname(e.name))).map((e) => join35(dir, e.name)).sort();
100527
+ return entries.filter((e) => e.isFile() && WORKFLOW_EXTS.has(extname(e.name))).map((e) => join36(dir, e.name)).sort();
100346
100528
  } catch {
100347
100529
  return null;
100348
100530
  }
@@ -100412,7 +100594,7 @@ function workflowAgentDirs2(options) {
100412
100594
  return options.agentDirs;
100413
100595
  if (options?.homeDir !== undefined) {
100414
100596
  const homeDir = options.homeDir;
100415
- return [join36(homeDir, CONFIG_DIR_NAME3, "agent")];
100597
+ return [join37(homeDir, CONFIG_DIR_NAME3, "agent")];
100416
100598
  }
100417
100599
  return [getAgentDir7()];
100418
100600
  }
@@ -100568,7 +100750,7 @@ async function discoverWorkflows(options) {
100568
100750
  registry = await applyBatch(candidates, registry, sources, diagnostics);
100569
100751
  }
100570
100752
  }
100571
- for (const dir of [join36(cwd, CONFIG_DIR_NAME3, "workflows")]) {
100753
+ for (const dir of [join37(cwd, CONFIG_DIR_NAME3, "workflows")]) {
100572
100754
  const candidates = await loadFromDir(dir, "project-local", diagnostics, getWorkflowHostModules);
100573
100755
  registry = await applyBatch(candidates, registry, sources, diagnostics);
100574
100756
  }
@@ -100580,7 +100762,7 @@ async function discoverWorkflows(options) {
100580
100762
  registry = await applyBatch(candidates, registry, sources, diagnostics);
100581
100763
  }
100582
100764
  }
100583
- for (const dir of agentDirs.map((agentDir) => join36(agentDir, "workflows")).reverse()) {
100765
+ for (const dir of agentDirs.map((agentDir) => join37(agentDir, "workflows")).reverse()) {
100584
100766
  const candidates = await loadFromDir(dir, "user-global", diagnostics, getWorkflowHostModules);
100585
100767
  registry = await applyBatch(candidates, registry, sources, diagnostics);
100586
100768
  }
@@ -100887,6 +101069,7 @@ async function dispatch(args, opts) {
100887
101069
  budget: args.budget,
100888
101070
  models: opts.models,
100889
101071
  executionMode: policy.mode,
101072
+ ...opts.routeConsoleToLog === true ? { routeConsoleToLog: true } : {},
100890
101073
  cwd: opts.cwd,
100891
101074
  defaultSessionDir: opts.defaultSessionDir,
100892
101075
  ...opts.origin === undefined ? {} : { origin: opts.origin },
@@ -101275,6 +101458,7 @@ function createExtensionRuntime(opts = {}) {
101275
101458
  models,
101276
101459
  ...defaultSessionDir !== undefined ? { defaultSessionDir } : {},
101277
101460
  ...policy !== undefined ? { executionMode: policy.mode } : {},
101461
+ ...opts.routeConsoleToLog === true ? { routeConsoleToLog: true } : {},
101278
101462
  registry,
101279
101463
  cwd: runtimeCwd,
101280
101464
  [hostWorkerBindings]: true
@@ -101425,6 +101609,7 @@ function createExtensionRuntime(opts = {}) {
101425
101609
  config,
101426
101610
  models,
101427
101611
  resolvePossibleStageEntry,
101612
+ ...opts.routeConsoleToLog === true ? { routeConsoleToLog: true } : {},
101428
101613
  policy: options?.policy,
101429
101614
  modelOwner: options?.modelOwner,
101430
101615
  ...options?.origin === undefined ? {} : { origin: options.origin },
@@ -101455,14 +101640,14 @@ function createExtensionRuntime(opts = {}) {
101455
101640
 
101456
101641
  // dist/builtin/workflows/src/extension/status-writer.ts
101457
101642
  import { mkdir as mkdir8, rename as rename2, writeFile as writeFile11 } from "node:fs/promises";
101458
- import { dirname as dirname19, join as join37 } from "node:path";
101643
+ import { dirname as dirname19, join as join38 } from "node:path";
101459
101644
  import { CONFIG_DIR_NAME as CONFIG_DIR_NAME4 } from "@bastani/atomic";
101460
- var DEFAULT_STATUS_SUBPATH = join37(CONFIG_DIR_NAME4, "workflows", "status.json");
101645
+ var DEFAULT_STATUS_SUBPATH = join38(CONFIG_DIR_NAME4, "workflows", "status.json");
101461
101646
  function resolveStatusFilePath(config, opts = {}) {
101462
101647
  if (config.statusFilePath)
101463
101648
  return config.statusFilePath;
101464
101649
  const root = opts.projectRoot ?? process.cwd();
101465
- return join37(root, DEFAULT_STATUS_SUBPATH);
101650
+ return join38(root, DEFAULT_STATUS_SUBPATH);
101466
101651
  }
101467
101652
  async function atomicWriteJson(path, content) {
101468
101653
  const dir = dirname19(path);
@@ -102662,7 +102847,7 @@ function createWorkflowExtensionRuntimeState(pi, adapters, options = {}) {
102662
102847
  function runtimeForContext(ctx) {
102663
102848
  const contextTrusted = ctx?.isProjectTrusted?.();
102664
102849
  const models = workflowModelCatalogFromContext(ctx, resolveLiveModelContext);
102665
- if (models === undefined && !ctx?.generateWorkflowSummary && contextTrusted === undefined)
102850
+ if (models === undefined && !ctx?.generateWorkflowSummary && contextTrusted === undefined && ctx?.mode !== "tui")
102666
102851
  return runtimeProxy;
102667
102852
  return createExtensionRuntime({
102668
102853
  registry: runtimeRef.current.registry,
@@ -102679,7 +102864,8 @@ function createWorkflowExtensionRuntimeState(pi, adapters, options = {}) {
102679
102864
  ...models === undefined ? {} : { models },
102680
102865
  summaryContext: ctx,
102681
102866
  resolveDefaultStageSessionDir,
102682
- beforeRestoreCompleted
102867
+ beforeRestoreCompleted,
102868
+ ...ctx?.mode === "tui" ? { routeConsoleToLog: true } : {}
102683
102869
  });
102684
102870
  }
102685
102871
  let lazyDiscoveryPromise = null;
@@ -107565,6 +107751,8 @@ function factory(pi) {
107565
107751
  let hostSessionContext;
107566
107752
  pi.on?.("session_start", (_event, ctx) => {
107567
107753
  hostSessionContext = ctx;
107754
+ if (ctx?.mode === "tui")
107755
+ routeWorkflowConsoleOutput(join39(getAgentDir8(), "workflow-logs"));
107568
107756
  });
107569
107757
  const ownerSessionClosing = () => (hostSessionContext?.getCurrentSessionSignal?.() ?? hostSessionContext?.sessionSignal)?.aborted === true;
107570
107758
  const adapters = buildRuntimeAdapters(pi, {