nolo-cli 0.107.0-alpha.4 → 0.107.0

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 (209) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-UDCSOTD2.js → _executeModel-C4EH5TZG.js} +77 -69
  3. package/action-GVA5ARSJ.js +20 -0
  4. package/{addContentAction-MB2HHMDZ.js → addContentAction-M2WOWZCL.js} +13 -12
  5. package/{addDialogAgentAction-MCEABSBA.js → addDialogAgentAction-QMAQ5Z6N.js} +19 -20
  6. package/{agentDeleteCommand-OWYHN6D6.js → agentDeleteCommand-D3RICSHX.js} +118 -43
  7. package/{agentEmailCommands-AU5I4M4W.js → agentEmailCommands-YC2A4USQ.js} +99 -89
  8. package/agentListCommands-UDJELMYP.js +741 -0
  9. package/{agentMachineCommands-YMNME2L6.js → agentMachineCommands-XH4IBGTO.js} +48 -44
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-CMVTBY5X.js} +97 -2
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-B4T2DJ5H.js} +1 -1
  12. package/agentRecordCommands-3EOC2QMN.js +138 -0
  13. package/agentRunCommand-BTHYOVVS.js +167 -0
  14. package/{agentRunControl-AVJR4JW4.js → agentRunControl-3HWA2LLQ.js} +2 -2
  15. package/{agentRuntimeLocal-KCMC2TBD.js → agentRuntimeLocal-N4YGKL7M.js} +44 -40
  16. package/{agentSlice-R7PR6KYM.js → agentSlice-NIN4T6CF.js} +15 -14
  17. package/{appDeleteCommands-JEPA3EWE.js → appDeleteCommands-7DAF33AM.js} +46 -42
  18. package/{appDeployCommands-UTB76XFM.js → appDeployCommands-ZPZSMFGZ.js} +46 -42
  19. package/{appDeployStatusCommands-LGHF2SBD.js → appDeployStatusCommands-FWBDSSS5.js} +46 -42
  20. package/{appGetCommands-PX2BFHOB.js → appGetCommands-SZZOHGEP.js} +46 -42
  21. package/{appListCommands-BSMPTWKC.js → appListCommands-FPMUBDPM.js} +46 -42
  22. package/{authCommand-YW42YZA4.js → authCommand-VL3G26NQ.js} +119 -25
  23. package/{authCommands-RGOGCPP6.js → authCommands-5RTUDYZW.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-ZK4K67Y5.js} +11 -9
  25. package/{chromeCommands-FZYAU75D.js → chromeCommands-AU5ZJXBG.js} +289 -37
  26. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-ZYTCMNHG.js} +156 -22
  27. package/{chunk-JDPFV2JV.js → chunk-2NNRWRM5.js} +20 -11
  28. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  29. package/{chunk-HVURBGF3.js → chunk-2U3NHADM.js} +6 -6
  30. package/{chunk-UVA7OYO3.js → chunk-2ZHBFX5R.js} +29 -9
  31. package/{chunk-QTGQ2LTL.js → chunk-3DQY5IFB.js} +6 -10
  32. package/chunk-4LCOCOR5.js +50 -0
  33. package/{chunk-JPGCXHNM.js → chunk-4LKMZ3RR.js} +1 -1
  34. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  35. package/{chunk-6D6VBVEW.js → chunk-4W24JM32.js} +80 -14
  36. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  37. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  38. package/chunk-5MMAK75Q.js +15 -0
  39. package/{chunk-7S4YWN7P.js → chunk-5UUIGN6I.js} +4 -4
  40. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  41. package/{chunk-IBOOZVVD.js → chunk-6IJDSYUA.js} +849 -279
  42. package/{chunk-4MK3I7Y4.js → chunk-6MAW4XOF.js} +5 -5
  43. package/chunk-76HO2DP6.js +15 -0
  44. package/chunk-7AY2H3GA.js +13692 -0
  45. package/{chunk-4CR5I7BD.js → chunk-7HYOPBUW.js} +47 -67
  46. package/{chunk-VLTIYV3X.js → chunk-7I25CBT5.js} +34 -8
  47. package/chunk-AGIM7IMJ.js +147 -0
  48. package/{chunk-5UTFL4QJ.js → chunk-AOTBKDRK.js} +7 -0
  49. package/{chunk-6OZ36FXI.js → chunk-BIPGGSJS.js} +22 -4
  50. package/{chunk-EYAQT56M.js → chunk-BNQMNUKZ.js} +9 -6
  51. package/{chunk-62CATUYY.js → chunk-CBUMFIFE.js} +834 -962
  52. package/{chunk-OIVSQH2O.js → chunk-CDEEFJXN.js} +308 -11
  53. package/chunk-CHOZJMJS.js +78 -0
  54. package/{chunk-ETI2NYVF.js → chunk-CIP3AAMT.js} +4 -4
  55. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  56. package/{chunk-IBOZNTG2.js → chunk-DGEUP3DK.js} +23 -28
  57. package/{chunk-Q554LLSI.js → chunk-DMXLXZKL.js} +1 -1
  58. package/{chunk-3VNWWVKB.js → chunk-E3YWHWCR.js} +50 -18
  59. package/{chunk-HKNXJGEC.js → chunk-ECFHBYUW.js} +85 -50
  60. package/{chunk-ACTMNVHM.js → chunk-EHSYSKXV.js} +1 -1
  61. package/{chunk-WV42OMV7.js → chunk-ELUDRSRD.js} +8 -8
  62. package/{chunk-ABQYVJBJ.js → chunk-EV235ILT.js} +5 -5
  63. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  64. package/{chunk-BFDFRLLQ.js → chunk-EZ4VZHAG.js} +5 -5
  65. package/{chunk-GO3Z72MT.js → chunk-FHLMQIU7.js} +65 -95
  66. package/{chunk-2F7RJC6L.js → chunk-FOXQ7BAB.js} +1 -1
  67. package/{chunk-SH43IESU.js → chunk-GGC55Q32.js} +199 -29
  68. package/chunk-GMZLP5DV.js +82 -0
  69. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  70. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  71. package/{chunk-QOKAKDPE.js → chunk-HIM3FCLF.js} +0 -1
  72. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  73. package/{chunk-BNGW5ASC.js → chunk-I2RGRVQ7.js} +22 -2
  74. package/{chunk-O6OSWFZQ.js → chunk-IHPDK6UD.js} +6 -0
  75. package/{chunk-QDSINZM3.js → chunk-IXH3HKY2.js} +1 -22
  76. package/{chunk-GQBOR3G6.js → chunk-JBKHQOYK.js} +8 -4
  77. package/{chunk-XD2MJFUG.js → chunk-JEFXP73H.js} +1 -1
  78. package/{chunk-PBA4UJBK.js → chunk-JIXGJTBU.js} +4 -4
  79. package/{chunk-AEOE4Z6Q.js → chunk-K6L5PNXK.js} +39 -15
  80. package/{chunk-Z77CRGTW.js → chunk-KA5O5KQL.js} +1 -1
  81. package/{chunk-GPCZ7UXG.js → chunk-KD6D6BLA.js} +1 -1
  82. package/{chunk-UZGQNTVW.js → chunk-KHKTDMYG.js} +8 -6
  83. package/{chunk-MRIHM22T.js → chunk-LBFL6RZG.js} +58 -9
  84. package/{chunk-C3M4465B.js → chunk-LKIVH2I2.js} +403 -658
  85. package/{chunk-LS2ZANRJ.js → chunk-LOCNXNOU.js} +1 -1
  86. package/{chunk-DHDMC6FO.js → chunk-LUBFABMJ.js} +15 -14
  87. package/{chunk-NA35QHCF.js → chunk-LVBFKW65.js} +1 -1
  88. package/chunk-LWLNLZC5.js +265 -0
  89. package/{chunk-EEGDMATE.js → chunk-M3NMHYRB.js} +86 -81
  90. package/chunk-N4NGJDT6.js +929 -0
  91. package/{chunk-GL3EHUR4.js → chunk-N7NLLRQQ.js} +68 -46
  92. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  93. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  94. package/chunk-NWENLDMM.js +42 -0
  95. package/chunk-O7SVKKLY.js +875 -0
  96. package/chunk-OCZKATRC.js +129 -0
  97. package/{chunk-6Z7MY3V7.js → chunk-OEJLGVBL.js} +5 -5
  98. package/{chunk-VMFTFOWF.js → chunk-OKGVNZTL.js} +35 -8
  99. package/{chunk-GEPUP7OO.js → chunk-OR2UWD6X.js} +3 -3
  100. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  101. package/{chunk-J4MOO56S.js → chunk-PNXHPLRU.js} +10 -2
  102. package/{chunk-3BMYXEUW.js → chunk-R5AJODNI.js} +1 -1
  103. package/{chunk-P5EVSOPA.js → chunk-R6EBQEQE.js} +22 -29
  104. package/{chunk-NOF3HDSN.js → chunk-RLSF5CSE.js} +11 -9
  105. package/chunk-RQ6CTX2E.js +164 -0
  106. package/{chunk-3UZPUAES.js → chunk-RSB4PWX4.js} +1 -1
  107. package/{chunk-KQ4ONNQD.js → chunk-RXA3HAVW.js} +190 -8
  108. package/{chunk-IIVGDG4I.js → chunk-SJKULPGX.js} +13 -7
  109. package/chunk-SQHMSDDU.js +8004 -0
  110. package/{chunk-Q67DOFOO.js → chunk-SZC4REES.js} +212 -105
  111. package/{chunk-JRQFUXY7.js → chunk-TBAXFWOS.js} +99 -22
  112. package/{chunk-PQFHGD77.js → chunk-TBM2RS3U.js} +161 -14
  113. package/{chunk-XT35TTFG.js → chunk-TCYU7L6V.js} +18 -20
  114. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  115. package/chunk-TY3TIUJK.js +89 -0
  116. package/{chunk-I3TQJXQ7.js → chunk-U3C3IA32.js} +9 -2
  117. package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
  118. package/chunk-UM7TA3K4.js +1008 -0
  119. package/{chunk-6YTOJY35.js → chunk-VBG7GWWR.js} +253 -8
  120. package/chunk-VIWDGTDA.js +8 -0
  121. package/chunk-VJVNU77E.js +83 -0
  122. package/{chunk-W7HLWAQ7.js → chunk-VPLUU4IX.js} +118 -90
  123. package/{chunk-UKWGR5SS.js → chunk-VY6VFGKR.js} +194 -1144
  124. package/chunk-VZLO4XJD.js +17 -0
  125. package/{chunk-AHAHBQMU.js → chunk-WDLSZMTA.js} +2 -2
  126. package/{chunk-53HEEOTT.js → chunk-WF5X57VW.js} +83 -16
  127. package/{chunk-VRTTFDBM.js → chunk-WPHY3VPF.js} +35 -22
  128. package/{chunk-ASIFZ2WY.js → chunk-YKZLFY5J.js} +66 -54
  129. package/chunk-YV25TM3R.js +780 -0
  130. package/{chunk-MS7TSPZR.js → chunk-YXKNBVYW.js} +19 -17
  131. package/chunk-ZRAU6T47.js +56 -0
  132. package/commandRegistry-UU6IOTHI.js +833 -0
  133. package/{contentThunks-IV2T3EJC.js → contentThunks-ARD56LKI.js} +39 -36
  134. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  135. package/{createAgentAutomationAction-JCOIEYY4.js → createAgentAutomationAction-HWJLU6DD.js} +40 -37
  136. package/createDialogAction-CHYA6PZE.js +70 -0
  137. package/{createPageAction-D2VOOLP3.js → createPageAction-TSCYNFX7.js} +47 -43
  138. package/{chunk-FG3HKPQP.js → cursorProvider-YGGNMVWX.js} +2751 -10185
  139. package/{dbSlice-A6C6H32X.js → dbSlice-TG4MZ5EB.js} +12 -11
  140. package/{deleteFile-YG6QMJLU.js → deleteFile-KESP65GC.js} +7 -6
  141. package/{dialogCommands-H7FPUYUQ.js → dialogCommands-IJYQAQMB.js} +49 -46
  142. package/{dialogSlice-6JZOOTDS.js → dialogSlice-H476I77R.js} +57 -37
  143. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  144. package/{docCreateCommands-WRG2JLGM.js → docCreateCommands-AZSK4NAG.js} +48 -44
  145. package/{docDeleteCommands-SHWJIBJS.js → docDeleteCommands-DDJMSMFZ.js} +49 -45
  146. package/{docReadCommands-WJN3WT6O.js → docReadCommands-5F5Q6EBZ.js} +47 -43
  147. package/{docStore-HUPQ2FSS.js → docStore-HW2RDZDM.js} +17 -13
  148. package/{docUpdateCommands-IE32IL6O.js → docUpdateCommands-XPNPVZOC.js} +48 -44
  149. package/{fetchMessages-EIU7UFFK.js → fetchMessages-3PXAHKCR.js} +5 -5
  150. package/{getPricing-LUSEABA6.js → getPricing-DOBBZLOK.js} +4 -4
  151. package/{handleSendMessageAction-DFPMQ7YM.js → handleSendMessageAction-IOXE7ILC.js} +109 -42
  152. package/index.js +87 -884
  153. package/{lib-FRRS27KN.js → lib-PU2G2MSO.js} +523 -191
  154. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-UYCKO7YZ.js} +2 -2
  155. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-TU6OBC76.js} +9 -6
  156. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-VKWVOPPI.js} +1 -1
  157. package/{machineCommands-M2T2I5NF.js → machineCommands-Q7TDGM6P.js} +96 -86
  158. package/machineWsRunDispatch-T5VFOQ3R.js +154 -0
  159. package/{memberThunks-P2ECUJ56.js → memberThunks-5S5D3N4U.js} +20 -18
  160. package/{models-T3SG6MJ5.js → models-PQU25T6Q.js} +2 -2
  161. package/oauthTokenStore-ITEB663N.js +23 -0
  162. package/package.json +1 -1
  163. package/processSpawn-SOAV3FEV.js +11 -0
  164. package/profileConfig-ZGOFORWV.js +43 -0
  165. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-HAQWVAQX.js} +7 -7
  166. package/{providerRegistry-757OWH3O.js → providerRegistry-5FGWB3X5.js} +11 -7
  167. package/{read-COE3ZYR6.js → read-LSYFLSIM.js} +8 -7
  168. package/{readDocTool-5USN4A6V.js → readDocTool-XWRXV3DR.js} +5 -3
  169. package/{readlineWorkspace-XQRDGWRZ.js → readlineWorkspace-25U6P3DG.js} +2595 -2031
  170. package/{removeDialogAgentAction-J6X5QMTA.js → removeDialogAgentAction-4TEFC3VL.js} +22 -26
  171. package/{runAgentClientLoop-5ZA62FBA.js → runAgentClientLoop-CZOYWHDN.js} +78 -71
  172. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-PIVSBZRZ.js} +4 -4
  173. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  174. package/{setDialogExtraReferencesAction-WX5VTY6O.js → setDialogExtraReferencesAction-LSEN44OY.js} +16 -14
  175. package/{setPrimaryDialogAgentAction-FN22THHT.js → setPrimaryDialogAgentAction-SR366X5A.js} +23 -27
  176. package/{chunk-GP5LKBUZ.js → settingThunks-CTVPPGIN.js} +226 -940
  177. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  178. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  179. package/{spaceCommands-5GLCWZPO.js → spaceCommands-3UK63WPE.js} +51 -47
  180. package/{streamAgentChatTurn-6UZJMYRB.js → streamAgentChatTurn-LV6ZWUD4.js} +214 -114
  181. package/{switchDialogAgentAction-LVTEV3FR.js → switchDialogAgentAction-M6NAFOOU.js} +19 -20
  182. package/{tableCommands-O6NWHFKV.js → tableCommands-6U4BMLRR.js} +10 -10
  183. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-AD7CXTA4.js} +4 -3
  184. package/tools-UJOV6CQZ.js +117 -0
  185. package/{tuiSummaryLlmCaller-OHHFTHMG.js → tuiSummaryLlmCaller-DEH7ZEM6.js} +25 -23
  186. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  187. package/{updateDialogTitleAction-QTKNIURB.js → updateDialogTitleAction-JYXKIBNJ.js} +84 -45
  188. package/action-P4TNFGAD.js +0 -31
  189. package/agentListCommands-B2V4YAC4.js +0 -410
  190. package/agentRecordCommands-G4KK4R7H.js +0 -128
  191. package/agentRunCommand-UTZJA23G.js +0 -156
  192. package/browser-image-compression-MFDTD7K6.js +0 -1763
  193. package/chatQueueReduxAdapter-2P6NFX64.js +0 -186
  194. package/chunk-CQ3WA2NE.js +0 -299
  195. package/chunk-M76ECQRD.js +0 -13658
  196. package/chunk-MEYIRKDN.js +0 -8967
  197. package/chunk-PUOC4YRO.js +0 -394
  198. package/chunk-Q5FJJ6XI.js +0 -103
  199. package/chunk-S7Z2HMCN.js +0 -25
  200. package/chunk-T75QD6AB.js +0 -20923
  201. package/chunk-Y5GCAMGP.js +0 -9
  202. package/chunk-YPREESF4.js +0 -225
  203. package/createDialogAction-NGG7YVNU.js +0 -65
  204. package/machineWsRunDispatch-ISBKOOD7.js +0 -144
  205. package/settingSlice-P4ZW7K5X.js +0 -204
  206. package/syncMapping-N6RGXGBW.js +0 -437
  207. package/tools-KMGFWO43.js +0 -110
  208. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  209. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
