@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.
- package/CHANGELOG.md +24 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +910 -722
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +35 -26
- package/dist/builtin/workflows/src/index.js +35 -26
- package/dist/builtin/workflows/src/local-worker-entry.mjs +35 -26
- package/dist/core/anthropic-thinking-guard.d.ts +5 -4
- package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
- package/dist/core/anthropic-thinking-guard.js +21 -73
- package/dist/core/anthropic-thinking-guard.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +5 -0
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
|
@@ -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
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 :
|
|
8448
|
-
const resolved = selection.kind === "sqlite" && !isAbsolute(selection.path) ? { ...selection, path:
|
|
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
|
|
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 :
|
|
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
|
|
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(
|
|
9068
|
+
if (nonZeroExitCode(safeField2(value2, "exitCode")))
|
|
8659
9069
|
return value2;
|
|
8660
|
-
if (nonEmptyProcessOutput(
|
|
9070
|
+
if (nonEmptyProcessOutput(safeField2(value2, "stdout")))
|
|
8661
9071
|
return value2;
|
|
8662
|
-
if (nonEmptyProcessOutput(
|
|
9072
|
+
if (nonEmptyProcessOutput(safeField2(value2, "stderr")))
|
|
8663
9073
|
return value2;
|
|
8664
9074
|
for (const key of ["cause", "error", "response", "body"]) {
|
|
8665
|
-
const selected = findProcessFailureError(
|
|
9075
|
+
const selected = findProcessFailureError(safeField2(value2, key), seen, depth + 1);
|
|
8666
9076
|
if (selected !== undefined)
|
|
8667
9077
|
return selected;
|
|
8668
9078
|
}
|
|
8669
|
-
const diagnostics =
|
|
9079
|
+
const diagnostics = safeField2(value2, "diagnostics");
|
|
8670
9080
|
if (Array.isArray(diagnostics)) {
|
|
8671
9081
|
for (const diagnostic of diagnostics) {
|
|
8672
|
-
const selected = findProcessFailureError(
|
|
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 =
|
|
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 <
|
|
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,
|
|
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
|
|
10468
|
+
import { join as join4 } from "node:path";
|
|
10059
10469
|
import {
|
|
10060
|
-
isStaleExtensionContextError as
|
|
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 (!
|
|
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 (!
|
|
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 ?
|
|
10488
|
-
modelsPath: options.agentDir ?
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
15835
|
+
return join5(dirname4(getAgentDir4()), "workflows");
|
|
15426
15836
|
}
|
|
15427
15837
|
function workflowArtifactRunsRoot() {
|
|
15428
|
-
return
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
17972
|
+
diffsDir: join13(setup.cwd, CONFIG_DIR_NAME, "workflows", "worktree-diffs", runId, scope),
|
|
17563
17973
|
outputIsolations: tasks.map((_, index) => ({
|
|
17564
|
-
baseDir:
|
|
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
|
|
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 =
|
|
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(
|
|
20876
|
+
candidates.push(join14(dirname11(importingFile), `${specifier.slice(0, -3)}.ts`));
|
|
20467
20877
|
}
|
|
20468
|
-
candidates.push(
|
|
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
|
|
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 =
|
|
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
|
|
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 () =>
|
|
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
|
|
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 =
|
|
57502
|
-
const candidatePath =
|
|
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:
|
|
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 =
|
|
57588
|
-
reviewReportPath =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
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
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
60150
|
-
const evaluationsDir =
|
|
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 =
|
|
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 =
|
|
60160
|
-
const evaluationPath =
|
|
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 =
|
|
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
|
|
60736
|
+
import { mkdirSync as mkdirSync7 } from "node:fs";
|
|
60327
60737
|
import { tmpdir, userInfo } from "node:os";
|
|
60328
|
-
import { join as
|
|
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
|
|
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
|
-
|
|
60377
|
-
|
|
60786
|
+
join24(tmpArtifactBase(), runId),
|
|
60787
|
+
join24(tmpdir(), "open-claude-design", runId)
|
|
60378
60788
|
];
|
|
60379
|
-
const candidates = process.env.NODE_ENV === "test" ? 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
|
-
|
|
60792
|
+
mkdirSync7(candidate, { recursive: true });
|
|
60383
60793
|
return {
|
|
60384
60794
|
runId,
|
|
60385
60795
|
artifactDir: candidate,
|
|
60386
|
-
previewPath:
|
|
60387
|
-
specPath:
|
|
60796
|
+
previewPath: join24(candidate, "preview.html"),
|
|
60797
|
+
specPath: join24(candidate, "spec.html")
|
|
60388
60798
|
};
|
|
60389
60799
|
} catch {}
|
|
60390
60800
|
}
|
|
60391
|
-
const fallback =
|
|
60801
|
+
const fallback = join24(tmpArtifactBase(), runId);
|
|
60392
60802
|
return {
|
|
60393
60803
|
runId,
|
|
60394
60804
|
artifactDir: fallback,
|
|
60395
|
-
previewPath:
|
|
60396
|
-
specPath:
|
|
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
|
|
60731
|
-
import { join as
|
|
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
|
|
61206
|
+
return join25(artifactDir, DESIGN_CONTEXT_FILENAME);
|
|
60797
61207
|
}
|
|
60798
61208
|
function referencesBriefPath(artifactDir) {
|
|
60799
|
-
return
|
|
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 ${
|
|
60826
|
-
`Also run \`agent-browser screenshot ${
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
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
|
|
64637
|
+
import { isStaleExtensionContextError as isStaleExtensionContextError7 } from "@bastani/atomic";
|
|
64228
64638
|
function reportsClosedSession(error) {
|
|
64229
|
-
return "code" in error && error.code === "SessionClosed" ||
|
|
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 <
|
|
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
|
|
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
|
|
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 (!
|
|
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 && (!
|
|
66155
|
+
if (storage !== undefined && (!isObject2(storage) || typeof storage.digest !== "string" || storage.source !== "env" && storage.source !== "settings"))
|
|
65746
66156
|
return false;
|
|
65747
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
66196
|
+
return join29(agentDir, "intercom");
|
|
65787
66197
|
}
|
|
65788
66198
|
function getBrokerPidPath(agentDir = getAgentDir5()) {
|
|
65789
|
-
return
|
|
66199
|
+
return join29(getIntercomDirPath(agentDir), "broker.pid");
|
|
65790
66200
|
}
|
|
65791
66201
|
function getBrokerSpawnLockPath(agentDir = getAgentDir5()) {
|
|
65792
|
-
return
|
|
66202
|
+
return join29(getIntercomDirPath(agentDir), "broker.spawn.lock");
|
|
65793
66203
|
}
|
|
65794
66204
|
function getBrokerLogPath(agentDir = getAgentDir5()) {
|
|
65795
|
-
return
|
|
66205
|
+
return join29(getIntercomDirPath(agentDir), "broker.log");
|
|
65796
66206
|
}
|
|
65797
66207
|
function getBrokerStartAnnouncementPath(agentDir = getAgentDir5()) {
|
|
65798
|
-
return
|
|
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
|
|
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
|
|
67512
|
-
import { join as
|
|
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(
|
|
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
|
|
67933
|
+
return join30(here, "..");
|
|
67524
67934
|
}
|
|
67525
67935
|
function resolveBrokerEntrypoint(packageRoot) {
|
|
67526
|
-
const bundled =
|
|
67527
|
-
return existsSync7(bundled) ? bundled :
|
|
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
|
-
|
|
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(
|
|
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
|
|
67958
|
+
return join30(dirname14(jitiPackage), "lib", "jiti-cli.mjs");
|
|
67549
67959
|
} catch {
|
|
67550
|
-
return
|
|
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
|
|
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
|
-
|
|
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 =
|
|
67676
|
-
const 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
|
-
|
|
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" ?
|
|
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
|
-
|
|
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
|
|
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" ?
|
|
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
|
|
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
|
|
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 =
|
|
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 <
|
|
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
|
|
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
|
|
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
|
|
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
|
|
82500
|
-
import { basename as basename6, dirname as dirname18, join as
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
82694
|
+
append2(this.groups, key, checkpoint);
|
|
82683
82695
|
const runId = checkpoint.topology?.run?.runId;
|
|
82684
82696
|
if (runId !== undefined)
|
|
82685
|
-
|
|
82697
|
+
append2(this.stagesByRunId, runId, checkpoint);
|
|
82686
82698
|
if (checkpoint.output !== undefined)
|
|
82687
|
-
|
|
82699
|
+
append2(this.outputsByReplayKey, checkpoint.replayKey, checkpoint);
|
|
82688
82700
|
const boundary = checkpoint.topology?.boundary;
|
|
82689
82701
|
if (boundary === undefined)
|
|
82690
82702
|
return;
|
|
82691
|
-
|
|
82692
|
-
|
|
82693
|
-
|
|
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
|
|
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 {
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (
|
|
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
|
|
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:
|
|
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
|
|
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 :
|
|
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 [
|
|
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() :
|
|
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 :
|
|
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) =>
|
|
98627
|
-
const projectCandidates = [
|
|
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
|
|
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
|
|
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) =>
|
|
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 [
|
|
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 [
|
|
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) =>
|
|
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
|
|
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 =
|
|
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
|
|
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, {
|