nolo-cli 0.98.0-alpha.3 → 0.98.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 (205) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-MA3D2J4W.js → _executeModel-GJK4ZVU6.js} +74 -67
  3. package/action-PNPQLJHG.js +20 -0
  4. package/{addContentAction-O7R66HEX.js → addContentAction-RBOUD7SJ.js} +12 -11
  5. package/{addDialogAgentAction-74OA7KYP.js → addDialogAgentAction-IODCR6TB.js} +18 -19
  6. package/{agentDeleteCommand-FHUJH5X4.js → agentDeleteCommand-GHRF6CH5.js} +47 -42
  7. package/{agentEmailCommands-KNYBWNMA.js → agentEmailCommands-O5BTHYZK.js} +97 -87
  8. package/agentListCommands-3REEM63V.js +742 -0
  9. package/{agentMachineCommands-N62I3D5Q.js → agentMachineCommands-2GW3CV7Q.js} +48 -43
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-IRNZXVGE.js} +1 -1
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-B4T2DJ5H.js} +1 -1
  12. package/agentRecordCommands-WYQODWZE.js +138 -0
  13. package/agentRunCommand-KAN65WPY.js +167 -0
  14. package/{agentRunControl-AVJR4JW4.js → agentRunControl-3HWA2LLQ.js} +2 -2
  15. package/{agentRuntimeLocal-VXZSDIGT.js → agentRuntimeLocal-IOFBNVIL.js} +48 -39
  16. package/{agentSlice-65ETD734.js → agentSlice-I45M32KO.js} +14 -13
  17. package/{appDeleteCommands-PDZ7HQYH.js → appDeleteCommands-SFS6IZEM.js} +46 -41
  18. package/{appDeployCommands-KLLW32YA.js → appDeployCommands-YZQESVRQ.js} +46 -41
  19. package/{appDeployStatusCommands-IPNJ445T.js → appDeployStatusCommands-FKUUDCKP.js} +46 -41
  20. package/{appGetCommands-QA57XGXS.js → appGetCommands-QUE7OQZC.js} +46 -41
  21. package/{appListCommands-YBTAUFZS.js → appListCommands-QEETFKMH.js} +46 -41
  22. package/{authCommand-F4EFRRX6.js → authCommand-NHDLY3IB.js} +118 -24
  23. package/{authCommands-RGOGCPP6.js → authCommands-UDBJVSZU.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-MAR5LPAC.js} +10 -8
  25. package/{chromeCommands-FZYAU75D.js → chromeCommands-K27J4OVZ.js} +124 -28
  26. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-IXRLN57H.js} +4 -3
  27. package/{chunk-6OZ36FXI.js → chunk-27ONFIEY.js} +22 -4
  28. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  29. package/{chunk-53HEEOTT.js → chunk-2WJ57RJA.js} +83 -16
  30. package/{chunk-OIVSQH2O.js → chunk-3BXNTXYI.js} +299 -5
  31. package/{chunk-ABQYVJBJ.js → chunk-46Y5D2BZ.js} +5 -5
  32. package/{chunk-EYAQT56M.js → chunk-4DPP773Q.js} +2 -2
  33. package/{chunk-H62HCIUP.js → chunk-4FFUDT6D.js} +24 -21
  34. package/chunk-4LCOCOR5.js +50 -0
  35. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  36. package/{chunk-IIVGDG4I.js → chunk-4YSOUKUR.js} +13 -7
  37. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  38. package/{chunk-FSX24MR3.js → chunk-5AUJB66Z.js} +550 -515
  39. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  40. package/chunk-5J3PYNUP.js +255 -0
  41. package/chunk-5MMAK75Q.js +15 -0
  42. package/{chunk-JPGCXHNM.js → chunk-5OA5HMTL.js} +1 -1
  43. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  44. package/{chunk-3BMYXEUW.js → chunk-6O4IK4V2.js} +1 -1
  45. package/{chunk-D2QT5FW4.js → chunk-6XDD7N7P.js} +47 -67
  46. package/{chunk-GQBOR3G6.js → chunk-7KVZ5LDQ.js} +2 -2
  47. package/{chunk-DNCEALKX.js → chunk-7MMSLEPA.js} +22 -29
  48. package/chunk-A4SQRTZ6.js +15 -0
  49. package/{chunk-7S4YWN7P.js → chunk-ADBZWMFB.js} +4 -4
  50. package/chunk-AGIM7IMJ.js +147 -0
  51. package/{chunk-5UTFL4QJ.js → chunk-AOTBKDRK.js} +7 -0
  52. package/{chunk-Q554LLSI.js → chunk-AUDNYVRC.js} +1 -1
  53. package/{chunk-GZBATRJA.js → chunk-B2DEZY6J.js} +20 -11
  54. package/chunk-BMQ2MJUK.js +153 -0
  55. package/{chunk-6YTOJY35.js → chunk-BZ7NPA6G.js} +35 -2
  56. package/chunk-C4DVDM72.js +13536 -0
  57. package/chunk-CHOZJMJS.js +78 -0
  58. package/{chunk-ACTMNVHM.js → chunk-CYSYR67N.js} +1 -1
  59. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  60. package/chunk-DZ7R5V3Y.js +164 -0
  61. package/{chunk-3VNWWVKB.js → chunk-E3YWHWCR.js} +50 -18
  62. package/{chunk-V4MJDUSR.js → chunk-E73ON47R.js} +2 -2
  63. package/{chunk-UY2NBS4V.js → chunk-EIFYNGU4.js} +24 -5
  64. package/{chunk-KQ4ONNQD.js → chunk-EKPKW6RM.js} +155 -8
  65. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  66. package/{chunk-HJUYAD4A.js → chunk-FJ5BGMNM.js} +5 -5
  67. package/{chunk-2F7RJC6L.js → chunk-FOXQ7BAB.js} +1 -1
  68. package/{chunk-TDRTS7QW.js → chunk-FY7DCYW7.js} +88 -17
  69. package/{chunk-J4MOO56S.js → chunk-GARACBQB.js} +10 -2
  70. package/{chunk-6VFARHZW.js → chunk-GDFA73QZ.js} +934 -1091
  71. package/chunk-GMZLP5DV.js +82 -0
  72. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  73. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  74. package/{chunk-QOKAKDPE.js → chunk-HIM3FCLF.js} +0 -1
  75. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  76. package/{chunk-VLTIYV3X.js → chunk-HP57OUJO.js} +4 -4
  77. package/{chunk-AD2L6YCC.js → chunk-I76SDF7A.js} +10 -10
  78. package/{chunk-PELKTR62.js → chunk-I7BCBNWZ.js} +24 -77
  79. package/{chunk-GPCZ7UXG.js → chunk-K6U4NKFJ.js} +1 -1
  80. package/{chunk-4OEFYTWL.js → chunk-LDCAFLXD.js} +64 -48
  81. package/{chunk-SNPMM7H3.js → chunk-LNVJHIGA.js} +18 -20
  82. package/{chunk-LS2ZANRJ.js → chunk-LOCNXNOU.js} +1 -1
  83. package/{chunk-5H7KJX7J.js → chunk-LQ4PDQCI.js} +5 -5
  84. package/{chunk-GABFWSOQ.js → chunk-M33GWZIZ.js} +67 -45
  85. package/{chunk-PUOC4YRO.js → chunk-M7VLQGQP.js} +11 -0
  86. package/chunk-NHDMQZJM.js +7881 -0
  87. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  88. package/{chunk-L5UXH3B2.js → chunk-NNCYNBYV.js} +22 -6
  89. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  90. package/chunk-NWENLDMM.js +42 -0
  91. package/{chunk-76WEAXJB.js → chunk-NZWAO6LH.js} +20 -17
  92. package/chunk-OCZKATRC.js +129 -0
  93. package/{chunk-N2WELJE7.js → chunk-OU36O6OR.js} +23 -28
  94. package/chunk-OW4APERY.js +870 -0
  95. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  96. package/{chunk-TVYSVSA2.js → chunk-P5L7VVMT.js} +11 -9
  97. package/{chunk-TOP2VXOR.js → chunk-PCF3QU5Q.js} +5 -5
  98. package/{chunk-WV42OMV7.js → chunk-PTDYOADJ.js} +8 -8
  99. package/{chunk-6D6VBVEW.js → chunk-SNMQMOD2.js} +80 -14
  100. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  101. package/{chunk-Z77CRGTW.js → chunk-TVCAR26G.js} +1 -1
  102. package/chunk-TY3TIUJK.js +89 -0
  103. package/{chunk-I3TQJXQ7.js → chunk-U3C3IA32.js} +9 -2
  104. package/{chunk-RG6JBBX5.js → chunk-U7XXEI5R.js} +166 -13
  105. package/{chunk-UZGQNTVW.js → chunk-UA324D4O.js} +8 -6
  106. package/chunk-UJXNKP5V.js +760 -0
  107. package/{chunk-UKZDAFYT.js → chunk-UM4PH574.js} +6 -10
  108. package/{chunk-BLJWCTRL.js → chunk-UVKDJUTL.js} +3 -3
  109. package/{chunk-ZCYXJSTU.js → chunk-V5OWQOJZ.js} +19 -88
  110. package/{chunk-YQTQQX2H.js → chunk-V7Y6KRAH.js} +1 -1
  111. package/{chunk-3DII57IT.js → chunk-VCAQFMVN.js} +1 -1
  112. package/{chunk-JRQFUXY7.js → chunk-VEYL5MO5.js} +99 -22
  113. package/chunk-VIWDGTDA.js +8 -0
  114. package/chunk-VJVNU77E.js +83 -0
  115. package/{chunk-UKWGR5SS.js → chunk-VY6VFGKR.js} +194 -1144
  116. package/{chunk-2FA3ITSX.js → chunk-W3RFFFFF.js} +873 -227
  117. package/{chunk-BP4XNZRM.js → chunk-W72ISAKC.js} +4 -4
  118. package/{chunk-DHDMC6FO.js → chunk-WCGC6S77.js} +14 -9
  119. package/{chunk-QDSINZM3.js → chunk-WJ3B6FX6.js} +1 -14
  120. package/{chunk-V4I3A7DR.js → chunk-WXHAOL7Y.js} +19 -17
  121. package/{chunk-FUUHG5LT.js → chunk-X2B2C4XD.js} +1 -1
  122. package/{chunk-HVURBGF3.js → chunk-XFUBXRVI.js} +6 -6
  123. package/{chunk-O6OSWFZQ.js → chunk-XUWRURDF.js} +6 -0
  124. package/{chunk-Q67DOFOO.js → chunk-Y3PMXGLH.js} +2 -0
  125. package/{chunk-QIAVMDHY.js → chunk-YPOPJAKN.js} +4 -4
  126. package/{chunk-SH43IESU.js → chunk-YUNJN43V.js} +44 -9
  127. package/chunk-YV25TM3R.js +780 -0
  128. package/chunk-ZRAU6T47.js +56 -0
  129. package/commandRegistry-RZNZ37BN.js +833 -0
  130. package/{contentThunks-Y6FA2TCW.js → contentThunks-DF7ZNCAG.js} +36 -34
  131. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  132. package/{createAgentAutomationAction-JXAFQO5V.js → createAgentAutomationAction-KPMOZ53Y.js} +38 -36
  133. package/createDialogAction-I2UDVAXN.js +69 -0
  134. package/{createPageAction-GUQDPKO5.js → createPageAction-IF5JXNKV.js} +45 -42
  135. package/{chunk-ZMD2CQFC.js → cursorProvider-YGGNMVWX.js} +2496 -9897
  136. package/{dbSlice-XVWBAGYN.js → dbSlice-Q25STFGJ.js} +11 -10
  137. package/{deleteFile-YG6QMJLU.js → deleteFile-AJ2EZMHT.js} +7 -6
  138. package/{dialogCommands-JJDASFIL.js → dialogCommands-LWHIIUQD.js} +49 -45
  139. package/{dialogSlice-J2YJNE6E.js → dialogSlice-74DFPFRV.js} +40 -33
  140. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  141. package/{docCreateCommands-OB3X3EQM.js → docCreateCommands-LVXQ6TNZ.js} +48 -43
  142. package/{docDeleteCommands-WMHRGF22.js → docDeleteCommands-7TVIGCLP.js} +49 -44
  143. package/{docReadCommands-NWGGLIAZ.js → docReadCommands-KYAXFLQ5.js} +47 -42
  144. package/{docStore-6KKYKAGQ.js → docStore-2JDRAYXJ.js} +16 -12
  145. package/{docUpdateCommands-3DDSOLPS.js → docUpdateCommands-TVC5KWPK.js} +48 -43
  146. package/{fetchMessages-EIU7UFFK.js → fetchMessages-I5ICDDHM.js} +5 -5
  147. package/{getPricing-LUSEABA6.js → getPricing-NMMFT3YI.js} +4 -4
  148. package/{handleSendMessageAction-A4XLEEPU.js → handleSendMessageAction-54GY3XOH.js} +110 -86
  149. package/index.js +87 -884
  150. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-ZHZ3KXDM.js} +2 -2
  151. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-TU6OBC76.js} +9 -6
  152. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-VKWVOPPI.js} +1 -1
  153. package/{machineCommands-Y64KAIRW.js → machineCommands-54RNLVJE.js} +91 -81
  154. package/machineWsRunDispatch-WE3VTD57.js +154 -0
  155. package/{memberThunks-QGFLFVCI.js → memberThunks-R75S3RWP.js} +20 -18
  156. package/{models-T3SG6MJ5.js → models-ZPU5EDF4.js} +2 -2
  157. package/oauthTokenStore-ITEB663N.js +23 -0
  158. package/package.json +1 -1
  159. package/pdf-U6KSUEZZ.js +26435 -0
  160. package/processSpawn-SOAV3FEV.js +11 -0
  161. package/profileConfig-ZGOFORWV.js +43 -0
  162. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-TEBH7FDX.js} +7 -7
  163. package/{providerRegistry-757OWH3O.js → providerRegistry-CBJLNCET.js} +11 -7
  164. package/{read-COE3ZYR6.js → read-SRQMNO26.js} +7 -6
  165. package/{readDocTool-5USN4A6V.js → readDocTool-RC3JUNJ2.js} +5 -3
  166. package/{readlineWorkspace-45XNHFXU.js → readlineWorkspace-UK5M5CJI.js} +2704 -2060
  167. package/{removeDialogAgentAction-IX3MN2ZO.js → removeDialogAgentAction-46XQV5Q7.js} +21 -25
  168. package/{runAgentClientLoop-ADZRHNG6.js → runAgentClientLoop-MTI5OU2W.js} +75 -69
  169. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-PIVSBZRZ.js} +4 -4
  170. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  171. package/{setDialogExtraReferencesAction-X4HCPNZL.js → setDialogExtraReferencesAction-J4V5ADQF.js} +15 -13
  172. package/{setPrimaryDialogAgentAction-4GMIQLOD.js → setPrimaryDialogAgentAction-UHHV2QZW.js} +22 -26
  173. package/{chunk-AFUORTY4.js → settingThunks-PPZZZOWN.js} +226 -940
  174. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  175. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  176. package/{spaceCommands-E7MQ4VU2.js → spaceCommands-446WWA73.js} +51 -46
  177. package/{streamAgentChatTurn-TUP7YO3H.js → streamAgentChatTurn-IANOWAKR.js} +199 -104
  178. package/{switchDialogAgentAction-N52LRPA3.js → switchDialogAgentAction-A2TMVGAE.js} +18 -19
  179. package/{tableCommands-O6NWHFKV.js → tableCommands-6U4BMLRR.js} +10 -10
  180. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-EJT6TMFG.js} +3 -3
  181. package/tools-WZZYTUNF.js +116 -0
  182. package/{tuiSummaryLlmCaller-WFRWERGK.js → tuiSummaryLlmCaller-Q65IBDGO.js} +24 -21
  183. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  184. package/{updateDialogTitleAction-KSWXWWFT.js → updateDialogTitleAction-Z2JTYLXD.js} +82 -44
  185. package/action-YVYQEAAV.js +0 -31
  186. package/agentListCommands-GATRXEMT.js +0 -406
  187. package/agentRecordCommands-GOC5K27T.js +0 -128
  188. package/agentRunCommand-JP2U3MQF.js +0 -155
  189. package/browser-image-compression-MFDTD7K6.js +0 -1763
  190. package/chatQueueReduxAdapter-5QOW43T4.js +0 -186
  191. package/chunk-DHDVZFNC.js +0 -18885
  192. package/chunk-M76ECQRD.js +0 -13658
  193. package/chunk-MEYIRKDN.js +0 -8967
  194. package/chunk-Q5FJJ6XI.js +0 -103
  195. package/chunk-S7Z2HMCN.js +0 -25
  196. package/chunk-Y5GCAMGP.js +0 -9
  197. package/chunk-YPREESF4.js +0 -225
  198. package/createDialogAction-O2QABXZF.js +0 -65
  199. package/machineWsRunDispatch-M366L2LJ.js +0 -144
  200. package/settingSlice-ZQZVUPKK.js +0 -204
  201. package/syncMapping-N6RGXGBW.js +0 -437
  202. package/tools-2VDNDFET.js +0 -110
  203. package/{chunk-VMFTFOWF.js → chunk-3AH7LNUB.js} +7 -7
  204. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  205. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
