@exaudeus/workrail 3.71.1 → 3.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-worktrain.js +4 -6
- package/dist/console-ui/assets/{index-CsX-nVV7.js → index-Yj9NHqbR.js} +1 -1
- package/dist/console-ui/index.html +1 -1
- package/dist/daemon/active-sessions.d.ts +17 -0
- package/dist/daemon/active-sessions.js +55 -0
- package/dist/daemon/context-loader.d.ts +32 -0
- package/dist/daemon/context-loader.js +34 -0
- package/dist/daemon/session-scope.d.ts +28 -0
- package/dist/daemon/session-scope.js +21 -0
- package/dist/daemon/tools/_shared.d.ts +38 -0
- package/dist/daemon/tools/_shared.js +101 -0
- package/dist/daemon/tools/bash.d.ts +3 -0
- package/dist/daemon/tools/bash.js +57 -0
- package/dist/daemon/tools/continue-workflow.d.ts +6 -0
- package/dist/daemon/tools/continue-workflow.js +208 -0
- package/dist/daemon/tools/file-tools.d.ts +6 -0
- package/dist/daemon/tools/file-tools.js +195 -0
- package/dist/daemon/tools/glob-grep.d.ts +4 -0
- package/dist/daemon/tools/glob-grep.js +172 -0
- package/dist/daemon/tools/report-issue.d.ts +3 -0
- package/dist/daemon/tools/report-issue.js +129 -0
- package/dist/daemon/tools/signal-coordinator.d.ts +4 -0
- package/dist/daemon/tools/signal-coordinator.js +105 -0
- package/dist/daemon/tools/spawn-agent.d.ts +6 -0
- package/dist/daemon/tools/spawn-agent.js +135 -0
- package/dist/daemon/turn-end/conversation-flusher.d.ts +4 -0
- package/dist/daemon/turn-end/conversation-flusher.js +8 -0
- package/dist/daemon/turn-end/detect-stuck.d.ts +2 -0
- package/dist/daemon/turn-end/detect-stuck.js +5 -0
- package/dist/daemon/turn-end/step-injector.d.ts +8 -0
- package/dist/daemon/turn-end/step-injector.js +10 -0
- package/dist/daemon/workflow-runner.d.ts +54 -29
- package/dist/daemon/workflow-runner.js +175 -989
- package/dist/infrastructure/storage/workflow-resolution.js +5 -6
- package/dist/manifest.json +161 -25
- package/dist/mcp/handlers/shared/request-workflow-reader.js +14 -0
- package/dist/trigger/coordinator-deps.d.ts +15 -0
- package/dist/trigger/coordinator-deps.js +322 -0
- package/dist/trigger/delivery-pipeline.d.ts +18 -0
- package/dist/trigger/delivery-pipeline.js +148 -0
- package/dist/trigger/dispatch-deduplicator.d.ts +6 -0
- package/dist/trigger/dispatch-deduplicator.js +24 -0
- package/dist/trigger/trigger-listener.d.ts +2 -3
- package/dist/trigger/trigger-listener.js +9 -276
- package/dist/trigger/trigger-router.d.ts +8 -7
- package/dist/trigger/trigger-router.js +19 -97
- package/dist/v2/usecases/console-routes.js +10 -2
- package/docs/ideas/backlog.md +82 -48
- package/package.json +1 -1
- package/workflows/wr.research.json +158 -0
|
@@ -28,14 +28,13 @@ function resolveWorkflowCandidates(candidates, variantResolutions) {
|
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
30
|
const bundledSource = sources.find(s => s.workflow.source.kind === 'bundled');
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const isWrNamespace = id.startsWith('wr.');
|
|
32
|
+
const nonBundledShadowers = bundledSource && isWrNamespace
|
|
33
|
+
? sources.filter(s => s !== bundledSource)
|
|
33
34
|
: [];
|
|
34
|
-
if (bundledSource &&
|
|
35
|
+
if (bundledSource && nonBundledShadowers.length > 0) {
|
|
35
36
|
const { sourceRef: bundledRef, workflow } = bundledSource;
|
|
36
|
-
const attemptedShadowRefs =
|
|
37
|
-
.filter(s => s !== bundledSource)
|
|
38
|
-
.map(s => s.sourceRef);
|
|
37
|
+
const attemptedShadowRefs = nonBundledShadowers.map(s => s.sourceRef);
|
|
39
38
|
const variantResolution = variantResolutions.get(id)?.get(bundledRef);
|
|
40
39
|
resolved.push({
|
|
41
40
|
workflow,
|
package/dist/manifest.json
CHANGED
|
@@ -238,8 +238,8 @@
|
|
|
238
238
|
"bytes": 31
|
|
239
239
|
},
|
|
240
240
|
"cli-worktrain.js": {
|
|
241
|
-
"sha256": "
|
|
242
|
-
"bytes":
|
|
241
|
+
"sha256": "8e356ca5fdb69b5695af24137ddc54466a1117668181c379b217831f45c46955",
|
|
242
|
+
"bytes": 59895
|
|
243
243
|
},
|
|
244
244
|
"cli.d.ts": {
|
|
245
245
|
"sha256": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
|
|
@@ -473,16 +473,16 @@
|
|
|
473
473
|
"sha256": "5fe866e54f796975dec5d8ba9983aefd86074db212d3fccd64eed04bc9f0b3da",
|
|
474
474
|
"bytes": 8011
|
|
475
475
|
},
|
|
476
|
-
"console-ui/assets/index-CsX-nVV7.js": {
|
|
477
|
-
"sha256": "57fceecd0a6f6e93abe8744b152ff1e13e3c7634ffe16e23ea65a6c974365a44",
|
|
478
|
-
"bytes": 768234
|
|
479
|
-
},
|
|
480
476
|
"console-ui/assets/index-DHrKiMCf.css": {
|
|
481
477
|
"sha256": "40290b50e21ee7e82433efe13b1aa31c1ea608bd057a5c4e324982f284bc928b",
|
|
482
478
|
"bytes": 60673
|
|
483
479
|
},
|
|
480
|
+
"console-ui/assets/index-Yj9NHqbR.js": {
|
|
481
|
+
"sha256": "53bd3633e60fb67314e935d0e4b06c2a7ce92ad6c5ac622a44b8a1cdf2470462",
|
|
482
|
+
"bytes": 768234
|
|
483
|
+
},
|
|
484
484
|
"console-ui/index.html": {
|
|
485
|
-
"sha256": "
|
|
485
|
+
"sha256": "0a06c276d8228a87c2ff7ea5d184e20a0358ca60edfa2583d1de98245235ecbe",
|
|
486
486
|
"bytes": 417
|
|
487
487
|
},
|
|
488
488
|
"console/standalone-console.d.ts": {
|
|
@@ -597,6 +597,14 @@
|
|
|
597
597
|
"sha256": "a3c7ee47d37f111561e2b73f7487670bb4dc894d45931a0745c26fe5acd8c759",
|
|
598
598
|
"bytes": 3493
|
|
599
599
|
},
|
|
600
|
+
"daemon/active-sessions.d.ts": {
|
|
601
|
+
"sha256": "26e768eafba633eb1585ec55759b14a1daffe7b13668116b7bc4cd54c3e559e9",
|
|
602
|
+
"bytes": 563
|
|
603
|
+
},
|
|
604
|
+
"daemon/active-sessions.js": {
|
|
605
|
+
"sha256": "12a7346bd7a7710939c44437f22b1532c5b540bca4effece866c878c723aab80",
|
|
606
|
+
"bytes": 1330
|
|
607
|
+
},
|
|
600
608
|
"daemon/agent-loop.d.ts": {
|
|
601
609
|
"sha256": "a05b27f2cdc7bacd35bb41b9b271367ba9d1f550c9cbf873f1a9b4fa092e8bbb",
|
|
602
610
|
"bytes": 3779
|
|
@@ -605,6 +613,14 @@
|
|
|
605
613
|
"sha256": "aa47bea99cf9a5ce35d2bc375b6dd51a9fbb68d36f2b185ee0a98176f67d647d",
|
|
606
614
|
"bytes": 9803
|
|
607
615
|
},
|
|
616
|
+
"daemon/context-loader.d.ts": {
|
|
617
|
+
"sha256": "db099ae68c8f0fd69503afd49daaf2f84fa0ada9791dc3c5e3278382506b13c5",
|
|
618
|
+
"bytes": 1375
|
|
619
|
+
},
|
|
620
|
+
"daemon/context-loader.js": {
|
|
621
|
+
"sha256": "a3db45565ef02ca178b8d66ea93cb2877def528f3008dc067787d9983c589bd0",
|
|
622
|
+
"bytes": 1255
|
|
623
|
+
},
|
|
608
624
|
"daemon/daemon-env.d.ts": {
|
|
609
625
|
"sha256": "4546caacd79c21b162d2d03c1cde24d4f6d232e684229828722be75d4a33920a",
|
|
610
626
|
"bytes": 213
|
|
@@ -637,6 +653,14 @@
|
|
|
637
653
|
"sha256": "497efb2389e49ec28c73624a580b4bddb4ae2c800c4f50c343bc931aacbe565a",
|
|
638
654
|
"bytes": 247
|
|
639
655
|
},
|
|
656
|
+
"daemon/session-scope.d.ts": {
|
|
657
|
+
"sha256": "1d4c5c8ad79bde16bf49d8f364f1e95a8294896caad8d9e4e16209301505496b",
|
|
658
|
+
"bytes": 1394
|
|
659
|
+
},
|
|
660
|
+
"daemon/session-scope.js": {
|
|
661
|
+
"sha256": "2f5295aa36b8d46b162a2b1f4d6f13af00517796aa468956563a8de46e2ecd56",
|
|
662
|
+
"bytes": 630
|
|
663
|
+
},
|
|
640
664
|
"daemon/soul-template.d.ts": {
|
|
641
665
|
"sha256": "abe720ac2d0bdc23b6e0a2b4aed78ae241b6553fd8f6784d0961a915f54d13c2",
|
|
642
666
|
"bytes": 2245
|
|
@@ -653,13 +677,101 @@
|
|
|
653
677
|
"sha256": "485b7407433f7246af41b6895dd8973efeb05228a9791f327e1dbc581a5c7ef8",
|
|
654
678
|
"bytes": 5921
|
|
655
679
|
},
|
|
680
|
+
"daemon/tools/_shared.d.ts": {
|
|
681
|
+
"sha256": "8cd108061918b5050211015498658ff0ca1a034749a81c5064ddb3e2d85213d3",
|
|
682
|
+
"bytes": 1670
|
|
683
|
+
},
|
|
684
|
+
"daemon/tools/_shared.js": {
|
|
685
|
+
"sha256": "665be333f6c300530410c7b87def06538442bb9b132c706992fbbf133ac2d0f8",
|
|
686
|
+
"bytes": 4410
|
|
687
|
+
},
|
|
688
|
+
"daemon/tools/bash.d.ts": {
|
|
689
|
+
"sha256": "7da73a970983f275477e513d348f6b9cf110edf1c7b72f83d4f2db7e1118a627",
|
|
690
|
+
"bytes": 301
|
|
691
|
+
},
|
|
692
|
+
"daemon/tools/bash.js": {
|
|
693
|
+
"sha256": "4a0cc6709a9a48a5ef1ca4e6531a1f038960865853dc757b4db58d17070653c1",
|
|
694
|
+
"bytes": 2841
|
|
695
|
+
},
|
|
696
|
+
"daemon/tools/continue-workflow.d.ts": {
|
|
697
|
+
"sha256": "592de45416a858a30069b4d55ef69f456c0da476122735918783f76838b49c75",
|
|
698
|
+
"bytes": 1124
|
|
699
|
+
},
|
|
700
|
+
"daemon/tools/continue-workflow.js": {
|
|
701
|
+
"sha256": "9d15df73d901875fe63efcc87533f22c118b6ed5b15b248fc5842e02711d2b0d",
|
|
702
|
+
"bytes": 11377
|
|
703
|
+
},
|
|
704
|
+
"daemon/tools/file-tools.d.ts": {
|
|
705
|
+
"sha256": "a05940e571d7e353007132b4264eb79eb37f1b68fc403e0fc1d4ed6125b54163",
|
|
706
|
+
"bytes": 819
|
|
707
|
+
},
|
|
708
|
+
"daemon/tools/file-tools.js": {
|
|
709
|
+
"sha256": "c47cfc384850bc4f823450fa44bebd507a608f848de7539c1bda537e4c805f68",
|
|
710
|
+
"bytes": 10714
|
|
711
|
+
},
|
|
712
|
+
"daemon/tools/glob-grep.d.ts": {
|
|
713
|
+
"sha256": "13b79eae6df2fa4b736543b821d868399a1659f3b05c60e5efac63fc5ea41b46",
|
|
714
|
+
"bytes": 488
|
|
715
|
+
},
|
|
716
|
+
"daemon/tools/glob-grep.js": {
|
|
717
|
+
"sha256": "44ae5bccd838e255096ff32e75b1f105a1591e605fbf6662a75ceae1dc491441",
|
|
718
|
+
"bytes": 7863
|
|
719
|
+
},
|
|
720
|
+
"daemon/tools/report-issue.d.ts": {
|
|
721
|
+
"sha256": "5f405011b3db32c72c6459912d698b2dcca50c81d224e18c8abd7db0fa876de0",
|
|
722
|
+
"bytes": 326
|
|
723
|
+
},
|
|
724
|
+
"daemon/tools/report-issue.js": {
|
|
725
|
+
"sha256": "33bb5a892edbebcbaa6da0ae94eed0c60ffaa044613acafb72fe02bf118855e7",
|
|
726
|
+
"bytes": 6285
|
|
727
|
+
},
|
|
728
|
+
"daemon/tools/signal-coordinator.d.ts": {
|
|
729
|
+
"sha256": "63e5a2bdfd6260a57365ae74aeb9d566c3233e52da36e246212b5ac9ab9ffbb8",
|
|
730
|
+
"bytes": 338
|
|
731
|
+
},
|
|
732
|
+
"daemon/tools/signal-coordinator.js": {
|
|
733
|
+
"sha256": "da4ffae6dec8930a995bf2452c128fcc05c30f06b96fbbd2a21de9b8c553908b",
|
|
734
|
+
"bytes": 4943
|
|
735
|
+
},
|
|
736
|
+
"daemon/tools/spawn-agent.d.ts": {
|
|
737
|
+
"sha256": "fc6f2f4403c96597041f81abb656fb3499a5d0e9a6f0800f273e444b60912d71",
|
|
738
|
+
"bytes": 605
|
|
739
|
+
},
|
|
740
|
+
"daemon/tools/spawn-agent.js": {
|
|
741
|
+
"sha256": "f740326855d0b051a4d99ce000046df2bc01d446c057980bfb0fe4539605738a",
|
|
742
|
+
"bytes": 7847
|
|
743
|
+
},
|
|
744
|
+
"daemon/turn-end/conversation-flusher.d.ts": {
|
|
745
|
+
"sha256": "5a8c1666ad18c31f49cb34ad2f4b5f134437bfb902dc5f89ea3db568ca44976d",
|
|
746
|
+
"bytes": 314
|
|
747
|
+
},
|
|
748
|
+
"daemon/turn-end/conversation-flusher.js": {
|
|
749
|
+
"sha256": "7a8f294be43e30c0c3a486418bcf42a31e507e2a1b7e793291e97d5b0ffe3c8e",
|
|
750
|
+
"bytes": 382
|
|
751
|
+
},
|
|
752
|
+
"daemon/turn-end/detect-stuck.d.ts": {
|
|
753
|
+
"sha256": "d2d88889b9397d0cb4893f73498c673ba57d264c052485449ef5c3fc50c1d806",
|
|
754
|
+
"bytes": 148
|
|
755
|
+
},
|
|
756
|
+
"daemon/turn-end/detect-stuck.js": {
|
|
757
|
+
"sha256": "a6ec84d4bca121179927ecb21ee7fb798999097bec52491be88e1f6d559357cf",
|
|
758
|
+
"bytes": 309
|
|
759
|
+
},
|
|
760
|
+
"daemon/turn-end/step-injector.d.ts": {
|
|
761
|
+
"sha256": "0f0e8dc1a1db140c2fc9a5b531f4990a284482a63795d13d4874f0f82e4ea6d3",
|
|
762
|
+
"bytes": 247
|
|
763
|
+
},
|
|
764
|
+
"daemon/turn-end/step-injector.js": {
|
|
765
|
+
"sha256": "073b6735f7bfa59c7e7ee398a9290fb15484465640d86f8bf28f06be83d6040f",
|
|
766
|
+
"bytes": 429
|
|
767
|
+
},
|
|
656
768
|
"daemon/workflow-runner.d.ts": {
|
|
657
|
-
"sha256": "
|
|
658
|
-
"bytes":
|
|
769
|
+
"sha256": "7820de494fa093f097dda8782ebea9269d25d2524cf87c3f230bc823363db25e",
|
|
770
|
+
"bytes": 12965
|
|
659
771
|
},
|
|
660
772
|
"daemon/workflow-runner.js": {
|
|
661
|
-
"sha256": "
|
|
662
|
-
"bytes":
|
|
773
|
+
"sha256": "ea88f10400e10af68282fe233b0a34d7b1ab8dde6bde0f74a61665058544db48",
|
|
774
|
+
"bytes": 77654
|
|
663
775
|
},
|
|
664
776
|
"di/container.d.ts": {
|
|
665
777
|
"sha256": "003bb7fb7478d627524b9b1e76bd0a963a243794a687ff233b96dc0e33a06d9f",
|
|
@@ -922,8 +1034,8 @@
|
|
|
922
1034
|
"bytes": 2389
|
|
923
1035
|
},
|
|
924
1036
|
"infrastructure/storage/workflow-resolution.js": {
|
|
925
|
-
"sha256": "
|
|
926
|
-
"bytes":
|
|
1037
|
+
"sha256": "476f99e6e9feb576c6ef4410bcc577d309815b9a874d924972090d9e86d1b93a",
|
|
1038
|
+
"bytes": 5978
|
|
927
1039
|
},
|
|
928
1040
|
"mcp-server.d.ts": {
|
|
929
1041
|
"sha256": "7ead2e703f41c763d04b37a1cf433380bec3551fbde206af6694fe9286ad4714",
|
|
@@ -994,8 +1106,8 @@
|
|
|
994
1106
|
"bytes": 2103
|
|
995
1107
|
},
|
|
996
1108
|
"mcp/handlers/shared/request-workflow-reader.js": {
|
|
997
|
-
"sha256": "
|
|
998
|
-
"bytes":
|
|
1109
|
+
"sha256": "29f648b1e806551703b8f961332d5e7ba5f8d0c1c472a63bc201332e14d9eb61",
|
|
1110
|
+
"bytes": 12198
|
|
999
1111
|
},
|
|
1000
1112
|
"mcp/handlers/shared/with-timeout.d.ts": {
|
|
1001
1113
|
"sha256": "31ca3db008cb5cd439e0d1132bc4b29be0900c403c452931e3a24a50e45beb54",
|
|
@@ -1669,6 +1781,14 @@
|
|
|
1669
1781
|
"sha256": "6728a2169f4007b9ea0414fade6b21500500d9c79d0b09296d92ef8bcabb9c79",
|
|
1670
1782
|
"bytes": 2763
|
|
1671
1783
|
},
|
|
1784
|
+
"trigger/coordinator-deps.d.ts": {
|
|
1785
|
+
"sha256": "cf5ea595ed2e817318744042e1010aab8766617caba9b105a46b9d5d35d2caae",
|
|
1786
|
+
"bytes": 854
|
|
1787
|
+
},
|
|
1788
|
+
"trigger/coordinator-deps.js": {
|
|
1789
|
+
"sha256": "a1f112821bde6c31037442bb3679a3e8b5e9103e6801764cdba6ac9ab191d2bd",
|
|
1790
|
+
"bytes": 15023
|
|
1791
|
+
},
|
|
1672
1792
|
"trigger/delivery-action.d.ts": {
|
|
1673
1793
|
"sha256": "559e2b2645aa60528f73de351cd35ebf45c5b82f47797aa15ddd681319315d39",
|
|
1674
1794
|
"bytes": 1759
|
|
@@ -1685,6 +1805,22 @@
|
|
|
1685
1805
|
"sha256": "da358ced4e99c327493b6d3ca975a623aca21f72e68787a092b2760601801c99",
|
|
1686
1806
|
"bytes": 1269
|
|
1687
1807
|
},
|
|
1808
|
+
"trigger/delivery-pipeline.d.ts": {
|
|
1809
|
+
"sha256": "b22d6048844357996bff383cea6c3cf5fc7ba75a0ee4441c755e83654af4b77b",
|
|
1810
|
+
"bytes": 858
|
|
1811
|
+
},
|
|
1812
|
+
"trigger/delivery-pipeline.js": {
|
|
1813
|
+
"sha256": "a5628cbf46cb65090e9e34c86fc78cb0b5fe2be6558efa2a3ce2009600a42d0a",
|
|
1814
|
+
"bytes": 6796
|
|
1815
|
+
},
|
|
1816
|
+
"trigger/dispatch-deduplicator.d.ts": {
|
|
1817
|
+
"sha256": "e1b7f48f7c03a391812ff7b40aa8cff7784d175df7c58de1a152e2a2c4eff060",
|
|
1818
|
+
"bytes": 179
|
|
1819
|
+
},
|
|
1820
|
+
"trigger/dispatch-deduplicator.js": {
|
|
1821
|
+
"sha256": "4848b5046aa65db19069300245733650c986bacf4eb066f742bc9ae70c36ce54",
|
|
1822
|
+
"bytes": 734
|
|
1823
|
+
},
|
|
1688
1824
|
"trigger/github-queue-config.d.ts": {
|
|
1689
1825
|
"sha256": "4dd68c2b880f808aa67c3b6be1867299c0b49ce5cf7e39f4f093dbd341d1a1e8",
|
|
1690
1826
|
"bytes": 800
|
|
@@ -1726,20 +1862,20 @@
|
|
|
1726
1862
|
"bytes": 22481
|
|
1727
1863
|
},
|
|
1728
1864
|
"trigger/trigger-listener.d.ts": {
|
|
1729
|
-
"sha256": "
|
|
1730
|
-
"bytes":
|
|
1865
|
+
"sha256": "57192a2e0e01d472985acd6d17be41930d2c189e029a11137661f990e1446ed3",
|
|
1866
|
+
"bytes": 1744
|
|
1731
1867
|
},
|
|
1732
1868
|
"trigger/trigger-listener.js": {
|
|
1733
|
-
"sha256": "
|
|
1734
|
-
"bytes":
|
|
1869
|
+
"sha256": "12a137a0ad256f2473171edc54bc624f4ad28f986d31bb4658538237b2082094",
|
|
1870
|
+
"bytes": 13222
|
|
1735
1871
|
},
|
|
1736
1872
|
"trigger/trigger-router.d.ts": {
|
|
1737
|
-
"sha256": "
|
|
1738
|
-
"bytes":
|
|
1873
|
+
"sha256": "24cc8e6abe08ca139af6599984e395863b5115076500b8faaae1d3b42bbe43b6",
|
|
1874
|
+
"bytes": 3220
|
|
1739
1875
|
},
|
|
1740
1876
|
"trigger/trigger-router.js": {
|
|
1741
|
-
"sha256": "
|
|
1742
|
-
"bytes":
|
|
1877
|
+
"sha256": "9676fb57236040d46b923c8016394b519561ab18c99884dc190cf2221e2f1ecf",
|
|
1878
|
+
"bytes": 20550
|
|
1743
1879
|
},
|
|
1744
1880
|
"trigger/trigger-store.d.ts": {
|
|
1745
1881
|
"sha256": "f846ca66494a2a1b834914652c845373d777bdeaaaefdc101ad1e78083d9ad5b",
|
|
@@ -3082,8 +3218,8 @@
|
|
|
3082
3218
|
"bytes": 572
|
|
3083
3219
|
},
|
|
3084
3220
|
"v2/usecases/console-routes.js": {
|
|
3085
|
-
"sha256": "
|
|
3086
|
-
"bytes":
|
|
3221
|
+
"sha256": "02e3be4472172bf03efb573376885fdb893af9b81b157370e25597750f77b03e",
|
|
3222
|
+
"bytes": 31729
|
|
3087
3223
|
},
|
|
3088
3224
|
"v2/usecases/console-service.d.ts": {
|
|
3089
3225
|
"sha256": "fc8fe65427fa9f4f3535344b385b36f66ca06b7e3bfaea708931817a3edcad2b",
|
|
@@ -209,6 +209,8 @@ async function listRememberedRoots(rememberedRootsStore) {
|
|
|
209
209
|
async function discoverWorkflowDirectoriesUnderRoot(rootPath) {
|
|
210
210
|
const discoveredPaths = [];
|
|
211
211
|
try {
|
|
212
|
+
if (await isWorkrailPackageDir(rootPath))
|
|
213
|
+
return { discovered: [], stale: false };
|
|
212
214
|
await walkForRootedWorkflowDirectories(rootPath, discoveredPaths);
|
|
213
215
|
}
|
|
214
216
|
catch (err) {
|
|
@@ -220,6 +222,8 @@ async function discoverWorkflowDirectoriesUnderRoot(rootPath) {
|
|
|
220
222
|
return { discovered: discoveredPaths, stale: false };
|
|
221
223
|
}
|
|
222
224
|
async function walkForRootedWorkflowDirectories(currentDirectory, discoveredPaths, depth = 0) {
|
|
225
|
+
if (depth > 0 && await isWorkrailPackageDir(currentDirectory))
|
|
226
|
+
return;
|
|
223
227
|
const entries = await promises_1.default.readdir(currentDirectory, { withFileTypes: true });
|
|
224
228
|
const sortedEntries = [...entries].sort((a, b) => a.name.localeCompare(b.name));
|
|
225
229
|
for (const entry of sortedEntries) {
|
|
@@ -250,6 +254,16 @@ async function walkForRootedWorkflowDirectories(currentDirectory, discoveredPath
|
|
|
250
254
|
function shouldSkipDirectory(name) {
|
|
251
255
|
return SKIP_DIRS.has(name);
|
|
252
256
|
}
|
|
257
|
+
async function isWorkrailPackageDir(dirPath) {
|
|
258
|
+
try {
|
|
259
|
+
const pkgJson = await promises_1.default.readFile(path_1.default.join(dirPath, 'package.json'), 'utf-8');
|
|
260
|
+
const pkg = JSON.parse(pkgJson);
|
|
261
|
+
return pkg.name === '@exaudeus/workrail';
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
253
267
|
async function isDirectory(targetPath) {
|
|
254
268
|
try {
|
|
255
269
|
return (await promises_1.default.stat(targetPath)).isDirectory();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { V2ToolContext } from '../mcp/types.js';
|
|
2
|
+
import type { AdaptiveCoordinatorDeps } from '../coordinators/adaptive-pipeline.js';
|
|
3
|
+
import type { WorkflowTrigger, SessionSource } from '../daemon/workflow-runner.js';
|
|
4
|
+
import type { ConsoleService } from '../v2/usecases/console-service.js';
|
|
5
|
+
export interface CoordinatorDepsDependencies {
|
|
6
|
+
readonly ctx: V2ToolContext;
|
|
7
|
+
readonly execFileAsync: (cmd: string, args: string[], opts?: object) => Promise<{
|
|
8
|
+
stdout: string;
|
|
9
|
+
}>;
|
|
10
|
+
readonly consoleService: InstanceType<typeof ConsoleService> | null;
|
|
11
|
+
}
|
|
12
|
+
export interface CoordinatorDepsWithDispatch extends AdaptiveCoordinatorDeps {
|
|
13
|
+
setDispatch(dispatch: (trigger: WorkflowTrigger, source?: SessionSource) => void): void;
|
|
14
|
+
}
|
|
15
|
+
export declare function createCoordinatorDeps(deps: CoordinatorDepsDependencies): CoordinatorDepsWithDispatch;
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createCoordinatorDeps = createCoordinatorDeps;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const os = __importStar(require("node:os"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
const node_crypto_1 = require("node:crypto");
|
|
41
|
+
const start_js_1 = require("../mcp/handlers/v2-execution/start.js");
|
|
42
|
+
const v2_token_ops_js_1 = require("../mcp/handlers/v2-token-ops.js");
|
|
43
|
+
const index_js_1 = require("../context-assembly/index.js");
|
|
44
|
+
const infra_js_1 = require("../context-assembly/infra.js");
|
|
45
|
+
function createCoordinatorDeps(deps) {
|
|
46
|
+
const { ctx, execFileAsync, consoleService } = deps;
|
|
47
|
+
let dispatch = null;
|
|
48
|
+
return {
|
|
49
|
+
setDispatch(fn) {
|
|
50
|
+
if (dispatch !== null) {
|
|
51
|
+
process.stderr.write('[WARN coordinator-deps] setDispatch() called more than once -- ignoring reassignment\n');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
dispatch = fn;
|
|
55
|
+
},
|
|
56
|
+
spawnSession: async (workflowId, goal, workspace, context, agentConfig) => {
|
|
57
|
+
if (dispatch === null) {
|
|
58
|
+
return { kind: 'err', error: 'in-process router not initialized -- coordinator deps not ready' };
|
|
59
|
+
}
|
|
60
|
+
const startResult = await (0, start_js_1.executeStartWorkflow)({ workflowId, workspacePath: workspace, goal }, ctx, { is_autonomous: 'true', workspacePath: workspace });
|
|
61
|
+
if (startResult.isErr()) {
|
|
62
|
+
const detail = `${startResult.error.kind}${'message' in startResult.error ? ': ' + startResult.error.message : ''}`;
|
|
63
|
+
return { kind: 'err', error: `Session creation failed: ${detail}` };
|
|
64
|
+
}
|
|
65
|
+
const startContinueToken = startResult.value.response.continueToken;
|
|
66
|
+
if (!startContinueToken) {
|
|
67
|
+
return { kind: 'ok', value: workflowId };
|
|
68
|
+
}
|
|
69
|
+
const tokenResult = await (0, v2_token_ops_js_1.parseContinueTokenOrFail)(startContinueToken, ctx.v2.tokenCodecPorts, ctx.v2.tokenAliasStore);
|
|
70
|
+
if (tokenResult.isErr()) {
|
|
71
|
+
process.stderr.write(`[ERROR trigger-listener:spawnSession] Failed to decode session handle from new session: ${tokenResult.error.message}\n`);
|
|
72
|
+
return { kind: 'err', error: 'Internal error: could not extract session handle from new session' };
|
|
73
|
+
}
|
|
74
|
+
const sessionHandle = tokenResult.value.sessionId;
|
|
75
|
+
const trigger = {
|
|
76
|
+
workflowId,
|
|
77
|
+
goal,
|
|
78
|
+
workspacePath: workspace,
|
|
79
|
+
context,
|
|
80
|
+
...(agentConfig !== undefined ? { agentConfig } : {}),
|
|
81
|
+
};
|
|
82
|
+
const r = startResult.value.response;
|
|
83
|
+
const allocatedSession = {
|
|
84
|
+
continueToken: r.continueToken ?? '',
|
|
85
|
+
checkpointToken: r.checkpointToken,
|
|
86
|
+
firstStepPrompt: r.pending?.prompt ?? '',
|
|
87
|
+
isComplete: r.isComplete,
|
|
88
|
+
triggerSource: 'daemon',
|
|
89
|
+
};
|
|
90
|
+
const source = { kind: 'pre_allocated', trigger, session: allocatedSession };
|
|
91
|
+
dispatch(trigger, source);
|
|
92
|
+
return { kind: 'ok', value: sessionHandle };
|
|
93
|
+
},
|
|
94
|
+
contextAssembler: (0, index_js_1.createContextAssembler)({
|
|
95
|
+
execGit: async (args, cwd) => {
|
|
96
|
+
try {
|
|
97
|
+
const { stdout } = await execFileAsync('git', [...args], { cwd });
|
|
98
|
+
return { kind: 'ok', value: stdout };
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
return { kind: 'err', error: e instanceof Error ? e.message : String(e) };
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
execGh: async (args, cwd) => {
|
|
105
|
+
try {
|
|
106
|
+
const { stdout } = await execFileAsync('gh', [...args], { cwd });
|
|
107
|
+
return { kind: 'ok', value: stdout };
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
return { kind: 'err', error: e instanceof Error ? e.message : String(e) };
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
listRecentSessions: (0, infra_js_1.createListRecentSessions)(),
|
|
114
|
+
nowIso: () => new Date().toISOString(),
|
|
115
|
+
}),
|
|
116
|
+
awaitSessions: async (handles, timeoutMs) => {
|
|
117
|
+
const POLL_INTERVAL_MS = 3000;
|
|
118
|
+
if (consoleService === null) {
|
|
119
|
+
process.stderr.write(`[WARN coord:reason=await_degraded] awaitSessions: ConsoleService unavailable -- returning all ${handles.length} session(s) as failed.\n`);
|
|
120
|
+
return {
|
|
121
|
+
results: [...handles].map((h) => ({
|
|
122
|
+
handle: h,
|
|
123
|
+
outcome: 'failed',
|
|
124
|
+
status: null,
|
|
125
|
+
durationMs: 0,
|
|
126
|
+
})),
|
|
127
|
+
allSucceeded: false,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const startMs = Date.now();
|
|
131
|
+
const pending = new Set(handles);
|
|
132
|
+
const results = new Map();
|
|
133
|
+
while (pending.size > 0) {
|
|
134
|
+
const elapsed = Date.now() - startMs;
|
|
135
|
+
if (elapsed >= timeoutMs) {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
for (const handle of [...pending]) {
|
|
139
|
+
try {
|
|
140
|
+
const detail = await consoleService.getSessionDetail(handle);
|
|
141
|
+
if (detail.isErr()) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const run = detail.value.runs[0];
|
|
145
|
+
if (!run)
|
|
146
|
+
continue;
|
|
147
|
+
const status = run.status;
|
|
148
|
+
if (status === 'complete' || status === 'complete_with_gaps') {
|
|
149
|
+
results.set(handle, { handle, outcome: 'success', status, durationMs: Date.now() - startMs });
|
|
150
|
+
pending.delete(handle);
|
|
151
|
+
}
|
|
152
|
+
else if (status === 'blocked') {
|
|
153
|
+
results.set(handle, { handle, outcome: 'failed', status, durationMs: Date.now() - startMs });
|
|
154
|
+
pending.delete(handle);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
results.set(handle, { handle, outcome: 'failed', status: null, durationMs: Date.now() - startMs });
|
|
159
|
+
pending.delete(handle);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (pending.size > 0) {
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const handle of pending) {
|
|
167
|
+
results.set(handle, { handle, outcome: 'timeout', status: null, durationMs: timeoutMs });
|
|
168
|
+
}
|
|
169
|
+
const resultsArray = [...results.values()];
|
|
170
|
+
return {
|
|
171
|
+
results: resultsArray,
|
|
172
|
+
allSucceeded: resultsArray.every((r) => r.outcome === 'success'),
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
getAgentResult: async (sessionHandle) => {
|
|
176
|
+
const emptyResult = { recapMarkdown: null, artifacts: [] };
|
|
177
|
+
if (consoleService === null) {
|
|
178
|
+
return emptyResult;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const detailResult = await consoleService.getSessionDetail(sessionHandle);
|
|
182
|
+
if (detailResult.isErr())
|
|
183
|
+
return emptyResult;
|
|
184
|
+
const run = detailResult.value.runs[0];
|
|
185
|
+
if (!run)
|
|
186
|
+
return emptyResult;
|
|
187
|
+
const tipNodeId = run.preferredTipNodeId;
|
|
188
|
+
if (!tipNodeId)
|
|
189
|
+
return emptyResult;
|
|
190
|
+
const allNodeIds = run.nodes.map((n) => n.nodeId).filter((id) => typeof id === 'string' && id !== '');
|
|
191
|
+
const nodeIdsToFetch = allNodeIds.length > 0 ? allNodeIds : [tipNodeId];
|
|
192
|
+
let recap = null;
|
|
193
|
+
const collectedArtifacts = [];
|
|
194
|
+
for (const nodeId of nodeIdsToFetch) {
|
|
195
|
+
try {
|
|
196
|
+
const nodeResult = await consoleService.getNodeDetail(sessionHandle, nodeId);
|
|
197
|
+
if (nodeResult.isErr())
|
|
198
|
+
continue;
|
|
199
|
+
if (nodeId === tipNodeId) {
|
|
200
|
+
recap = nodeResult.value.recapMarkdown;
|
|
201
|
+
}
|
|
202
|
+
if (nodeResult.value.artifacts.length > 0) {
|
|
203
|
+
collectedArtifacts.push(...nodeResult.value.artifacts);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { recapMarkdown: recap, artifacts: collectedArtifacts };
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
214
|
+
process.stderr.write(`[WARN coord:reason=exception handle=${sessionHandle.slice(0, 16)}] getAgentResult: ${msg}\n`);
|
|
215
|
+
return emptyResult;
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
listOpenPRs: async (workspace) => {
|
|
219
|
+
try {
|
|
220
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'list', '--json', 'number,title,headRefName'], {
|
|
221
|
+
cwd: workspace,
|
|
222
|
+
timeout: 30000,
|
|
223
|
+
});
|
|
224
|
+
const parsed = JSON.parse(stdout);
|
|
225
|
+
return parsed.map((p) => ({ number: p.number, title: p.title, headRef: p.headRefName }));
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return [];
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
mergePR: async (prNumber, workspace) => {
|
|
232
|
+
try {
|
|
233
|
+
await execFileAsync('gh', ['pr', 'merge', String(prNumber), '--squash', '--auto'], {
|
|
234
|
+
cwd: workspace,
|
|
235
|
+
timeout: 60000,
|
|
236
|
+
});
|
|
237
|
+
return { kind: 'ok', value: undefined };
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
241
|
+
return { kind: 'err', error: msg };
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
writeFile: async (filePath, content) => {
|
|
245
|
+
await fs.promises.writeFile(filePath, content, 'utf-8');
|
|
246
|
+
},
|
|
247
|
+
readFile: (filePath) => fs.promises.readFile(filePath, 'utf-8'),
|
|
248
|
+
appendFile: (filePath, content) => fs.promises.appendFile(filePath, content, 'utf-8'),
|
|
249
|
+
mkdir: (dirPath, opts) => fs.promises.mkdir(dirPath, opts),
|
|
250
|
+
homedir: os.homedir,
|
|
251
|
+
joinPath: path.join,
|
|
252
|
+
nowIso: () => new Date().toISOString(),
|
|
253
|
+
generateId: () => (0, node_crypto_1.randomUUID)(),
|
|
254
|
+
stderr: (line) => process.stderr.write(line + '\n'),
|
|
255
|
+
now: () => Date.now(),
|
|
256
|
+
fileExists: (p) => fs.existsSync(p),
|
|
257
|
+
archiveFile: (src, dest) => fs.promises.rename(src, dest),
|
|
258
|
+
pollForPR: async (branchPattern, timeoutMs) => {
|
|
259
|
+
const pollIntervalMs = 30000;
|
|
260
|
+
const deadline = Date.now() + timeoutMs;
|
|
261
|
+
while (Date.now() < deadline) {
|
|
262
|
+
try {
|
|
263
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'list', '--head', branchPattern, '--json', 'url', '--limit', '1'], { timeout: 30000 });
|
|
264
|
+
const parsed = JSON.parse(stdout);
|
|
265
|
+
if (parsed.length > 0 && parsed[0] && parsed[0].url) {
|
|
266
|
+
return parsed[0].url;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
}
|
|
271
|
+
const remaining = deadline - Date.now();
|
|
272
|
+
if (remaining <= 0)
|
|
273
|
+
break;
|
|
274
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(pollIntervalMs, remaining)));
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
},
|
|
278
|
+
postToOutbox: async (message, metadata) => {
|
|
279
|
+
const workrailDir = path.join(os.homedir(), '.workrail');
|
|
280
|
+
const outboxPath = path.join(workrailDir, 'outbox.jsonl');
|
|
281
|
+
await fs.promises.mkdir(workrailDir, { recursive: true });
|
|
282
|
+
const entry = JSON.stringify({
|
|
283
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
284
|
+
message,
|
|
285
|
+
metadata,
|
|
286
|
+
timestamp: new Date().toISOString(),
|
|
287
|
+
});
|
|
288
|
+
await fs.promises.appendFile(outboxPath, entry + '\n', 'utf-8');
|
|
289
|
+
},
|
|
290
|
+
pollOutboxAck: async (requestId, timeoutMs) => {
|
|
291
|
+
const pollIntervalMs = 5 * 60 * 1000;
|
|
292
|
+
const workrailDir = path.join(os.homedir(), '.workrail');
|
|
293
|
+
const outboxPath = path.join(workrailDir, 'outbox.jsonl');
|
|
294
|
+
const cursorPath = path.join(workrailDir, 'inbox-cursor.json');
|
|
295
|
+
let snapshotCount = 0;
|
|
296
|
+
try {
|
|
297
|
+
const outboxContent = await fs.promises.readFile(outboxPath, 'utf-8');
|
|
298
|
+
snapshotCount = outboxContent.split('\n').filter((l) => l.trim() !== '').length;
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
}
|
|
302
|
+
void requestId;
|
|
303
|
+
const deadline = Date.now() + timeoutMs;
|
|
304
|
+
while (Date.now() < deadline) {
|
|
305
|
+
const remaining = deadline - Date.now();
|
|
306
|
+
if (remaining <= 0)
|
|
307
|
+
break;
|
|
308
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(pollIntervalMs, remaining)));
|
|
309
|
+
try {
|
|
310
|
+
const cursorContent = await fs.promises.readFile(cursorPath, 'utf-8');
|
|
311
|
+
const cursor = JSON.parse(cursorContent);
|
|
312
|
+
if (typeof cursor.lastReadCount === 'number' && cursor.lastReadCount > snapshotCount) {
|
|
313
|
+
return 'acked';
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return 'timeout';
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
}
|