nolo-cli 0.72.0-alpha.1 → 0.72.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 (68) hide show
  1. package/{_executeModel-TKD22VDA.js → _executeModel-T3FPYFVF.js} +11 -11
  2. package/{agentDeleteCommand-FSIMTL4K.js → agentDeleteCommand-UAMLWTPS.js} +6 -6
  3. package/{agentEmailCommands-G53VVKIL.js → agentEmailCommands-65FRADWQ.js} +15 -14
  4. package/{agentListCommands-2YWZYH52.js → agentListCommands-63DOSBY7.js} +7 -7
  5. package/{agentMachineCommands-A7D55KN2.js → agentMachineCommands-HMMAULDF.js} +6 -6
  6. package/{agentRecordCommands-UVU5UPJB.js → agentRecordCommands-HX5AEFP7.js} +15 -14
  7. package/{agentRunCommand-PDKUP3L4.js → agentRunCommand-KXPU5X7D.js} +15 -14
  8. package/{agentRuntimeLocal-O6DZDTK4.js → agentRuntimeLocal-XG3IDNOC.js} +4 -4
  9. package/{agentSlice-FZBFYKP3.js → agentSlice-EACXUOWW.js} +1 -1
  10. package/{appDeleteCommands-HIJNWSK7.js → appDeleteCommands-TJXDMOYT.js} +7 -7
  11. package/{appDeployCommands-XULV2ZN6.js → appDeployCommands-ECZJQAAL.js} +7 -7
  12. package/{appDeployStatusCommands-ETY4Z7K6.js → appDeployStatusCommands-DZKVFG3Y.js} +7 -7
  13. package/{appGetCommands-M253LKDA.js → appGetCommands-JIT4OPUD.js} +7 -7
  14. package/{appListCommands-XYFXJMNP.js → appListCommands-NR2HRMDY.js} +7 -7
  15. package/{chatQueueReduxAdapter-E2D4NR2W.js → chatQueueReduxAdapter-XEIJO5WR.js} +2 -2
  16. package/chromeCommands-VOIRNJBL.js +499 -0
  17. package/chromeOpsCommands-M7DPCX2T.js +258 -0
  18. package/{chunk-7GCIXOQA.js → chunk-226XC5JW.js} +2 -2
  19. package/{chunk-SV63E2UZ.js → chunk-4SUTS5DI.js} +91 -6
  20. package/{chunk-B62OSA77.js → chunk-AFIKMMGC.js} +1 -1
  21. package/{chunk-Q4OT2DC7.js → chunk-AFIWC5NH.js} +1 -1
  22. package/{chunk-4NI7LU7J.js → chunk-AI5QKFXK.js} +5580 -349
  23. package/{chunk-AOKRQAUQ.js → chunk-ALGK6TIE.js} +2 -2
  24. package/{chunk-JWXTOIGR.js → chunk-CDVGNZDA.js} +2 -2
  25. package/{chunk-2QDDKFG5.js → chunk-CQ3WA2NE.js} +77 -0
  26. package/{chunk-CJ23A7U4.js → chunk-CUQ6PG2C.js} +14 -5
  27. package/{chunk-3LBE76GR.js → chunk-D74EWXL4.js} +87 -47
  28. package/{chunk-JWO3RQSH.js → chunk-DWPNOYMB.js} +1 -1
  29. package/{chunk-EDKF7RX4.js → chunk-EOARMOVD.js} +2 -0
  30. package/{chunk-T7PQFKJU.js → chunk-FSFQ3A7S.js} +1 -1
  31. package/{chunk-S4IVP3JA.js → chunk-H5I6AJX4.js} +22 -6
  32. package/{chunk-ZDB5QFH4.js → chunk-H7UKKEIS.js} +1 -1
  33. package/{chunk-YCDWJX45.js → chunk-KC5FAHVS.js} +1 -1
  34. package/{chunk-3U3EA3BO.js → chunk-L2Y24GRM.js} +2 -2
  35. package/{chunk-R5NCDOHB.js → chunk-MEVSATIF.js} +22 -8
  36. package/{chunk-R4XZMDRV.js → chunk-P7FA2HMM.js} +66 -120
  37. package/{chunk-AUKZOZFG.js → chunk-QA6YKM3H.js} +1 -1
  38. package/{chunk-HXAINXPQ.js → chunk-QC5LGHYP.js} +1 -1
  39. package/chunk-QCZX4FTW.js +242 -0
  40. package/{chunk-I5O24WHB.js → chunk-QRBAZ5PW.js} +2 -2
  41. package/{chunk-RVCBKVIR.js → chunk-QUH3XHL5.js} +3 -3
  42. package/{chunk-U4N7NIN3.js → chunk-U6LKJRJB.js} +4 -4
  43. package/{chunk-IDZTNRP2.js → chunk-X7HHHIOZ.js} +10 -2
  44. package/{chunk-S2RB4LMB.js → chunk-X7Z7U4Z6.js} +5 -5
  45. package/{contentThunks-QLAU2LGJ.js → contentThunks-3SPROFG5.js} +3 -3
  46. package/{createAgentAutomationAction-JUSLLNYE.js → createAgentAutomationAction-EIP2EG3O.js} +3 -3
  47. package/{createDialogAction-B52IPGBY.js → createDialogAction-RLUSTN4D.js} +4 -4
  48. package/{createPageAction-ACAIWRDQ.js → createPageAction-4Y52G7WG.js} +3 -3
  49. package/{dialogCommands-PE5FEFJ5.js → dialogCommands-CJCAMML3.js} +7 -7
  50. package/{dialogSlice-RM3EW5AO.js → dialogSlice-THY45JWM.js} +2 -2
  51. package/{docCreateCommands-IPDFZVPG.js → docCreateCommands-H65RSKT4.js} +6 -6
  52. package/{docDeleteCommands-VQ4Y66CM.js → docDeleteCommands-PBYGJ6CZ.js} +7 -7
  53. package/{docReadCommands-PD33VV27.js → docReadCommands-4VRYN5R5.js} +6 -6
  54. package/{docStore-Q45M4B2I.js → docStore-ZQ3ECOPY.js} +1 -1
  55. package/{docUpdateCommands-CGUQ2JY3.js → docUpdateCommands-COZG3ZDB.js} +6 -6
  56. package/{handleSendMessageAction-I6KFXKDM.js → handleSendMessageAction-CE4M5XIE.js} +2 -2
  57. package/index.js +108 -48
  58. package/{machineCommands-QEYH5J5E.js → machineCommands-JE4G4JYB.js} +14 -13
  59. package/{machineWsRunDispatch-MFYQADTQ.js → machineWsRunDispatch-FUQOSWD4.js} +14 -13
  60. package/package.json +1 -1
  61. package/{readlineWorkspace-WQZX3WSK.js → readlineWorkspace-Z4V3EB52.js} +45 -26
  62. package/{runAgentClientLoop-SLKSZWCS.js → runAgentClientLoop-NE5EHXSS.js} +9 -9
  63. package/{spaceCommands-Y47DDAQD.js → spaceCommands-WGXHETMT.js} +6 -6
  64. package/{streamAgentChatTurn-FLA6GTFJ.js → streamAgentChatTurn-A6L6O22P.js} +11 -11
  65. package/{tools-NA2SK5QX.js → tools-JS475NYO.js} +6 -6
  66. package/{tuiSummaryLlmCaller-J5BEPLW5.js → tuiSummaryLlmCaller-3Z24VUWM.js} +2 -2
  67. package/{updateCommands-AJYSD73Y.js → updateCommands-Y363MC3L.js} +2 -2
  68. package/{updateDialogTitleAction-55Q3R6RJ.js → updateDialogTitleAction-GMZUT6RP.js} +3 -3