@@ -1,12 +1,12 @@
1
- import {
2
- defaultOpenBrowser
3
- } from "./chunk-6D6VBVEW.js";
4
1
  import {
5
2
  generateCloudflareEmailRoutingToken,
6
3
  parseFlagWithOptionalValue,
7
4
  runCloudflareOAuthLogin,
8
5
  upsertEnvVariable
9
- } from "./chunk-GPCZ7UXG.js";
6
+ } from "./chunk-K6U4NKFJ.js";
7
+ import {
8
+ defaultOpenBrowser
9
+ } from "./chunk-SNMQMOD2.js";
10
10
  import {
11
11
  ANTHROPIC_OAUTH_AUTHORIZE_URL,
12
12
  ANTHROPIC_OAUTH_CALLBACK_PORT,
@@ -39,6 +39,7 @@ import {
39
39
  generatePkcePair,
40
40
  normalizeAnthropicTokenPayload,
41
41
  readJsonBody,
42
+ refreshAntigravityOAuthToken,
42
43
  renderDeviceCodeDisplay,
43
44
  runAntigravityOAuthLogin,
44
45
  runOpenAiCodexBrowserPkce,
@@ -46,50 +47,58 @@ import {
46
47
  startCallbackServer,
47
48
  validateXAIEndpoint,
48
49
  xaiOAuthDiscovery
49
- } from "./chunk-53HEEOTT.js";
50
+ } from "./chunk-2WJ57RJA.js";
51
+ import "./chunk-TY3TIUJK.js";
50
52
  import "./chunk-ESHYE7WU.js";
51
53
  import "./chunk-JBTJAPUF.js";
52
- import "./chunk-2F7RJC6L.js";
54
+ import {
55
+ extractGoogleValidationLink
56
+ } from "./chunk-BMQ2MJUK.js";
57
+ import "./chunk-FOXQ7BAB.js";
53
58
  import "./chunk-GLKOYSRU.js";
54
59
  import {
55
60
  buildDevinAuthUrl,
56
61
  buildDevinOAuthCredential,
57
62
  detectLocalDevinCredentials,
58
- extractDevinToken
59
- } from "./chunk-Q5FJJ6XI.js";
63
+ extractDevinToken,
64
+ fetchAntigravityCloudCodeCompletion
65
+ } from "./chunk-OW4APERY.js";
66
+ import "./chunk-GMZLP5DV.js";
60
67
  import "./chunk-5ZUL4CUO.js";
