nolo-cli 0.90.0-alpha.1 → 0.92.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/{_executeModel-W26HVI75.js → _executeModel-SKXPDRHT.js} +34 -34
  2. package/{action-6DXQGJMX.js → action-5DATYWOM.js} +6 -6
  3. package/{addContentAction-I7VX5SAC.js → addContentAction-5OLTVWIE.js} +4 -4
  4. package/{addDialogAgentAction-OJSFV7DZ.js → addDialogAgentAction-BRGMORV4.js} +3 -3
  5. package/{agentDeleteCommand-XNFWCKBH.js → agentDeleteCommand-KIJCEDIQ.js} +20 -20
  6. package/{agentEmailCommands-W3X3EJ3V.js → agentEmailCommands-KVJQBG6I.js} +42 -42
  7. package/{agentListCommands-DFWFU6XO.js → agentListCommands-S2WK34WE.js} +22 -22
  8. package/{agentMachineCommands-LMFOAEL4.js → agentMachineCommands-ESEVMWBG.js} +20 -20
  9. package/{agentProviderCommands-ZBYHGTGY.js → agentProviderCommands-I26OTLEQ.js} +1 -1
  10. package/{agentRecordCommands-FVVVCQFM.js → agentRecordCommands-TTYG2GYM.js} +41 -41
  11. package/{agentRunCommand-HTBVIBGV.js → agentRunCommand-PQ2D3MTU.js} +41 -41
  12. package/{agentRuntimeLocal-2JFG4HDU.js → agentRuntimeLocal-ZLZCZO3C.js} +17 -17
  13. package/{agentSlice-ZNLGFUB5.js → agentSlice-JF7MQKXG.js} +4 -4
  14. package/{appDeleteCommands-2UN4N2NR.js → appDeleteCommands-KHSC6H42.js} +21 -21
  15. package/{appDeployCommands-37D74KRR.js → appDeployCommands-KCCU76AG.js} +21 -21
  16. package/{appDeployStatusCommands-QBLWL2IA.js → appDeployStatusCommands-UBGX7463.js} +21 -21
  17. package/{appGetCommands-6KXIDF2T.js → appGetCommands-CGVGNM5J.js} +21 -21
  18. package/{appListCommands-G2WFGEWQ.js → appListCommands-JUVQUOGH.js} +21 -21
  19. package/{authCommand-V2DJ7DB7.js → authCommand-ETL233F2.js} +7 -7
  20. package/{builtinSkillRegistry-WBGYKIAZ.js → builtinSkillRegistry-PJU2R6ST.js} +4 -4
  21. package/{chatQueueReduxAdapter-XCJHIY3R.js → chatQueueReduxAdapter-NIJ6XFDN.js} +15 -15
  22. package/{chromeCommands-VOIRNJBL.js → chromeCommands-FZYAU75D.js} +1 -1
  23. package/{chromeOpsCommands-M7DPCX2T.js → chromeOpsCommands-62P2Q2YB.js} +31 -1
  24. package/{chunk-FQYMLZ6C.js → chunk-2D6QK26I.js} +4 -4
  25. package/{chunk-3CMTBX3X.js → chunk-2HBFQM4C.js} +3 -3
  26. package/{chunk-CLI4LFSM.js → chunk-2L3O7RDP.js} +1 -1
  27. package/{chunk-XMGHGEN6.js → chunk-2WHQZTB7.js} +1 -1
  28. package/{chunk-TL6L5XUT.js → chunk-3JIXYIXV.js} +83 -15
  29. package/{chunk-XKQJJK4F.js → chunk-3QC3NGWZ.js} +1 -1
  30. package/{chunk-5NMZNPTN.js → chunk-43WRG6QQ.js} +4 -4
  31. package/{chunk-3CR2LC6X.js → chunk-46TSVHGZ.js} +1 -1
  32. package/{chunk-ZAB3A45K.js → chunk-4B3TDK3S.js} +3 -3
  33. package/{chunk-4DRWWIOL.js → chunk-5LRIZC2W.js} +1 -1
  34. package/{chunk-DNQPPRHY.js → chunk-5NHGLCPL.js} +1 -1
  35. package/{chunk-PH5J5VUY.js → chunk-6R425QS6.js} +2 -2
  36. package/{chunk-NFMHIUY3.js → chunk-7GDFU22A.js} +19 -19
  37. package/{chunk-4BYPU626.js → chunk-BJ7HBUL2.js} +9 -9
  38. package/{chunk-2AYMFHUG.js → chunk-CDS4FQMP.js} +3 -3
  39. package/{chunk-WS22FPWT.js → chunk-DMFLXNFM.js} +1 -1
  40. package/{chunk-QHETQ3KI.js → chunk-EKXNV6EM.js} +2 -2
  41. package/{chunk-AQZRTHDZ.js → chunk-EONDQISD.js} +15 -15
  42. package/{chunk-N3OAPEZE.js → chunk-FEAPBZQW.js} +3 -3
  43. package/{chunk-XTUY5EL4.js → chunk-G3V74DVM.js} +3 -3
  44. package/{chunk-ZBT3WNBK.js → chunk-HNUNYXYB.js} +1 -1
  45. package/{chunk-ND2J3NRB.js → chunk-I2MX6JST.js} +2 -2
  46. package/{chunk-SMZSWB44.js → chunk-IMCXPAQV.js} +3 -3
  47. package/{chunk-YOXYA2GU.js → chunk-IP2RNQU3.js} +1 -0
  48. package/{chunk-WXPVOQD7.js → chunk-MOH3ETXO.js} +29 -29
  49. package/{chunk-HMEMJ7GH.js → chunk-NNJ4EAEH.js} +25 -22
  50. package/{chunk-5DFFKASO.js → chunk-NU2SOATM.js} +3 -3
  51. package/{chunk-6BEA566T.js → chunk-PIOIPOSY.js} +2 -2
  52. package/{chunk-2F4VYGFW.js → chunk-PNBZBDRM.js} +4 -3
  53. package/{chunk-ASGDO77C.js → chunk-Q67DOFOO.js} +92 -4
  54. package/{chunk-VRLI2WNW.js → chunk-QTV7ZYBE.js} +11 -7
  55. package/{chunk-VHJLQHPQ.js → chunk-RAYTIPJ5.js} +2 -2
  56. package/{chunk-576IMUGH.js → chunk-S46FYEWL.js} +1 -1
  57. package/{chunk-3R5PH4IP.js → chunk-S6SP3GWJ.js} +1 -1
  58. package/{chunk-JTK3TJYV.js → chunk-SATOEEL6.js} +1 -1
  59. package/{chunk-QCZX4FTW.js → chunk-SH43IESU.js} +173 -15
  60. package/{chunk-RZANZZL2.js → chunk-T67757YH.js} +1 -1
  61. package/{chunk-A2C4AKKM.js → chunk-TLO2X5C6.js} +1 -1
  62. package/{chunk-HYZHJ5GW.js → chunk-TLPTMSX3.js} +3 -3
  63. package/{chunk-GRYGRGPS.js → chunk-TSD5BVVP.js} +129 -4
  64. package/{chunk-DPQ2WVBY.js → chunk-TUEPUNFO.js} +1 -1
  65. package/{chunk-UTCCPWB2.js → chunk-TZB6Y4OD.js} +2 -2
  66. package/{chunk-Z33ARZCP.js → chunk-U7HSBX3I.js} +1 -1
  67. package/{chunk-L2ICPOAL.js → chunk-UT5NALV3.js} +1 -1
  68. package/{chunk-K7M3MWCE.js → chunk-UYJKSCJ4.js} +2 -2
  69. package/{chunk-2ADBVBEM.js → chunk-VUHXTHIK.js} +2 -2
  70. package/{chunk-F2CGG72C.js → chunk-W6MEYAGX.js} +4 -4
  71. package/{chunk-TVNI5FLG.js → chunk-YC2MP5NP.js} +4 -4
  72. package/{chunk-IIKPWSPX.js → chunk-YDEMAQEY.js} +1 -1
  73. package/{chunk-7MYYE7WX.js → chunk-YNI45YOE.js} +12 -12
  74. package/{chunk-UA5S3LQQ.js → chunk-YNNVVLMV.js} +3 -3
  75. package/{chunk-JBBZ5KUM.js → chunk-YQPWX5EE.js} +9 -9
  76. package/{chunk-5V4NJHRM.js → chunk-ZIK2FIX4.js} +5 -5
  77. package/{chunk-MJHQ3NRV.js → chunk-ZKYHTHNE.js} +1 -1
  78. package/{contentThunks-VURN3DFW.js → contentThunks-N7MGBLZJ.js} +16 -16
  79. package/{createAgentAutomationAction-QZAAY77R.js → createAgentAutomationAction-DNOR2HPB.js} +16 -16
  80. package/{createDialogAction-CHGXVTAC.js → createDialogAction-Y5CTGDHJ.js} +18 -18
  81. package/{createPageAction-IOGAFIN7.js → createPageAction-HIQCWUNG.js} +16 -16
  82. package/{dbSlice-YXQ6RYIH.js → dbSlice-NP52Y5TF.js} +3 -3
  83. package/{dialogCommands-XREAP6WQ.js → dialogCommands-RDCQ2IFS.js} +23 -21
  84. package/{dialogSlice-DOPGWGS4.js → dialogSlice-CCADNU4F.js} +15 -15
  85. package/{docCreateCommands-3PYZGSCL.js → docCreateCommands-7BQO7QFJ.js} +20 -20
  86. package/{docDeleteCommands-3Y6MU44Q.js → docDeleteCommands-AXWDDTVX.js} +21 -21
  87. package/{docReadCommands-UBANMAFR.js → docReadCommands-NMDWZKZW.js} +20 -20
  88. package/{docStore-SYYFBENY.js → docStore-RSIMI5PS.js} +4 -4
  89. package/{docUpdateCommands-4GK2X6BN.js → docUpdateCommands-KFIRA6WM.js} +20 -20
  90. package/{getPricing-F2C65RIX.js → getPricing-SLZYHJXY.js} +3 -3
  91. package/{handleSendMessageAction-NPVTY2GE.js → handleSendMessageAction-ZIABBL3A.js} +15 -15
  92. package/index.js +63 -54
  93. package/{machineCommands-I66X2XB7.js → machineCommands-H6TGKZYD.js} +40 -40
  94. package/{machineWsRunDispatch-W4FVBOUM.js → machineWsRunDispatch-YU4MGUB5.js} +40 -40
  95. package/{memberThunks-5T4J6KXQ.js → memberThunks-XJFHFZ5M.js} +4 -4
  96. package/{models-WW7VFNXB.js → models-WYXEJZAX.js} +2 -2
  97. package/package.json +1 -1
  98. package/{providerPresetApply-OCWWKBSD.js → providerPresetApply-RWISXOW7.js} +6 -6
  99. package/{providerRegistry-ZJQU7AJ7.js → providerRegistry-5KY7YV6K.js} +6 -6
  100. package/{read-M2Q6WEKB.js → read-KFAALANF.js} +2 -2
  101. package/{readDocTool-T37P3YPB.js → readDocTool-XNMCT64I.js} +1 -1
  102. package/{readlineWorkspace-VY5AMOGR.js → readlineWorkspace-JTU5LTZI.js} +44 -44
  103. package/{removeDialogAgentAction-HB3JBVAI.js → removeDialogAgentAction-X3IS7JNU.js} +6 -6
  104. package/{runAgentClientLoop-3NDADLVE.js → runAgentClientLoop-5TPQBYB6.js} +32 -32
  105. package/{setDialogExtraReferencesAction-4XLHRV37.js → setDialogExtraReferencesAction-QTV3ZJNH.js} +4 -4
  106. package/{setPrimaryDialogAgentAction-C3JOFC4W.js → setPrimaryDialogAgentAction-EUUISNQ2.js} +6 -6
  107. package/{settingSlice-CZRURSTH.js → settingSlice-UMATY3PD.js} +5 -5
  108. package/{spaceCommands-ENYCUUZH.js → spaceCommands-PR6QHSEG.js} +20 -20
  109. package/{streamAgentChatTurn-634OFUSR.js → streamAgentChatTurn-TXMNTXML.js} +36 -36
  110. package/{switchDialogAgentAction-C6KVUKJP.js → switchDialogAgentAction-HWFDQNY5.js} +3 -3
  111. package/{tools-ILBLCF7D.js → tools-GEVUKUVY.js} +29 -29
  112. package/{tuiSummaryLlmCaller-LFUBZKXK.js → tuiSummaryLlmCaller-PKZYGY3B.js} +10 -10
  113. package/{updateDialogTitleAction-RKFET73N.js → updateDialogTitleAction-MFR3UGL5.js} +16 -16
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  fetchReferenceContents,
3
3
  resolveReferenceAssets