@@ -1,6 +1,7 @@
1
1
  import {
2
- createChromeConnectorClient
3
- } from "./chunk-SH43IESU.js";
2
+ createChromeConnectorClient,
3
+ createVerifiedChromeConnectorClient
4
+ } from "./chunk-GGC55Q32.js";
4
5
  import {
5
6
  toErrorMessage
6
7
  } from "./chunk-HNMXYYJR.js";
@@ -23,6 +24,14 @@ function wantsHelp(args) {
23
24
  function readTrimmedOption(args, flag) {
24
25
  return (readOption(args, flag) ?? "").trim();
25
26
  }
27
+ function readBrowserFlag(args) {
28
+ const equalsForm = args.find((arg) => arg.startsWith("--browser="));
29
+ const raw = equalsForm !== void 0 ? equalsForm.slice("--browser=".length) : readOption(args, "--browser");
30
+ if (raw === void 0) return void 0;
31
+ const value = raw.trim();
32
+ if (value === "chrome" || value === "firefox") return value;
33
+ return null;
34
+ }
26
35
  function readAllOptions(args, flag) {
27
36
  const values = [];
28
37
  for (let i = 0; i < args.length; i++) {
@@ -44,6 +53,25 @@ function readIntOption(args, flag, usage) {
44
53
  }
45
54
  return value;
46
55
  }
56
+ function readNonNegativeIntOption(args, flag, usage) {
57
+ const equalsForm = args.find((arg) => arg.startsWith(`${flag}=`));
58
+ const raw = equalsForm !== void 0 ? equalsForm.slice(`${flag}=`.length) : readOption(args, flag);
59
+ if (raw === void 0) {
60
+ if (args.includes(flag)) {
61
+ throw new Error(`Invalid ${flag} <N>. Usage: ${usage}`);
62
+ }
63
+ return void 0;
64
+ }
65
+ const trimmed = raw.trim();
66
+ if (!/^\d+$/.test(trimmed)) {
67
+ throw new Error(`Invalid ${flag} <N>. Usage: ${usage}`);
68
+ }
69
+ const value = Number.parseInt(trimmed, 10);
70
+ if (!Number.isFinite(value) || value < 0) {
71
+ throw new Error(`Invalid ${flag} <N>. Usage: ${usage}`);
72
+ }
73
+ return value;
74
+ }
47
75
  function requireTabId(args, usage) {
48
76
  const tabId = readTrimmedOption(args, "--tab");
49
77
  if (!tabId) {
@@ -67,12 +95,12 @@ function requireTarget(args, usage) {
67
95
  var CHROME_OPS_SUBCOMMANDS = {
68
96
  "list-tabs": {
69
97
  action: "list_tabs",
70
- usage: "nolo chrome list-tabs",
98
+ usage: "nolo browser list-tabs",
71
99
  payload: () => ({})
72
100
  },
73
101
  "open-tab": {
74
102
  action: "open_tab",
75
- usage: "nolo chrome open-tab --url <url> [--active]",
103
+ usage: "nolo browser open-tab --url <url> [--active]",
76
104
  payload: (args, usage) => {
77
105
  const url = readTrimmedOption(args, "--url");
78
106
  if (!url) {
@@ -83,12 +111,12 @@ var CHROME_OPS_SUBCOMMANDS = {
83
111
  },
84
112
  "close-tab": {
85
113
  action: "close_tab",
86
- usage: "nolo chrome close-tab --tab <id>",
114
+ usage: "nolo browser close-tab --tab <id>",
87
115
  payload: (args, usage) => ({ tabId: requireTabId(args, usage) })
88
116
  },
89
117
  "read-page": {
90
118
  action: "read_page",
91
- usage: "nolo chrome read-page --tab <id> [--selector <css>] [--detail compact|full] [--max-elements N]",
119
+ usage: "nolo browser read-page --tab <id> [--selector <css>] [--detail compact|full] [--max-elements N] [--offset N] [--viewport]",
92
120
  payload: (args, usage) => {
93
121
  const payload = { tabId: requireTabId(args, usage) };
94
122
  const selector = readTrimmedOption(args, "--selector");
@@ -97,12 +125,15 @@ var CHROME_OPS_SUBCOMMANDS = {
97
125
  if (detail) payload.detail = detail;
98
126
  const maxElements = readIntOption(args, "--max-elements", usage);
99
127
  if (maxElements !== void 0) payload.maxElements = maxElements;
128
+ const offset = readNonNegativeIntOption(args, "--offset", usage);
129
+ if (offset !== void 0) payload.offset = offset;
130
+ if (args.includes("--viewport")) payload.viewportOnly = true;
100
131
  return payload;
101
132
  }
102
133
  },
103
134
  click: {
104
135
  action: "click",
105
- usage: "nolo chrome click --tab <id> (--ref <elementRef> | --selector <css>)",
136
+ usage: "nolo browser click --tab <id> (--ref <elementRef> | --selector <css>)",
106
137
  payload: (args, usage) => ({
107
138
  tabId: requireTabId(args, usage),
108
139
  ...requireTarget(args, usage)
@@ -110,7 +141,7 @@ var CHROME_OPS_SUBCOMMANDS = {
110
141
  },
111
142
  type: {
112
143
  action: "type",
113
- usage: "nolo chrome type --tab <id> (--ref <elementRef> | --selector <css>) --text <text> [--append]",
144
+ usage: "nolo browser type --tab <id> (--ref <elementRef> | --selector <css>) --text <text> [--append]",
114
145
  payload: (args, usage) => {
115
146
  const text = readOption(args, "--text");
116
147
  if (text === void 0 || text.startsWith("--")) {
@@ -126,7 +157,7 @@ var CHROME_OPS_SUBCOMMANDS = {
126
157
  },
127
158
  upload: {
128
159
  action: "set_files",
129
- usage: "nolo chrome upload --tab <id> (--ref <elementRef> | --selector <css>) --file <path> [--file <path>...]",
160
+ usage: "nolo browser upload --tab <id> (--ref <elementRef> | --selector <css>) --file <path> [--file <path>...]",
130
161
  payload: (args, usage) => {
131
162
  const files = readAllOptions(args, "--file");
132
163
  if (files.length === 0) {
@@ -144,7 +175,7 @@ var CHROME_OPS_SUBCOMMANDS = {
144
175
  },
145
176
  press: {
146
177
  action: "press",
147
- usage: "nolo chrome press --tab <id> --key <key>",
178
+ usage: "nolo browser press --tab <id> --key <key>",
148
179
  payload: (args, usage) => {
149
180
  const key = readTrimmedOption(args, "--key");
150
181
  if (!key) {
@@ -155,7 +186,7 @@ var CHROME_OPS_SUBCOMMANDS = {
155
186
  },
156
187
  scroll: {
157
188
  action: "scroll",
158
- usage: "nolo chrome scroll --tab <id> [--delta-x N] [--delta-y N]",
189
+ usage: "nolo browser scroll --tab <id> [--delta-x N] [--delta-y N]",
159
190
  payload: (args, usage) => {
160
191
  const payload = { tabId: requireTabId(args, usage) };
161
192
  const deltaX = readIntOption(args, "--delta-x", usage);
@@ -167,7 +198,7 @@ var CHROME_OPS_SUBCOMMANDS = {
167
198
  },
168
199
  screenshot: {
169
200
  action: "screenshot",
170
- usage: "nolo chrome screenshot --tab <id> [--out <path>] [--full-page]",
201
+ usage: "nolo browser screenshot --tab <id> [--out <path>] [--full-page]",
171
202
  payload: (args, usage) => ({
172
203
  tabId: requireTabId(args, usage),
173
204
  ...args.includes("--full-page") ? { fullPage: true } : {}
@@ -175,7 +206,7 @@ var CHROME_OPS_SUBCOMMANDS = {
175
206
  },
176
207
  "read-console": {
177
208
  action: "read_console",
178
- usage: "nolo chrome read-console --tab <id> [--limit N]",
209
+ usage: "nolo browser read-console --tab <id> [--limit N]",
179
210
  payload: (args, usage) => {
180
211
  const payload = { tabId: requireTabId(args, usage) };
181
212
  const limit = readIntOption(args, "--limit", usage);
@@ -185,7 +216,7 @@ var CHROME_OPS_SUBCOMMANDS = {
185
216
  },
186
217
  "read-network": {
187
218
  action: "read_network",
188
- usage: "nolo chrome read-network --tab <id> [--limit N] [--include-assets]",
219
+ usage: "nolo browser read-network --tab <id> [--limit N] [--include-assets]",
189
220
  payload: (args, usage) => {
190
221
  const payload = { tabId: requireTabId(args, usage) };
191
222
  const limit = readIntOption(args, "--limit", usage);
@@ -197,28 +228,59 @@ var CHROME_OPS_SUBCOMMANDS = {
197
228
  };
198
229
  function renderChromeOpsHelp() {
199
230
  const lines = [
200
- "Operate the user's Chrome through the Nolo Chrome connector (the desktop bridge;",
201
- "the same RPC the chrome_* agent tools use).",
231
+ "Operate the user's browser (Chrome or Firefox) through the Nolo Browser Connector",
232
+ "(the desktop bridge; the same RPC the browser_* agent tools use \u2014 legacy `chrome_*` names still work).",
202
233
  "",
203
234
  "Usage:",
204
- " nolo chrome <subcommand> [flags]",
235
+ " nolo browser <subcommand> [flags]",
236
+ " nolo chrome <subcommand> [flags] # compatibility alias",
205
237
  "",
206
238
  "Subcommands:",
207
239
  ...Object.values(CHROME_OPS_SUBCOMMANDS).map(
208
- (spec) => ` ${spec.usage.replace(/^nolo chrome /, "")}`
240
+ (spec) => ` ${spec.usage.replace(/^nolo browser /, "")}`
209
241
  ),
210
242
  "",
211
243
  "Notes:",
212
- " --ref takes an elementRef copied from `nolo chrome read-page` (revision-scoped,",
244
+ " --ref takes an elementRef copied from `nolo browser read-page` (revision-scoped,",
213
245
  " preferred over --selector); --selector takes a CSS selector.",
214
246
  " Actions the connector classifies as irreversible (Submit / Delete / Pay ...)",
215
247
  " are refused with CONFIRMATION_REQUIRED \u2014 ask the user to perform them.",
248
+ " read-console / read-network / upload work on Chrome only (Firefox lacks chrome.debugger).",
249
+ " --browser chrome|firefox selects which connector endpoint serves the call (default",
250
+ " auto-detects single online browser: chrome = 127.0.0.1:38947, firefox = 127.0.0.1:38948);",
251
+ " the wrong browser is refused.",
216
252
  " Every subcommand prints the connector's raw JSON result; failures exit 1.",
217
- " Endpoint: NOLO_CHROME_CONNECTOR_RPC_URL or http://127.0.0.1:38947/rpc."
253
+ " Endpoint: NOLO_CHROME_CONNECTOR_RPC_URL or per-browser NOLO_CHROME_CONNECTOR_PORT /",
254
+ " NOLO_FIREFOX_CONNECTOR_PORT (default http://127.0.0.1:38947/rpc)."
218
255
  ];
219
256
  return lines.join("\n");
220
257
  }
221
258
  var CHROME_OPS_HELP_TEXT = renderChromeOpsHelp();
259
+ async function defaultProbeBrowser(browser) {
260
+ try {
261
+ const client = createChromeConnectorClient({
262
+ browser,
263
+ fetchImpl: (input, init) => {
264
+ return fetch(input, {
265
+ ...init,
266
+ signal: AbortSignal.timeout(400)
267
+ });
268
+ }
269
+ });
270
+ const info = await client.request("connector_info", {});
271
+ return typeof info?.extensionId === "string";
272
+ } catch (error) {
273
+ if (error?.code === "CHROME_CONNECTOR_UNAVAILABLE") {
274
+ return false;
275
+ }
276
+ const handshakeError = new Error(
277
+ `\u63A2\u6D4B\u5230\u7AEF\u70B9\u4F46\u63E1\u624B\u5931\u8D25\uFF1A${toErrorMessage(error)}`
278
+ );
279
+ handshakeError.code = error?.code || "CHROME_CONNECTOR_HANDSHAKE_FAILED";
280
+ handshakeError.details = error?.details;
281
+ throw handshakeError;
282
+ }
283
+ }
222
284
  async function runChromeOpsCommand(subcommand, args, deps = {}) {
223
285
  const io = {
224
286
  stdout: (text) => console.log(text),
@@ -227,7 +289,7 @@ async function runChromeOpsCommand(subcommand, args, deps = {}) {
227
289
  };
228
290
  const spec = CHROME_OPS_SUBCOMMANDS[subcommand];
229
291
  if (!spec) {
230
- io.stderr(`Unknown chrome subcommand: ${subcommand}
292
+ io.stderr(`Unknown browser subcommand "${subcommand}".
231
293
 
232
294
  ${CHROME_OPS_HELP_TEXT}`);
233
295
  return 1;
@@ -236,6 +298,13 @@ ${CHROME_OPS_HELP_TEXT}`);
236
298
  io.stdout(CHROME_OPS_HELP_TEXT);
237
299
  return 0;
238
300
  }
301
+ const browserFlag = readBrowserFlag(args);
302
+ if (browserFlag === null) {
303
+ io.stderr(
304
+ `Invalid --browser value: expected "chrome" or "firefox". Usage: ${spec.usage}`
305
+ );
306
+ return 1;
307
+ }
239
308
  let payload;
240
309
  try {
241
310
  payload = spec.payload(args, spec.usage);
@@ -245,7 +314,72 @@ ${CHROME_OPS_HELP_TEXT}`);
245
314
  }
246
315
  let result;
247
316
  try {
248
- const client = deps.client ?? createChromeConnectorClient();
317
+ const env = deps.env ?? process.env;
318
+ let client;
319
+ if (deps.client) {
320
+ client = deps.client;
321
+ } else {
322
+ let targetBrowser = browserFlag;
323
+ if (!targetBrowser && !env.NOLO_CHROME_CONNECTOR_RPC_URL) {
324
+ const probe = deps.probeBrowser ?? defaultProbeBrowser;
325
+ const [chromeResult, firefoxResult] = await Promise.allSettled([
326
+ probe("chrome"),
327
+ probe("firefox")
328
+ ]);
329
+ const chromeOnline = chromeResult.status === "fulfilled" && chromeResult.value === true;
330
+ const firefoxOnline = firefoxResult.status === "fulfilled" && firefoxResult.value === true;
331
+ if (chromeOnline && firefoxOnline) {
332
+ const error = new Error(
333
+ "Both Chrome and Firefox connectors are online. Specify --browser chrome or --browser firefox."
334
+ );
335
+ error.code = "MULTIPLE_BROWSERS_AVAILABLE";
336
+ throw error;
337
+ }
338
+ if (chromeOnline) {
339
+ targetBrowser = "chrome";
340
+ } else if (firefoxOnline) {
341
+ targetBrowser = "firefox";
342
+ } else {
343
+ if (chromeResult.status === "rejected") {
344
+ const reason = toErrorMessage(chromeResult.reason);
345
+ const err = new Error(
346
+ reason.startsWith("\u63A2\u6D4B\u5230\u7AEF\u70B9\u4F46\u63E1\u624B\u5931\u8D25\uFF1A") ? reason : `\u63A2\u6D4B\u5230\u7AEF\u70B9\u4F46\u63E1\u624B\u5931\u8D25\uFF1A${reason}`
347
+ );
348
+ err.code = chromeResult.reason?.code || "CHROME_CONNECTOR_HANDSHAKE_FAILED";
349
+ err.details = chromeResult.reason?.details;
350
+ throw err;
351
+ }
352
+ if (firefoxResult.status === "rejected") {
353
+ const reason = toErrorMessage(firefoxResult.reason);
354
+ const err = new Error(
355
+ reason.startsWith("\u63A2\u6D4B\u5230\u7AEF\u70B9\u4F46\u63E1\u624B\u5931\u8D25\uFF1A") ? reason : `\u63A2\u6D4B\u5230\u7AEF\u70B9\u4F46\u63E1\u624B\u5931\u8D25\uFF1A${reason}`
356
+ );
357
+ err.code = firefoxResult.reason?.code || "CHROME_CONNECTOR_HANDSHAKE_FAILED";
358
+ err.details = firefoxResult.reason?.details;
359
+ throw err;
360
+ }
361
+ const chromePort = env.NOLO_CHROME_CONNECTOR_PORT || 38947;
362
+ const firefoxPort = env.NOLO_FIREFOX_CONNECTOR_PORT || 38948;
363
+ const chromeEndpoint = `http://127.0.0.1:${chromePort}/rpc`;
364
+ const firefoxEndpoint = `http://127.0.0.1:${firefoxPort}/rpc`;
365
+ const error = new Error(
366
+ `Chrome connector RPC endpoint is unavailable at ${chromeEndpoint} or ${firefoxEndpoint}.`
367
+ );
368
+ error.code = "CHROME_CONNECTOR_UNAVAILABLE";
369
+ throw error;
370
+ }
371
+ }
372
+ if (deps.createClient) {
373
+ client = deps.createClient(targetBrowser);
374
+ } else if (targetBrowser) {
375
+ client = createVerifiedChromeConnectorClient({
376
+ client: createChromeConnectorClient({ browser: targetBrowser }),
377
+ expectedBrowser: targetBrowser
378
+ });
379
+ } else {
380
+ client = createChromeConnectorClient();
381
+ }
382
+ }
249
383
  result = await client.request(spec.action, payload);
250
384
  } catch (error) {
251
385
  const code = typeof error?.code === "string" ? error.code : "CHROME_COMMAND_FAILED";
@@ -1,16 +1,16 @@
1
1
  import {
2
- require_date_fns
3
- } from "./chunk-M76ECQRD.js";
2
+ formatISO
3
+ } from "./chunk-ZRAU6T47.js";
4
4
  import {
5
5
  require_react
6
6
  } from "./chunk-YDH3FDFQ.js";
7
- import {
8
- toErrorMessage
9
- } from "./chunk-HNMXYYJR.js";
10
7
  import {
11
8
  patch,
12
9
  readAndWait
13
- } from "./chunk-VRTTFDBM.js";
10
+ } from "./chunk-WPHY3VPF.js";
11
+ import {
12
+ toErrorMessage
13
+ } from "./chunk-HNMXYYJR.js";
14
14
  import {
15
15
  asOptionalTrimmedString
16
16
  } from "./chunk-G3SUCT4W.js";
@@ -20,7 +20,6 @@ import {
20
20
 
21
21
  // packages/render/page/docStore.ts
22
22
  var import_react = __toESM(require_react(), 1);
23
- var import_date_fns = __toESM(require_date_fns(), 1);
24
23
  var createInitialState = () => ({
25
24
  content: null,
26
25
  slateData: null,
@@ -52,6 +51,7 @@ var createInitialState = () => ({
52
51
  var listeners = /* @__PURE__ */ new Set();
53
52
  var version = 0;
54
53
  var state = createInitialState();
54
+ var latestInitRequestKey = null;
55
55
  var notify = () => {
56
56
  for (const listener of listeners) {
57
57
  try {
@@ -102,6 +102,9 @@ function getDocField(selector) {
102
102
  function getDocPageKey() {
103
103
  return state.pageKey;
104
104
  }
105
+ function isDocStateForPage(state2, pageKey) {
106
+ return Boolean(pageKey) && state2.pageKey === pageKey;
107
+ }
105
108
  function getDocIsInitialized() {
106
109
  return state.isInitialized;
107
110
  }
@@ -143,6 +146,7 @@ function updateDocTags(tags) {
143
146
  setState((prev) => ({ ...prev, tags }));
144
147
  }
145
148
  function resetDocState() {
149
+ latestInitRequestKey = null;
146
150
  setState(createInitialState());
147
151
  }
148
152
  function previewDocState(payload) {
@@ -190,6 +194,7 @@ function applyExternalDocUpdate(payload) {
190
194
  }
191
195
  async function initDocState(args, { dispatch }) {
192
196
  const { pageKey, isReadOnly } = args;
197
+ latestInitRequestKey = pageKey;
193
198
  setState((prev) => ({
194
199
  ...createInitialState(),
195
200
  isLoading: true,
@@ -198,6 +203,7 @@ async function initDocState(args, { dispatch }) {
198
203
  }));
199
204
  try {
200
205
  const readAction = await dispatch(readAndWait(pageKey));
206
+ if (latestInitRequestKey !== pageKey) return;
201
207
  if (readAndWait.fulfilled.match(readAction) && readAction.payload) {
202
208
  const data = readAction.payload;
203
209
  if (data.type !== "page" /* DOC */) {
@@ -247,6 +253,7 @@ async function initDocState(args, { dispatch }) {
247
253
  }));
248
254
  }
249
255
  } catch (e) {
256
+ if (latestInitRequestKey !== pageKey) return;
250
257
  setState((prev) => ({
251
258
  ...prev,
252
259
  isLoading: false,
@@ -300,7 +307,7 @@ async function saveDocState(arg, { dispatch, getState }) {
300
307
  { slateToRenderMarkdown },
301
308
  { buildSkillSummaryMarker }
302
309
  ] = await Promise.all([
303
- import("./slateUtils-RIZES3PV.js"),
310
+ import("./slateUtils-NGV2NMKM.js"),
304
311
  import("./slateToRenderMarkdown-Y5IYN73U.js"),
305
312
  import("./skillSummaryMarker-42HKSXYY.js")
306
313
  ]);
@@ -309,7 +316,7 @@ async function saveDocState(arg, { dispatch, getState }) {
309
316
  const skillSummary = buildSkillSummaryMarker(meta);
310
317
  const content = slateToRenderMarkdown(slateData);
311
318
  const now = /* @__PURE__ */ new Date();
312
- const updatedAt = (0, import_date_fns.formatISO)(now);
319
+ const updatedAt = formatISO(now);
313
320
  await dispatch(
314
321
  patch({
315
322
  dbKey: pageKey,
@@ -326,7 +333,7 @@ async function saveDocState(arg, { dispatch, getState }) {
326
333
  ).unwrap();
327
334
  if (dbSpaceId) {
328
335
  try {
329
- const { updateContentTitle } = await import("./contentThunks-IV2T3EJC.js");
336
+ const { updateContentTitle } = await import("./contentThunks-ARD56LKI.js");
330
337
  await dispatch(
331
338
  updateContentTitle({
332
339
  spaceId: dbSpaceId,
@@ -365,7 +372,7 @@ async function saveDocState(arg, { dispatch, getState }) {
365
372
  }
366
373
  }
367
374
  async function createDocState(args, thunkApi) {
368
- const { createPageAction } = await import("./createPageAction-D2VOOLP3.js");
375
+ const { createPageAction } = await import("./createPageAction-TSCYNFX7.js");
369
376
  return createPageAction(args, thunkApi);
370
377
  }
371
378
  function subscribe(listener) {
@@ -387,6 +394,7 @@ function useDocField(selector) {
387
394
  }
388
395
  function resetDocStoreForTests() {
389
396
  state = createInitialState();
397
+ latestInitRequestKey = null;
390
398
  bump();
391
399
  }
392
400
 
@@ -394,6 +402,7 @@ export {
394
402
  getDocState,
395
403
  getDocField,
396
404
  getDocPageKey,
405
+ isDocStateForPage,
397
406
  getDocIsInitialized,
398
407
  getDocIsReadOnly,
399
408
  getDocHasPendingChanges,