61
- import "./chunk-UZGQNTVW.js";
62
- import "./chunk-6OZ36FXI.js";
63
- import "./chunk-GQBOR3G6.js";
64
- import "./chunk-OIVSQH2O.js";
65
68
  import {
66
- createOAuthTokenStore
67
- } from "./chunk-ONXOABJR.js";
69
+ createOAuthTokenStore,
70
+ resolveFreshAccessToken
71
+ } from "./chunk-HNGRBWYF.js";
72
+ import "./chunk-UA324D4O.js";
73
+ import "./chunk-27ONFIEY.js";
74
+ import "./chunk-7KVZ5LDQ.js";
75
+ import "./chunk-3BXNTXYI.js";
68
76
  import "./chunk-W7XHHYWM.js";
69
77
  import {
70
78
  toErrorMessage
71
79
  } from "./chunk-HNMXYYJR.js";
80
+ import "./chunk-A7GB5UGH.js";
81
+ import "./chunk-OLZBQWZU.js";
72
82
  import {
73
83
  buildEnvFromProfile,
74
84
  getProfileOAuthSync,
75
85
  loadProfileConfig,
76
86
  saveProfileOAuthSync
77
- } from "./chunk-BYMV6QZG.js";
78
- import "./chunk-A7GB5UGH.js";
79
- import "./chunk-OLZBQWZU.js";
80
- import "./chunk-Q67DOFOO.js";
81
- import "./chunk-VMFTFOWF.js";
82
- import {
83
- asOptionalFiniteNumber
84
- } from "./chunk-WWC7I6TA.js";
87
+ } from "./chunk-TNIX77YM.js";
88
+ import "./chunk-Y3PMXGLH.js";
85
89
  import "./chunk-QSJ3HFEF.js";
