openfox 1.6.74 → 1.6.76

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.
Files changed (65) hide show
  1. package/dist/{ask-3RK5YJZE.js → ask-5SSOA6SZ.js} +2 -2
  2. package/dist/{auth-LZZX63KI.js → auth-56SIRACI.js} +3 -6
  3. package/dist/auto-compaction-V3PA77WG.js +27 -0
  4. package/dist/{branch.api-XADFZZAA.js → branch.api-PWFW26KC.js} +2 -2
  5. package/dist/{chat-handler-KYMMXPP6.js → chat-handler-7DKHGTVO.js} +31 -29
  6. package/dist/{chunk-5UTTLO4D.js → chunk-5ZD3GZTK.js} +89 -49
  7. package/dist/{chunk-AFATQ5LJ.js → chunk-B5AP3RSV.js} +1 -1
  8. package/dist/{chunk-22CTURMH.js → chunk-BJYPTN5S.js} +1 -1
  9. package/dist/{chunk-DLINTLB7.js → chunk-BSTVRSV6.js} +7 -5
  10. package/dist/{chunk-7JPKRM6M.js → chunk-CMQCO27Y.js} +22 -12
  11. package/dist/{chunk-R4HADRYO.js → chunk-CQGTEGKL.js} +1 -1
  12. package/dist/{chunk-J5DV33SS.js → chunk-CUDAT6SS.js} +46 -18
  13. package/dist/{chunk-ETIXH35K.js → chunk-H5EICXF3.js} +499 -277
  14. package/dist/{chunk-ODOA4RNN.js → chunk-K2V7EW5F.js} +541 -299
  15. package/dist/{chunk-PNBH3RAX.js → chunk-K44MW7JJ.js} +1 -1
  16. package/dist/{chunk-BLNFJ22S.js → chunk-KIOUKC3Z.js} +6 -4
  17. package/dist/{chunk-4CQ7CUQ6.js → chunk-LCQ3MPXD.js} +5 -5
  18. package/dist/{chunk-CTAIXOZJ.js → chunk-NDJ6FKSP.js} +1 -1
  19. package/dist/{chunk-IA4O65CR.js → chunk-NHJ2GVCF.js} +100 -68
  20. package/dist/{chunk-GQZGIMJO.js → chunk-OXI26S7U.js} +12 -7
  21. package/dist/{chunk-NBU6KIOD.js → chunk-PBGOZMVY.js} +4 -4
  22. package/dist/{chunk-B7E3BICY.js → chunk-RGRBWDZP.js} +2 -4
  23. package/dist/{chunk-CLBUWGUB.js → chunk-RQ4XSKUR.js} +15 -16
  24. package/dist/{chunk-KFBIHS3S.js → chunk-STYHKCG7.js} +20 -14
  25. package/dist/{chunk-55Z3DJ7G.js → chunk-TGWEH2BC.js} +10 -11
  26. package/dist/{chunk-TYUNDOX2.js → chunk-UKMRZDWM.js} +90 -41
  27. package/dist/{chunk-PFRQO5Z3.js → chunk-VAMTEAYI.js} +49 -27
  28. package/dist/{chunk-574HZVLE.js → chunk-VRGRAQDG.js} +2 -2
  29. package/dist/{chunk-JQBTYHUR.js → chunk-WR6QCJJO.js} +53 -15
  30. package/dist/{chunk-RBPOAAIZ.js → chunk-XKIEDGQF.js} +22 -18
  31. package/dist/cli/dev.js +2 -2
  32. package/dist/cli/index.js +2 -2
  33. package/dist/{config-6T4EHAP2.js → config-5CONAOL7.js} +7 -7
  34. package/dist/{events-LKEZ3YCW.js → events-BDXQOC7F.js} +6 -6
  35. package/dist/{folding-JN2WT44N.js → folding-2HW7FIKL.js} +2 -2
  36. package/dist/{inspect-proxy-Y4MRAVB7.js → inspect-proxy-Y75AXMRX.js} +3 -3
  37. package/dist/{manager-HM2J5VMW.js → manager-W7N3XQ4Q.js} +3 -3
  38. package/dist/orchestrator-KCHEENHK.js +43 -0
  39. package/dist/package.json +19 -3
  40. package/dist/{paths-ZRI56O63.js → paths-X46PPOI2.js} +2 -2
  41. package/dist/{processor-23O4HPSS.js → processor-6TS37IYH.js} +15 -11
  42. package/dist/{project-creator-LASKNQPA.js → project-creator-VD7MLOWE.js} +8 -5
  43. package/dist/{projects-HEUOWNSR.js → projects-XLMSDFTQ.js} +4 -4
  44. package/dist/{protocol-5AWNGFLH.js → protocol-4CTV7OZC.js} +3 -3
  45. package/dist/{protocol-DRBnujwe.d.ts → protocol-4xbfAlGO.d.ts} +3 -0
  46. package/dist/{provider-AKN355YH.js → provider-ESEBV3LL.js} +15 -11
  47. package/dist/{pwa-GHQCMCIU.js → pwa-76XP2DY2.js} +2 -2
  48. package/dist/{runtime-config-ZCK74XKM.js → runtime-config-CBJJJGBD.js} +2 -2
  49. package/dist/{serve-W6CHNSRO.js → serve-OLDABBV3.js} +29 -27
  50. package/dist/server/index.d.ts +6 -1
  51. package/dist/server/index.js +22 -22
  52. package/dist/server/public/__inspect__.js +2 -1
  53. package/dist/{service-74Z7JK2J.js → service-D6LC3CAM.js} +3 -2
  54. package/dist/{settings-NI4ITGV6.js → settings-TQNQB56H.js} +4 -4
  55. package/dist/shared/index.d.ts +2 -2
  56. package/dist/shared/index.js +2 -2
  57. package/dist/{store-2IF3ZSLD.js → store-OQ45KONN.js} +2 -2
  58. package/dist/{tools-RUAY6EVI.js → tools-BHYHS3RY.js} +18 -18
  59. package/dist/{vision-fallback-AXH3BGJC.js → vision-fallback-ED27LH6C.js} +3 -3
  60. package/dist/web/assets/{index-9GgVgB7B.js → index-DAuZ02-Q.js} +57 -57
  61. package/dist/web/index.html +1 -1
  62. package/dist/web/sw.js +1 -1
  63. package/package.json +19 -3
  64. package/dist/auto-compaction-OW4P2QWQ.js +0 -27
  65. package/dist/orchestrator-QP4O7MUM.js +0 -43
@@ -2,7 +2,7 @@ import {
2
2
  createVerifierNudgeConfig,
3
3
  runBuilderTurn,
4
4
  runChatTurn
5
- } from "./chunk-IA4O65CR.js";
5
+ } from "./chunk-NHJ2GVCF.js";
6
6
  import {
7
7
  TurnMetrics,
8
8
  agentExists,
@@ -37,31 +37,31 @@ import {
37
37
  setSkillEnabled,
38
38
  skillExists,
39
39
  spawnShellProcess
40
- } from "./chunk-ETIXH35K.js";
40
+ } from "./chunk-H5EICXF3.js";
41
41
  import {
42
42
  getProject
43
- } from "./chunk-7JPKRM6M.js";
43
+ } from "./chunk-CMQCO27Y.js";
44
44
  import {
45
45
  getPathSeparator,
46
46
  getPlatformShell,
47
47
  isAbsolutePath,
48
48
  onProcessEvent
49
- } from "./chunk-NBU6KIOD.js";
49
+ } from "./chunk-PBGOZMVY.js";
50
50
  import {
51
51
  createProviderManager,
52
52
  parseDefaultModelSelection
53
- } from "./chunk-JQBTYHUR.js";
53
+ } from "./chunk-WR6QCJJO.js";
54
54
  import {
55
55
  SessionNotFoundError,
56
56
  createLLMClient,
57
57
  detectModel,
58
58
  getLlmStatus
59
- } from "./chunk-55Z3DJ7G.js";
59
+ } from "./chunk-TGWEH2BC.js";
60
60
  import {
61
61
  detectBackend,
62
62
  getBackendDisplayName,
63
63
  getModelProfile
64
- } from "./chunk-J5DV33SS.js";
64
+ } from "./chunk-CUDAT6SS.js";
65
65
  import {
66
66
  createSession,
67
67
  deleteSession,
@@ -87,14 +87,14 @@ import {
87
87
  updateSessionProvider,
88
88
  updateSessionRunning,
89
89
  updateSessionSummary
90
- } from "./chunk-5UTTLO4D.js";
90
+ } from "./chunk-5ZD3GZTK.js";
91
91
  import {
92
92
  initDatabase
93
- } from "./chunk-BLNFJ22S.js";
93
+ } from "./chunk-KIOUKC3Z.js";
94
94
  import {
95
95
  buildMessagesFromStoredEvents,
96
96
  foldPendingConfirmations
97
- } from "./chunk-PFRQO5Z3.js";
97
+ } from "./chunk-VAMTEAYI.js";
98
98
  import {
99
99
  createChatErrorMessage,
100
100
  createChatMessageMessage,
@@ -108,28 +108,28 @@ import {
108
108
  parseClientMessage,
109
109
  serializeServerMessage,
110
110
  storedEventToServerMessage
111
- } from "./chunk-KFBIHS3S.js";
111
+ } from "./chunk-STYHKCG7.js";
112
112
  import {
113
113
  EventEmitter,
114
114
  provideAnswer
115
- } from "./chunk-22CTURMH.js";
115
+ } from "./chunk-BJYPTN5S.js";
116
116
  import {
117
117
  computeSessionStats
118
- } from "./chunk-B7E3BICY.js";
118
+ } from "./chunk-RGRBWDZP.js";
119
119
  import {
120
120
  createServerMessage
121
- } from "./chunk-CTAIXOZJ.js";
121
+ } from "./chunk-NDJ6FKSP.js";
122
122
  import {
123
123
  getGlobalConfigDir
124
- } from "./chunk-R4HADRYO.js";
124
+ } from "./chunk-CQGTEGKL.js";
125
125
  import {
126
126
  getRuntimeConfig,
127
127
  setRuntimeConfig
128
- } from "./chunk-AFATQ5LJ.js";
128
+ } from "./chunk-B5AP3RSV.js";
129
129
  import {
130
130
  logger,
131
131
  setLogLevel
132
- } from "./chunk-PNBH3RAX.js";
132
+ } from "./chunk-K44MW7JJ.js";
133
133
 
134
134
  // src/server/index.ts
135
135
  import express from "express";
@@ -446,7 +446,12 @@ var RULES = [
446
446
  },