@@ -0,0 +1,258 @@
1
+ import {
2
+ createChromeConnectorClient
3
+ } from "./chunk-QCZX4FTW.js";
4
+ import {
5
+ toErrorMessage
6
+ } from "./chunk-HNMXYYJR.js";
7
+ import {
8
+ readOption
9
+ } from "./chunk-A7GB5UGH.js";
10
+ import "./chunk-OLZBQWZU.js";
11
+ import "./chunk-KUG52IAP.js";
12
+ import "./chunk-LCBAMY2M.js";
13
+ import "./chunk-4SN6J65J.js";
14
+ import "./chunk-CF7PE763.js";
15
+ import "./chunk-G3SUCT4W.js";
16
+ import "./chunk-4VNS5WPM.js";
17
+
18
+ // packages/cli/chromeOpsCommands.ts
19
+ import { writeFile } from "node:fs/promises";
20
+ function wantsHelp(args) {
21
+ return args.includes("--help") || args.includes("-h");
22
+ }
23
+ function readTrimmedOption(args, flag) {
24
+ return (readOption(args, flag) ?? "").trim();
25
+ }
26
+ function readIntOption(args, flag, usage) {
27
+ const raw = readOption(args, flag);
28
+ if (raw === void 0) return void 0;
29
+ const value = Number.parseInt(raw, 10);
30
+ if (!Number.isFinite(value)) {
31
+ throw new Error(`Invalid ${flag} <N>. Usage: ${usage}`);
32
+ }
33
+ return value;
34
+ }
35
+ function requireTabId(args, usage) {
36
+ const tabId = readTrimmedOption(args, "--tab");
37
+ if (!tabId) {
38
+ throw new Error(`Missing required --tab <id>. Usage: ${usage}`);
39
+ }
40
+ return tabId;
41
+ }
42
+ function requireTarget(args, usage) {
43
+ const elementRef = readTrimmedOption(args, "--ref");
44
+ const selector = readTrimmedOption(args, "--selector");
45
+ if (!elementRef && !selector) {
46
+ throw new Error(
47
+ `Provide --ref <elementRef> (from read-page) or --selector <css>. Usage: ${usage}`
48
+ );
49
+ }
50
+ return {
51
+ ...elementRef ? { elementRef } : {},
52
+ ...selector ? { selector } : {}
53
+ };
54
+ }
55
+ var CHROME_OPS_SUBCOMMANDS = {
56
+ "list-tabs": {
57
+ action: "list_tabs",
58
+ usage: "nolo chrome list-tabs",
59
+ payload: () => ({})
60
+ },
61
+ "open-tab": {
62
+ action: "open_tab",
63
+ usage: "nolo chrome open-tab --url <url> [--active]",
64
+ payload: (args, usage) => {
65
+ const url = readTrimmedOption(args, "--url");
66
+ if (!url) {
67
+ throw new Error(`Missing required --url <url>. Usage: ${usage}`);
68
+ }
69
+ return { url, active: args.includes("--active") };
70
+ }
71
+ },
72
+ "close-tab": {
73
+ action: "close_tab",
74
+ usage: "nolo chrome close-tab --tab <id>",
75
+ payload: (args, usage) => ({ tabId: requireTabId(args, usage) })
76
+ },
77
+ "read-page": {
78
+ action: "read_page",
79
+ usage: "nolo chrome read-page --tab <id> [--selector <css>] [--detail compact|full] [--max-elements N]",
80
+ payload: (args, usage) => {
81
+ const payload = { tabId: requireTabId(args, usage) };
82
+ const selector = readTrimmedOption(args, "--selector");
83
+ if (selector) payload.selector = selector;
84
+ const detail = readTrimmedOption(args, "--detail");
85
+ if (detail) payload.detail = detail;
86
+ const maxElements = readIntOption(args, "--max-elements", usage);
87
+ if (maxElements !== void 0) payload.maxElements = maxElements;
88
+ return payload;
89
+ }
90
+ },
91
+ click: {
92
+ action: "click",
93
+ usage: "nolo chrome click --tab <id> (--ref <elementRef> | --selector <css>)",
94
+ payload: (args, usage) => ({
95
+ tabId: requireTabId(args, usage),
96
+ ...requireTarget(args, usage)
97
+ })
98
+ },
99
+ type: {
100
+ action: "type",
101
+ usage: "nolo chrome type --tab <id> (--ref <elementRef> | --selector <css>) --text <text> [--append]",
102
+ payload: (args, usage) => {
103
+ const text = readOption(args, "--text");
104
+ if (text === void 0 || text.startsWith("--")) {
105
+ throw new Error(`Missing required --text <text>. Usage: ${usage}`);
106
+ }
107
+ return {
108
+ tabId: requireTabId(args, usage),
109
+ ...requireTarget(args, usage),
110
+ text,
111
+ ...args.includes("--append") ? { clearFirst: false } : {}
112
+ };
113
+ }
114
+ },
115
+ press: {
116
+ action: "press",
117
+ usage: "nolo chrome press --tab <id> --key <key>",
118
+ payload: (args, usage) => {
119
+ const key = readTrimmedOption(args, "--key");
120
+ if (!key) {
121
+ throw new Error(`Missing required --key <key>. Usage: ${usage}`);
122
+ }
123
+ return { tabId: requireTabId(args, usage), key };
124
+ }
125
+ },
126
+ scroll: {
127
+ action: "scroll",
128
+ usage: "nolo chrome scroll --tab <id> [--delta-x N] [--delta-y N]",
129
+ payload: (args, usage) => {
130
+ const payload = { tabId: requireTabId(args, usage) };
131
+ const deltaX = readIntOption(args, "--delta-x", usage);
132
+ const deltaY = readIntOption(args, "--delta-y", usage);
133
+ if (deltaX !== void 0) payload.deltaX = deltaX;
134
+ if (deltaY !== void 0) payload.deltaY = deltaY;
135
+ return payload;
136
+ }
137
+ },
138
+ screenshot: {
139
+ action: "screenshot",
140
+ usage: "nolo chrome screenshot --tab <id> [--out <path>] [--full-page]",
141
+ payload: (args, usage) => ({
142
+ tabId: requireTabId(args, usage),
143
+ ...args.includes("--full-page") ? { fullPage: true } : {}
144
+ })
145
+ },
146
+ "read-console": {
147
+ action: "read_console",
148
+ usage: "nolo chrome read-console --tab <id> [--limit N]",
149
+ payload: (args, usage) => {
150
+ const payload = { tabId: requireTabId(args, usage) };
151
+ const limit = readIntOption(args, "--limit", usage);
152
+ if (limit !== void 0) payload.limit = limit;
153
+ return payload;
154
+ }
155
+ },
156
+ "read-network": {
157
+ action: "read_network",
158
+ usage: "nolo chrome read-network --tab <id> [--limit N] [--include-assets]",
159
+ payload: (args, usage) => {
160
+ const payload = { tabId: requireTabId(args, usage) };
161
+ const limit = readIntOption(args, "--limit", usage);
162
+ if (limit !== void 0) payload.limit = limit;
163
+ if (args.includes("--include-assets")) payload.includeAssets = true;
164
+ return payload;
165
+ }
166
+ }
167
+ };
168
+ function renderChromeOpsHelp() {
169
+ const lines = [
170
+ "Operate the user's Chrome through the Nolo Chrome connector (the desktop bridge;",
171
+ "the same RPC the chrome_* agent tools use).",
172
+ "",
173
+ "Usage:",
174
+ " nolo chrome <subcommand> [flags]",
175
+ "",
176
+ "Subcommands:",
177
+ ...Object.values(CHROME_OPS_SUBCOMMANDS).map(
178
+ (spec) => ` ${spec.usage.replace(/^nolo chrome /, "")}`
179
+ ),
180
+ "",
181
+ "Notes:",
182
+ " --ref takes an elementRef copied from `nolo chrome read-page` (revision-scoped,",
183
+ " preferred over --selector); --selector takes a CSS selector.",
184
+ " Actions the connector classifies as irreversible (Submit / Delete / Pay ...)",
185
+ " are refused with CONFIRMATION_REQUIRED \u2014 ask the user to perform them.",
186
+ " Every subcommand prints the connector's raw JSON result; failures exit 1.",
187
+ " Endpoint: NOLO_CHROME_CONNECTOR_RPC_URL or http://127.0.0.1:38947/rpc."
188
+ ];
189
+ return lines.join("\n");
190
+ }
191
+ var CHROME_OPS_HELP_TEXT = renderChromeOpsHelp();
192
+ async function runChromeOpsCommand(subcommand, args, deps = {}) {
193
+ const io = {
194
+ stdout: (text) => console.log(text),
195
+ stderr: (text) => console.error(text),
196
+ ...deps.io
197
+ };
198
+ const spec = CHROME_OPS_SUBCOMMANDS[subcommand];
199
+ if (!spec) {
200
+ io.stderr(`Unknown chrome subcommand: ${subcommand}
201
+
202
+ ${CHROME_OPS_HELP_TEXT}`);
203
+ return 1;
204
+ }
205
+ if (wantsHelp(args)) {
206
+ io.stdout(CHROME_OPS_HELP_TEXT);
207
+ return 0;
208
+ }
209
+ let payload;
210
+ try {
211
+ payload = spec.payload(args, spec.usage);
212
+ } catch (error) {
213
+ io.stderr(toErrorMessage(error));
214
+ return 1;
215
+ }
216
+ let result;
217
+ try {
218
+ const client = deps.client ?? createChromeConnectorClient();
219
+ result = await client.request(spec.action, payload);
220
+ } catch (error) {
221
+ const code = typeof error?.code === "string" ? error.code : "CHROME_COMMAND_FAILED";
222
+ io.stderr(JSON.stringify({ ok: false, error: { code, message: toErrorMessage(error) } }, null, 2));
223
+ return 1;
224
+ }
225
+ if (subcommand === "screenshot") {
226
+ const out = readTrimmedOption(args, "--out");
227
+ const dataUrl = result?.dataUrl;
228
+ if (out && typeof dataUrl === "string") {
229
+ const base64 = dataUrl.includes(",") ? dataUrl.slice(dataUrl.indexOf(",") + 1) : dataUrl;
230
+ const bytes = Buffer.from(base64, "base64");
231
+ try {
232
+ await writeFile(out, bytes);
233
+ } catch (error) {
234
+ io.stderr(
235
+ JSON.stringify(
236
+ {
237
+ ok: false,
238
+ error: { code: "SCREENSHOT_WRITE_FAILED", message: toErrorMessage(error) }
239
+ },
240
+ null,
241
+ 2
242
+ )
243
+ );
244
+ return 1;
245
+ }
246
+ io.stdout(JSON.stringify({ ok: true, result: { savedTo: out, bytes: bytes.byteLength } }, null, 2));
247
+ return 0;
248
+ }
249
+ }
250
+ io.stdout(JSON.stringify({ ok: true, result }, null, 2));
251
+ return 0;
252
+ }
253
+ export {
254
+ CHROME_OPS_HELP_TEXT,
255
+ CHROME_OPS_SUBCOMMANDS,
256
+ renderChromeOpsHelp,
257
+ runChromeOpsCommand
258
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clearCliLocalRuntimePreparedAgentCache
3
- } from "./chunk-SV63E2UZ.js";
3
+ } from "./chunk-4SUTS5DI.js";
4
4
  import {
5
5
  getReadableCliDb
6
6
  } from "./chunk-RXX4GDIH.js";