4
- } from "./chunk-7MYYE7WX.js";
4
+ } from "./chunk-YNI45YOE.js";
5
5
 
6
6
  // packages/ai/agent/fetchAgentContexts.ts
7
7
  async function fetchAgentContexts(references, dispatch) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  requireTokenUser
3
- } from "./chunk-XKQJJK4F.js";
3
+ } from "./chunk-3QC3NGWZ.js";
4
4
  import {
5
5
  resolveServerUrl
6
6
  } from "./chunk-A7GB5UGH.js";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  patch,
9
9
  selectById
10
- } from "./chunk-UA5S3LQQ.js";
10
+ } from "./chunk-YNNVVLMV.js";
11
11
  import {
12
12
  __toESM
13
13
  } from "./chunk-4VNS5WPM.js";
@@ -6,19 +6,146 @@ import {
6
6
  } from "./chunk-KUG52IAP.js";
7
7
 
8
8
  // packages/desktop-chrome-connector/chromeConnector.ts
9
- import { existsSync, readFileSync } from "node:fs";
10
- import { resolve } from "node:path";
9
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
10
+ import { resolve as resolve2 } from "node:path";
11
+
12
+ // packages/desktop-chrome-connector/uploadSecurity.mjs
13
+ import { existsSync, realpathSync, statSync } from "node:fs";
14
+ import { isAbsolute, relative, resolve } from "node:path";
15
+ var DEFAULT_MAX_FILE_BYTES = 25 * 1024 * 1024;
16
+ var DEFAULT_MAX_FILES = 10;
17
+ var UploadSecurityError = class extends Error {
18
+ constructor(code, message) {
19
+ super(message);
20
+ this.name = "UploadSecurityError";
21
+ this.code = code;
22
+ }
23
+ };
24
+ function createUploadSecurityError(code, message) {
25
+ return new UploadSecurityError(code, message);
26
+ }
27
+ function isSubpath(parent, child) {
28
+ const rel = relative(parent, child);
29
+ return !rel.startsWith("..") && !isAbsolute(rel);
30
+ }
31
+ function parseAllowedRoots(env = process.env) {
32
+ const raw = env?.NOLO_CHROME_UPLOAD_ROOTS;
33
+ if (!raw || typeof raw !== "string") {
34
+ return [];
35
+ }
36
+ return raw.split(",").map((entry) => entry.trim()).filter(Boolean).filter((entry) => isAbsolute(entry)).map((entry) => {
37
+ const resolved = resolve(entry);
38
+ if (existsSync(resolved)) {
39
+ try {
40
+ return realpathSync(resolved);
41
+ } catch {
42
+ return resolved;
43
+ }
44
+ }
45
+ return resolved;
46
+ });
47
+ }
48
+ function validateUploadFiles(options = {}) {
49
+ const {
50
+ files,
51
+ env = process.env,
52
+ maxFiles = DEFAULT_MAX_FILES,
53
+ maxFileBytes = DEFAULT_MAX_FILE_BYTES
54
+ } = options;
55
+ if (!Array.isArray(files) || files.length === 0) {
56
+ throw createUploadSecurityError("no_files", "Provide at least one file to upload.");
57
+ }
58
+ if (files.length > maxFiles) {
59
+ throw createUploadSecurityError(
60
+ "too_many_files",
61
+ `Too many files: ${files.length} provided, maximum allowed is ${maxFiles}.`
62
+ );
63
+ }
64
+ const allowedRoots = parseAllowedRoots(env);
65
+ if (allowedRoots.length === 0) {
66
+ throw createUploadSecurityError(
67
+ "path_not_allowed",
68
+ "Upload roots not configured in NOLO_CHROME_UPLOAD_ROOTS; all uploads are refused."
69
+ );
70
+ }
71
+ const fileStats = [];
72
+ const canonicalFiles = [];
73
+ let totalBytes = 0;
74
+ for (const rawFile of files) {
75
+ if (typeof rawFile !== "string" || !rawFile.trim()) {
76
+ throw createUploadSecurityError("path_not_allowed", "File path must be a non-empty string.");
77
+ }
78
+ const trimmed = rawFile.trim();
79
+ const resolvedCandidate = resolve(trimmed);
80
+ if (!existsSync(resolvedCandidate)) {
81
+ throw createUploadSecurityError("path_not_allowed", `File not found or inaccessible: ${rawFile}`);
82
+ }
83
+ let real;
84
+ try {
85
+ real = realpathSync(resolvedCandidate);
86
+ } catch {
87
+ throw createUploadSecurityError("path_not_allowed", `Could not resolve canonical path for: ${rawFile}`);
88
+ }
89
+ let st;
90
+ try {
91
+ st = statSync(real);
92
+ } catch {
93
+ throw createUploadSecurityError("path_not_allowed", `Could not stat file: ${rawFile}`);
94
+ }
95
+ if (!st.isFile()) {
96
+ throw createUploadSecurityError("path_not_allowed", `Target path is not a regular file: ${rawFile}`);
97
+ }
98
+ if (st.size > maxFileBytes) {
99
+ throw createUploadSecurityError(
100
+ "too_large",
101
+ `File size ${st.size} bytes exceeds maximum allowed limit of ${maxFileBytes} bytes: ${rawFile}`
102
+ );
103
+ }
104
+ const realInside = allowedRoots.some((root) => isSubpath(root, real));
105
+ if (!realInside) {
106
+ throw createUploadSecurityError(
107
+ "path_not_allowed",
108
+ `Path '${rawFile}' (resolved: '${real}') is not within allowed upload roots.`
109
+ );
110
+ }
111
+ canonicalFiles.push(real);
112
+ fileStats.push({ path: real, bytes: st.size });
113
+ totalBytes += st.size;
114
+ }
115
+ return {
116
+ ok: true,
117
+ files: canonicalFiles,
118
+ fileStats,
119
+ totalBytes
120
+ };
121
+ }
122
+ function formatUploadAuditLog(entry = {}) {
123
+ const ts = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
124
+ const safeTabId = String(entry.tabId ?? "").replace(/[\x00-\x1f\x7f-\x9f]+/g, " ");
125
+ const safeTarget = String(entry.target ?? "").replace(/[\x00-\x1f\x7f-\x9f]+/g, " ");
126
+ const files = Array.isArray(entry.files) ? entry.files : [];
127
+ const totalBytes = files.reduce((sum, f) => sum + (Number(f.bytes) || 0), 0);
128
+ const fileDetails = files.map((f) => `${String(f.path || "").replace(/[\x00-\x1f\x7f-\x9f]+/g, " ")}(${f.bytes || 0}B)`).join(", ");
129
+ return `[chrome-upload] ${ts} tabId=${safeTabId} target=${safeTarget} files=[${fileDetails}] totalBytes=${totalBytes}`;
130
+ }
131
+ function logUploadAudit(entry, logFn = console.warn) {
132
+ const line = formatUploadAuditLog(entry);
133
+ logFn(line);
134
+ return line;
135
+ }
136
+
137
+ // packages/desktop-chrome-connector/chromeConnector.ts
11
138
  var NOLO_CHROME_CONNECTOR_EXTENSION_ID = "ahpdoopadkamnglhlacfjdfnonpjdplg";