86
90
  import {
87
91
  isRecord
88
92
  } from "./chunk-KUG52IAP.js";
93
+ import "./chunk-3AH7LNUB.js";
94
+ import {
95
+ asOptionalFiniteNumber
96
+ } from "./chunk-WWC7I6TA.js";
97
+ import "./chunk-OW765XBU.js";
98
+ import "./chunk-U6VC4MU4.js";
89
99
  import {
90
100
  asTrimmedString
91
101
  } from "./chunk-3EUW3WEO.js";
92
- import "./chunk-U6VC4MU4.js";
93
102
  import "./chunk-LCBAMY2M.js";
94
103
  import "./chunk-4SN6J65J.js";
95
104
  import "./chunk-CF7PE763.js";
@@ -759,7 +768,7 @@ This authorizes model API access only. It does NOT log you into the Nolo platfor
759
768
  To manage agents, docs, spaces, and other Nolo resources, run "nolo login" first.
760
769
 
761
770
  Usage:
762
- nolo auth antigravity [--browser] [--no-browser] [--sync-to-server] [--help]
771
+ nolo auth antigravity [--browser] [--no-browser] [--verify] [--sync-to-server] [--help]
763
772
 
764
773
  Opens a browser to https://accounts.google.com (OIDC PKCE loopback on 127.0.0.1:51121).
765
774
  After approval, the flow provisions a Cloud Code Assist project and stores the
@@ -771,6 +780,8 @@ oh-my-pi; Google does not publish a public Cloud Code Assist client registration
771
780
  Options:
772
781
  --browser Use the browser PKCE flow (default for antigravity).
773
782
  --no-browser Print the authorization URL only.
783
+ --verify Check the current Google one-time verification challenge
784
+ and open the validation link in a browser (no re-auth).
774
785
  ${SYNC_HELP_LINE}
775
786
  --help, -h Show this help and exit.
776
787
 
@@ -975,6 +986,7 @@ async function runAuthProviderCommand(provider, args, _ctx, deps = {}) {
975
986
  const useBrowser = args.includes("--browser");
976
987
  const noBrowser = args.includes("--no-browser") || deps.noBrowserByDefault;
977
988
  const syncOnly = args.includes("--sync-only");
989
+ const verify = args.includes("--verify");
978
990
  const generateToken = args.includes("--generate-token");
979
991
  const writeToEnvRaw = parseFlagWithOptionalValue(args, "--write-to-env");
980
992
  const writeToEnvPath = typeof writeToEnvRaw === "string" ? writeToEnvRaw : writeToEnvRaw === true ? ".env" : void 0;
@@ -990,6 +1002,88 @@ async function runAuthProviderCommand(provider, args, _ctx, deps = {}) {
990
1002
  await syncCredentialToServer(provider, credential, deps);
991
1003
  return 0;
992
1004
  }
1005
+ if (verify) {
1006
+ if (provider !== "antigravity") {
1007
+ error.error(`[nolo] --verify is only supported for "nolo auth antigravity".`);
1008
+ return 1;
1009
+ }
1010
+ const credential = tokenStore.read(provider);
1011
+ if (!credential?.accessToken) {
1012
+ error.error(
1013
+ `[nolo] No local antigravity credential. Run: nolo auth antigravity`
1014
+ );
1015
+ return 1;
1016
+ }
1017
+ output.log(
1018
+ `[nolo] Checking the current verification challenge (one lightweight request)...`
1019
+ );
1020
+ let accessToken = null;
1021
+ let refreshError;
1022
+ try {
1023
+ accessToken = await resolveFreshAccessToken({
1024
+ provider,
1025
+ store: tokenStore,
1026
+ refresh: deps.refreshAntigravityToken ?? refreshAntigravityOAuthToken
1027
+ });
1028
+ } catch (err) {
1029
+ refreshError = toErrorMessage(err);
1030
+ if (/invalid_grant|unauthorized_client|revoked|invalid_token|refresh[_ ]token[^.]*(expired|invalid|revoked)|expired[^.]*refresh/i.test(
1031
+ refreshError
1032
+ )) {
1033
+ error.error(
1034
+ `[nolo] The antigravity refresh token is no longer valid (${refreshError}). Re-run \`nolo auth antigravity\` to re-authorize this account.`
1035
+ );
1036
+ return 1;
1037
+ }
1038
+ }
1039
+ let result;
1040
+ try {
1041
+ result = await fetchAntigravityCloudCodeCompletion({
1042
+ agentConfig: { model: "gemini-3.1-pro" },
1043
+ accessToken: accessToken ?? credential.accessToken,
1044
+ metadata: credential.metadata ?? null,
1045
+ openAiBody: { messages: [{ role: "user", content: "hi" }] },
1046
+ fetchImpl: deps.fetchImpl ?? fetch
1047
+ });
1048
+ } catch (err) {
1049
+ const msg = toErrorMessage(err);
1050
+ if (/projectId|metadata\.projectId|Re-run `nolo auth/i.test(msg)) {
1051
+ error.error(
1052
+ `[nolo] The stored antigravity credential is incomplete (${msg}). Re-run \`nolo auth antigravity\` to re-authorize.`
1053
+ );
1054
+ } else {
1055
+ error.error(
1056
+ `[nolo] Could not reach the antigravity provider: ${msg}. Check your network and retry.`
1057
+ );
1058
+ }
1059
+ return 1;
1060
+ }
1061
+ if (result.status >= 200 && result.status < 300) {
1062
+ output.log(
1063
+ `[nolo] \u2713 The credential is working \u2014 no verification is required right now. You can retry your agent.`
1064
+ );
1065
+ return 0;
1066
+ }
1067
+ const { url: validationUrl } = extractGoogleValidationLink(
1068
+ JSON.stringify(result.body ?? {})
1069
+ );
1070
+ if (result.status === 403 && validationUrl) {
1071
+ output.log(
1072
+ `[nolo] Google requires a one-time account verification for ${credential.accountId ?? "this account"}.`
1073
+ );
1074
+ output.log(`[nolo] ${validationUrl}`);
1075
+ const opener = noBrowser ? void 0 : deps.openBrowser ?? defaultOpenBrowser;
1076
+ const opened = opener ? await opener(validationUrl) : false;
1077
+ output.log(
1078
+ opened ? `[nolo] \u2713 Opened it in your browser \u2014 complete the verification there (sign in with the same Google account), then retry your agent.` : `[nolo] Copy the URL above into a browser signed into ${credential.accountId ?? "that account"}, complete the verification, then retry your agent.`
1079
+ );
1080
+ return 0;
1081
+ }
1082
+ error.error(
1083
+ `[nolo] The provider returned HTTP ${result.status} without a verification link \u2014 this is not the one-time-verification case --verify handles.` + (refreshError ? ` (token refresh also failed earlier: ${refreshError})` : "") + ` Response detail: ${JSON.stringify(result.body ?? {}).slice(0, 400)}`
1084
+ );
1085
+ return 1;
1086
+ }
993
1087
  const flowDeps = {
994
1088
  ...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {},
995
1089
  ...deps.sleep ? { sleep: deps.sleep } : {},
@@ -7,18 +7,20 @@ import {
7
7
  runLogoutCommand,
8
8
  runWhoamiCommand,
9
9
  saveTokenLogin
10
- } from "./chunk-6D6VBVEW.js";
10
+ } from "./chunk-SNMQMOD2.js";
11
+ import "./chunk-TY3TIUJK.js";
11
12
  import "./chunk-ESHYE7WU.js";