@@ -12,7 +12,7 @@ import {
12
12
  resolveAgentRecordFromHybridStore,
13
13
  sanitizeAgentRecordForCliOutput,
14
14
  writeAgentRecord
15
- } from "./chunk-AUKZOZFG.js";
15
+ } from "./chunk-QA6YKM3H.js";
16
16
  import {
17
17
  resolveCliAgentKeyInput
18
18
  } from "./chunk-SPAQ4PVV.js";
@@ -5,6 +5,11 @@ import {
5
5
  refreshOpenAiCodexToken,
6
6
  xaiRefresh
7
7
  } from "./chunk-GBPZKFYK.js";
8
+ import {
9
+ createChromeConnectorClient,
10
+ createVerifiedChromeConnectorClient,
11
+ executeChromeConnectorTool
12
+ } from "./chunk-QCZX4FTW.js";
8
13
  import {
9
14
  defaultLoopbackRequest
10
15
  } from "./chunk-EADNWBAZ.js";
@@ -55,11 +60,12 @@ import {
55
60
  import {
56
61
  inlineImageUrlsForCustomProvider,
57
62
  prepareTools
58
- } from "./chunk-AOKRQAUQ.js";
63
+ } from "./chunk-ALGK6TIE.js";
59
64
  import {
60
65
  getServerProviderSecret
61
66
  } from "./chunk-HS7MLR74.js";
