nolo-cli 0.6.1 → 0.8.0-alpha.10

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 (175) hide show
  1. package/_executeModel-CPDNUUQV.js +198 -0
  2. package/action-PAXRPJJF.js +27 -0
  3. package/addContentAction-CZVWF3QZ.js +25 -0
  4. package/addDialogAgentAction-CCIDTPHC.js +67 -0
  5. package/agentDeleteCommand-OSUMJMZM.js +323 -0
  6. package/agentEmailCommands-OQTJIPQU.js +621 -0
  7. package/agentListCommands-FATQEUYT.js +219 -0
  8. package/agentMachineCommands-6LZWF4GL.js +421 -0
  9. package/agentPullCommand-O2MTUAFR.js +122 -0
  10. package/agentRecordCommands-TIHFU65Z.js +89 -0
  11. package/agentRunCommand-R64Y3HCH.js +102 -0
  12. package/agentRunControl-K4VKNEHF.js +57 -0
  13. package/agentRuntimeLocal-6PIWAHLQ.js +99 -0
  14. package/agentSlice-TP4VARJF.js +41 -0
  15. package/authCommand-WXMD3IPR.js +574 -0
  16. package/authCommands-X74AFDTC.js +26 -0
  17. package/chunk-2EISRLRC.js +238 -0
  18. package/chunk-2FTTDCD4.js +675 -0
  19. package/chunk-2MALU52L.js +51 -0
  20. package/chunk-2TPUKEU7.js +1078 -0
  21. package/chunk-3ASDTTEI.js +1774 -0
  22. package/chunk-3EUW3WEO.js +8 -0
  23. package/chunk-3LY4F7SV.js +9293 -0
  24. package/chunk-4CQLVGRV.js +50 -0
  25. package/chunk-4IJYA27C.js +342 -0
  26. package/chunk-4SN6J65J.js +38 -0
  27. package/chunk-4VNS5WPM.js +42 -0
  28. package/chunk-572EKYLF.js +792 -0
  29. package/chunk-5MIDPSSK.js +206 -0
  30. package/chunk-5MMAK75Q.js +15 -0
  31. package/chunk-5VV37AT4.js +222 -0
  32. package/chunk-63W5N6P3.js +150 -0
  33. package/chunk-6A5EF6IR.js +929 -0
  34. package/chunk-6HYVJV7B.js +102 -0
  35. package/chunk-6P2WX5IA.js +3631 -0
  36. package/chunk-6WD3OOJS.js +20 -0
  37. package/chunk-ATNTHIZI.js +13 -0
  38. package/chunk-AUGHVUFE.js +69 -0
  39. package/chunk-AVMKZHBC.js +85 -0
  40. package/chunk-AZPCASRE.js +36 -0
  41. package/chunk-BNMT7YY5.js +34 -0
  42. package/chunk-BR2WP3DF.js +548 -0
  43. package/chunk-BSTNFPHD.js +231 -0
  44. package/chunk-BU4OPIXC.js +171 -0
  45. package/chunk-CF2WZF4N.js +134 -0
  46. package/chunk-CF7PE763.js +10 -0
  47. package/chunk-CKOJQDKR.js +198 -0
  48. package/chunk-CM54RSSA.js +206 -0
  49. package/chunk-CWMSB67P.js +34 -0
  50. package/chunk-DA2OEKS6.js +27 -0
  51. package/chunk-DFFIZ25G.js +30 -0
  52. package/chunk-DWLEOOGR.js +8 -0
  53. package/chunk-DZ3XJVET.js +231 -0
  54. package/chunk-EHLHSX7R.js +1433 -0
  55. package/chunk-ELRRLDWI.js +478 -0
  56. package/chunk-EYEEHCU4.js +3066 -0
  57. package/chunk-FQZWM5YX.js +628 -0
  58. package/chunk-G3SUCT4W.js +8 -0
  59. package/chunk-G5H7RNFL.js +807 -0
  60. package/chunk-GAKEBQD6.js +30 -0
  61. package/chunk-GBRG75BQ.js +86 -0
  62. package/chunk-H2RMRZJE.js +113 -0
  63. package/chunk-H33743XH.js +25 -0
  64. package/chunk-HD63YREL.js +19 -0
  65. package/chunk-HEIIIZBX.js +104 -0
  66. package/chunk-HNMXYYJR.js +12 -0
  67. package/chunk-HOMYP7GZ.js +2152 -0
  68. package/chunk-HZFOMJRA.js +4300 -0
  69. package/chunk-IAXBCTTE.js +175 -0
  70. package/chunk-IDZTNRP2.js +85 -0
  71. package/chunk-IHHA5Y2S.js +9013 -0
  72. package/chunk-ISNCLGUZ.js +146 -0
  73. package/chunk-IYQV26RA.js +138 -0
  74. package/chunk-J4576WMJ.js +91 -0
  75. package/chunk-JBTJAPUF.js +35 -0
  76. package/chunk-JZPBVBIY.js +94 -0
  77. package/chunk-KQHGZWSV.js +63 -0
  78. package/chunk-KUG52IAP.js +8 -0
  79. package/chunk-KX6YBIHG.js +8 -0
  80. package/chunk-LCBAMY2M.js +60 -0
  81. package/chunk-LM25IZBJ.js +902 -0
  82. package/chunk-LM6IYQ3F.js +16 -0
  83. package/chunk-M76ECQRD.js +13658 -0
  84. package/chunk-MRC4Q34M.js +188 -0
  85. package/chunk-NEMRK4EK.js +944 -0
  86. package/chunk-NXZGF7F7.js +2878 -0
  87. package/chunk-OF5H3QWS.js +300 -0
  88. package/chunk-OLZBQWZU.js +6 -0
  89. package/chunk-OOYVBFM7.js +191 -0
  90. package/chunk-OWOHNGCN.js +50 -0
  91. package/chunk-PN7AFLOK.js +3401 -0
  92. package/chunk-POCFIDGQ.js +562 -0
  93. package/chunk-Q6WACBKB.js +1949 -0
  94. package/chunk-QFV2OAIM.js +421 -0
  95. package/chunk-QJ6V2NIN.js +1447 -0
  96. package/chunk-QSJ3HFEF.js +8 -0
  97. package/chunk-QUWDTOUP.js +190 -0
  98. package/chunk-QYXLLLGL.js +4519 -0
  99. package/chunk-ROWQEJRP.js +139 -0
  100. package/chunk-S7Z2HMCN.js +25 -0
  101. package/chunk-TDIQFT2F.js +301 -0
  102. package/chunk-TILFE6LV.js +381 -0
  103. package/chunk-TKOUBWBO.js +24674 -0
  104. package/chunk-TYH5JE6N.js +27158 -0
  105. package/chunk-U4TRT5V4.js +246 -0
  106. package/chunk-U6VC4MU4.js +8 -0
  107. package/chunk-UAD2WT54.js +64 -0
  108. package/chunk-USZMK5UT.js +105 -0
  109. package/chunk-VEJLAVTC.js +2052 -0
  110. package/chunk-VF4K2QE6.js +21 -0
  111. package/chunk-VHBWHNVT.js +59 -0
  112. package/chunk-VIDPVFP3.js +20 -0
  113. package/chunk-VP4WJWKW.js +8882 -0
  114. package/chunk-VQ2AJRGD.js +148 -0
  115. package/chunk-W4NVOSFF.js +37 -0
  116. package/chunk-WWC7I6TA.js +8 -0
  117. package/chunk-X7W4TNB4.js +1550 -0
  118. package/chunk-XDVAYP26.js +537 -0
  119. package/chunk-XKIMRZO2.js +221 -0
  120. package/chunk-Y5GCAMGP.js +9 -0
  121. package/chunk-YWPXYBY7.js +360 -0
  122. package/chunk-Z4NR32XR.js +50 -0
  123. package/chunk-ZNFJWEN4.js +56 -0
  124. package/cliExecutor-DNE7TCC4.js +36 -0
  125. package/clipboardy-BVE3LVEH.js +12001 -0
  126. package/createAgentAutomationAction-KLKS2HGU.js +864 -0
  127. package/createDialogAction-Z33JMBF5.js +52 -0
  128. package/createPageAction-AQVNOAAI.js +169 -0
  129. package/db-HCJ5PRB5.js +271 -0
  130. package/dbSlice-C4UJLRZP.js +59 -0
  131. package/deleteFile-4SKGPHOZ.js +41 -0
  132. package/dialogCommands-W5PD6MZU.js +59 -0
  133. package/dialogSlice-RBJYVSAR.js +146 -0
  134. package/docCreateCommands-MM34S4Z3.js +215 -0
  135. package/docDeleteCommands-JJTU722V.js +176 -0
  136. package/docReadCommands-GLYDMCTU.js +129 -0
  137. package/docStore-5TYME4DO.js +96 -0
  138. package/docUpdateCommands-ZCGQ7URR.js +313 -0
  139. package/fetchMessages-JOCYIFKL.js +16 -0
  140. package/getPricing-PWPJ6MNV.js +30 -0
  141. package/handleSendMessageAction-KA2MRW6E.js +183 -0
  142. package/index.js +184 -112254
  143. package/lib-FYYBQIXS.js +19839 -0
  144. package/localDialogRead-D3BELSTF.js +26 -0
  145. package/localFirstLog-DHNOY2NA.js +19 -0
  146. package/localRuntimeAuthority-TEGCOWX4.js +471 -0
  147. package/localRuntimeDb-LGDF6FQP.js +12 -0
  148. package/machineCommands-ZB5WUSPF.js +774 -0
  149. package/machineInfo-M6KB6HZN.js +10 -0
  150. package/machineWsRunDispatch-GWCAPPCM.js +105 -0
  151. package/memoryCommands-O4MIPIWQ.js +476 -0
  152. package/models-XLEOET3E.js +9 -0
  153. package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
  154. package/package.json +3 -25
  155. package/read-RIJCIVKX.js +17 -0
  156. package/readDocTool-GZD2N3LO.js +16 -0
  157. package/readlineWorkspace-FEDY44AA.js +5357 -0
  158. package/removeDialogAgentAction-CXLST3N6.js +72 -0
  159. package/runAgentClientLoop-W4NKE64V.js +288 -0
  160. package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
  161. package/setDialogExtraReferencesAction-LP6VYGU7.js +59 -0
  162. package/setPrimaryDialogAgentAction-D3GGH23T.js +79 -0
  163. package/settingSlice-J4I3Z5H7.js +198 -0
  164. package/skillSummaryMarker-42HKSXYY.js +9 -0
  165. package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
  166. package/slateUtils-2M7MUTWX.js +19 -0
  167. package/spaceCommands-LC4FDAKE.js +450 -0
  168. package/spaceSlice-32XOGBEF.js +145 -0
  169. package/streamAgentChatTurn-YQW32AQH.js +4503 -0
  170. package/tableCommands-GOFP7QKA.js +1286 -0
  171. package/toolApiClient-QI3YBNWB.js +26 -0
  172. package/tools-XGTFRYD7.js +83 -0
  173. package/understanding-HCSFPE7R.js +318 -0
  174. package/updateCommands-VOSPKXFF.js +31 -0
  175. package/updateDialogTitleAction-4LHQDNHQ.js +185 -0