12
139
  var NOLO_CHROME_CONNECTOR_PROTOCOL_VERSION = "2";
13
140
  function defaultTokenPath() {
14
- return resolve(
141
+ return resolve2(
15
142
  process.env.HOME || "",
16
143
  "Library/Application Support/Nolo/ChromeConnector/token"
17
144
  );
18
145
  }
19
146
  function readConnectorToken(tokenPath = defaultTokenPath()) {
20
147
  if (process.env.NOLO_CHROME_CONNECTOR_TOKEN) return process.env.NOLO_CHROME_CONNECTOR_TOKEN;
21
- if (!existsSync(tokenPath)) return "";
148
+ if (!existsSync2(tokenPath)) return "";
22
149
  return readFileSync(tokenPath, "utf8").trim();
23
150
  }
24
151
  var CHROME_TOOL_ACTIONS = {
@@ -32,7 +159,10 @@ var CHROME_TOOL_ACTIONS = {
32
159
  chrome_scroll: "scroll",
33
160
  chrome_screenshot: "screenshot",
34
161
  chrome_read_console: "read_console",
35
- chrome_read_network: "read_network"
162
+ chrome_read_network: "read_network",
163
+ chrome_set_files: "set_files",
164
+ chrome_upload_file: "set_files",
165
+ chrome_upload: "set_files"
36
166
  };
37
167
  function createConnectorError(code, message, details) {
38
168
  const error = new Error(message);
@@ -59,8 +189,8 @@ function errorPayload(error) {
59
189
  ...error?.details !== void 0 ? { details: error.details } : {}
60
190
  };
61
191
  }
62
- var TARGET_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["click", "type"]);
63
- var TAB_ID_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["close_tab", "detach"]);
192
+ var TARGET_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["click", "type", "set_files"]);
193
+ var TAB_ID_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["close_tab", "detach", "set_files"]);
64
194
  function validateChromeConnectorPayload(action, payload) {
65
195
  if (TAB_ID_REQUIRED_ACTIONS.has(action)) {
66
196
  const raw = payload.tabId;
@@ -71,16 +201,42 @@ function validateChromeConnectorPayload(action, payload) {
71
201
  `Provide the tabId from chrome_list_tabs before calling ${action}.`
72
202
  );
73
203
  }
74
- return;
204
+ if (!TARGET_REQUIRED_ACTIONS.has(action)) return;
75
205
  }