62
67
  import {
68
+ CHROME_CONNECTOR_TOOL_NAMES,
63
69
  CONTROL_AGENT_RUN_ACTIONS,
64
70
  buildControlAgentRunFunctionSchema,
65
71
  buildStartAgentRunFunctionSchema,
@@ -72,7 +78,7 @@ import {
72
78
  rememberMemoryFunctionSchema,
73
79
  resolveAgentRequiredPackIds,
74
80
  setTodoListFunc
75
- } from "./chunk-R5NCDOHB.js";
81
+ } from "./chunk-MEVSATIF.js";
76
82
  import {
77
83
  fetchWithTransientRetry,
78
84
  isTransientFetchError
@@ -95,13 +101,13 @@ import {
95
101
  prepareTokenUsageData,
96
102
  resolveBuiltinPlatformAgentConfig,
97
103
  runKeyed
98
- } from "./chunk-3LBE76GR.js";
104
+ } from "./chunk-D74EWXL4.js";
99
105
  import {
100
106
  BUILTIN_TITLE_LLM_CONFIG
101
107
  } from "./chunk-EVBFYPDC.js";
102
108
  import {
103
109
  fetchServerSyncedCredential
104
- } from "./chunk-RVCBKVIR.js";
110
+ } from "./chunk-QUH3XHL5.js";
105
111
  import {
106
112
  require_date_fns
107
113
  } from "./chunk-M76ECQRD.js";