12
13
  import "./chunk-JBTJAPUF.js";
13
- import "./chunk-2F7RJC6L.js";
14
+ import "./chunk-FOXQ7BAB.js";
14
15
  import "./chunk-GLKOYSRU.js";
15
- import "./chunk-BYMV6QZG.js";
16
16
  import "./chunk-A7GB5UGH.js";
17
17
  import "./chunk-OLZBQWZU.js";
18
- import "./chunk-VMFTFOWF.js";
18
+ import "./chunk-TNIX77YM.js";
19
+ import "./chunk-3AH7LNUB.js";
19
20
  import "./chunk-WWC7I6TA.js";
20
- import "./chunk-3EUW3WEO.js";
21
+ import "./chunk-OW765XBU.js";
21
22
  import "./chunk-U6VC4MU4.js";
23
+ import "./chunk-3EUW3WEO.js";
22
24
  import "./chunk-LCBAMY2M.js";
23
25
  import "./chunk-4SN6J65J.js";
24
26
  import "./chunk-CF7PE763.js";
@@ -7,18 +7,20 @@ import {
7
7
  resolveBuiltinSkillEntry,
8
8
  resolveBuiltinSkillPage,
9
9
  resolveBuiltinSkillSlug
10
- } from "./chunk-JRQFUXY7.js";
11
- import "./chunk-DHDMC6FO.js";
12
- import "./chunk-Q554LLSI.js";
10
+ } from "./chunk-VEYL5MO5.js";
11
+ import "./chunk-WCGC6S77.js";
12
+ import "./chunk-WJ3B6FX6.js";
13
+ import "./chunk-AUDNYVRC.js";
14
+ import "./chunk-A4SQRTZ6.js";
13
15
  import "./chunk-KHCLMKZZ.js";
14
- import "./chunk-O6OSWFZQ.js";
15
- import "./chunk-QDSINZM3.js";
16
- import "./chunk-VMFTFOWF.js";
17
- import "./chunk-WWC7I6TA.js";
16
+ import "./chunk-XUWRURDF.js";
17
+ import "./chunk-5J3PYNUP.js";
18
18
  import "./chunk-BNGW5ASC.js";
19
19
  import "./chunk-M2EJHDJP.js";
20
- import "./chunk-3EUW3WEO.js";
20
+ import "./chunk-3AH7LNUB.js";
21
+ import "./chunk-WWC7I6TA.js";
21
22
  import "./chunk-U6VC4MU4.js";
23
+ import "./chunk-3EUW3WEO.js";
22
24
  import "./chunk-G3SUCT4W.js";
23
25
  import "./chunk-4VNS5WPM.js";
24
26
  export {
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  NOLO_CHROME_CONNECTOR_EXTENSION_ID,
3
3
  NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION,
4
+ NOLO_CONNECTOR_EXTENSION_IDS,
5
+ NOLO_FIREFOX_CONNECTOR_EXTENSION_ID,
4
6
  REQUIRED_CHROME_CONNECTOR_FEATURES,
5
7
  createChromeConnectorClient
6
- } from "./chunk-SH43IESU.js";
8
+ } from "./chunk-YUNJN43V.js";
7
9
  import {
8
10
  toErrorMessage
9
11
  } from "./chunk-HNMXYYJR.js";
@@ -21,6 +23,7 @@ import { dirname, resolve } from "node:path";
21
23
  import { execFileSync } from "node:child_process";
22
24
  import { fileURLToPath } from "node:url";
23
25
  var DEFAULT_CONNECTOR_ROOT = dirname(fileURLToPath(import.meta.url));