76
206
  if (!TARGET_REQUIRED_ACTIONS.has(action)) return;
77
- const elementRef = typeof payload.elementRef === "string" ? payload.elementRef.trim() : "";
207
+ const rawRef = typeof payload.elementRef === "string" ? payload.elementRef : typeof payload.ref === "string" ? payload.ref : "";
208
+ const elementRef = rawRef.trim();
78
209
  const selector = typeof payload.selector === "string" ? payload.selector.trim() : "";
79
- if (elementRef || selector) return;
80
- throw createConnectorError(
81
- "ELEMENT_TARGET_REQUIRED",
82
- "Provide elementRef from chrome_read_page or a CSS selector."
83
- );
210
+ if (!elementRef && !selector) {
211
+ throw createConnectorError(
212
+ "ELEMENT_TARGET_REQUIRED",
213
+ "Provide elementRef from chrome_read_page or a CSS selector."
214
+ );
215
+ }
216
+ if (action === "set_files") {
217
+ if (!Array.isArray(payload.files) || payload.files.length === 0) {
218
+ throw createConnectorError(
219
+ "no_files",
220
+ "Provide at least one file path in files array."
221
+ );
222
+ }
223
+ try {
224
+ const validated = validateUploadFiles({
225
+ files: payload.files,
226
+ env: process.env
227
+ });
228
+ payload.files = validated.files;
229
+ const targetStr = elementRef ? `ref:${elementRef}` : `selector:${selector}`;
230
+ logUploadAudit({
231
+ tabId: String(payload.tabId),
232
+ target: targetStr,
233
+ files: validated.fileStats
234
+ });
235
+ } catch (err) {
236
+ const code = err?.code ?? "path_not_allowed";
237
+ throw createConnectorError(code, toErrorMessage(err));
238
+ }
239
+ }
84
240
  }