@@ -153,7 +159,7 @@ import {
153
159
  resolveOpenAiCompatibleProviderConfig,
154
160
  shouldUseGeminiNativeToolRoute,
155
161
  summarizeToolArguments
156
- } from "./chunk-CJ23A7U4.js";
162
+ } from "./chunk-CUQ6PG2C.js";
157
163
  import {
158
164
  PlatformStreamInterruptedError,
159
165
  buildPlatformChatCompletionRequest,
@@ -165,7 +171,7 @@ import {
165
171
  readSseDataValues,
166
172
  resolvePlatformChatProviderConfig,
167
173
  shouldUsePlatformChatProvider
168
- } from "./chunk-HXAINXPQ.js";
174
+ } from "./chunk-QC5LGHYP.js";
169
175
  import {
170
176
  resolveAgentRuntimeConfigFromRecord,
171
177
  resolveHistoricalToolContentCap
@@ -1672,6 +1678,17 @@ var LOCAL_SERVER_MEMORY_TOOL_NAME_SET = new Set(
1672
1678
  );
1673
1679
 
1674
1680
  // packages/cli/client/localRuntimeTools.ts
1681
+ var CLI_CHROME_CONNECTOR_TOOL_NAME_SET = new Set(
1682
+ CHROME_CONNECTOR_TOOL_NAMES
1683
+ );
1684
+ function filterCliChromeConnectorToolNames(toolNames) {
1685
+ return (toolNames ?? []).filter(
1686
+ (name) => CLI_CHROME_CONNECTOR_TOOL_NAME_SET.has(name)
1687
+ );
1688
+ }
1689
+ function buildCliChromeConnectorOpenAiTools(args) {
1690
+ return prepareTools(filterCliChromeConnectorToolNames(args.toolNames));
1691
+ }
1675
1692
  function buildOpenAiTools(args) {
1676
1693
  const toolset = buildLocalWorkspaceToolsetForEnv(args);
1677
1694
  const workspaceToolNames = toolset.toolNames;
@@ -1719,6 +1736,7 @@ function buildOpenAiTools(args) {
1719
1736
  toolNames: args.effectiveToolNames ?? workspaceToolNames,
1720
1737
  exposeShellTools: toolset.exposeShellTools
1721
1738
  }),
1739
+ ...buildCliChromeConnectorOpenAiTools({ toolNames: args.toolNames }),
1722
1740
  ...buildServerPlatformOpenAiTools({ toolNames: args.toolNames }),
1723
1741
  ...buildNoloWorkspaceOpenAiTools({ toolNames: args.toolNames }),
1724
1742
  ...buildOrchestrationOpenAiTools({
@@ -2524,6 +2542,46 @@ async function detectCurrentMachineId(env) {
2524
2542
  }
2525
2543
 
2526
2544
  // packages/cli/client/cliProviderHelpers.ts
2545
+ var CYCLE_SCAN_NODE_BUDGET = 2e4;
2546
+ function keysForJson(value) {
2547
+ if (Array.isArray(value)) {
2548
+ const keys = [];
2549
+ for (let i = 0; i < value.length; i++) keys.push(String(i));
2550
+ return keys;
2551
+ }
2552
+ return Object.keys(value);
2553
+ }
2554
+ function hasJsonCycle(root) {
2555
+ if (typeof root !== "object" || root === null) return false;
2556
+ if (typeof root.toJSON === "function") return false;
2557
+ const onPath = /* @__PURE__ */ new Set([root]);
2558
+ const stack = [
2559
+ { holder: root, keys: keysForJson(root), index: 0 }
2560
+ ];
2561
+ let visited = 1;
2562
+ while (stack.length > 0) {
2563
+ const frame = stack[stack.length - 1];
2564
+ if (frame.index >= frame.keys.length) {
2565
+ onPath.delete(frame.holder);
2566
+ stack.pop();
2567
+ continue;
2568
+ }
2569
+ const key = frame.keys[frame.index++];
2570
+ let child;
2571
+ try {
2572
+ child = frame.holder[key];
2573
+ } catch {
2574
+ continue;
2575
+ }
2576
+ if (typeof child !== "object" || child === null) continue;
2577
+ if (typeof child.toJSON === "function") continue;
2578
+ if (onPath.has(child)) return true;
2579
+ if (++visited > CYCLE_SCAN_NODE_BUDGET) return false;
2580
+ onPath.add(child);
2581
+ stack.push({ holder: child, keys: keysForJson(child), index: 0 });
2582
+ }
2583
+ return false;
2584
+ }
2527
2585
  function buildDelegatedTaskContent(task, input) {
2528
2586
  if (input === void 0 || input === null) {
2529
2587
  return task;
@@ -2540,6 +2598,9 @@ ${input}`;
2540
2598
  }
2541
2599
  let jsonStr;
2542
2600
  try {
2601
+ if (hasJsonCycle(input)) {
2602
+ throw new TypeError("Converting circular structure to JSON");
2603
+ }
2543
2604
  const serialized = JSON.stringify(input, null, 2);
2544
2605
  if (serialized === void 0) {
2545
2606
  return task;
@@ -2564,6 +2625,9 @@ function calculateDelegatedPayloadMetrics(task, input, delegatedContent) {
2564
2625
  serializedInputForTokens = input;
2565
2626
  } else {
2566
2627
  try {
2628
+ if (hasJsonCycle(input)) {
2629
+ throw new TypeError("Converting circular structure to JSON");
2630
+ }
2567
2631
  const serialized = JSON.stringify(input, null, 2);
2568
2632
  if (serialized !== void 0) {
2569
2633
  inputChars = serialized.length;
@@ -11271,6 +11335,19 @@ function createCliControlAgentRunExecutor(deps = {}) {
11271
11335
  };
11272
11336
  }
11273
11337
 
11338
+ // packages/cli/client/cliChromeConnectorToolExecutors.ts
11339
+ function buildCliChromeConnectorToolExecutors(args) {
11340
+ const client = createVerifiedChromeConnectorClient({
11341
+ client: args?.client ?? createChromeConnectorClient()
11342
+ });
11343
+ return Object.fromEntries(
11344
+ CHROME_CONNECTOR_TOOL_NAMES.map((toolName) => [
11345
+ toolName,
11346
+ (call) => executeChromeConnectorTool({ client, call })
11347
+ ])
11348
+ );
11349
+ }
11350
+
11274
11351
  // packages/cli/client/cliLocalToolExecutors.ts
11275
11352
  var MAX_PASTED_TEXT_LINES_PER_READ = 200;
11276
11353
  var PASTED_TEXT_EXPLICIT_OVERSHOOT_LINES = 20;
@@ -11557,6 +11634,12 @@ function buildLocalToolExecutors(args) {
11557
11634
  };
11558
11635
  },
11559
11636
  ...args.pastedTextStore ? { readPastedText: createReadPastedTextExecutor(args.pastedTextStore) } : {},
11637
+ // Nolo Browser Connector: the CLI drives the user's real Chrome through the same verified
11638
+ // client + executor as the desktop runtime (before this, every chrome_* call answered
11639
+ // "only executable in the Nolo desktop local runtime").
11640
+ ...buildCliChromeConnectorToolExecutors(
11641
+ args.chromeConnectorClient ? { client: args.chromeConnectorClient } : {}
11642
+ ),
11560
11643
  ...args.localToolExecutors ?? {}
11561
11644
  };
11562
11645
  }
@@ -12389,6 +12472,7 @@ function createCliLocalRuntimeAdapter(deps) {
12389
12472
  workspaceRoot,
12390
12473
  env: deps.env,
12391
12474
  fetchImpl,
12475
+ ...deps.chromeConnectorClient ? { chromeConnectorClient: deps.chromeConnectorClient } : {},
12392
12476
  localToolExecutors: deps.localToolExecutors,
12393
12477
  readXPost: deps.readXPost,
12394
12478
  readXhsProfile: deps.readXhsProfile,
@@ -12465,6 +12549,7 @@ function createCliLocalRuntimeAdapter(deps) {
12465
12549
  workspaceRoot,
12466
12550
  env: deps.env,
12467
12551
  fetchImpl,
12552
+ ...deps.chromeConnectorClient ? { chromeConnectorClient: deps.chromeConnectorClient } : {},
12468
12553
  localToolExecutors: deps.localToolExecutors,
12469
12554
  readXPost: deps.readXPost,
12470
12555
  readXhsProfile: deps.readXhsProfile,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readDbRecord,
3
3
  writeAgentRecord
4
- } from "./chunk-AUKZOZFG.js";
4
+ } from "./chunk-QA6YKM3H.js";
5
5
  import {
6
6
  buildSkillSummaryMarker
7
7
  } from "./chunk-VF4K2QE6.js";
@@ -2,7 +2,7 @@ import {
2
2
  deleteDbRecord,
3
3
  queryUserRecords,
4
4
  readDbRecord
5
- } from "./chunk-AUKZOZFG.js";
5
+ } from "./chunk-QA6YKM3H.js";
6
6
  import {
7
7
  mergeAndDedupUserData
8
8
  } from "./chunk-KQHGZWSV.js";