447
447
  {
448
448
  match: /create.*src\/utils\.ts.*greet/i,
449
- tools: [{ name: "write_file", arguments: { path: "src/utils.ts", content: 'export function greet() { return "Hello!" }' } }],
449
+ tools: [
450
+ {
451
+ name: "write_file",
452
+ arguments: { path: "src/utils.ts", content: 'export function greet() { return "Hello!" }' }
453
+ }
454
+ ],
450
455
  response: "Created utils.ts with greet function."
451
456
  },
452
457
  {
@@ -476,7 +481,10 @@ var RULES = [
476
481
  match: /edit_file.*replaceAll.*const.*let/i,
477
482
  tools: [
478
483
  { name: "read_file", arguments: { path: "src/multi.ts" } },
479
- { name: "edit_file", arguments: { path: "src/multi.ts", old_string: "const", new_string: "let", replaceAll: true } }
484
+ {
485
+ name: "edit_file",
486
+ arguments: { path: "src/multi.ts", old_string: "const", new_string: "let", replaceAll: true }
487
+ }
480
488
  ],
481
489
  response: "Replaced all occurrences."
482
490
  },
@@ -484,7 +492,10 @@ var RULES = [
484
492
  match: /edit_file.*NONEXISTENT_STRING/i,
485
493
  tools: [
486
494
  { name: "read_file", arguments: { path: "src/math.ts" } },
487
- { name: "edit_file", arguments: { path: "src/math.ts", old_string: "NONEXISTENT_STRING_XYZ", new_string: "replacement" } }
495
+ {
496
+ name: "edit_file",
497
+ arguments: { path: "src/math.ts", old_string: "NONEXISTENT_STRING_XYZ", new_string: "replacement" }
498
+ }
488
499
  ],
489
500
  response: "Attempted to edit with non-existent string."
490
501
  },
@@ -590,27 +601,31 @@ var RULES = [
590
601
  // -------------------------------------------------------------------------
591
602
  {
592
603
  match: /todo_write.*Read files.*Make changes/i,
593
- tools: [{
594
- name: "todo",
595
- arguments: {
596
- action: "write",
597
- todos: [
598
- { content: "Read files", status: "in_progress" },
599
- { content: "Make changes", status: "pending" }
600
- ]
604
+ tools: [
605
+ {
606
+ name: "todo",
607
+ arguments: {
608
+ action: "write",
609
+ todos: [
610
+ { content: "Read files", status: "in_progress" },
611
+ { content: "Make changes", status: "pending" }
612
+ ]
613
+ }
601
614
  }
602
- }],
615
+ ],
603
616
  response: "Created todo list."
604
617
  },
605
618
  {
606
619
  match: /todo_write|todo.*list/i,
607
- tools: [{
608
- name: "todo",
609
- arguments: {
610
- action: "write",
611
- todos: [{ content: "Test task", status: "pending" }]
620
+ tools: [
621
+ {
622
+ name: "todo",
623
+ arguments: {
624
+ action: "write",
625
+ todos: [{ content: "Test task", status: "pending" }]
626
+ }
612
627
  }
613
- }],
628
+ ],
614
629
  response: "Created todo list."
615
630
  },
616
631
  // -------------------------------------------------------------------------
@@ -809,20 +824,24 @@ function getPromptAwareToolResponse(prompt) {
809
824
  const quotedValues = [...prompt.matchAll(/"([^"]+)"/g)].map((match) => match[1]);
810
825
  if (/Use the todo_write tool to create a todo list with 2 items/i.test(prompt)) {
811
826
  return {
812
- tools: [{
813
- name: "todo",
814
- arguments: {
815
- action: "write",
816
- todos: [
817
- { content: "Read files", status: "in_progress" },
818
- { content: "Make changes", status: "pending" }
819
- ]
827
+ tools: [
828
+ {
829
+ name: "todo",
830
+ arguments: {
831
+ action: "write",
832
+ todos: [
833
+ { content: "Read files", status: "in_progress" },
834
+ { content: "Make changes", status: "pending" }
835
+ ]
836
+ }
820
837
  }
821
- }],
838
+ ],
822
839
  response: "Created todo list."
823
840
  };
824
841
  }
825
- if (/First call get_criteria to see what needs to be done, then create src\/test\.ts and call complete_criterion for ["']test-file["']\./i.test(prompt)) {
842
+ if (/First call get_criteria to see what needs to be done, then create src\/test\.ts and call complete_criterion for ["']test-file["']\./i.test(
843
+ prompt
844
+ )) {
826
845
  return {
827
846
  tools: [
828
847
  { name: "criterion", arguments: { action: "get" } },
@@ -837,7 +856,10 @@ function getPromptAwareToolResponse(prompt) {
837
856
  return {
838
857
  tools: [
839
858
  { name: "write_file", arguments: { path: "src/utils.ts", content: "export const created = true" } },
840
- { name: "criterion", arguments: { action: "complete", id: "file-created", reason: "Created the requested file" } },
859
+ {
860
+ name: "criterion",
861
+ arguments: { action: "complete", id: "file-created", reason: "Created the requested file" }
862
+ },
841
863
  { name: "step_done", arguments: {} }
842
864
  ],
843
865
  response: "Created the file and completed the criterion."
@@ -845,13 +867,20 @@ function getPromptAwareToolResponse(prompt) {
845
867
  }
846
868
  if (/Create a new file called src\/utils\.ts/i.test(prompt)) {
847
869
  return {
848
- tools: [{ name: "write_file", arguments: { path: "src/utils.ts", content: 'export function greet() { return "Hello!" }' } }],
870
+ tools: [
871
+ {
872
+ name: "write_file",
873
+ arguments: { path: "src/utils.ts", content: 'export function greet() { return "Hello!" }' }
874
+ }
875
+ ],
849
876
  response: "Created src/utils.ts."
850
877
  };
851
878
  }
852
879
  if (/Create a new file at src\/newfile\.ts/i.test(prompt)) {
853
880
  return {
854
- tools: [{ name: "write_file", arguments: { path: "src/newfile.ts", content: 'export const greeting = "hello"' } }],
881
+ tools: [
882
+ { name: "write_file", arguments: { path: "src/newfile.ts", content: 'export const greeting = "hello"' } }
883
+ ],
855
884
  response: "Created src/newfile.ts."
856
885
  };
857
886
  }
@@ -865,7 +894,10 @@ function getPromptAwareToolResponse(prompt) {
865
894
  return {
866
895
  tools: [
867
896
  { name: "read_file", arguments: { path: "src/math.ts" } },
868
- { name: "edit_file", arguments: { path: "src/math.ts", old_string: quotedValues[0], new_string: quotedValues[1] } }
897
+ {
898
+ name: "edit_file",
899
+ arguments: { path: "src/math.ts", old_string: quotedValues[0], new_string: quotedValues[1] }
900
+ }
869
901
  ],
870
902
  response: "Updated src/math.ts."
871
903
  };
@@ -926,27 +958,46 @@ function getConversationAwareToolResponse(request) {
926
958
  if (conversationText.includes("inspect-src")) {
927
959
  tools.push(
928
960
  { name: "read_file", arguments: { path: "src" } },
929
- { name: "criterion", arguments: { action: "complete", id: "inspect-src", reason: "Inspected the src directory and reported what exists" } }
961
+ {
962
+ name: "criterion",
963
+ arguments: {
964
+ action: "complete",
965
+ id: "inspect-src",
966
+ reason: "Inspected the src directory and reported what exists"
967
+ }
968
+ }
930
969
  );
931
970
  completedCriteria.push("inspect-src");
932
971
  }
933
972
  if (conversationText.includes("trivial-pass")) {
934
- tools.push({ name: "criterion", arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" } });
973
+ tools.push({
974
+ name: "criterion",
975
+ arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" }
976
+ });
935
977
  completedCriteria.push("trivial-pass");
936
978
  }
937
979
  if (conversationText.includes("verify-fail")) {
938
- tools.push({ name: "criterion", arguments: { action: "complete", id: "verify-fail", reason: "Prepared criterion for verification" } });
980
+ tools.push({
981
+ name: "criterion",
982
+ arguments: { action: "complete", id: "verify-fail", reason: "Prepared criterion for verification" }
983
+ });
939
984
  completedCriteria.push("verify-fail");
940
985
  }
941
986
  if (conversationText.includes("file-created")) {
942
987
  tools.push(
943
988
  { name: "write_file", arguments: { path: "src/utils.ts", content: "export const created = true" } },
944
- { name: "criterion", arguments: { action: "complete", id: "file-created", reason: "Created the requested file" } }
989
+ {
990
+ name: "criterion",
991
+ arguments: { action: "complete", id: "file-created", reason: "Created the requested file" }
992
+ }
945
993
  );
946
994
  completedCriteria.push("file-created");
947
995
  }
948
996
  if (tools.length === 0) {
949
- tools.push({ name: "criterion", arguments: { action: "complete", id: "mock-crit", reason: "Completed for testing" } });
997
+ tools.push({
998
+ name: "criterion",
999
+ arguments: { action: "complete", id: "mock-crit", reason: "Completed for testing" }
1000
+ });
950
1001
  completedCriteria.push("mock-crit");
951
1002
  }
952
1003
  tools.push({ name: "step_done", arguments: {} });
@@ -969,17 +1020,32 @@ function getConversationAwareToolResponse(request) {
969
1020
  if (conversationText.includes("file-created")) {
970
1021
  tools.push(
971
1022
  { name: "write_file", arguments: { path: "src/utils.ts", content: "export const created = true" } },
972
- { name: "criterion", arguments: { action: "complete", id: "file-created", reason: "Created the requested file" } }
1023
+ {
1024
+ name: "criterion",
1025
+ arguments: { action: "complete", id: "file-created", reason: "Created the requested file" }
1026
+ }
973
1027
  );
974
1028
  } else if (conversationText.includes("trivial-pass")) {
975
- tools.push({ name: "criterion", arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" } });
1029
+ tools.push({
1030
+ name: "criterion",
1031
+ arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" }
1032
+ });
976
1033
  } else if (conversationText.includes("verify-fail")) {
977
- tools.push({ name: "criterion", arguments: { action: "complete", id: "verify-fail", reason: "Prepared criterion for verification" } });
1034
+ tools.push({
1035
+ name: "criterion",
1036
+ arguments: { action: "complete", id: "verify-fail", reason: "Prepared criterion for verification" }
1037
+ });
978
1038
  } else {
979
1039
  if (/1 criteria remaining/i.test(prompt)) {
980
- tools.push({ name: "criterion", arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" } });
1040
+ tools.push({
1041
+ name: "criterion",
1042
+ arguments: { action: "complete", id: "trivial-pass", reason: "Trivial criterion passes immediately" }
1043
+ });
981
1044
  } else {
982
- tools.push({ name: "criterion", arguments: { action: "complete", id: "mock-crit", reason: "Completed for testing" } });
1045
+ tools.push({
1046
+ name: "criterion",
1047
+ arguments: { action: "complete", id: "mock-crit", reason: "Completed for testing" }
1048
+ });
983
1049
  }
984
1050
  }
985
1051
  tools.push({ name: "step_done", arguments: {} });
@@ -1000,27 +1066,53 @@ function getConversationAwareToolResponse(request) {
1000
1066
  const tools = [];
1001
1067
  const terminalizedCriteria = [];
1002
1068
  if (conversationText.includes("trivial-pass")) {
1003
- tools.push({ name: "criterion", arguments: { action: "pass", id: "trivial-pass", reason: "Verified successfully" } });
1069
+ tools.push({
1070
+ name: "criterion",
1071
+ arguments: { action: "pass", id: "trivial-pass", reason: "Verified successfully" }
1072
+ });
1004
1073
  terminalizedCriteria.push("trivial-pass");
1005
1074
  }
1006
1075
  if (conversationText.includes("inspect-src")) {
1007
- tools.push({ name: "criterion", arguments: { action: "pass", id: "inspect-src", reason: "Verified the src directory was inspected successfully" } });
1076
+ tools.push({
1077
+ name: "criterion",
1078
+ arguments: {
1079
+ action: "pass",
1080
+ id: "inspect-src",
1081
+ reason: "Verified the src directory was inspected successfully"
1082
+ }
1083
+ });
1008
1084
  terminalizedCriteria.push("inspect-src");
1009
1085
  }
1010
1086
  if (conversationText.includes("verify-fail")) {
1011
- tools.push({ name: "criterion", arguments: { action: "complete", id: "verify-fail", reason: "Verification fails intentionally for this criterion" } });
1087
+ tools.push({
1088
+ name: "criterion",
1089
+ arguments: {
1090
+ action: "complete",
1091
+ id: "verify-fail",
1092
+ reason: "Verification fails intentionally for this criterion"
1093
+ }
1094
+ });
1012
1095
  terminalizedCriteria.push("verify-fail");
1013
1096
  }
1014
1097
  if (conversationText.includes("file-created")) {
1015
- tools.push({ name: "criterion", arguments: { action: "pass", id: "file-created", reason: "Verified the file was created successfully" } });
1098
+ tools.push({
1099
+ name: "criterion",
1100
+ arguments: { action: "pass", id: "file-created", reason: "Verified the file was created successfully" }
1101
+ });
1016
1102
  terminalizedCriteria.push("file-created");
1017
1103
  }
1018
1104
  if (conversationText.includes("impossible/path")) {
1019
- tools.push({ name: "criterion", arguments: { action: "complete", id: "auto-impossible", reason: "Impossible path does not exist" } });
1105
+ tools.push({
1106
+ name: "criterion",
1107
+ arguments: { action: "complete", id: "auto-impossible", reason: "Impossible path does not exist" }
1108
+ });
1020
1109
  terminalizedCriteria.push("auto-impossible");
1021
1110
  }
1022
1111
  if (tools.length > 0) {
1023
- tools.push({ name: "return_value", arguments: { summary: `Terminalized verifier work for: ${terminalizedCriteria.join(", ")}.` } });
1112
+ tools.push({
1113
+ name: "return_value",
1114
+ arguments: { summary: `Terminalized verifier work for: ${terminalizedCriteria.join(", ")}.` }
1115
+ });
1024
1116
  return {
1025
1117
  tools,
1026
1118
  response: `Terminalized verifier work for: ${terminalizedCriteria.join(", ")}.`
@@ -1129,7 +1221,11 @@ function createMockLLMClient() {
1129
1221
  if (request.signal?.aborted) throw new Error("Aborted");
1130
1222
  const response = buildMockResponse(request);
1131
1223
  if (process.env["OPENFOX_TEST_VERBOSE"] === "true") {
1132
- logger.debug("MockLLM completion", { prompt: prompt.slice(0, 50), hasTools: response.toolCalls.length > 0, tools: response.toolCalls.map((tc) => tc.name) });
1224
+ logger.debug("MockLLM completion", {
1225
+ prompt: prompt.slice(0, 50),
1226
+ hasTools: response.toolCalls.length > 0,
1227
+ tools: response.toolCalls.map((tc) => tc.name)
1228
+ });
1133
1229
  }
1134
1230
  return {
1135
1231
  id: `mock-${Date.now()}`,
@@ -1145,7 +1241,11 @@ function createMockLLMClient() {
1145
1241
  if (request.signal?.aborted) throw new Error("Aborted");
1146
1242
  const response = buildMockResponse(request);
1147
1243
  if (process.env["OPENFOX_TEST_VERBOSE"] === "true") {
1148
- logger.debug("MockLLM stream", { prompt: prompt.slice(0, 50), hasTools: response.toolCalls.length > 0, tools: response.toolCalls.map((tc) => tc.name) });
1244
+ logger.debug("MockLLM stream", {
1245
+ prompt: prompt.slice(0, 50),
1246
+ hasTools: response.toolCalls.length > 0,
1247
+ tools: response.toolCalls.map((tc) => tc.name)
1248
+ });
1149
1249
  }
1150
1250
  for (let i = 0; i < response.toolCalls.length; i++) {
1151
1251
  const tc = response.toolCalls[i];
@@ -1320,10 +1420,12 @@ function registerOutputHandler() {
1320
1420
  (s) => s.sessionId === output.sessionId && s.ws.readyState === WebSocket.OPEN
1321
1421
  );
1322
1422
  for (const sub of subs) {
1323
- sub.ws.send(JSON.stringify({
1324
- type: "terminal.output",
1325
- payload: { sessionId: output.sessionId, data: output.data }
1326
- }));
1423
+ sub.ws.send(
1424
+ JSON.stringify({
1425
+ type: "terminal.output",
1426
+ payload: { sessionId: output.sessionId, data: output.data }
1427
+ })
1428
+ );
1327
1429
  }
1328
1430
  });
1329
1431
  }
@@ -1335,10 +1437,12 @@ function registerExitHandler() {
1335
1437
  (s) => s.sessionId === sessionId && s.ws.readyState === WebSocket.OPEN
1336
1438
  );
1337
1439
  for (const sub of subs) {
1338
- sub.ws.send(JSON.stringify({
1339
- type: "terminal.exit",
1340
- payload: { sessionId, exitCode }
1341
- }));
1440
+ sub.ws.send(
1441
+ JSON.stringify({
1442
+ type: "terminal.exit",
1443
+ payload: { sessionId, exitCode }
1444
+ })
1445
+ );
1342
1446
  }
1343
1447
  for (const sub of subscriptions) {
1344
1448
  if (sub.sessionId === sessionId) {
@@ -1363,10 +1467,12 @@ function handleTerminalMessage(ws, message) {
1363
1467
  const history = terminalManager.getOutputHistory(sessionId);
1364
1468
  if (history) {
1365
1469
  setTimeout(() => {
1366
- ws.send(JSON.stringify({
1367
- type: "terminal.output",
1368
- payload: { sessionId, data: history }
1369
- }));
1470
+ ws.send(
1471
+ JSON.stringify({
1472
+ type: "terminal.output",
1473
+ payload: { sessionId, data: history }
1474
+ })
1475
+ );
1370
1476
  }, 100);
1371
1477
  }
1372
1478
  }
@@ -1392,10 +1498,12 @@ function handleTerminalMessage(ws, message) {
1392
1498
  subscriptions.delete(sub);
1393
1499
  }
1394
1500
  }
1395
- ws.send(JSON.stringify({
1396
- type: "terminal.killed",
1397
- payload: { sessionId: message.payload.sessionId }
1398
- }));
1501
+ ws.send(
1502
+ JSON.stringify({
1503
+ type: "terminal.killed",
1504
+ payload: { sessionId: message.payload.sessionId }
1505
+ })
1506
+ );
1399
1507
  }
1400
1508
  break;
1401
1509
  }
@@ -1466,10 +1574,7 @@ async function loadUserWorkflows(configDir) {
1466
1574
  return loadWorkflowsFromDir(getWorkflowsDir(configDir));
1467
1575
  }
1468
1576
  async function loadAllWorkflows(configDir) {
1469
- const [defaultWorkflows, userWorkflows] = await Promise.all([
1470
- loadDefaultWorkflows(),
1471
- loadUserWorkflows(configDir)
1472
- ]);
1577
+ const [defaultWorkflows, userWorkflows] = await Promise.all([loadDefaultWorkflows(), loadUserWorkflows(configDir)]);
1473
1578
  const workflowMap = /* @__PURE__ */ new Map();
1474
1579
  for (const workflow of defaultWorkflows) {
1475
1580
  workflowMap.set(workflow.metadata.id, workflow);
@@ -1587,9 +1692,18 @@ function executeShellCommand(command, cwd, timeout, signal) {
1587
1692
  var TEMPLATE_VARIABLES = [
1588
1693
  { name: "workdir", description: "Working directory of the session" },
1589
1694
  { name: "reason", description: 'Human-readable reason (e.g. "2 criteria remaining")' },
1590
- { name: "stepOutput", description: "Structured output from the previous step (content, stdout, stderr, exitCode, etc.)" },
1591
- { name: "verifierFindings", description: "@deprecated Use stepOutput.content instead. Output from the last sub-agent step" },
1592
- { name: "previousStepOutput", description: "@deprecated Use stepOutput.stdout instead. Output from the last shell step" },
1695
+ {
1696
+ name: "stepOutput",
1697
+ description: "Structured output from the previous step (content, stdout, stderr, exitCode, etc.)"
1698
+ },
1699
+ {
1700
+ name: "verifierFindings",
1701
+ description: "@deprecated Use stepOutput.content instead. Output from the last sub-agent step"
1702
+ },
1703
+ {
1704
+ name: "previousStepOutput",
1705
+ description: "@deprecated Use stepOutput.stdout instead. Output from the last shell step"
1706
+ },
1593
1707
  { name: "criteriaCount", description: "Total number of criteria" },
1594
1708
  { name: "pendingCount", description: "Number of pending/failed criteria" },
1595
1709
  { name: "summary", description: "Session summary generated by planner" },
@@ -1648,23 +1762,28 @@ function evaluateTransitions(transitions, criteria, stepOutcome) {
1648
1762
  }
1649
1763
  function emitWorkflowMessage(eventStore, sessionId, content, windowOptions, onMessage) {
1650
1764
  const msgId = crypto.randomUUID();
1651
- eventStore.append(sessionId, createMessageStartEvent(msgId, "user", content, {
1652
- ...windowOptions ?? {},
1653
- isSystemGenerated: true,
1654
- messageKind: "correction",
1655
- metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1656
- }));
1657
- eventStore.append(sessionId, { type: "message.done", data: { messageId: msgId } });
1658
- if (onMessage) {
1659
- onMessage(createChatMessageMessage({
1660
- id: msgId,
1661
- role: "user",
1662
- content,
1663
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1765
+ eventStore.append(
1766
+ sessionId,
1767
+ createMessageStartEvent(msgId, "user", content, {
1768
+ ...windowOptions ?? {},
1664
1769
  isSystemGenerated: true,
1665
1770
  messageKind: "correction",
1666
1771
  metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1667
- }));
1772
+ })
1773
+ );
1774
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: msgId } });
1775
+ if (onMessage) {
1776
+ onMessage(
1777
+ createChatMessageMessage({
1778
+ id: msgId,
1779
+ role: "user",
1780
+ content,
1781
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1782
+ isSystemGenerated: true,
1783
+ messageKind: "correction",
1784
+ metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1785
+ })
1786
+ );
1668
1787
  }
1669
1788
  return msgId;
1670
1789
  }
@@ -1693,15 +1812,15 @@ async function executeWorkflow(workflow, options) {
1693
1812
  if (workflow.startCondition && workflow.startCondition.type !== "always") {
1694
1813
  const session = sessionManager.requireSession(sessionId);
1695
1814
  const criteria = session.criteria;
1696
- const conditionMet = evaluateCondition(
1697
- workflow.startCondition,
1698
- criteria,
1699
- null
1700
- );
1815
+ const conditionMet = evaluateCondition(workflow.startCondition, criteria, null);
1701
1816
  if (!conditionMet) {
1702
1817
  logger.debug("Workflow start condition not met", { sessionId, condition: workflow.startCondition.type });
1703
1818
  return {
1704
- finalAction: { type: "BLOCKED", reason: `Start condition not met: ${workflow.startCondition.type}`, blockedCriteria: [] },
1819
+ finalAction: {
1820
+ type: "BLOCKED",
1821
+ reason: `Start condition not met: ${workflow.startCondition.type}`,
1822
+ blockedCriteria: []
1823
+ },
1705
1824
  iterations: 0,
1706
1825
  totalTime: (performance.now() - startTime) / 1e3
1707
1826
  };
@@ -1709,12 +1828,19 @@ async function executeWorkflow(workflow, options) {
1709
1828
  }
1710
1829
  const startMsgId = crypto.randomUUID();
1711
1830
  const startWindowOpts = getCurrentWindowMessageOptions(sessionId);
1712
- eventStore.append(sessionId, createMessageStartEvent(
1713
- startMsgId,
1714
- "user",
1715
- JSON.stringify({ workflowName: workflow.metadata.name, workflowId: workflow.metadata.id, workflowColor: workflow.metadata.color }),
1716
- { ...startWindowOpts ?? {}, isSystemGenerated: true, messageKind: "workflow-started" }
1717
- ));
1831
+ eventStore.append(
1832
+ sessionId,
1833
+ createMessageStartEvent(
1834
+ startMsgId,
1835
+ "user",
1836
+ JSON.stringify({
1837
+ workflowName: workflow.metadata.name,
1838
+ workflowId: workflow.metadata.id,
1839
+ workflowColor: workflow.metadata.color
1840
+ }),
1841
+ { ...startWindowOpts ?? {}, isSystemGenerated: true, messageKind: "workflow-started" }
1842
+ )
1843
+ );
1718
1844
  eventStore.append(sessionId, { type: "message.done", data: { messageId: startMsgId } });
1719
1845
  if (options.userMessage) {
1720
1846
  sessionManager.addMessage(sessionId, {
@@ -1765,29 +1891,35 @@ async function executeWorkflow(workflow, options) {
1765
1891
  const agentStep = step;
1766
1892
  const STEP_DONE_PROMPT = "\n\nOnce you're done, call step_done()";
1767
1893
  const STEP_DONE_NUDGE = "You haven't called step_done(). If you haven't finished the task, continue and when you're finished call step_done()";
1768
- let promptContent = null;
1769
- let nudgeContent = null;
1894
+ let promptContent;
1895
+ let nudgeContent;
1770
1896
  if (isFirstBuilderEntry && agentStep.prompt) {
1771
1897
  const resolvedPrompt = resolveTemplate(agentStep.prompt, templateCtx);
1772
1898
  promptContent = resolvedPrompt + STEP_DONE_PROMPT;
1773
1899
  const promptMsgId = crypto.randomUUID();
1774
- eventStore.append(sessionId, createMessageStartEvent(promptMsgId, "user", promptContent, {
1775
- ...currentWindowMessageOptions ?? {},
1776
- isSystemGenerated: true,
1777
- messageKind: "auto-prompt",
1778
- metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1779
- }));
1780
- eventStore.append(sessionId, { type: "message.done", data: { messageId: promptMsgId } });
1781
- if (onMessage) {
1782
- onMessage(createChatMessageMessage({
1783
- id: promptMsgId,
1784
- role: "user",
1785
- content: promptContent,
1786
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1900
+ const msgMetadata = { type: "workflow", name: "Workflow", color: "#f59e0b" };
1901
+ eventStore.append(
1902
+ sessionId,
1903
+ createMessageStartEvent(promptMsgId, "user", promptContent, {
1904
+ ...currentWindowMessageOptions ?? {},
1787
1905
  isSystemGenerated: true,
1788
1906
  messageKind: "auto-prompt",
1789
- metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1790
- }));
1907
+ metadata: msgMetadata
1908
+ })
1909
+ );
1910
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: promptMsgId } });
1911
+ if (onMessage) {
1912
+ onMessage(
1913
+ createChatMessageMessage({
1914
+ id: promptMsgId,
1915
+ role: "user",
1916
+ content: promptContent,
1917
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1918
+ isSystemGenerated: true,
1919
+ messageKind: "auto-prompt",
1920
+ metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1921
+ })
1922
+ );
1791
1923
  }
1792
1924
  } else if (!isFirstBuilderEntry) {
1793
1925
  const parts = [];
@@ -1800,23 +1932,34 @@ async function executeWorkflow(workflow, options) {
1800
1932
  emitWorkflowMessage(eventStore, sessionId, nudgeContent, currentWindowMessageOptions, onMessage);
1801
1933
  }
1802
1934
  const turnMetrics = new TurnMetrics();
1803
- const agentResult = await runBuilderTurn({
1804
- sessionManager,
1805
- sessionId,
1806
- llmClient,
1807
- injectStepDone: true,
1808
- ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
1809
- ...isFirstBuilderEntry && !agentStep.prompt && options.injectBuilderKickoff === true ? { injectBuilderKickoff: true } : {},
1810
- ...signal ? { signal } : {},
1811
- ...onMessage ? { onMessage } : {}
1812
- }, turnMetrics);
1935
+ const agentResult = await runBuilderTurn(
1936
+ {
1937
+ sessionManager,
1938
+ sessionId,
1939
+ llmClient,
1940
+ injectStepDone: true,
1941
+ ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
1942
+ ...isFirstBuilderEntry && !agentStep.prompt && options.injectBuilderKickoff === true ? { injectBuilderKickoff: true } : {},
1943
+ ...signal ? { signal } : {},
1944
+ ...onMessage ? { onMessage } : {}
1945
+ },
1946
+ turnMetrics
1947
+ );
1813
1948
  isFirstBuilderEntry = false;
1814
1949
  const agentReturnValue = agentResult.returnValueResult ?? "completed";
1815
1950
  const stepDoneCalled = agentResult.stepDoneCalled ?? false;
1816
- lastStepOutput = { ...agentResult.returnValueContent ? { content: agentResult.returnValueContent } : {}, ...agentResult.returnValueResult ? { result: agentResult.returnValueResult } : {}, stepDoneCalled: String(stepDoneCalled) };
1951
+ lastStepOutput = {
1952
+ ...agentResult.returnValueContent ? { content: agentResult.returnValueContent } : {},
1953
+ ...agentResult.returnValueResult ? { result: agentResult.returnValueResult } : {},
1954
+ stepDoneCalled: String(stepDoneCalled)
1955
+ };
1817
1956
  stepOutcome = { result: agentReturnValue, output: lastStepOutput };
1818
1957
  if (!stepDoneCalled) {
1819
- logger.debug("step_done not called, looping agent step", { sessionId, stepId: step.id, iteration: iterations });
1958
+ logger.debug("step_done not called, looping agent step", {
1959
+ sessionId,
1960
+ stepId: step.id,
1961
+ iteration: iterations
1962
+ });
1820
1963
  continue;
1821
1964
  }
1822
1965
  break;
@@ -1848,7 +1991,12 @@ async function executeWorkflow(workflow, options) {
1848
1991
  llmClient,
1849
1992
  toolRegistry: filteredToolRegistry,
1850
1993
  turnMetrics,
1851
- statsIdentity: options.statsIdentity ?? { providerId: "", providerName: "", backend: "unknown", model: llmClient.getModel() },
1994
+ statsIdentity: options.statsIdentity ?? {
1995
+ providerId: "",
1996
+ providerName: "",
1997
+ backend: "unknown",
1998
+ model: llmClient.getModel()
1999
+ },
1852
2000
  ...signal ? { signal } : {},
1853
2001
  ...onMessage ? { onMessage } : {},
1854
2002
  nudgeConfig
@@ -1863,22 +2011,27 @@ async function executeWorkflow(workflow, options) {
1863
2011
  const timeout = shellStep.timeout ?? 6e4;
1864
2012
  const successCodes = shellStep.successExitCodes ?? [0];
1865
2013
  const shellMsgId = crypto.randomUUID();
1866
- eventStore.append(sessionId, createMessageStartEvent(shellMsgId, "user", `Running: \`${command}\``, {
1867
- ...currentWindowMessageOptions ?? {},
1868
- isSystemGenerated: true,
1869
- messageKind: "auto-prompt",
1870
- metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1871
- }));
1872
- if (onMessage) {
1873
- onMessage(createChatMessageMessage({
1874
- id: shellMsgId,
1875
- role: "user",
1876
- content: `Running: \`${command}\``,
1877
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2014
+ eventStore.append(
2015
+ sessionId,
2016
+ createMessageStartEvent(shellMsgId, "user", `Running: \`${command}\``, {
2017
+ ...currentWindowMessageOptions ?? {},
1878
2018
  isSystemGenerated: true,
1879
2019
  messageKind: "auto-prompt",
1880
2020
  metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
1881
- }));
2021
+ })
2022
+ );
2023
+ if (onMessage) {
2024
+ onMessage(
2025
+ createChatMessageMessage({
2026
+ id: shellMsgId,
2027
+ role: "user",
2028
+ content: `Running: \`${command}\``,
2029
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2030
+ isSystemGenerated: true,
2031
+ messageKind: "auto-prompt",
2032
+ metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
2033
+ })
2034
+ );
1882
2035
  }
1883
2036
  const result = await executeShellCommand(command, session.workdir, timeout, signal);
1884
2037
  const output = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
@@ -1889,42 +2042,40 @@ ${output.slice(0, 1e4)}
1889
2042
  \`\`\`` : `Exit code: ${result.exitCode}`;
1890
2043
  eventStore.append(sessionId, { type: "message.done", data: { messageId: shellMsgId } });
1891
2044
  const outputMsgId = crypto.randomUUID();
1892
- eventStore.append(sessionId, createMessageStartEvent(outputMsgId, "user", outputContent, {
1893
- ...currentWindowMessageOptions ?? {},
1894
- isSystemGenerated: true,
1895
- messageKind: "correction"
1896
- }));
1897
- eventStore.append(sessionId, { type: "message.done", data: { messageId: outputMsgId } });
1898
- if (onMessage) {
1899
- onMessage(createChatMessageMessage({
1900
- id: outputMsgId,
1901
- role: "user",
1902
- content: outputContent,
1903
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2045
+ eventStore.append(
2046
+ sessionId,
2047
+ createMessageStartEvent(outputMsgId, "user", outputContent, {
2048
+ ...currentWindowMessageOptions ?? {},
1904
2049
  isSystemGenerated: true,
1905
2050
  messageKind: "correction"
1906
- }));
2051
+ })
2052
+ );
2053
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: outputMsgId } });
2054
+ if (onMessage) {
2055
+ onMessage(
2056
+ createChatMessageMessage({
2057
+ id: outputMsgId,
2058
+ role: "user",
2059
+ content: outputContent,
2060
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2061
+ isSystemGenerated: true,
2062
+ messageKind: "correction"
2063
+ })
2064
+ );
1907
2065
  }
1908
2066
  stepOutcome = { result: successCodes.includes(result.exitCode) ? "success" : "failure", output: lastStepOutput };
1909
2067
  break;
1910
2068
  }
1911
2069
  }
1912
2070
  const refreshedSession = sessionManager.requireSession(sessionId);
1913
- const nextStepId = evaluateTransitions(
1914
- step.transitions,
1915
- refreshedSession.criteria,
1916
- stepOutcome
1917
- );
2071
+ const nextStepId = evaluateTransitions(step.transitions, refreshedSession.criteria, stepOutcome);
1918
2072
  if (nextStepId === TERMINAL_DONE) {
1919
2073
  sessionManager.setPhase(sessionId, "done");
1920
2074
  const totalTimeSeconds = Math.round((performance.now() - startTime) / 100) / 10;
1921
2075
  const completedSession = sessionManager.requireSession(sessionId);
1922
2076
  const workflowMessages = completedSession.messages.slice(messagesBeforeWorkflow);
1923
2077
  const workflowStats = computeSessionStats(workflowMessages);
1924
- const totalToolCalls = workflowMessages.reduce(
1925
- (sum, m) => sum + (m.toolCalls?.length ?? 0),
1926
- 0
1927
- );
2078
+ const totalToolCalls = workflowMessages.reduce((sum, m) => sum + (m.toolCalls?.length ?? 0), 0);
1928
2079
  const taskCompletedData = {
1929
2080
  summary: null,
1930
2081
  iterations,
@@ -1941,11 +2092,14 @@ ${output.slice(0, 1e4)}
1941
2092
  };
1942
2093
  eventStore.append(sessionId, { type: "task.completed", data: taskCompletedData });
1943
2094
  const markerMsgId = crypto.randomUUID();
1944
- eventStore.append(sessionId, createMessageStartEvent(markerMsgId, "user", JSON.stringify(taskCompletedData), {
1945
- ...currentWindowMessageOptions ?? {},
1946
- isSystemGenerated: true,
1947
- messageKind: "task-completed"
1948
- }));
2095
+ eventStore.append(
2096
+ sessionId,
2097
+ createMessageStartEvent(markerMsgId, "user", JSON.stringify(taskCompletedData), {
2098
+ ...currentWindowMessageOptions ?? {},
2099
+ isSystemGenerated: true,
2100
+ messageKind: "task-completed"
2101
+ })
2102
+ );
1949
2103
  eventStore.append(sessionId, { type: "message.done", data: { messageId: markerMsgId } });
1950
2104
  logger.debug("Workflow executor complete", { sessionId, iterations });
1951
2105
  const doneAction = { type: "DONE" };
@@ -1957,7 +2111,9 @@ ${output.slice(0, 1e4)}
1957
2111
  }
1958
2112
  if (nextStepId === TERMINAL_BLOCKED) {
1959
2113
  sessionManager.setPhase(sessionId, "blocked");
1960
- const blockedCriteria = refreshedSession.criteria.filter((c) => c.status.type === "failed" && c.attempts.filter((a) => a.status === "failed").length >= RUNNER_CONFIG.maxVerifyRetries).map((c) => c.id);
2114
+ const blockedCriteria = refreshedSession.criteria.filter(
2115
+ (c) => c.status.type === "failed" && c.attempts.filter((a) => a.status === "failed").length >= RUNNER_CONFIG.maxVerifyRetries
2116
+ ).map((c) => c.id);
1961
2117
  const reason = blockedCriteria.length > 0 ? `Retry limit reached for: ${blockedCriteria.join(", ")}` : "No matching transition";
1962
2118
  emitWorkflowMessage(eventStore, sessionId, `Runner blocked: ${reason}`, currentWindowMessageOptions, onMessage);
1963
2119
  logger.warn("Workflow executor blocked", { sessionId, iterations, reason });
@@ -1972,7 +2128,11 @@ ${output.slice(0, 1e4)}
1972
2128
  }
1973
2129
  logger.warn("Workflow executor max iterations reached", { sessionId, iterations });
1974
2130
  return {
1975
- finalAction: { type: "BLOCKED", reason: `Max iterations (${workflow.settings.maxIterations}) reached`, blockedCriteria: [] },
2131
+ finalAction: {
2132
+ type: "BLOCKED",
2133
+ reason: `Max iterations (${workflow.settings.maxIterations}) reached`,
2134
+ blockedCriteria: []
2135
+ },
1976
2136
  iterations,
1977
2137
  totalTime: (performance.now() - startTime) / 1e3
1978
2138
  };
@@ -2027,11 +2187,13 @@ async function loadPrivateKey() {
2027
2187
  cachedPrivateKey = await readFile2(keyPath, "utf-8");
2028
2188
  return cachedPrivateKey;
2029
2189
  } catch {
2030
- const { privateKey } = await import("crypto").then((c) => c.generateKeyPairSync("rsa", {
2031
- modulusLength: 2048,
2032
- privateKeyEncoding: { type: "pkcs8", format: "pem" },
2033
- publicKeyEncoding: { type: "spki", format: "pem" }
2034
- }));
2190
+ const { privateKey } = await import("crypto").then(
2191
+ (c) => c.generateKeyPairSync("rsa", {
2192
+ modulusLength: 2048,
2193
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
2194
+ publicKeyEncoding: { type: "spki", format: "pem" }
2195
+ })
2196
+ );
2035
2197
  await mkdir2(keyDir, { recursive: true });
2036
2198
  await writeFile2(keyPath, privateKey, { mode: 384 });
2037
2199
  cachedPrivateKey = privateKey;
@@ -2073,10 +2235,7 @@ async function verifyPassword(password) {
2073
2235
  if (!encryptedPassword) return false;
2074
2236
  const privateKey = await loadPrivateKey();
2075
2237
  try {
2076
- const decrypted = privateDecrypt(
2077
- { key: privateKey, padding: 1 },
2078
- Buffer.from(encryptedPassword, "base64")
2079
- );
2238
+ const decrypted = privateDecrypt({ key: privateKey, padding: 1 }, Buffer.from(encryptedPassword, "base64"));
2080
2239
  return decrypted.toString() === password;
2081
2240
  } catch {
2082
2241
  return false;
@@ -2155,13 +2314,28 @@ function processQueueAndRestartTurn(sessionManager, sessionId, drainFn, queueMod
2155
2314
  if (!next) return false;
2156
2315
  for (const remaining of messages.slice(1)) {
2157
2316
  if (queueMessageFn) {
2158
- queueMessageFn(sessionId, queueMode, remaining.content, remaining.attachments, remaining.messageKind);
2317
+ queueMessageFn(
2318
+ sessionId,
2319
+ queueMode,
2320
+ remaining.content,
2321
+ remaining.attachments,
2322
+ remaining.messageKind
2323
+ );
2159
2324
  } else {
2160
2325
  sessionManager.queueMessage(sessionId, queueMode, remaining.content, remaining.attachments);
2161
2326
  }
2162
2327
  }
2163
2328
  broadcastFn(sessionId, createQueueStateMessage(sessionManager.getQueueState(sessionId)));
2164
- addUserMessageAndBroadcast(sessionManager, sessionId, { content: next.content, ...next.attachments ? { attachments: next.attachments } : {}, ...next.messageKind ? { messageKind: next.messageKind } : {} }, broadcastFn);
2329
+ addUserMessageAndBroadcast(
2330
+ sessionManager,
2331
+ sessionId,
2332
+ {
2333
+ content: next.content,
2334
+ ...next.attachments ? { attachments: next.attachments } : {},
2335
+ ...next.messageKind ? { messageKind: next.messageKind } : {}
2336
+ },
2337
+ broadcastFn
2338
+ );
2165
2339
  const newController = new AbortController();
2166
2340
  activeAgents2.set(sessionId, newController);
2167
2341
  startTurnFn(sessionId, newController);
@@ -2195,7 +2369,12 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2195
2369
  const baseUrl = provider.url.includes("/v1") ? provider.url : `${provider.url}/v1`;
2196
2370
  const sessionConfig = {
2197
2371
  ...config,
2198
- llm: { ...config.llm, baseUrl, model: session.providerModel }
2372
+ llm: {
2373
+ ...config.llm,
2374
+ baseUrl,
2375
+ model: session.providerModel,
2376
+ ...provider.apiKey && { apiKey: provider.apiKey }
2377
+ }
2199
2378
  };
2200
2379
  const client = createLLMClient(sessionConfig);
2201
2380
  if (provider.backend !== "auto") {
@@ -2294,7 +2473,12 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2294
2473
  const session = sessionManager.getSession(sessionId);
2295
2474
  if (session) {
2296
2475
  const { messages, pendingConfirmations } = buildSessionState(sessionManager, sessionId);
2297
- ws.send(serializeServerMessage({ ...createSessionStateMessage(session, messages, pendingConfirmations), sessionId }));
2476
+ ws.send(
2477
+ serializeServerMessage({
2478
+ ...createSessionStateMessage(session, messages, pendingConfirmations),
2479
+ sessionId
2480
+ })
2481
+ );
2298
2482
  }
2299
2483
  continue;
2300
2484
  }
@@ -2302,7 +2486,12 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2302
2486
  if (event.type === "session_updated") {
2303
2487
  const { session, messages, pendingConfirmations } = buildSessionState(sessionManager, sessionId);
2304
2488
  if (session) {
2305
- ws.send(serializeServerMessage({ ...createSessionStateMessage(session, messages, pendingConfirmations), sessionId }));
2489
+ ws.send(
2490
+ serializeServerMessage({
2491
+ ...createSessionStateMessage(session, messages, pendingConfirmations),
2492
+ sessionId
2493
+ })
2494
+ );
2306
2495
  }
2307
2496
  }
2308
2497
  if (event.type === "running_changed") {
@@ -2320,18 +2509,22 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2320
2509
  }
2321
2510
  };
2322
2511
  devServerManager.onOutput((workdir, chunk) => {
2323
- broadcastAll(createServerMessage("devServer.output", {
2324
- workdir,
2325
- stream: chunk.stream,
2326
- content: chunk.content
2327
- }));
2512
+ broadcastAll(
2513
+ createServerMessage("devServer.output", {
2514
+ workdir,
2515
+ stream: chunk.stream,
2516
+ content: chunk.content
2517
+ })
2518
+ );
2328
2519
  });
2329
2520
  devServerManager.onStateChange((workdir, state, errorMessage) => {
2330
- broadcastAll(createServerMessage("devServer.state", {
2331
- workdir,
2332
- state,
2333
- errorMessage
2334
- }));
2521
+ broadcastAll(
2522
+ createServerMessage("devServer.state", {
2523
+ workdir,
2524
+ state,
2525
+ errorMessage
2526
+ })
2527
+ );
2335
2528
  });
2336
2529
  onProcessEvent((_processId, msg) => {
2337
2530
  const sessionId = msg.sessionId;
@@ -2386,16 +2579,29 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
2386
2579
  }
2387
2580
  const client = clients.get(ws);
2388
2581
  try {
2389
- await handleClientMessage(ws, client, message, getLLMClient, getActiveProvider, sessionManager, broadcastForSession, providerManager, getSessionLLMClient, getSessionStatsIdentity, llmForSession, statsForSession, startTurnWithCompletionChain, cleanupAfterTurn);
2582
+ await handleClientMessage(
2583
+ ws,
2584
+ client,
2585
+ message,
2586
+ getLLMClient,
2587
+ getActiveProvider,
2588
+ sessionManager,
2589
+ broadcastForSession,
2590
+ providerManager,
2591
+ getSessionLLMClient,
2592
+ getSessionStatsIdentity,
2593
+ llmForSession,
2594
+ statsForSession,
2595
+ startTurnWithCompletionChain,
2596
+ cleanupAfterTurn
2597
+ );
2390
2598
  } catch (error) {
2391
2599
  logger.error("Error handling client message", { error, type: message.type });
2392
- ws.send(serializeServerMessage(
2393
- createErrorMessage(
2394
- "INTERNAL_ERROR",
2395
- error instanceof Error ? error.message : "Unknown error",
2396
- message.id
2600
+ ws.send(
2601
+ serializeServerMessage(
2602
+ createErrorMessage("INTERNAL_ERROR", error instanceof Error ? error.message : "Unknown error", message.id)
2397
2603
  )
2398
- ));
2604
+ );
2399
2605
  }
2400
2606
  });
2401
2607
  ws.on("close", () => {
@@ -2456,7 +2662,13 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
2456
2662
  case "session.delete":
2457
2663
  case "session.deleteAll":
2458
2664
  case "session.setProvider":
2459
- send(createErrorMessage("DEPRECATED_MESSAGE_TYPE", `${message.type} removed. Use REST API instead. See docs/REST-API.md`, message.id));
2665
+ send(
2666
+ createErrorMessage(
2667
+ "DEPRECATED_MESSAGE_TYPE",
2668
+ `${message.type} removed. Use REST API instead. See docs/REST-API.md`,
2669
+ message.id
2670
+ )
2671
+ );
2460
2672
  return;
2461
2673
  // =========================================================================
2462
2674
  // Session Load - Required for WS subscription mechanism
@@ -2479,7 +2691,12 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
2479
2691
  const events = eventStore.getEvents(session.id);
2480
2692
  const messages = buildMessagesFromStoredEvents(events);
2481
2693
  const pendingConfirmations = foldPendingConfirmations(events);
2482
- logger.debug("Loaded messages from EventStore", { sessionId: session.id, eventCount: events.length, messageCount: messages.length, pendingConfirmationsCount: pendingConfirmations.length });
2694
+ logger.debug("Loaded messages from EventStore", {
2695
+ sessionId: session.id,
2696
+ eventCount: events.length,
2697
+ messageCount: messages.length,
2698
+ pendingConfirmationsCount: pendingConfirmations.length
2699
+ });
2483
2700
  sendForSession(session.id, createSessionStateMessage(session, messages, pendingConfirmations, message.id));
2484
2701
  const contextState = sessionManager.getContextState(session.id);
2485
2702
  sendForSession(session.id, createContextStateMessage(contextState));
@@ -2521,10 +2738,13 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
2521
2738
  sendForSession(sessionId, createSessionStateMessage(updatedSession, compactMessages, pendingConfirmations));
2522
2739
  } catch (error) {
2523
2740
  logger.error("Compaction failed", { error, sessionId });
2524
- sendForSession(sessionId, createChatErrorMessage(
2525
- `Compaction failed: ${error instanceof Error ? error.message : "Unknown error"}`,
2526
- true
2527
- ));
2741
+ sendForSession(
2742
+ sessionId,
2743
+ createChatErrorMessage(
2744
+ `Compaction failed: ${error instanceof Error ? error.message : "Unknown error"}`,
2745
+ true
2746
+ )
2747
+ );
2528
2748
  }
2529
2749
  })();
2530
2750
  break;
@@ -2599,7 +2819,12 @@ ${content}` : workflowInfo;
2599
2819
  statsIdentity: statsForSession(sessionId),
2600
2820
  injectBuilderKickoff: !hasUserMessage,
2601
2821
  ...launchPayload?.workflowId ? { workflowId: launchPayload.workflowId } : {},
2602
- ...hasUserMessage ? { userMessage: { content: hasUserContent ? launchPayload.content : "", ...hasUserAttachments ? { attachments: launchAttachments } : {} } } : {},
2822
+ ...hasUserMessage ? {
2823
+ userMessage: {
2824
+ content: hasUserContent ? launchPayload.content : "",
2825
+ ...hasUserAttachments ? { attachments: launchAttachments } : {}
2826
+ }
2827
+ } : {},
2603
2828
  signal: controller.signal,
2604
2829
  onMessage: (msg) => sendForSession(sessionId, msg)
2605
2830
  // For path confirmation dialogs
@@ -2617,7 +2842,13 @@ ${content}` : workflowInfo;
2617
2842
  // Path Confirmation
2618
2843
  // =========================================================================
2619
2844
  case "path.confirm": {
2620
- send(createErrorMessage("DEPRECATED", "path.confirm removed. Use REST API: POST /api/sessions/:id/confirm-path", message.id));
2845
+ send(
2846
+ createErrorMessage(
2847
+ "DEPRECATED",
2848
+ "path.confirm removed. Use REST API: POST /api/sessions/:id/confirm-path",
2849
+ message.id
2850
+ )
2851
+ );
2621
2852
  break;
2622
2853
  }
2623
2854
  // =========================================================================
@@ -2731,12 +2962,9 @@ var LspServer = class {
2731
2962
  new StreamMessageReader(this.process.stdout),
2732
2963
  new StreamMessageWriter(this.process.stdin)
2733
2964
  );
2734
- this.connection.onNotification(
2735
- LSP.publishDiagnostics,
2736
- (params) => {
2737
- this.handleDiagnostics(params);
2738
- }
2739
- );
2965
+ this.connection.onNotification(LSP.publishDiagnostics, (params) => {
2966
+ this.handleDiagnostics(params);
2967
+ });
2740
2968
  this.process.on("error", (err) => {
2741
2969
  logger.error("LSP server process error", { language: this.config.id, error: err.message });
2742
2970
  this.handleProcessExit();
@@ -2773,9 +3001,7 @@ var LspServer = class {
2773
3001
  workspaceFolders: true
2774
3002
  }
2775
3003
  },
2776
- workspaceFolders: [
2777
- { uri: `file://${this.workdir}`, name: "workspace" }
2778
- ],
3004
+ workspaceFolders: [{ uri: `file://${this.workdir}`, name: "workspace" }],
2779
3005
  initializationOptions: this.config.initOptions
2780
3006
  };
2781
3007
  const result = await this.connection.sendRequest(LSP.initialize, initParams);
@@ -3846,6 +4072,17 @@ var SessionManager = class {
3846
4072
  updateSessionDangerLevel(sessionId, dangerLevel);
3847
4073
  return this.requireSession(sessionId);
3848
4074
  }
4075
+ /**
4076
+ * Rename session. Updates title in DB and emits session_updated.
4077
+ */
4078
+ renameSession(sessionId, title) {
4079
+ this.requireSession(sessionId);
4080
+ logger.debug("Renaming session", { sessionId, title });
4081
+ updateSessionMetadata(sessionId, { title });
4082
+ const updatedSession = this.requireSession(sessionId);
4083
+ this.emit({ type: "session_updated", session: updatedSession });
4084
+ return updatedSession;
4085
+ }
3849
4086
  /**
3850
4087
  * Set session running state. Emits running.changed event.
3851
4088
  */
@@ -4122,9 +4359,7 @@ ${summary}`, {
4122
4359
  if (!state.criteria.find((c) => c.id === criterionId)) {
4123
4360
  throw new Error(`Criterion not found: ${criterionId}`);
4124
4361
  }
4125
- const updatedCriteria = state.criteria.map(
4126
- (c) => c.id === criterionId ? { ...c, ...updates } : c
4127
- );
4362
+ const updatedCriteria = state.criteria.map((c) => c.id === criterionId ? { ...c, ...updates } : c);
4128
4363
  emitCriteriaSet(sessionId, updatedCriteria);
4129
4364
  return updatedCriteria;
4130
4365
  }
@@ -4175,7 +4410,10 @@ ${summary}`, {
4175
4410
  const queue = this.messageQueues.get(sessionId);
4176
4411
  if (!queue) return [];
4177
4412
  const asap = queue.filter((m) => m.mode === "asap");
4178
- this.messageQueues.set(sessionId, queue.filter((m) => m.mode !== "asap"));
4413
+ this.messageQueues.set(
4414
+ sessionId,
4415
+ queue.filter((m) => m.mode !== "asap")
4416
+ );
4179
4417
  for (const msg of asap) {
4180
4418
  this.emit({ type: "queue_drained", sessionId, queueId: msg.queueId });
4181
4419
  }
@@ -4185,7 +4423,10 @@ ${summary}`, {
4185
4423
  const queue = this.messageQueues.get(sessionId);
4186
4424
  if (!queue) return [];
4187
4425
  const completion = queue.filter((m) => m.mode === "completion");
4188
- this.messageQueues.set(sessionId, queue.filter((m) => m.mode !== "completion"));
4426
+ this.messageQueues.set(
4427
+ sessionId,
4428
+ queue.filter((m) => m.mode !== "completion")
4429
+ );
4189
4430
  for (const msg of completion) {
4190
4431
  this.emit({ type: "queue_drained", sessionId, queueId: msg.queueId });
4191
4432
  }
@@ -4402,7 +4643,9 @@ ${summary}`,
4402
4643
  criteria: eventState.criteria,
4403
4644
  contextWindows: [],
4404
4645
  // Derived from events, not stored separately
4405
- executionState: eventState.lastModeWithReminder ? { lastModeWithReminder: eventState.lastModeWithReminder } : null
4646
+ executionState: eventState.lastModeWithReminder ? {
4647
+ lastModeWithReminder: eventState.lastModeWithReminder
4648
+ } : null
4406
4649
  };
4407
4650
  }
4408
4651
  };
@@ -4419,10 +4662,7 @@ function computeOverrideIds(defaults, userItems) {
4419
4662
  function createSkillRoutes(configDir) {
4420
4663
  const router = Router();
4421
4664
  router.get("/", async (_req, res) => {
4422
- const [defaults, userItems] = await Promise.all([
4423
- loadDefaultSkills(),
4424
- loadUserSkills(configDir)
4425
- ]);
4665
+ const [defaults, userItems] = await Promise.all([loadDefaultSkills(), loadUserSkills(configDir)]);
4426
4666
  const overrideIds = computeOverrideIds(defaults, userItems);
4427
4667
  res.json({
4428
4668
  defaults: defaults.map((s) => ({
@@ -4555,10 +4795,7 @@ async function loadUserCommands(configDir) {
4555
4795
  });
4556
4796
  }
4557
4797
  async function loadAllCommands(configDir) {
4558
- const [defaultCommands, userCommands] = await Promise.all([
4559
- loadDefaultCommands(),
4560
- loadUserCommands(configDir)
4561
- ]);
4798
+ const [defaultCommands, userCommands] = await Promise.all([loadDefaultCommands(), loadUserCommands(configDir)]);
4562
4799
  const commandMap = /* @__PURE__ */ new Map();
4563
4800
  for (const cmd of defaultCommands) {
4564
4801
  commandMap.set(cmd.metadata.id, cmd);
@@ -4614,10 +4851,7 @@ async function deleteCommand(configDir, commandId) {
4614
4851
  function createCommandRoutes(configDir) {
4615
4852
  const router = Router2();
4616
4853
  router.get("/", async (_req, res) => {
4617
- const [defaults, userItems] = await Promise.all([
4618
- loadDefaultCommands(),
4619
- loadUserCommands(configDir)
4620
- ]);
4854
+ const [defaults, userItems] = await Promise.all([loadDefaultCommands(), loadUserCommands(configDir)]);
4621
4855
  const overrideIds = computeOverrideIds(defaults, userItems);
4622
4856
  res.json({
4623
4857
  defaults: defaults.map((c) => c.metadata),
@@ -4708,10 +4942,7 @@ import { Router as Router3 } from "express";
4708
4942
  function createAgentRoutes(configDir) {
4709
4943
  const router = Router3();
4710
4944
  router.get("/", async (_req, res) => {
4711
- const [defaults, userItems] = await Promise.all([
4712
- loadDefaultAgents(),
4713
- loadUserAgents(configDir)
4714
- ]);
4945
+ const [defaults, userItems] = await Promise.all([loadDefaultAgents(), loadUserAgents(configDir)]);
4715
4946
  const overrideIds = computeOverrideIds(defaults, userItems);
4716
4947
  res.json({
4717
4948
  defaults: defaults.map((a) => a.metadata),
@@ -4802,10 +5033,7 @@ import { Router as Router4 } from "express";
4802
5033
  function createWorkflowRoutes(configDir, config) {
4803
5034
  const router = Router4();
4804
5035
  router.get("/", async (_req, res) => {
4805
- const [defaults, userItems] = await Promise.all([
4806
- loadDefaultWorkflows(),
4807
- loadUserWorkflows(configDir)
4808
- ]);
5036
+ const [defaults, userItems] = await Promise.all([loadDefaultWorkflows(), loadUserWorkflows(configDir)]);
4809
5037
  const overrideIds = computeOverrideIds(defaults, userItems);
4810
5038
  res.json({
4811
5039
  defaults: defaults.map((p) => ({ ...p.metadata, startCondition: p.startCondition })),
@@ -5014,7 +5242,7 @@ function createTerminalRoutes() {
5014
5242
  }
5015
5243
 
5016
5244
  // src/constants.ts
5017
- var VERSION = "1.6.74";
5245
+ var VERSION = "1.6.76";
5018
5246
 
5019
5247
  // src/server/index.ts
5020
5248
  var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
@@ -5133,7 +5361,7 @@ async function createServerHandle(config) {
5133
5361
  res.json({ tools });
5134
5362
  });
5135
5363
  app.get("/api/projects", async (_req, res) => {
5136
- const { listProjects } = await import("./projects-HEUOWNSR.js");
5364
+ const { listProjects } = await import("./projects-XLMSDFTQ.js");
5137
5365
  const projects = listProjects();
5138
5366
  res.json({ projects });
5139
5367
  });
@@ -5142,12 +5370,12 @@ async function createServerHandle(config) {
5142
5370
  if (!name || !workdir) {
5143
5371
  return res.status(400).json({ error: "name and workdir are required" });
5144
5372
  }
5145
- const { createDirectoryWithGit } = await import("./project-creator-LASKNQPA.js");
5373
+ const { createDirectoryWithGit } = await import("./project-creator-VD7MLOWE.js");
5146
5374
  const project = await createDirectoryWithGit(name, workdir);
5147
5375
  res.status(201).json({ project });
5148
5376
  });
5149
5377
  app.get("/api/projects/:id", async (req, res) => {
5150
- const { getProject: getProject2 } = await import("./projects-HEUOWNSR.js");
5378
+ const { getProject: getProject2 } = await import("./projects-XLMSDFTQ.js");
5151
5379
  const project = getProject2(req.params.id);
5152
5380
  if (!project) {
5153
5381
  return res.status(404).json({ error: "Project not found" });
@@ -5155,7 +5383,7 @@ async function createServerHandle(config) {
5155
5383
  res.json({ project });
5156
5384
  });
5157
5385
  app.put("/api/projects/:id", async (req, res) => {
5158
- const { updateProject } = await import("./projects-HEUOWNSR.js");
5386
+ const { updateProject } = await import("./projects-XLMSDFTQ.js");
5159
5387
  const { name, customInstructions } = req.body;
5160
5388
  const updates = {};
5161
5389
  if (name !== void 0) updates.name = name;
@@ -5167,7 +5395,7 @@ async function createServerHandle(config) {
5167
5395
  res.json({ project: updated });
5168
5396
  });
5169
5397
  app.delete("/api/projects/:id", async (req, res) => {
5170
- const { getProject: getProject2, deleteProject } = await import("./projects-HEUOWNSR.js");
5398
+ const { getProject: getProject2, deleteProject } = await import("./projects-XLMSDFTQ.js");
5171
5399
  const project = getProject2(req.params.id);
5172
5400
  if (!project) {
5173
5401
  return res.status(404).json({ error: "Project not found" });
@@ -5176,7 +5404,7 @@ async function createServerHandle(config) {
5176
5404
  res.json({ success: true });
5177
5405
  });
5178
5406
  app.get("/api/sessions", async (req, res) => {
5179
- const { getRecentUserPromptsForSession } = await import("./events-LKEZ3YCW.js");
5407
+ const { getRecentUserPromptsForSession } = await import("./events-BDXQOC7F.js");
5180
5408
  const projectId = req.query["projectId"];
5181
5409
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
5182
5410
  const offset = parseInt(req.query["offset"]) || 0;
@@ -5209,8 +5437,8 @@ async function createServerHandle(config) {
5209
5437
  res.status(201).json({ session });
5210
5438
  });
5211
5439
  app.get("/api/sessions/:id", async (req, res) => {
5212
- const { getEventStore: getEventStore2 } = await import("./events-LKEZ3YCW.js");
5213
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-JN2WT44N.js");
5440
+ const { getEventStore: getEventStore2 } = await import("./events-BDXQOC7F.js");
5441
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2HW7FIKL.js");
5214
5442
  const session = sessionManager.getSession(req.params.id);
5215
5443
  if (!session) {
5216
5444
  return res.status(404).json({ error: "Session not found" });
@@ -5240,8 +5468,8 @@ async function createServerHandle(config) {
5240
5468
  res.json({ success: true });
5241
5469
  });
5242
5470
  app.post("/api/sessions/:id/provider", async (req, res) => {
5243
- const { getEventStore: getEventStore2 } = await import("./events-LKEZ3YCW.js");
5244
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-JN2WT44N.js");
5471
+ const { getEventStore: getEventStore2 } = await import("./events-BDXQOC7F.js");
5472
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2HW7FIKL.js");
5245
5473
  const sessionId = req.params.id;
5246
5474
  const session = sessionManager.getSession(sessionId);
5247
5475
  if (!session) {
@@ -5252,7 +5480,7 @@ async function createServerHandle(config) {
5252
5480
  return res.status(400).json({ error: "providerId is required" });
5253
5481
  }
5254
5482
  sessionManager.setSessionProvider(sessionId, providerId, model ?? "auto");
5255
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-6T4EHAP2.js");
5483
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-5CONAOL7.js");
5256
5484
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5257
5485
  const updatedConfig = setDefaultModelSelection(globalConfig, providerId, model ?? "auto");
5258
5486
  await saveGlobalConfig(config.mode ?? "production", updatedConfig);
@@ -5278,8 +5506,8 @@ async function createServerHandle(config) {
5278
5506
  res.json({ success: true });
5279
5507
  });
5280
5508
  app.put("/api/sessions/:id/mode", async (req, res) => {
5281
- const { getEventStore: getEventStore2 } = await import("./events-LKEZ3YCW.js");
5282
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-JN2WT44N.js");
5509
+ const { getEventStore: getEventStore2 } = await import("./events-BDXQOC7F.js");
5510
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2HW7FIKL.js");
5283
5511
  const sessionId = req.params.id;
5284
5512
  const session = sessionManager.getSession(sessionId);
5285
5513
  if (!session) {
@@ -5311,20 +5539,34 @@ async function createServerHandle(config) {
5311
5539
  const updatedSession = sessionManager.getSession(sessionId);
5312
5540
  res.json({ session: updatedSession });
5313
5541
  });
5542
+ app.put("/api/sessions/:id/title", async (req, res) => {
5543
+ const sessionId = req.params.id;
5544
+ const session = sessionManager.getSession(sessionId);
5545
+ if (!session) {
5546
+ return res.status(404).json({ error: "Session not found" });
5547
+ }
5548
+ const { title } = req.body;
5549
+ if (!title || typeof title !== "string") {
5550
+ return res.status(400).json({ error: "title is required" });
5551
+ }
5552
+ sessionManager.renameSession(sessionId, title.slice(0, 100));
5553
+ const updatedSession = sessionManager.getSession(sessionId);
5554
+ res.json({ session: updatedSession });
5555
+ });
5314
5556
  app.post("/api/sessions/:id/confirm-path", async (req, res) => {
5315
5557
  const sessionId = req.params.id;
5316
5558
  const { callId, approved, alwaysAllow } = req.body;
5317
5559
  if (!callId || approved === void 0) {
5318
5560
  return res.status(400).json({ error: "callId and approved are required" });
5319
5561
  }
5320
- const { providePathConfirmation } = await import("./tools-RUAY6EVI.js");
5562
+ const { providePathConfirmation } = await import("./tools-BHYHS3RY.js");
5321
5563
  const result = providePathConfirmation(callId, approved, alwaysAllow);
5322
5564
  if (!result.found) {
5323
5565
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
5324
5566
  }
5325
- const { getEventStore: getEventStore2 } = await import("./events-LKEZ3YCW.js");
5326
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-JN2WT44N.js");
5327
- const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-5AWNGFLH.js");
5567
+ const { getEventStore: getEventStore2 } = await import("./events-BDXQOC7F.js");
5568
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-2HW7FIKL.js");
5569
+ const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-4CTV7OZC.js");
5328
5570
  const eventStore = getEventStore2();
5329
5571
  const events = eventStore.getEvents(sessionId);
5330
5572
  const messages = buildMessagesFromStoredEvents2(events);
@@ -5341,7 +5583,7 @@ async function createServerHandle(config) {
5341
5583
  if (!callId || !answer) {
5342
5584
  return res.status(400).json({ error: "callId and answer are required" });
5343
5585
  }
5344
- const { provideAnswer: provideAnswer2 } = await import("./tools-RUAY6EVI.js");
5586
+ const { provideAnswer: provideAnswer2 } = await import("./tools-BHYHS3RY.js");
5345
5587
  const found = provideAnswer2(callId, answer);
5346
5588
  if (!found) {
5347
5589
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -5377,14 +5619,14 @@ async function createServerHandle(config) {
5377
5619
  if (!session) {
5378
5620
  return res.status(404).json({ error: "Session not found" });
5379
5621
  }
5380
- const { stopSessionExecution } = await import("./chat-handler-KYMMXPP6.js");
5381
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-RUAY6EVI.js");
5622
+ const { stopSessionExecution } = await import("./chat-handler-7DKHGTVO.js");
5623
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-BHYHS3RY.js");
5382
5624
  stopSessionExecution(sessionId, sessionManager);
5383
5625
  abortSession(sessionId);
5384
5626
  cancelQuestionsForSession(sessionId, "Session stopped by user");
5385
5627
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
5386
5628
  sessionManager.clearMessageQueue(sessionId);
5387
- const eventStore = (await import("./events-LKEZ3YCW.js")).getEventStore();
5629
+ const eventStore = (await import("./events-BDXQOC7F.js")).getEventStore();
5388
5630
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
5389
5631
  res.json({ success: true });
5390
5632
  });
@@ -5415,13 +5657,13 @@ async function createServerHandle(config) {
5415
5657
  res.json({ accepted: true });
5416
5658
  });
5417
5659
  app.get("/api/settings/:key", async (req, res) => {
5418
- const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-NI4ITGV6.js");
5660
+ const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-TQNQB56H.js");
5419
5661
  const key = req.params.key;
5420
5662
  const value = getSetting(key) ?? SETTINGS_DEFAULTS[key] ?? null;
5421
5663
  res.json({ key, value });
5422
5664
  });
5423
5665
  app.put("/api/settings/:key", async (req, res) => {
5424
- const { setSetting } = await import("./settings-NI4ITGV6.js");
5666
+ const { setSetting } = await import("./settings-TQNQB56H.js");
5425
5667
  const key = req.params.key;
5426
5668
  const { value } = req.body;
5427
5669
  if (value === void 0) {
@@ -5436,7 +5678,7 @@ async function createServerHandle(config) {
5436
5678
  let visionFallback;
5437
5679
  let globalWorkdir;
5438
5680
  try {
5439
- const { loadGlobalConfig, getVisionFallback } = await import("./config-6T4EHAP2.js");
5681
+ const { loadGlobalConfig, getVisionFallback } = await import("./config-5CONAOL7.js");
5440
5682
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5441
5683
  const fallback = getVisionFallback(globalConfig);
5442
5684
  if (fallback) {
@@ -5515,7 +5757,7 @@ async function createServerHandle(config) {
5515
5757
  return res.status(400).json({ error: "name, url, and backend are required" });
5516
5758
  }
5517
5759
  try {
5518
- const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-6T4EHAP2.js");
5760
+ const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-5CONAOL7.js");
5519
5761
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5520
5762
  const providerBackend = backend;
5521
5763
  const configWithProvider = addProvider(globalConfig, {
@@ -5548,7 +5790,7 @@ async function createServerHandle(config) {
5548
5790
  app.post("/api/init/config", async (req, res) => {
5549
5791
  const { workdir, visionFallback } = req.body;
5550
5792
  try {
5551
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-6T4EHAP2.js");
5793
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-5CONAOL7.js");
5552
5794
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5553
5795
  const updatedConfig = {
5554
5796
  ...globalConfig,
@@ -5576,7 +5818,7 @@ async function createServerHandle(config) {
5576
5818
  });
5577
5819
  app.delete("/api/providers/:id", async (req, res) => {
5578
5820
  const { id } = req.params;
5579
- const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-6T4EHAP2.js");
5821
+ const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-5CONAOL7.js");
5580
5822
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5581
5823
  const updatedConfig = removeProvider(globalConfig, id);
5582
5824
  await saveGlobalConfig(config.mode ?? "production", updatedConfig);
@@ -5596,7 +5838,7 @@ async function createServerHandle(config) {
5596
5838
  return res.status(400).json({ error: result.error });
5597
5839
  }
5598
5840
  const llmClient = getLLMClient();
5599
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-6T4EHAP2.js");
5841
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-5CONAOL7.js");
5600
5842
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5601
5843
  const updatedConfig = setDefaultModelSelection(globalConfig, id, llmClient.getModel());
5602
5844
  await saveGlobalConfig(config.mode ?? "production", updatedConfig);
@@ -5627,7 +5869,7 @@ async function createServerHandle(config) {
5627
5869
  if (!result.success) {
5628
5870
  return res.status(400).json({ error: result.error });
5629
5871
  }
5630
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-6T4EHAP2.js");
5872
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-5CONAOL7.js");
5631
5873
  const globalConfig = await loadGlobalConfig(config.mode ?? "production");
5632
5874
  const updatedProviders = providerManager.getProviders();
5633
5875
  const updatedConfig = {
@@ -5677,13 +5919,13 @@ async function createServerHandle(config) {
5677
5919
  app.use("/api/dev-server", createDevServerRoutes());
5678
5920
  app.use("/api/terminals", createTerminalRoutes());
5679
5921
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
5680
- const { getSessionProcesses } = await import("./manager-HM2J5VMW.js");
5922
+ const { getSessionProcesses } = await import("./manager-W7N3XQ4Q.js");
5681
5923
  const sessionId = req.params.id;
5682
5924
  const processes = getSessionProcesses(sessionId);
5683
5925
  res.json({ processes });
5684
5926
  });
5685
5927
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
5686
- const { stopProcess } = await import("./manager-HM2J5VMW.js");
5928
+ const { stopProcess } = await import("./manager-W7N3XQ4Q.js");
5687
5929
  const sessionId = req.params.id;
5688
5930
  const processId = req.params.processId;
5689
5931
  const session = sessionManager.getSession(sessionId);
@@ -5697,7 +5939,7 @@ async function createServerHandle(config) {
5697
5939
  res.status(500).json({ error: err instanceof Error ? err.message : "Failed to stop process" });
5698
5940
  }
5699
5941
  });
5700
- const { getCurrentBranch } = await import("./branch.api-XADFZZAA.js");
5942
+ const { getCurrentBranch } = await import("./branch.api-PWFW26KC.js");
5701
5943
  app.get("/api/branch", async (req, res) => {
5702
5944
  await getCurrentBranch(req, res);
5703
5945
  });
@@ -5852,7 +6094,7 @@ async function createServerHandle(config) {
5852
6094
  providerManager
5853
6095
  );
5854
6096
  const wss = wssExports.wss;
5855
- const { QueueProcessor } = await import("./processor-23O4HPSS.js");
6097
+ const { QueueProcessor } = await import("./processor-6TS37IYH.js");
5856
6098
  const queueProcessor = new QueueProcessor({
5857
6099
  sessionManager,
5858
6100
  providerManager,
@@ -5890,9 +6132,9 @@ async function createServerHandle(config) {
5890
6132
  logger.info("Shutting down...");
5891
6133
  void (async () => {
5892
6134
  await devServerManager.stopAll();
5893
- const { stopAllInspectProxies } = await import("./inspect-proxy-Y4MRAVB7.js");
6135
+ const { stopAllInspectProxies } = await import("./inspect-proxy-Y75AXMRX.js");
5894
6136
  stopAllInspectProxies();
5895
- const { cleanupAllProcesses } = await import("./store-2IF3ZSLD.js");
6137
+ const { cleanupAllProcesses } = await import("./store-OQ45KONN.js");
5896
6138
  cleanupAllProcesses();
5897
6139
  viteServer?.close();
5898
6140
  for (const client of wss.clients) {
@@ -5927,4 +6169,4 @@ export {
5927
6169
  createServerHandle,
5928
6170
  createServer
5929
6171
  };
5930
- //# sourceMappingURL=chunk-ODOA4RNN.js.map
6172
+ //# sourceMappingURL=chunk-K2V7EW5F.js.map