85
241
  function createChromeConnectorClient(args) {
86
242
  if (args?.request) return { request: args.request };
@@ -90,6 +246,7 @@ function createChromeConnectorClient(args) {
90
246
  const token = args?.token ?? readConnectorToken(args?.tokenPath);
91
247
  return {
92
248
  async request(action, payload) {
249
+ validateChromeConnectorPayload(action, payload);
93
250
  let response;
94
251
  try {
95
252
  response = await fetchImpl(endpoint, {
@@ -131,7 +288,8 @@ var REQUIRED_CHROME_CONNECTOR_FEATURES = {
131
288
  screenshot: ["browser_debug"],
132
289
  read_console: ["browser_debug"],
133
290
  read_network: ["browser_debug"],
134
- detach: ["browser_debug"]
291
+ detach: ["browser_debug"],
292
+ set_files: ["compact_observation_v2", "file_upload"]
135
293
  };
136
294
  function requiredFeaturesForConnectorAction(action) {
137
295
  return [...REQUIRED_CHROME_CONNECTOR_FEATURES[action] ?? []];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BUILTIN_NOLO_AGENT_KEY
3
- } from "./chunk-TL6L5XUT.js";
3
+ } from "./chunk-3JIXYIXV.js";
4
4
 
5
5
  // packages/ai/tools/agentCapabilities.ts
6
6
  var SYSTEM_AGENT_CAPABILITIES = [
@@ -2,7 +2,7 @@ import {
2
2
  deleteDbRecord,
3
3
  queryUserRecords,
4
4
  readDbRecord
5
- } from "./chunk-UTCCPWB2.js";
5
+ } from "./chunk-TZB6Y4OD.js";
6
6
  import {
7
7
  mergeAndDedupUserData
8
8
  } from "./chunk-KQHGZWSV.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  toolRegistry
3
- } from "./chunk-WXPVOQD7.js";
3
+ } from "./chunk-MOH3ETXO.js";
4
4
  import {
5
5
  i18n_default
6
- } from "./chunk-HMEMJ7GH.js";
6
+ } from "./chunk-NNJ4EAEH.js";
7
7
  import {
8
8
  canonicalizeToolNames
9
9
  } from "./chunk-O6OSWFZQ.js";
10
10
  import {
11
11
  isNoloHostedProvider
12
- } from "./chunk-ASGDO77C.js";
12
+ } from "./chunk-Q67DOFOO.js";
13
13
  import {
14
14
  asTrimmedLowercaseString
15
15
  } from "./chunk-QSJ3HFEF.js";
@@ -7,7 +7,7 @@ import {
7
7
  listUserRecordsFromServers,
8
8
  readDbRecordFromServers,
9
9
  readLiveDbRecordAfterTombstoneMerge
10
- } from "./chunk-A2C4AKKM.js";
10
+ } from "./chunk-TLO2X5C6.js";
11
11
  import {
12
12
  fetchWithTransientRetry
13
13
  } from "./chunk-5UTFL4QJ.js";
@@ -30,7 +30,7 @@ import {
30
30
  boundSummaryText,
31
31
  buildDialogReadEnvelope,
32
32
  projectDialogReadForAgent
33
- } from "./chunk-YOXYA2GU.js";
33
+ } from "./chunk-IP2RNQU3.js";
34
34
  import {
35
35
  toErrorMessage
36
36
  } from "./chunk-HNMXYYJR.js";