@@ -0,0 +1,206 @@
1
+ import {
2
+ extractCustomId
3
+ } from "./chunk-DFFIZ25G.js";
4
+ import {
5
+ getActiveDialogKey
6
+ } from "./chunk-3ASDTTEI.js";
7
+ import {
8
+ compactWhitespace
9
+ } from "./chunk-DWLEOOGR.js";
10
+ import {
11
+ asTrimmedLowercaseString
12
+ } from "./chunk-QSJ3HFEF.js";
13
+ import {
14
+ isRecord
15
+ } from "./chunk-KUG52IAP.js";
16
+
17
+ // packages/ai/tools/toolApiClient.ts
18
+ var MAIN_SERVER = "https://nolo.chat";
19
+ var getIsDesktopApp = () => typeof window !== "undefined" && Boolean(window.__NOLO_DESKTOP__);
20
+ var isLocalServerUrl = (value) => {
21
+ if (!value) return false;
22
+ try {
23
+ const hostname = new URL(value).hostname.toLowerCase();
24
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
25
+ } catch {
26
+ return false;
27
+ }
28
+ };
29
+ var resolveDesktopSafeServer = (value) => {
30
+ if (!getIsDesktopApp()) return value || MAIN_SERVER;
31
+ return isLocalServerUrl(value) ? MAIN_SERVER : value || MAIN_SERVER;
32
+ };
33
+ var selectCurrentServerFromState = (state) => resolveDesktopSafeServer(state?.settings?.currentServer);
34
+ var selectCurrentTokenFromState = (state) => typeof state?.auth?.currentToken === "string" ? state.auth.currentToken : null;
35
+ var selectCurrentDialogKeyFromState = (_state) => getActiveDialogKey();
36
+ var resolveToolBaseUrl = (currentServer) => {
37
+ const _window = globalThis.window;
38
+ if (!_window) return (currentServer || "").replace(/\/+$/, "");
39
+ const fallbackLocal = _window.location.origin;
40
+ if (!currentServer) return fallbackLocal;
41
+ return currentServer.replace(/\/+$/, "");
42
+ };
43
+ var DESKTOP_LOCAL_TOOL_PATHS = /* @__PURE__ */ new Set([
44
+ "/api/exec-shell",
45
+ "/api/check-env",
46
+ "/api/read-file",
47
+ "/api/write-file",
48
+ "/api/apply-edit",
49
+ "/api/apply-line-edits",
50
+ "/api/code-search",
51
+ "/api/search-repo",
52
+ "/api/desktop/files/roots",
53
+ "/api/desktop/files/roots/request",
54
+ "/api/desktop/files/list",
55
+ "/api/desktop/files/read",
56
+ "/api/desktop/files/plan",
57
+ "/api/desktop/files/approve",
58
+ "/api/desktop/files/execute",
59
+ "/api/desktop/files/undo",
60
+ "/api/desktop/files/history"
61
+ ]);
62
+ var getWindowOrigin = () => {
63
+ const _window = globalThis.window;
64
+ const origin = _window?.location?.origin;
65
+ return typeof origin === "string" && origin ? origin.replace(/\/+$/, "") : null;
66
+ };
67
+ var resolveToolApiBaseUrl = (currentServer, path) => {
68
+ if (path && DESKTOP_LOCAL_TOOL_PATHS.has(path) && getIsDesktopApp()) {
69
+ const localOrigin = getWindowOrigin();
70
+ if (localOrigin) return localOrigin;
71
+ }
72
+ return resolveToolBaseUrl(currentServer);
73
+ };
74
+ var getRequestConfig = (thunkApi) => {
75
+ const state = thunkApi.getState();
76
+ const currentServer = selectCurrentServerFromState(state);
77
+ const token = selectCurrentTokenFromState(state);
78
+ if (!currentServer) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u670D\u52A1\u5668\u5730\u5740\u3002");
79
+ return { currentServer, token };
80
+ };
81
+ var getToolBaseUrl = (thunkApi) => {
82
+ const { currentServer } = getRequestConfig(thunkApi);
83
+ const baseUrl = resolveToolBaseUrl(currentServer);
84
+ if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
85
+ return baseUrl;
86
+ };
87
+ var getToolRequestContext = (thunkApi) => {
88
+ const { currentServer, token } = getRequestConfig(thunkApi);
89
+ const baseUrl = resolveToolBaseUrl(currentServer);
90
+ if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
91
+ return {
92
+ currentServer,
93
+ token,
94
+ baseUrl
95
+ };
96
+ };
97
+ var maybeAttachDialogId = (thunkApi, body) => {
98
+ if (!isRecord(body)) return body;
99
+ if ("dialogId" in body) return body;
100
+ const state = thunkApi.getState();
101
+ const currentDialogKey = selectCurrentDialogKeyFromState(state);
102
+ const dialogId = currentDialogKey ? extractCustomId(currentDialogKey) : null;
103
+ if (!dialogId) return body;
104
+ return {
105
+ ...body,
106
+ dialogId
107
+ };
108
+ };
109
+ var ToolApiError = class extends Error {
110
+ status;
111
+ code;
112
+ details;
113
+ constructor(message, options) {
114
+ super(message);
115
+ this.name = "ToolApiError";
116
+ this.status = options?.status;
117
+ this.code = options?.code;
118
+ this.details = options?.details;
119
+ }
120
+ };
121
+ var buildToolRequestHeaders = (thunkApi, options = {}) => {
122
+ const { withAuth = false, agentKey } = options;
123
+ const { token } = getRequestConfig(thunkApi);
124
+ const headers = { "Content-Type": "application/json" };
125
+ if (withAuth && token) {
126
+ headers["Authorization"] = `Bearer ${token}`;
127
+ }
128
+ if (agentKey && typeof agentKey === "string" && agentKey.trim()) {
129
+ headers["X-Nolo-Agent-Key"] = agentKey.trim();
130
+ }
131
+ if (typeof window !== "undefined" && window.__NOLO_DESKTOP__) {
132
+ headers["X-Nolo-Desktop-Tool"] = "1";
133
+ }
134
+ return headers;
135
+ };
136
+ var buildResponsePreview = (text) => compactWhitespace(text).slice(0, 240);
137
+ var looksLikeHtmlResponse = (text, contentType) => {
138
+ if (contentType?.toLowerCase().includes("text/html")) return true;
139
+ const trimmed = asTrimmedLowercaseString(text);
140
+ return trimmed.startsWith("<!doctype html") || trimmed.startsWith("<html");
141
+ };
142
+ async function callToolApi(thunkApi, path, body, options = {}) {
143
+ const { currentServer } = getRequestConfig(thunkApi);
144
+ const baseUrl = resolveToolApiBaseUrl(currentServer, path);
145
+ if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
146
+ const url = `${baseUrl}${path}`;
147
+ const headers = buildToolRequestHeaders(thunkApi, options);
148
+ const response = await fetch(url, {
149
+ method: "POST",
150
+ headers,
151
+ body: JSON.stringify(maybeAttachDialogId(thunkApi, body))
152
+ });
153
+ const contentType = response.headers.get("content-type");
154
+ const responseText = await response.text();
155
+ if (!response.ok) {
156
+ let errorMessage = `API \u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${response.status}`;
157
+ let errorCode;
158
+ let errorDetails;
159
+ try {
160
+ const errorData = JSON.parse(responseText);
161
+ const err = errorData?.error;
162
+ if (err) {
163
+ errorMessage += `: ${err.message ?? JSON.stringify(err)}`;
164
+ errorCode = typeof err.code === "string" ? err.code : void 0;
165
+ errorDetails = err.details;
166
+ }
167
+ } catch {
168
+ errorCode = looksLikeHtmlResponse(responseText, contentType) ? "HTML_ERROR_RESPONSE" : "NON_JSON_ERROR_RESPONSE";
169
+ errorDetails = {
170
+ contentType,
171
+ responsePreview: buildResponsePreview(responseText)
172
+ };
173
+ if (typeof errorDetails.responsePreview === "string" && errorDetails.responsePreview) {
174
+ errorMessage += `: ${errorDetails.responsePreview}`;
175
+ }
176
+ }
177
+ throw new ToolApiError(errorMessage, {
178
+ status: response.status,
179
+ code: errorCode,
180
+ details: errorDetails
181
+ });
182
+ }
183
+ try {
184
+ return JSON.parse(responseText);
185
+ } catch {
186
+ throw new ToolApiError("\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u975E JSON \u54CD\u5E94", {
187
+ status: response.status,
188
+ code: looksLikeHtmlResponse(responseText, contentType) ? "HTML_RESPONSE" : "INVALID_JSON_RESPONSE",
189
+ details: {
190
+ contentType,
191
+ responsePreview: buildResponsePreview(responseText)
192
+ }
193
+ });
194
+ }
195
+ }
196
+
197
+ export {
198
+ resolveToolBaseUrl,
199
+ resolveToolApiBaseUrl,
200
+ getRequestConfig,
201
+ getToolBaseUrl,
202
+ getToolRequestContext,
203
+ ToolApiError,
204
+ buildToolRequestHeaders,
205
+ callToolApi
206
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ compactWhitespace
3
+ } from "./chunk-DWLEOOGR.js";
4
+
5
+ // packages/core/clipCompactText.ts
6
+ function clipCompactText(value, max, ellipsis = "...") {
7
+ const compact = compactWhitespace(value);
8
+ if (compact.length <= max) return compact;
9
+ if (max <= ellipsis.length) return compact.slice(0, max);
10
+ return `${compact.slice(0, max - ellipsis.length)}${ellipsis}`;
11
+ }
12
+
13
+ export {
14
+ clipCompactText
15
+ };
@@ -0,0 +1,222 @@
1
+ import {
2
+ clearCliLocalRuntimePreparedAgentCache
3
+ } from "./chunk-IHHA5Y2S.js";
4
+ import {
5
+ getReadableCliDb
6
+ } from "./chunk-W4NVOSFF.js";
7
+ import {
8
+ buildCreatedAgentRecord,
9
+ buildUpdatedAgentRecord,
10
+ normalizeAgentRecordForOutput,
11
+ parseAgentUpdateArgs,
12
+ resolveAgentRecordFromHybridStore,
13
+ sanitizeAgentRecordForCliOutput,
14
+ writeAgentRecord
15
+ } from "./chunk-FQZWM5YX.js";
16
+ import {
17
+ resolveCliAgentKeyInput
18
+ } from "./chunk-VHBWHNVT.js";
19
+ import {
20
+ parseUserIdFromAuthToken,
21
+ resolveAuthToken
22
+ } from "./chunk-ISNCLGUZ.js";
23
+ import {
24
+ toErrorMessage
25
+ } from "./chunk-HNMXYYJR.js";
26
+
27
+ // packages/cli/agentRecordCommands.ts
28
+ async function runAgentReadCommand(args, deps = {}) {
29
+ const env = deps.env ?? process.env;
30
+ const output = deps.output ?? process.stdout;
31
+ const agentInput = args[0]?.trim();
32
+ if (!agentInput || agentInput === "--help" || agentInput === "-h") {
33
+ output.write("Usage: nolo agent read <agent>\n");
34
+ return agentInput ? 0 : 1;
35
+ }
36
+ const authToken = resolveAuthToken(args, env);
37
+ if (!authToken) {
38
+ output.write("[nolo] agent read requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
39
+ return 1;
40
+ }
41
+ const agentKey = resolveCliAgentKeyInput(agentInput);
42
+ const db = deps.db ?? await getReadableCliDb(output);
43
+ const fetchImpl = deps.fetchImpl ?? fetch;
44
+ const fallbackFetchImpl = deps.fallbackFetchImpl;
45
+ try {
46
+ const result = await resolveAgentRecordFromHybridStore({
47
+ agentInput,
48
+ cliArgs: args,
49
+ env,
50
+ db,
51
+ fetchImpl,
52
+ fallbackFetchImpl
53
+ });
54
+ if (!result) {
55
+ throw new Error(`agent not found: ${agentKey}`);
56
+ }
57
+ output.write(JSON.stringify({
58
+ ...normalizeAgentRecordForOutput(result.agentKey, authToken, result.record),
59
+ source: result.source
60
+ }, null, 2));
61
+ output.write("\n");
62
+ return 0;
63
+ } catch (error) {
64
+ output.write(
65
+ `[nolo] agent read failed: ${toErrorMessage(error)}
66
+ `
67
+ );
68
+ return 1;
69
+ }
70
+ }
71
+ async function runAgentUpdateCommand(args, deps = {}) {
72
+ const env = deps.env ?? process.env;
73
+ const output = deps.output ?? process.stdout;
74
+ let parsed;
75
+ try {
76
+ parsed = parseAgentUpdateArgs(args);
77
+ } catch (error) {
78
+ output.write(`[nolo] agent update failed: ${toErrorMessage(error)}
79
+ `);
80
+ return 1;
81
+ }
82
+ if (!parsed) {
83
+ output.write(
84
+ "Usage: nolo agent update <agent> [--model <id>] [--cli-provider <provider>] [--api-source <source>] [--max-concurrent <n>] [--expires-at <iso>] [--prompt <text> | --prompt-file <path> | --prompt-doc <pageKey>] [--tools <json>] [--copy-provider-from <agent>] [--field key=value]\n".replace("[--field key=value]", `[--handle <name>] [--field key=value] (e.g. --field disabledTools='["exa_search"]' to disable default tools)`)
85
+ );
86
+ return args[0] ? 0 : 1;
87
+ }
88
+ const authToken = resolveAuthToken(args, env);
89
+ if (!authToken) {
90
+ output.write("[nolo] agent update requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
91
+ return 1;
92
+ }
93
+ const userId = parseUserIdFromAuthToken(authToken);
94
+ if (!userId) {
95
+ output.write("[nolo] agent update could not read userId from AUTH_TOKEN.\n");
96
+ return 1;
97
+ }
98
+ const db = deps.db ?? await getReadableCliDb(output);
99
+ const fetchImpl = deps.fetchImpl ?? fetch;
100
+ const fallbackFetchImpl = deps.fallbackFetchImpl;
101
+ try {
102
+ const built = await buildUpdatedAgentRecord({
103
+ cliArgs: args,
104
+ parsed,
105
+ env,
106
+ db,
107
+ fetchImpl,
108
+ fallbackFetchImpl,
109
+ authToken
110
+ });
111
+ await writeAgentRecord({
112
+ agentKey: built.agentKey,
113
+ authToken,
114
+ fallbackFetchImpl,
115
+ fetchImpl,
116
+ serverUrl: built.serverUrl,
117
+ userId,
118
+ record: built.nextRecord
119
+ });
120
+ await db.put(built.agentKey, {
121
+ ...built.nextRecord,
122
+ dbKey: built.agentKey,
123
+ key: built.nextRecord?.key || built.agentKey,
124
+ serverOrigin: built.serverUrl
125
+ });
126
+ clearCliLocalRuntimePreparedAgentCache();
127
+ output.write(JSON.stringify({
128
+ ok: true,
129
+ agentKey: built.agentKey,
130
+ baseUrl: built.serverUrl,
131
+ updates: sanitizeAgentRecordForCliOutput(built.updates),
132
+ record: sanitizeAgentRecordForCliOutput(built.nextRecord)
133
+ }, null, 2));
134
+ output.write("\n");
135
+ return 0;
136
+ } catch (error) {
137
+ output.write(
138
+ `[nolo] agent update failed: ${toErrorMessage(error)}
139
+ `
140
+ );
141
+ return 1;
142
+ }
143
+ }
144
+ async function runAgentCreateCommand(args, deps = {}) {
145
+ const env = deps.env ?? process.env;
146
+ const output = deps.output ?? process.stdout;
147
+ let parsed;
148
+ try {
149
+ parsed = parseAgentUpdateArgs(args);
150
+ } catch (error) {
151
+ output.write(`[nolo] agent create failed: ${toErrorMessage(error)}
152
+ `);
153
+ return 1;
154
+ }
155
+ if (!parsed) {
156
+ output.write(
157
+ "Usage: nolo agent create <agent> [--model <id>] [--cli-provider <provider>] [--api-source <source>] [--max-concurrent <n>] [--expires-at <iso>] [--prompt <text> | --prompt-file <path> | --prompt-doc <pageKey>] [--tools <json>] [--copy-provider-from <agent>] [--name <name>] [--custom-provider-url <url>] [--provider-api-key <key>] [--field key=value]\n".replace("[--field key=value]", "[--handle <name>] [--field key=value]")
158
+ );
159
+ return args[0] ? 0 : 1;
160
+ }
161
+ const authToken = resolveAuthToken(args, env);
162
+ if (!authToken) {
163
+ output.write("[nolo] agent create requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
164
+ return 1;
165
+ }
166
+ const userId = parseUserIdFromAuthToken(authToken);
167
+ if (!userId) {
168
+ output.write("[nolo] agent create could not read userId from AUTH_TOKEN.\n");
169
+ return 1;
170
+ }
171
+ const db = deps.db ?? await getReadableCliDb(output);
172
+ const fetchImpl = deps.fetchImpl ?? fetch;
173
+ const fallbackFetchImpl = deps.fallbackFetchImpl;
174
+ try {
175
+ const built = await buildCreatedAgentRecord({
176
+ cliArgs: args,
177
+ parsed,
178
+ env,
179
+ db,
180
+ fetchImpl,
181
+ fallbackFetchImpl,
182
+ authToken
183
+ });
184
+ await writeAgentRecord({
185
+ agentKey: built.agentKey,
186
+ authToken,
187
+ fallbackFetchImpl,
188
+ fetchImpl,
189
+ serverUrl: built.serverUrl,
190
+ userId,
191
+ record: built.nextRecord
192
+ });
193
+ await db.put(built.agentKey, {
194
+ ...built.nextRecord,
195
+ dbKey: built.agentKey,
196
+ key: built.nextRecord?.key || built.agentKey,
197
+ serverOrigin: built.serverUrl
198
+ });
199
+ clearCliLocalRuntimePreparedAgentCache();
200
+ output.write(JSON.stringify({
201
+ ok: true,
202
+ agentKey: built.agentKey,
203
+ baseUrl: built.serverUrl,
204
+ updates: sanitizeAgentRecordForCliOutput(built.updates),
205
+ record: sanitizeAgentRecordForCliOutput(built.nextRecord)
206
+ }, null, 2));
207
+ output.write("\n");
208
+ return 0;
209
+ } catch (error) {
210
+ output.write(
211
+ `[nolo] agent create failed: ${toErrorMessage(error)}
212
+ `
213
+ );
214
+ return 1;
215
+ }
216
+ }
217
+
218
+ export {
219
+ runAgentReadCommand,
220
+ runAgentUpdateCommand,
221
+ runAgentCreateCommand
222
+ };
@@ -0,0 +1,150 @@
1
+ // packages/create/editor/transforms/slateToRenderMarkdown.ts
2
+ function renderTextNode(node) {
3
+ if (!node || typeof node.text !== "string") return "";
4
+ let text = node.text;
5
+ if (!text) return "";
6
+ if (node.bold) text = `**${text}**`;
7
+ if (node.italic) text = `*${text}*`;
8
+ if (node.strikethrough) text = `~~${text}~~`;
9
+ return text;
10
+ }
11
+ function renderPlainText(node, options = {}) {
12
+ if (!node) return "";
13
+ if (typeof node.text === "string") return renderTextNode(node);
14
+ if (!Array.isArray(node.children)) return "";
15
+ return node.children.map((child) => renderPlainText(child, options)).join("");
16
+ }
17
+ function renderTable(node, options) {
18
+ const rows = Array.isArray(node.children) ? node.children : [];
19
+ if (rows.length === 0) return "";
20
+ const alignments = Array.isArray(node.columns) ? node.columns.map((column) => column?.align || "left") : [];
21
+ const renderedRows = rows.map(
22
+ (row) => (Array.isArray(row?.children) ? row.children : []).map((cell) => {
23
+ const content = renderPlainText(cell, options).replace(/\n+/g, " ").trim();
24
+ return content || " ";
25
+ })
26
+ );
27
+ const header = renderedRows[0] || [];
28
+ const divider = header.map((_, index) => {
29
+ const align = alignments[index];
30
+ if (align === "center") return ":---:";
31
+ if (align === "right") return "---:";
32
+ return "---";
33
+ });
34
+ const body = renderedRows.slice(1);
35
+ return [header, divider, ...body].map((cells) => `| ${cells.join(" | ")} |`).join("\n") + "\n\n";
36
+ }
37
+ function renderListItem(node, listDepth, ordered, start, index, options = {}) {
38
+ const indentation = " ".repeat(listDepth);
39
+ const marker = node.checked === true ? "- [x]" : node.checked === false ? "- [ ]" : ordered ? `${start + index}.` : "-";
40
+ const segments = Array.isArray(node.children) ? node.children : [];
41
+ const renderedSegments = segments.flatMap((child) => {
42
+ const rendered = renderNode(child, listDepth + 1, options).trimEnd();
43
+ return rendered ? [rendered] : [];
44
+ });
45
+ if (renderedSegments.length === 0) {
46
+ return `${indentation}${marker}
47
+ `;
48
+ }
49
+ const [first, ...rest] = renderedSegments;
50
+ const lines = first.split("\n");
51
+ const firstLine = lines.shift() || "";
52
+ const restFirst = lines.map((line) => `${indentation} ${line}`).join("\n");
53
+ const restBlocks = rest.map((block) => `${indentation} ${block}`).join("\n");
54
+ return [
55
+ `${indentation}${marker} ${firstLine}`,
56
+ restFirst,
57
+ restBlocks
58
+ ].filter(Boolean).join("\n") + "\n";
59
+ }
60
+ function renderNode(node, listDepth = 0, options = {}) {
61
+ if (!node) return "";
62
+ switch (node.type) {
63
+ case "heading-one":
64
+ return `# ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
65
+
66
+ `;
67
+ case "heading-two":
68
+ return `## ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
69
+
70
+ `;
71
+ case "heading-three":
72
+ return `### ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
73
+
74
+ `;
75
+ case "heading-four":
76
+ return `#### ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
77
+
78
+ `;
79
+ case "heading-five":
80
+ return `##### ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
81
+
82
+ `;
83
+ case "heading-six":
84
+ return `###### ${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
85
+
86
+ `;
87
+ case "paragraph":
88
+ return `${node.children.map((n) => renderNode(n, listDepth, options)).join("")}
89
+
90
+ `;
91
+ case "list":
92
+ return node.children.map(
93
+ (item, index) => renderListItem(item, listDepth, !!node.ordered, node.start || 1, index, options)
94
+ ).join("");
95
+ case "list-item":
96
+ return renderListItem(node, listDepth, false, 1, 0, options);
97
+ case "quote": {
98
+ const content = node.children.map((n) => renderNode(n, listDepth, options)).join("").trim();
99
+ return `> ${content.replace(/\n/g, "\n> ")}
100
+
101
+ `;
102
+ }
103
+ case "code-block": {
104
+ const code = node.children.map(
105
+ (line) => (line.children || []).map((text) => text.text).join("")
106
+ ).join("\n");
107
+ return "```" + (node.language || "") + "\n" + code + "\n```\n\n";
108
+ }
109
+ case "link": {
110
+ const linkText = node.children.map((n) => renderNode(n, listDepth, options)).join("");
111
+ return `[${linkText}](${node.url})`;
112
+ }
113
+ case "table":
114
+ return renderTable(node, options);
115
+ case "code-inline":
116
+ return `\`${node.children.map((n) => renderNode(n, listDepth, options)).join("")}\``;
117
+ case "mention": {
118
+ if (options.mentionResolver) {
119
+ return options.mentionResolver(node);
120
+ }
121
+ const label = node.label || node.resourceId || "mention";
122
+ const resourceType = node.resourceType || "unknown";
123
+ const resourceId = node.resourceId || "unknown";
124
+ return `@[${resourceType}:${resourceId}|${label}]`;
125
+ }
126
+ case "image": {
127
+ const alt = node.alt || "";
128
+ const title = node.title ? ` "${node.title}"` : "";
129
+ return `![${alt}](${node.url || ""}${title})`;
130
+ }
131
+ case "html-inline":
132
+ return typeof node.html === "string" ? node.html : "";
133
+ case "html-block":
134
+ return typeof node.html === "string" ? `${node.html}
135
+
136
+ ` : "";
137
+ case "thematic-break":
138
+ return "---\n\n";
139
+ default:
140
+ return renderTextNode(node) || (node.children ? node.children.map((child) => renderNode(child, listDepth, options)).join("") : "");
141
+ }
142
+ }
143
+ function slateToRenderMarkdown(nodes, options = {}) {
144
+ if (!nodes || nodes.length === 0) return "";
145
+ return nodes.map((node) => renderNode(node, 0, options)).join("").trim() + "\n";
146
+ }
147
+
148
+ export {
149
+ slateToRenderMarkdown
150
+ };