26
+ var FIREFOX_EXTENSION_ID = "nolo-browser-connector@nolo.chat";
24
27
  function extensionIdFromPublicKey(publicKeyBase64) {
25
28
  const digest = createHash("sha256").update(Buffer.from(publicKeyBase64, "base64")).digest();
26
29
  return Array.from(
@@ -40,8 +43,23 @@ function resolveNodePath() {
40
43
  }
41
44
  function nativeMessagingHostsDir({
42
45
  home = process.env.HOME || "",
43
- platform = process.platform
46
+ platform = process.platform,
47
+ browser = "chrome"
44
48
  } = {}) {
49
+ if (browser === "firefox") {
50
+ if (platform === "darwin") {
51
+ return resolve(home, "Library/Application Support/Mozilla/NativeMessagingHosts");
52
+ }
53
+ if (platform === "linux") {
54
+ return resolve(home, ".mozilla/native-messaging-hosts");
55
+ }
56
+ throw new Error(
57
+ `Firefox native host installation is not implemented for platform "${platform}". Windows needs a registry value under HKCU\\Software\\Mozilla\\NativeMessagingHosts pointing at the manifest file.`
58
+ );
59
+ }
60
+ if (browser !== "chrome") {
61
+ throw new Error(`Unknown native messaging browser target: "${browser}".`);
62
+ }
45
63
  if (platform === "darwin") {
46
64
  return resolve(home, "Library/Application Support/Google/Chrome/NativeMessagingHosts");
47
65
  }
@@ -55,16 +73,18 @@ function nativeMessagingHostsDir({
55
73
  function resolveNativeHostInstallPaths({
56
74
  home = process.env.HOME || "",
57
75
  connectorRoot = DEFAULT_CONNECTOR_ROOT,
58
- platform = process.platform
76
+ platform = process.platform,
77
+ browser = "chrome"
59
78
  } = {}) {
60
79
  const supportDir = resolve(home, "Library/Application Support/Nolo/ChromeConnector");
61
80
  return {
62
81
  connectorRoot,
82
+ browser,
63
83
  extensionManifestPath: resolve(connectorRoot, "extension", "manifest.json"),
64
84
  hostPath: resolve(connectorRoot, "native-host", "nolo-chrome-native-host.mjs"),
65
85
  templatePath: resolve(connectorRoot, "native-host", "com.nolo.chrome_connector.json"),
66
86
  nativeManifestPath: resolve(
67
- nativeMessagingHostsDir({ home, platform }),
87
+ nativeMessagingHostsDir({ home, platform, browser }),
68
88
  "com.nolo.chrome_connector.json"
69
89
  ),
70
90
  supportDir,
@@ -77,12 +97,13 @@ function installNativeHostManifest({
77
97
  connectorRoot = DEFAULT_CONNECTOR_ROOT,
78
98
  platform = process.platform,
79
99
  extensionId,
80
- nodePath
100
+ nodePath,
101
+ browser = "chrome"
81
102
  } = {}) {
82
- const paths = resolveNativeHostInstallPaths({ home, connectorRoot, platform });
103
+ const paths = resolveNativeHostInstallPaths({ home, connectorRoot, platform, browser });
83
104
  const manifest = JSON.parse(readFileSync(paths.templatePath, "utf8"));
84
105
  const extensionManifest = JSON.parse(readFileSync(paths.extensionManifestPath, "utf8"));
85
- const resolvedExtensionId = extensionId || extensionIdFromPublicKey(extensionManifest.key);
106
+ const resolvedExtensionId = extensionId || (browser === "firefox" ? FIREFOX_EXTENSION_ID : extensionIdFromPublicKey(extensionManifest.key));
86
107
  const resolvedNodePath = nodePath || resolveNodePath();
87
108
  mkdirSync(paths.supportDir, { recursive: true });
88
109
  const existingToken = existsSync(paths.tokenPath) ? readFileSync(paths.tokenPath, "utf8").trim() : "";
@@ -97,12 +118,18 @@ NOLO_CHROME_CONNECTOR_TOKEN=${JSON.stringify(token)} exec ${JSON.stringify(resol
97
118
  );
98
119
  chmodSync(paths.wrapperPath, 493);
99
120
  manifest.path = paths.wrapperPath;
100
- manifest.allowed_origins = [`chrome-extension://${resolvedExtensionId}/`];
121
+ if (browser === "firefox") {
122
+ delete manifest.allowed_origins;
123
+ manifest.allowed_extensions = [FIREFOX_EXTENSION_ID];
124
+ } else {
125
+ manifest.allowed_origins = [`chrome-extension://${resolvedExtensionId}/`];
126
+ }
101
127
  mkdirSync(dirname(paths.nativeManifestPath), { recursive: true });
102
128
  writeFileSync(paths.nativeManifestPath, `${JSON.stringify(manifest, null, 2)}
103
129
  `);
104
130
  return {
105
131
  extensionId: resolvedExtensionId,
132
+ browser,
106
133
  nodePath: resolvedNodePath,
107
134
  tokenPath: paths.tokenPath,
108
135
  ...paths
@@ -119,6 +146,21 @@ var CLI_CONNECTOR_ROOT_CANDIDATES = [
119
146
  var FULL_SUPPORT_CHROME_FEATURES = [
120
147
  ...new Set(Object.values(REQUIRED_CHROME_CONNECTOR_FEATURES).flat())
121
148
  ].sort();
149
+ var FIREFOX_UNAVAILABLE_FEATURES = ["browser_debug", "file_upload"];
150
+ function resolveConnectorBrowser(extensionId) {
151
+ if (!extensionId) return null;
152
+ if (extensionId === NOLO_FIREFOX_CONNECTOR_EXTENSION_ID) return "firefox";
153
+ if (NOLO_CONNECTOR_EXTENSION_IDS.includes(extensionId)) return "chrome";
154
+ return null;
155
+ }
156
+ function expectedFeaturesForBrowser(browser) {
157
+ return browser === "firefox" ? FULL_SUPPORT_CHROME_FEATURES.filter(
158
+ (feature) => !FIREFOX_UNAVAILABLE_FEATURES.includes(feature)
159
+ ) : FULL_SUPPORT_CHROME_FEATURES;
160
+ }
161
+ function browserLabel(browser) {
162
+ return browser === "firefox" ? "Firefox" : browser === "chrome" ? "Chrome" : "browser";
163
+ }
122
164
  function pickCliConnectorRoot(candidates) {
123
165
  for (const candidate of candidates) {
124
166
  if (existsSync2(resolve2(candidate, "extension", "manifest.json"))) return candidate;
@@ -233,9 +275,13 @@ async function probeConnectorRpc(requestChrome) {
233
275
  }
234
276
  }
235
277
  function resolveStatusNextStep(report) {
278
+ const targetBrowser = report.rpc.browser ?? report.nativeHost.browser;
279
+ const installCmd = targetBrowser === "firefox" ? "nolo chrome install --browser firefox" : "nolo chrome install";
280
+ const connectedLabel = browserLabel(targetBrowser);
281
+ const browserText = connectedLabel === "browser" ? "the browser" : connectedLabel;
236
282
  if (!report.connectorRoot) {
237
283
  if (report.rpc.online && report.rpc.protocolVersion === report.rpc.expectedProtocolVersion) {
238
- return "Chrome connector is online, but this CLI cannot see a connector checkout, so `nolo chrome install` / manifest checks are unavailable here. Set NOLO_CHROME_CONNECTOR_ROOT (or run the CLI from a repo checkout) to enable them.";
284
+ return "The Nolo Browser Connector is online, but this CLI cannot see a connector checkout, so `nolo chrome install` / manifest checks are unavailable here. Set NOLO_CHROME_CONNECTOR_ROOT (or run the CLI from a repo checkout) to enable them.";
239
285
  }
240
286
  return "Run the CLI from a repo checkout that contains packages/desktop-chrome-connector, or set NOLO_CHROME_CONNECTOR_ROOT to one, then rerun `nolo chrome status`.";
241
287
  }
@@ -243,20 +289,20 @@ function resolveStatusNextStep(report) {
243
289
  return `This platform has no supported native messaging host install (Chrome looks the host up through a registry value on Windows), so non-interactive install is not available: ${report.nativeHost.platformError ?? "unsupported platform"}`;
244
290
  }
245
291
  if (!report.nativeHost.installed || !report.token.present) {
246
- return "nolo chrome install";
292
+ return installCmd;
247
293
  }
248
294
  if (!report.nativeHost.wrapperPathMatches || !report.nativeHost.allowedOriginMatches) {
249
295
  const installedWrapperPath = report.nativeHost.installedWrapperPath;
250
296
  if (!report.nativeHost.wrapperPathMatches && installedWrapperPath && installedWrapperPath !== report.nativeHost.wrapperPath && existsSync2(installedWrapperPath)) {
251
- return `Native host is installed for a different checkout (${installedWrapperPath}); this CLI is looking at ${report.connectorRoot}. Run \`nolo chrome status\` from the checkout that installed it, or run \`nolo chrome install\` from here only if Chrome should switch to this one.`;
297
+ return `Native host is installed for a different checkout (${installedWrapperPath}); this CLI is looking at ${report.connectorRoot}. Run \`nolo chrome status\` from the checkout that installed it, or run \`${installCmd}\` from here only if ${browserText} should switch to this one.`;
252
298
  }
253
- return "nolo chrome install (the installed manifest does not point at this checkout's wrapper / extension id, which Chrome silently ignores)";
299
+ return `${installCmd} (the installed manifest does not point at this checkout's wrapper / extension id, which ${browserText} silently ignores)`;
254
300
  }
255
301
  if (!report.rpc.online) {
256
- return `Load the unpacked extension from ${report.extension.path} in chrome://extensions (Developer mode) or install it from the Chrome Web Store, then rerun \`nolo chrome status\`.`;
302
+ return `Load the unpacked extension from ${report.extension.path} in chrome://extensions (Chrome) or about:debugging#/runtime/this-firefox (Firefox), or install the Nolo Browser Connector from https://nolo.chat/downloads, then rerun \`nolo chrome status\`.`;
257
303
  }
258
- if (report.rpc.extensionId && report.rpc.extensionId !== report.extension.expectedId) {
259
- return `The connected extension (${report.rpc.extensionId}) is not the connector at ${report.extension.path}; remove the other copy and rerun \`nolo chrome status\`.`;
304
+ if (report.rpc.extensionId && report.rpc.browser === null) {
305
+ return `The connected extension (${report.rpc.extensionId}) is not a recognized Nolo Browser Connector build; reload it (\`nolo chrome reload\`) or remove the other copy, then rerun \`nolo chrome status\`.`;
260
306
  }
261
307
  if (report.rpc.protocolVersion !== report.rpc.expectedProtocolVersion) {
262
308
  return `nolo chrome reload (the running extension does not speak protocol ${report.rpc.expectedProtocolVersion}; a reload restarts the worker with the files on disk)`;
@@ -264,7 +310,7 @@ function resolveStatusNextStep(report) {
264
310
  if (report.rpc.missingFeatures.length > 0) {
265
311
  return `nolo chrome reload (the running extension is missing ${report.rpc.missingFeatures.join(", ")}); if that persists, the checkout's extension is older than the CLI expects.`;
266
312
  }
267
- return "Chrome connector is online: chrome_* tools execute against this Chrome profile.";
313
+ return `The Nolo Browser Connector is online (${connectedLabel}): connector tools execute against this ${connectedLabel} profile.`;
268
314
  }
269
315
  async function buildChromeConnectorStatus(args = {}) {
270
316
  const env = args.env ?? process.env;
@@ -295,7 +341,8 @@ async function buildChromeConnectorStatus(args = {}) {
295
341
  wrapperPath: null,
296
342
  installedWrapperPath: null,
297
343
  wrapperPathMatches: false,
298
- allowedOriginMatches: false
344
+ allowedOriginMatches: false,
345
+ browser: null
299
346
  },
300
347
  token: { path: null, present: false },
301
348
  rpc: {
@@ -303,6 +350,7 @@ async function buildChromeConnectorStatus(args = {}) {
303
350
  extensionId: null,
304
351
  protocolVersion: null,
305
352
  features: [],
353
+ browser: null,
306
354
  missingFeatures: [...FULL_SUPPORT_CHROME_FEATURES],
307
355
  expectedProtocolVersion: NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION
308
356
  },
@@ -314,19 +362,48 @@ async function buildChromeConnectorStatus(args = {}) {
314
362
  report.rpc.extensionId = probe.extensionId;
315
363
  report.rpc.protocolVersion = probe.protocolVersion;
316
364
  report.rpc.features = probe.features;
317
- report.rpc.missingFeatures = FULL_SUPPORT_CHROME_FEATURES.filter(
365
+ report.rpc.browser = probe.online ? resolveConnectorBrowser(probe.extensionId) ?? (probe.extensionId === expectedId ? "chrome" : null) : null;
366
+ report.rpc.missingFeatures = expectedFeaturesForBrowser(report.rpc.browser).filter(
318
367
  (feature) => !probe.features.includes(feature)
319
368
  );
320
369
  if (!probe.online) report.rpc.error = probe.error;
321
370
  if (!connectorRoot) {
322
371
  if (rootError) report.connectorRootError = rootError;
323
- report.ok = report.rpc.online && probe.extensionId === expectedId && probe.protocolVersion === NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION && report.rpc.missingFeatures.length === 0;
372
+ report.nativeHost.browser = report.rpc.browser;
373
+ report.ok = report.rpc.online && report.rpc.browser !== null && probe.protocolVersion === NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION && report.rpc.missingFeatures.length === 0;
324
374
  report.nextStep = resolveStatusNextStep(report);
325
375
  return report;
326
376
  }
377
+ let manifestBrowser = report.rpc.browser === "firefox" ? "firefox" : "chrome";
378
+ if (!report.rpc.browser) {
379
+ try {
380
+ const chromeManifestPath = resolveNativeHostInstallPaths({
381
+ home,
382
+ connectorRoot,
383
+ platform,
384
+ browser: "chrome"
385
+ }).nativeManifestPath;
386
+ const firefoxManifestPath = resolveNativeHostInstallPaths({
387
+ home,
388
+ connectorRoot,
389
+ platform,
390
+ browser: "firefox"
391
+ }).nativeManifestPath;
392
+ if (!existsSync2(chromeManifestPath) && existsSync2(firefoxManifestPath)) {
393
+ manifestBrowser = "firefox";
394
+ }
395
+ } catch {
396
+ }
397
+ }
398
+ report.nativeHost.browser = manifestBrowser;
327
399
  let paths = null;
328
400
  try {
329
- paths = resolveNativeHostInstallPaths({ home, connectorRoot, platform });
401
+ paths = resolveNativeHostInstallPaths({
402
+ home,
403
+ connectorRoot,
404
+ platform,
405
+ browser: manifestBrowser
406
+ });
330
407
  } catch (error) {
331
408
  report.nativeHost.supported = false;
332
409
  report.nativeHost.platformError = toErrorMessage(error);
@@ -340,8 +417,7 @@ async function buildChromeConnectorStatus(args = {}) {
340
417
  report.nativeHost.installed = installedManifest !== null;
341
418
  report.nativeHost.installedWrapperPath = typeof installedManifest?.path === "string" ? installedManifest.path : null;
342
419
  report.nativeHost.wrapperPathMatches = report.nativeHost.installedWrapperPath === paths.wrapperPath;
343
- const expectedOrigin = `chrome-extension://${expectedId}/`;
344
- report.nativeHost.allowedOriginMatches = Array.isArray(installedManifest?.allowed_origins) && installedManifest.allowed_origins.includes(expectedOrigin);
420
+ report.nativeHost.allowedOriginMatches = manifestBrowser === "firefox" ? Array.isArray(installedManifest?.allowed_extensions) && installedManifest.allowed_extensions.includes(NOLO_FIREFOX_CONNECTOR_EXTENSION_ID) : Array.isArray(installedManifest?.allowed_origins) && installedManifest.allowed_origins.includes(`chrome-extension://${expectedId}/`);
345
421
  if (existsSync2(paths.tokenPath)) {
346
422
  try {
347
423
  report.token.present = readFileSync2(paths.tokenPath, "utf8").trim().length > 0;
@@ -349,7 +425,7 @@ async function buildChromeConnectorStatus(args = {}) {
349
425
  report.token.present = false;
350
426
  }
351
427
  }
352
- report.ok = report.nativeHost.supported && report.nativeHost.installed && report.nativeHost.wrapperPathMatches && report.nativeHost.allowedOriginMatches && report.token.present && probe.online && probe.extensionId === expectedId && probe.protocolVersion === NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION && report.rpc.missingFeatures.length === 0;
428
+ report.ok = report.nativeHost.supported && report.nativeHost.installed && report.nativeHost.wrapperPathMatches && report.nativeHost.allowedOriginMatches && report.token.present && probe.online && report.rpc.browser !== null && probe.protocolVersion === NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION && report.rpc.missingFeatures.length === 0;
353
429
  report.nextStep = resolveStatusNextStep(report);
354
430
  return report;
355
431
  }
@@ -357,7 +433,7 @@ function yesNo(value) {
357
433
  return value ? "ok" : "mismatch";
358
434
  }
359
435
  function formatChromeConnectorStatus(report) {
360
- const lines = ["Nolo Chrome connector"];
436
+ const lines = ["Nolo Browser Connector"];
361
437
  lines.push(
362
438
  ` connector source : ${report.connectorRoot ?? "(not found)"}`
363
439
  );
@@ -377,7 +453,7 @@ function formatChromeConnectorStatus(report) {
377
453
  const rpc = report.rpc;
378
454
  if (rpc.online) {
379
455
  lines.push(
380
- ` RPC : online extension ${rpc.extensionId ?? "unknown"} protocolVersion ${rpc.protocolVersion ?? "unknown"} features ${rpc.features.length > 0 ? rpc.features.join(", ") : "(none)"}`
456
+ ` RPC : online browser ${rpc.browser ?? "unrecognized"} extension ${rpc.extensionId ?? "unknown"} protocolVersion ${rpc.protocolVersion ?? "unknown"} features ${rpc.features.length > 0 ? rpc.features.join(", ") : "(none)"}`
381
457
  );
382
458
  } else {
383
459
  lines.push(
@@ -406,9 +482,25 @@ async function runChromeStatusCommand(args, deps = {}) {
406
482
  }
407
483
  return report.ok ? 0 : 1;
408
484
  }
485
+ function readBrowserOption(args) {
486
+ const equalsForm = args.find((arg) => arg.startsWith("--browser="));
487
+ const index = args.indexOf("--browser");
488
+ const raw = equalsForm !== void 0 ? equalsForm.slice("--browser=".length) : index >= 0 ? args[index + 1] : void 0;
489
+ if (raw === void 0) return "chrome";
490
+ const value = raw.trim();
491
+ if (value === "chrome" || value === "firefox") return value;
492
+ return null;
493
+ }
409
494
  async function runChromeInstallCommand(args, deps = {}) {
410
495
  const env = deps.env ?? process.env;
411
496
  const output = deps.output ?? process.stdout;
497
+ const browser = readBrowserOption(args);
498
+ if (browser === null) {
499
+ output.write(
500
+ '[nolo] Chrome native host install failed: --browser must be "chrome" or "firefox".\n'
501
+ );
502
+ return 1;
503
+ }
412
504
  const install = deps.installNativeHost ?? installNativeHostManifest;
413
505
  let connectorRoot;
414
506
  try {
@@ -432,6 +524,7 @@ async function runChromeInstallCommand(args, deps = {}) {
432
524
  result = install({
433
525
  home: deps.home ?? env.HOME ?? "",
434
526
  connectorRoot,
527
+ browser,
435
528
  ...deps.platform ? { platform: deps.platform } : {},
436
529
  ...deps.nodePath ? { nodePath: deps.nodePath } : {}
437
530
  });
@@ -446,12 +539,12 @@ async function runChromeInstallCommand(args, deps = {}) {
446
539
  } else {
447
540
  output.write(
448
541
  [
449
- "Nolo Chrome connector native host installed.",
542
+ `Nolo Browser Connector native host installed (${browser}).`,
450
543
  ` manifest : ${result.nativeManifestPath}`,
451
544
  ` wrapper : ${result.wrapperPath} -> ${result.nodePath}`,
452
545
  ` token : ${result.tokenPath} (an existing token is kept, so reruns are idempotent)`,
453
546
  ` extension: ${result.extensionId}`,
454
- `Next step: load the unpacked extension from ${resolve2(connectorRoot, "extension")} in chrome://extensions (Developer mode) or install it from the Chrome Web Store, then run \`nolo chrome status\`.`,
547
+ `Next step: load the unpacked extension from ${resolve2(connectorRoot, "extension")} in ` + (browser === "firefox" ? "about:debugging#/runtime/this-firefox, or install the signed Nolo Browser Connector add-on from https://nolo.chat/downloads, then run `nolo chrome status`." : "chrome://extensions (Developer mode), or install the Nolo Browser Connector from https://nolo.chat/downloads (Chrome or Firefox), then run `nolo chrome status`."),
455
548
  ""
456
549
  ].join("\n")
457
550
  );
@@ -480,7 +573,7 @@ The connector service worker restarts within ~1s; verify with \`nolo chrome stat
480
573
  `);
481
574
  if (code === "CHROME_CONNECTOR_UNAVAILABLE") {
482
575
  output.write(
483
- "The native host is not reachable: load the unpacked connector extension in chrome://extensions (or start Chrome), then rerun `nolo chrome reload`.\n"
576
+ "The native host is not reachable: open Chrome or Firefox with the Nolo Browser Connector extension enabled, or install it from https://nolo.chat/downloads (or load the unpacked connector extension in chrome://extensions), then rerun `nolo chrome reload`.\n"
484
577
  );
485
578
  }
486
579
  return 1;
@@ -488,11 +581,14 @@ The connector service worker restarts within ~1s; verify with \`nolo chrome stat
488
581
  }
489
582
  export {
490
583
  CLI_CONNECTOR_ROOT_CANDIDATES,
584
+ FIREFOX_UNAVAILABLE_FEATURES,
491
585
  FULL_SUPPORT_CHROME_FEATURES,
492
586
  buildChromeConnectorStatus,
493
587
  detectWorktreeCheckout,
588
+ expectedFeaturesForBrowser,
494
589
  formatChromeConnectorStatus,
495
590
  resolveCliConnectorRoot,
591
+ resolveConnectorBrowser,
496
592
  runChromeInstallCommand,
497
593
  runChromeReloadCommand,
498
594
  runChromeStatusCommand
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createChromeConnectorClient
3
- } from "./chunk-SH43IESU.js";
3
+ } from "./chunk-YUNJN43V.js";
4
4
  import {
5
5
  toErrorMessage
6
6
  } from "./chunk-HNMXYYJR.js";
@@ -197,8 +197,8 @@ var CHROME_OPS_SUBCOMMANDS = {
197
197
  };
198
198
  function renderChromeOpsHelp() {
199
199
  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).",
200
+ "Operate the user's browser (Chrome or Firefox) through the Nolo Browser Connector",
201
+ "(the desktop bridge; the same RPC the browser_* agent tools use \u2014 legacy `chrome_*` names still work).",
202
202
  "",
203
203
  "Usage:",
204
204
  " nolo chrome <subcommand> [flags]",
@@ -213,6 +213,7 @@ function renderChromeOpsHelp() {
213
213
  " preferred over --selector); --selector takes a CSS selector.",
214
214
  " Actions the connector classifies as irreversible (Submit / Delete / Pay ...)",
215
215
  " are refused with CONFIRMATION_REQUIRED \u2014 ask the user to perform them.",
216
+ " read-console / read-network / upload work on Chrome only (Firefox lacks chrome.debugger).",
216
217
  " Every subcommand prints the connector's raw JSON result; failures exit 1.",
217
218
  " Endpoint: NOLO_CHROME_CONNECTOR_RPC_URL or http://127.0.0.1:38947/rpc."
218
219
  ];