@@ -210,7 +210,8 @@ var VALUE_FLAGS = /* @__PURE__ */ new Set([
210
210
  "--token",
211
211
  "--machine-key",
212
212
  "--user",
213
- "--max-response-chars"
213
+ "--max-response-chars",
214
+ "--per-dialog"
214
215
  ]);
215
216
  function hasFlag(args, flag) {
216
217
  return args.includes(flag);
@@ -1820,6 +1821,129 @@ async function runDialogDeleteCommand(args, deps = {}) {
1820
1821
  }
1821
1822
  return hasErrors ? 1 : 0;
1822
1823
  }
1824
+ function printSearchUsage(output) {
1825
+ output.write(`Usage:
1826
+ nolo dialog search <query> [--limit <n>] [--per-dialog <n>] [--json]
1827
+
1828
+ Options:
1829
+ --limit <n> Max dialogs to return (default 20, max 50).
1830
+ --per-dialog <n> Max match snippets per dialog (default 3, max 10).
1831
+ --json Print machine-readable JSON.
1832
+ --server <url> Override NOLO_SERVER/BASE_URL.
1833
+ --token <jwt> Override AUTH_TOKEN.
1834
+
1835
+ Searches messages across the current user's dialogs via the server endpoint.
1836
+ Server requires NOLO_DIALOG_SEARCH=1 to be enabled.
1837
+ `);
1838
+ }
1839
+ async function runDialogSearchCommand(args, deps = {}) {
1840
+ const env = deps.env ?? process.env;
1841
+ const output = deps.output ?? process.stdout;
1842
+ if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
1843
+ printSearchUsage(output);
1844
+ return 0;
1845
+ }
1846
+ const query = readFirstPositional(args);
1847
+ if (!query) {
1848
+ output.write("[nolo] dialog search requires a search query.\n\n");
1849
+ printSearchUsage(output);
1850
+ return 1;
1851
+ }
1852
+ const authToken = resolveAuthToken(args, env);
1853
+ if (!authToken) {
1854
+ output.write("[nolo] dialog search requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
1855
+ return 1;
1856
+ }
1857
+ const fetchImpl = deps.fetchImpl ?? fetch;
1858
+ const serverUrl = resolveServerUrl(args, env);
1859
+ const serverUrls = resolveServerCandidates(args, env, serverUrl);
1860
+ const limitRaw = readOption(args, "--limit");
1861
+ const perDialogRaw = readOption(args, "--per-dialog");
1862
+ const queryParams = new URLSearchParams({ q: query });
1863
+ if (limitRaw) queryParams.set("limit", limitRaw);
1864
+ if (perDialogRaw) queryParams.set("perDialog", perDialogRaw);
1865
+ const isJson = hasFlag(args, "--json");
1866
+ let lastError = null;
1867
+ let lastStatus = null;
1868
+ let searchResult = null;
1869
+ for (const candidateBase of serverUrls) {
1870
+ const trimmedBase = candidateBase.replace(/\/+$/, "");
1871
+ const targetUrl = `${trimmedBase}/api/dialog-search?${queryParams.toString()}`;
1872
+ try {
1873
+ const res = await fetchImpl(targetUrl, {
1874
+ method: "GET",
1875
+ headers: {
1876
+ Authorization: `Bearer ${authToken}`
1877
+ }
1878
+ });
1879
+ lastStatus = res.status;
1880
+ if (!res.ok) {
1881
+ const errorData = await res.json().catch(() => ({}));
1882
+ if (res.status === 403) {
1883
+ const hint = errorData?.hint ? ` (${errorData.hint})` : "";
1884
+ const msg = errorData?.message ? `: ${errorData.message}` : "";
1885
+ throw new Error(`Server returned 403 Forbidden${hint}${msg}. Please ensure NOLO_DIALOG_SEARCH=1 is enabled on the server.`);
1886
+ }
1887
+ if (res.status === 401) {
1888
+ throw new Error(`Server returned 401 Unauthorized. Please check your AUTH_TOKEN.`);
1889
+ }
1890
+ throw new Error(`HTTP ${res.status}: ${JSON.stringify(errorData)}`);
1891
+ }
1892
+ searchResult = await res.json();
1893
+ break;
1894
+ } catch (err) {
1895
+ lastError = err;
1896
+ }
1897
+ }
1898
+ if (!searchResult) {
1899
+ const errorMsg = lastError ? toErrorMessage(lastError) : "Failed to connect to candidate servers";
1900
+ if (isJson) {
1901
+ output.write(JSON.stringify({ error: errorMsg, status: lastStatus }, null, 2) + "\n");
1902
+ } else {
1903
+ output.write(`[nolo] dialog search failed: ${errorMsg}
1904
+ `);
1905
+ }
1906
+ return 1;
1907
+ }
1908
+ if (isJson) {
1909
+ output.write(JSON.stringify(searchResult, null, 2) + "\n");
1910
+ return 0;
1911
+ }
1912
+ const { dialogs, totalMatches, scannedDialogs, scannedMessages, elapsedMs, truncated } = searchResult;
1913
+ output.write(`query: ${query}
1914
+ `);
1915
+ output.write(`scanned: ${scannedDialogs} dialogs, ${scannedMessages} messages (${elapsedMs}ms)
1916
+ `);
1917
+ output.write(`matches: ${totalMatches} total match(es) across ${dialogs?.length ?? 0} dialog(s)`);
1918
+ if (truncated) {
1919
+ output.write(" [truncated]");
1920
+ }
1921
+ output.write("\n");
1922
+ if (!Array.isArray(dialogs) || dialogs.length === 0) {
1923
+ output.write("\nNo matching dialog messages found.\n");
1924
+ return 0;
1925
+ }
1926
+ for (const d of dialogs) {
1927
+ output.write(`
1928
+ ${d.title}
1929
+ `);
1930
+ output.write(`id=${d.dialogId}
1931
+ `);
1932
+ output.write(`updatedAt=${d.updatedAt ?? "-"}
1933
+ `);
1934
+ output.write(`matches=${d.matchCount}
1935
+ `);
1936
+ if (Array.isArray(d.matches) && d.matches.length > 0) {
1937
+ for (const m of d.matches) {
1938
+ const role = m.role ? `[${m.role}]` : "";
1939
+ const snippet = String(m.snippet ?? "").replace(/\r?\n/g, " ");
1940
+ output.write(` - ${role} ${snippet}
1941
+ `);
1942
+ }
1943
+ }
1944
+ }
1945
+ return 0;
1946
+ }
1823
1947
 
1824
1948
  export {
1825
1949
  normalizeDialogRecord,
@@ -1832,5 +1956,6 @@ export {
1832
1956
  runDialogStatusCommand,
1833
1957
  runDialogQueryCommand,
1834
1958
  runDialogListCommand,
1835
- runDialogDeleteCommand
1959
+ runDialogDeleteCommand,
1960
+ runDialogSearchCommand
1836
1961
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_AGENT_BASE_POLICY,
3
3
  DEFAULT_USER_PREFERENCE_PROFILE
4
- } from "./chunk-PH5J5VUY.js";
4
+ } from "./chunk-6R425QS6.js";
5
5
 
6
6
  // packages/ai/policy/runtimePolicy.ts
7
7
  var clampLevel = (value, fallback) => {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  buildLocalAgentLookupKeys,
3
3
  shouldReadAgentKeyRemotely
4
- } from "./chunk-IIKPWSPX.js";
4
+ } from "./chunk-YDEMAQEY.js";
5
5
  import {
6
6
  resolveCliAgentKeyInput
7
7
  } from "./chunk-SAFZABH7.js";
@@ -507,7 +507,7 @@ async function buildCreatedAgentRecord(args) {
507
507
  const resolvedAgentInput = resolveCliAgentKeyInput(args.parsed.agentInput);
508
508
  const agentKey = resolvedAgentInput.startsWith("agent-") ? resolvedAgentInput : createAgentKey.private(userId || "local", resolvedAgentInput);
509
509
  if (args.parsed.presetId) {
510
- const { resolveProviderPresetFields } = await import("./providerPresetApply-OCWWKBSD.js");
510
+ const { resolveProviderPresetFields } = await import("./providerPresetApply-RWISXOW7.js");
511
511
  const fields = resolveProviderPresetFields(args.parsed.presetId);
512
512
  if (fields.kind === "manual") {
513
513
  throw new Error(
@@ -11,7 +11,7 @@ import {
11
11
  getAntigravityUserAgent,
12
12
  normalizeAntigravityTokenPayload,
13
13
  refreshAntigravityToken
14
- } from "./chunk-MJHQ3NRV.js";
14
+ } from "./chunk-ZKYHTHNE.js";
15
15
  import {
16
16
  writeOAuthCredential
17
17
  } from "./chunk-ONXOABJR.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BUILTIN_PLATFORM_AGENT_KEYS
3
- } from "./chunk-TL6L5XUT.js";
3
+ } from "./chunk-3JIXYIXV.js";
4
4
  import {
5
5
  getRuntimeServerContext,
6
6
  partitionReadServers,
@@ -3,7 +3,7 @@ import {
3
3
  resolvePlatformChatCompletionsEndpoint,
4
4
  resolvePlatformHostedCredentialProvider,
5
5
  resolvePlatformResponsesEndpoint
6
- } from "./chunk-ND2J3NRB.js";
6
+ } from "./chunk-I2MX6JST.js";
7
7
  import {
8
8
  CLI_PROVIDER_VALUES
9
9
  } from "./chunk-W7XHHYWM.js";
@@ -11,7 +11,7 @@ import {
11
11
  CLIENT_VERSION_TOO_OLD_CODE,
12
12
  buildClientVersionGateErrorDetail,
13
13
  evaluatePlatformHostedClientVersionGate
14
- } from "./chunk-ASGDO77C.js";
14
+ } from "./chunk-Q67DOFOO.js";
15
15
  import {
16
16
  asTrimmedLowercaseString
17
17
  } from "./chunk-QSJ3HFEF.js";
@@ -6,7 +6,7 @@ import {
6
6
  buildBuiltinObjectSkillDbKey,
7
7
  buildBuiltinObjectSkillPageContent,
8
8
  buildCodeWorkDiscipline
9
- } from "./chunk-CLI4LFSM.js";
9
+ } from "./chunk-2L3O7RDP.js";
10
10
  import {
11
11
  buildSkillDocMarkdown,
12
12
  resolvePageSkillMetadata
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-O6OSWFZQ.js";
17
17
  import {
18
18
  nolotusId
19
- } from "./chunk-RZANZZL2.js";
19
+ } from "./chunk-T67757YH.js";
20
20
  import {
21
21
  asNonEmptyStringArray
22
22
  } from "./chunk-VMFTFOWF.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  normalizeTimingMs
3
- } from "./chunk-VHJLQHPQ.js";
3
+ } from "./chunk-RAYTIPJ5.js";
4
4
  import {
5
5
  MODEL_LOOKUP_MAP
6
- } from "./chunk-VRLI2WNW.js";
6
+ } from "./chunk-QTV7ZYBE.js";
7
7
  import {
8
8
  ALL_MODELS
9
- } from "./chunk-WS22FPWT.js";
9
+ } from "./chunk-DMFLXNFM.js";
10
10
  import {
11
11
  asTrimmedNonEmptyStringArray
12
12
  } from "./chunk-VMFTFOWF.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-WWC7I6TA.js";
16
16
  import {
17
17
  BUILTIN_NOLO_AGENT_KEY
18
- } from "./chunk-TL6L5XUT.js";
18
+ } from "./chunk-3JIXYIXV.js";
19
19
  import {
20
20
  asOptionalTrimmedString
21
21
  } from "./chunk-G3SUCT4W.js";
@@ -11,7 +11,7 @@ import {
11
11
  patch,
12
12
  remove,
13
13
  write
14
- } from "./chunk-UA5S3LQQ.js";
14
+ } from "./chunk-YNNVVLMV.js";
15
15
  import {
16
16
  createAgentKey,
17
17
  toTrimmedString
@@ -304,7 +304,7 @@ var slice = createSliceWithThunks({
304
304
  const overrides = {};
305
305
  if (args.systemPromptOverride !== void 0) overrides.prompt = args.systemPromptOverride;
306
306
  if (args.toolsOverride !== void 0) overrides.tools = args.toolsOverride;
307
- const { _executeModel } = await import("./_executeModel-W26HVI75.js");
307
+ const { _executeModel } = await import("./_executeModel-SKXPDRHT.js");
308
308
  return _executeModel(
309
309
  {
310
310
  isStreaming: args.isStreaming ?? false,
@@ -325,7 +325,7 @@ var slice = createSliceWithThunks({
325
325
  * - 循环直到无工具调用或触发其他运行时停止条件
326
326
  */
327
327
  runAgent: create.asyncThunk(async (args, thunkApi) => {
328
- const { runAgentClientLoop } = await import("./runAgentClientLoop-3NDADLVE.js");
328
+ const { runAgentClientLoop } = await import("./runAgentClientLoop-5TPQBYB6.js");
329
329
  const { content: loopContent, toolCallCount } = await runAgentClientLoop(
330
330
  {
331
331
  agentKey: args.agentKey,
@@ -341,7 +341,7 @@ var slice = createSliceWithThunks({
341
341
  * 聊天轮次流式 Agent 调用
342
342
  */
343
343
  streamAgentChatTurn: create.asyncThunk(async (args, thunkApi) => {
344
- const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-634OFUSR.js");
344
+ const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-TXMNTXML.js");
345
345
  return streamAgentChatTurnHandler(args, thunkApi);
346
346
  }),
347
347
  /**
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  buildAgentRuntimeAgentLookupKeys,
3
3
  shouldFetchAgentRuntimeRecordRemotely
4
- } from "./chunk-YOXYA2GU.js";
4
+ } from "./chunk-IP2RNQU3.js";
5
5
 
6
6
  // packages/cli/client/localAgentRecords.ts
7
7
  var buildLocalAgentLookupKeys = buildAgentRuntimeAgentLookupKeys;