nolo-cli 0.1.29 → 0.1.31

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 (329) hide show
  1. package/agent-runtime/agentRecordConfig.ts +0 -2
  2. package/agent-runtime/hostAdapter.ts +0 -1
  3. package/agent-runtime/hostRuntimeCapabilities.ts +7 -0
  4. package/agent-runtime/hostRuntimeConfig.ts +86 -0
  5. package/agent-runtime/index.ts +13 -0
  6. package/agent-runtime/localToolPolicy.ts +13 -6
  7. package/agent-runtime/localWorkspaceTools.ts +333 -30
  8. package/agent-runtime/platformChatProvider.ts +4 -1
  9. package/agent-runtime/runtimeToolPolicy.ts +32 -47
  10. package/agent-runtime/shellCommandPolicy.ts +117 -0
  11. package/agent-runtime/toolGate.ts +38 -0
  12. package/agentCreateCustomCommands.ts +9 -4
  13. package/agentDialogsCommands.ts +4 -3
  14. package/agentDoctorCommands.ts +3 -3
  15. package/agentListCommands.ts +3 -3
  16. package/agentMachineCommands.ts +6 -6
  17. package/agentPullCommand.ts +4 -12
  18. package/agentRecordCommands.ts +5 -3
  19. package/agentRecordHelpers.ts +42 -23
  20. package/agentRunCommand.ts +2 -6
  21. package/agentRunParsing.ts +18 -5
  22. package/agentRuntimeLocal.ts +10 -0
  23. package/agentUnpublishCommands.ts +3 -2
  24. package/ai/agent/agentRunDialogLineage.ts +56 -0
  25. package/ai/agent/agentSlice.ts +45 -10
  26. package/ai/agent/avatarUtils.ts +1 -1
  27. package/ai/agent/buildSystemPrompt.ts +1 -2
  28. package/ai/agent/cliExecutor.ts +330 -19
  29. package/ai/agent/createAgentSchema.ts +22 -0
  30. package/ai/agent/hooks/fetchPublicAgents.ts +14 -39
  31. package/ai/agent/hooks/usePublicAgents.ts +90 -192
  32. package/ai/agent/publicAgentCatalog.ts +359 -0
  33. package/ai/agent/publicAgentIdentity.ts +76 -0
  34. package/ai/agent/server/fetchPublicAgents.ts +21 -46
  35. package/ai/agent/serverOrigin.ts +7 -0
  36. package/ai/agent/streamAgentChatTurn.ts +23 -21
  37. package/ai/agent/streamAgentChatTurnUtils.ts +292 -6
  38. package/ai/agent/types.ts +2 -0
  39. package/ai/agent/web/agentDisplayUtils.ts +171 -0
  40. package/ai/agent/web/useAgentModelAvatarComponent.ts +32 -0
  41. package/ai/ai.locale.ts +8 -0
  42. package/ai/chat/sendOpenAICompletionsRequest.native.ts +15 -0
  43. package/ai/chat/sendOpenAICompletionsRequest.ts +93 -1
  44. package/ai/chat/sendOpenAIResponseRequest.ts +86 -9
  45. package/ai/chat/updateTotalUsage.ts +7 -0
  46. package/ai/llm/deepinfra.ts +30 -15
  47. package/ai/llm/mistral.ts +3 -4
  48. package/ai/llm/providers.ts +2 -0
  49. package/ai/llm/types.ts +15 -0
  50. package/ai/memory/capture.ts +3 -3
  51. package/ai/memory/consolidate.ts +2 -2
  52. package/ai/memory/delete.ts +4 -3
  53. package/ai/memory/query.ts +3 -3
  54. package/ai/memory/remember.ts +2 -2
  55. package/ai/memory/store.ts +3 -3
  56. package/ai/memory/storeShared.ts +3 -2
  57. package/ai/policy/commercialMultiplier.ts +16 -0
  58. package/ai/token/billingAdminAuditEvent.ts +68 -0
  59. package/ai/token/billingAdminAuditEventWriter.ts +41 -0
  60. package/ai/token/billingAnomaly.ts +90 -0
  61. package/ai/token/billingAnomalyLifecycle.ts +54 -0
  62. package/ai/token/billingAnomalyLifecycleWriter.ts +44 -0
  63. package/ai/token/billingAnomalyWriter.ts +41 -0
  64. package/ai/token/calculatePrice.ts +3 -2
  65. package/ai/token/deepinfraReconciliation.ts +153 -0
  66. package/ai/token/deepinfraRequestIdQuery.ts +92 -0
  67. package/ai/token/externalToolCost.ts +54 -41
  68. package/ai/token/missingUsageEstimate.ts +12 -3
  69. package/ai/token/normalizeUsage.ts +45 -5
  70. package/ai/token/openaiReconciliation.ts +188 -0
  71. package/ai/token/providerBillableEvent.ts +84 -0
  72. package/ai/token/providerBillableEventWriter.ts +36 -0
  73. package/ai/token/providerBillingAnomalyDrilldown.ts +308 -0
  74. package/ai/token/providerBillingDrilldown.ts +361 -0
  75. package/ai/token/providerBillingHealthReport.ts +366 -0
  76. package/ai/token/providerCall.ts +144 -0
  77. package/ai/token/providerCallSweeper.ts +168 -0
  78. package/ai/token/providerCallWriter.ts +33 -0
  79. package/ai/token/providerCredential.ts +89 -0
  80. package/ai/token/providerCredentialAnomaly.ts +154 -0
  81. package/ai/token/providerCredentialLifecycle.ts +59 -0
  82. package/ai/token/providerCredentialLifecycleWriter.ts +44 -0
  83. package/ai/token/providerCredentialRegistry.ts +83 -0
  84. package/ai/token/providerCredentialRegistryCommand.ts +97 -0
  85. package/ai/token/providerCredentialRegistryList.ts +124 -0
  86. package/ai/token/providerCredentialRegistryResolver.ts +150 -0
  87. package/ai/token/providerCredentialRegistryWriter.ts +41 -0
  88. package/ai/token/providerCredentialRotationCommand.ts +102 -0
  89. package/ai/token/providerCredentialRuntime.ts +56 -0
  90. package/ai/token/providerDispatchIntent.ts +67 -0
  91. package/ai/token/providerDispatchIntentWriter.ts +36 -0
  92. package/ai/token/providerGateway.ts +260 -0
  93. package/ai/token/providerReconciliation.ts +148 -0
  94. package/ai/token/providerReconciliationLocal.ts +97 -0
  95. package/ai/token/providerReconciliationRunner.ts +165 -0
  96. package/ai/token/providerReconciliationWriter.ts +41 -0
  97. package/ai/token/ratingResult.ts +202 -0
  98. package/ai/token/ratingResultWriter.ts +33 -0
  99. package/ai/token/serverDialogProjection.ts +5 -3
  100. package/ai/token/serverTokenWriter.ts +11 -3
  101. package/ai/token/types.ts +10 -0
  102. package/ai/tools/agent/callAgentTool.ts +3 -4
  103. package/ai/tools/agent/presets/appBuilderPreset.ts +5 -7
  104. package/ai/tools/agent/runStreamingAgentTool.ts +1 -2
  105. package/ai/tools/agent/streamParallelAgentsTool.ts +2 -3
  106. package/ai/tools/readXPostTool.ts +1 -5
  107. package/app/admin/adminPages.ts +9 -0
  108. package/app/i18n/i18n.config.ts +5 -0
  109. package/app/i18n/translations/pricing.locale.ts +397 -0
  110. package/app/utils/desktopAgentRuntimeStatusClient.ts +5 -4
  111. package/app/utils/desktopAgentRuntimeTurnClient.ts +4 -1
  112. package/app/utils/imageUtils.ts +64 -34
  113. package/auth/adminPermissions.ts +18 -0
  114. package/auth/authSlice.ts +26 -12
  115. package/auth/hooks/useFetchUsers.ts +3 -0
  116. package/auth/routes.ts +46 -0
  117. package/auth/server/accessActivity.ts +4 -3
  118. package/auth/server/adminPermissions.ts +43 -0
  119. package/auth/server/adminUsageReport.ts +375 -0
  120. package/auth/server/billingAnomalies.ts +235 -0
  121. package/auth/server/billingUsageReport.ts +41 -2
  122. package/auth/server/creatorEarningCreditConversion.ts +10 -2
  123. package/auth/server/deduct.ts +14 -7
  124. package/auth/server/delete.ts +10 -2
  125. package/auth/server/disable.ts +4 -3
  126. package/auth/server/emailAutomation.ts +7 -5
  127. package/auth/server/emailDbConfig.ts +4 -2
  128. package/auth/server/emailDelivery.ts +24 -20
  129. package/auth/server/emailDeliveryGuards.ts +10 -7
  130. package/auth/server/emailPreferences.ts +6 -4
  131. package/auth/server/emailReport.ts +6 -4
  132. package/auth/server/emailRuntimeConfig.ts +3 -3
  133. package/auth/server/emailScenarioNotifications.ts +9 -8
  134. package/auth/server/enable.ts +4 -3
  135. package/auth/server/getRechargeHistory.ts +3 -2
  136. package/auth/server/getUser.ts +3 -2
  137. package/auth/server/gptProAccess.ts +44 -0
  138. package/auth/server/inviteReward.ts +10 -7
  139. package/auth/server/listusers.ts +6 -4
  140. package/auth/server/login.ts +2 -2
  141. package/auth/server/productEntitlements.ts +7 -4
  142. package/auth/server/productPurchase.ts +10 -2
  143. package/auth/server/providerBillingDrilldown.ts +47 -0
  144. package/auth/server/providerBillingHealth.ts +71 -0
  145. package/auth/server/providerCredentials.ts +136 -0
  146. package/auth/server/recharge.ts +14 -8
  147. package/auth/server/revokeSessions.ts +4 -3
  148. package/auth/server/route.ts +77 -0
  149. package/auth/server/sendEmail.ts +5 -4
  150. package/auth/server/signup.ts +10 -3
  151. package/auth/server/token.ts +53 -55
  152. package/auth/server/tokenUsageBilling.ts +18 -7
  153. package/auth/server/usageManagementAccess.ts +43 -0
  154. package/auth/server/usageReport.ts +59 -0
  155. package/auth/types.ts +12 -0
  156. package/auth/utils.ts +24 -22
  157. package/authCommands.ts +36 -2
  158. package/buildPublish.ts +3 -1
  159. package/buildPublishArtifactAssembly.ts +62 -1
  160. package/buildPublishImportAnalysis.ts +21 -16
  161. package/chat/dialog/dialogLaunchScope.ts +32 -0
  162. package/chat/dialog/objectAssistantRegistry.ts +2 -2
  163. package/chat/dialog/useCreateDialog.ts +1 -1
  164. package/chat/hooks/useChatInput.ts +41 -10
  165. package/chat/messages/messageSlice.ts +5 -1
  166. package/chat/messages/pendingAttachmentParts.ts +28 -2
  167. package/chat/messages/sendFirstMessage.ts +76 -79
  168. package/chat/messages/types.ts +9 -0
  169. package/chat/messages/web/streamingMarkdownModel.ts +41 -0
  170. package/chat/messages/web/useStreamingReveal.ts +91 -0
  171. package/chat/web/messageInputAgentUi.ts +94 -6
  172. package/cliEnvHelpers.ts +68 -13
  173. package/cliRuntimeDoctorReport.ts +193 -0
  174. package/client/agentConfigResolver.test.ts +0 -2
  175. package/client/agentRun.test.ts +171 -10
  176. package/client/agentRun.ts +44 -637
  177. package/client/agentRunInput.ts +10 -0
  178. package/client/agentRunLocalExecutor.ts +179 -0
  179. package/client/agentRunServerTransport.ts +394 -0
  180. package/client/agentRunTaskRunRecorder.ts +176 -0
  181. package/client/localRuntimeAdapter.test.ts +236 -9
  182. package/client/localRuntimeAdapter.ts +221 -23
  183. package/client/localToolPolicy.test.ts +28 -4
  184. package/connector-experimental/daemonLauncher.ts +38 -4
  185. package/connectorRunArtifact.ts +34 -10
  186. package/connectorWebSocketTarget.ts +40 -15
  187. package/core/builtinAgents.ts +155 -11
  188. package/create/space/contentLabels.ts +1 -1
  189. package/create/space/contentTypeMeta.ts +3 -2
  190. package/create/space/sidebarVisibleTypes.ts +27 -0
  191. package/create/space/space.locale.ts +76 -4
  192. package/database/actions/agentReadResolution.ts +2 -8
  193. package/database/actions/read.ts +11 -9
  194. package/database/actions/readAndWait.ts +10 -5
  195. package/database/server/agentDelegation.ts +3 -2
  196. package/database/server/authorityStoreConformance.ts +209 -0
  197. package/database/server/authorityStoreTypes.ts +31 -0
  198. package/database/server/coreDataProxy.ts +1 -1
  199. package/database/server/dataHandlers.ts +13 -5
  200. package/database/server/db.ts +15 -34
  201. package/database/server/delete.ts +88 -71
  202. package/database/server/emailRepository.ts +11 -9
  203. package/database/server/fileService.ts +2 -1
  204. package/database/server/legacyServerDb.ts +58 -0
  205. package/database/server/levelAuthorityStore.ts +75 -0
  206. package/database/server/memoryAuthorityStore.ts +133 -0
  207. package/database/server/patch.ts +13 -12
  208. package/database/server/query.ts +3 -2
  209. package/database/server/read.ts +33 -30
  210. package/database/server/resourceAccess.ts +7 -5
  211. package/database/server/serverStoreFactory.ts +124 -0
  212. package/database/server/spaceMemberAuthority.ts +3 -2
  213. package/database/server/storeBatchCompat.ts +37 -0
  214. package/database/server/testAuthorityStore.ts +76 -0
  215. package/database/server/write.ts +29 -27
  216. package/dialogReadCommands.ts +2 -1
  217. package/dialogStatusCommands.ts +2 -1
  218. package/integrations/anthropic/anthropicModels.ts +12 -12
  219. package/integrations/deepseek/models.ts +67 -67
  220. package/integrations/google/models.ts +111 -53
  221. package/integrations/openai/models.ts +22 -22
  222. package/integrations/xai/models.ts +1 -1
  223. package/localRuntimeDb.ts +39 -2
  224. package/machineCommandPrompts.ts +2 -0
  225. package/machineCommands.ts +193 -62
  226. package/machineStatusCommands.ts +4 -12
  227. package/machineWsRunDispatch.ts +80 -15
  228. package/machineWsSession.ts +46 -2
  229. package/noloReadBridgePrompt.ts +16 -0
  230. package/package.json +114 -21
  231. package/pageCreateCommands.ts +2 -2
  232. package/pageDeleteCommands.ts +3 -3
  233. package/pageReadCommands.ts +3 -3
  234. package/pageUpdateCommands.ts +3 -3
  235. package/render/layout/mainLayoutViewMode.ts +25 -0
  236. package/render/page/server/createPage.ts +3 -1
  237. package/render/page/server/handleCreatePage.ts +2 -11
  238. package/runtimeDoctorCommands.ts +18 -69
  239. package/server/api/methods.ts +34 -12
  240. package/server/api/tableHandlers.ts +6 -3
  241. package/server/authenticateToken.ts +47 -2
  242. package/server/billingLedgerRoutes.ts +15 -0
  243. package/server/buildManifest.ts +54 -0
  244. package/server/coreReadiness.ts +34 -25
  245. package/server/coreRuntime.ts +15 -10
  246. package/server/handlers/activityStatsHandler.ts +5 -2
  247. package/server/handlers/agentEmailRegistrationE2EHandler.ts +25 -23
  248. package/server/handlers/agentRun/agentLookup.ts +1 -7
  249. package/server/handlers/agentRun/autonomousRuntime.ts +11 -10
  250. package/server/handlers/agentRun/builtinAgents.ts +12 -88
  251. package/server/handlers/agentRun/continueDialogContext.ts +15 -3
  252. package/server/handlers/agentRun/{inheritedDialogPrompt.ts → conversationReference.ts} +3 -3
  253. package/server/handlers/agentRun/dialogLookup.ts +4 -3
  254. package/server/handlers/agentRun/index.ts +864 -404
  255. package/server/handlers/agentRun/localRuntimeBootstrap.ts +17 -1
  256. package/server/handlers/agentRun/loop.ts +920 -508
  257. package/server/handlers/agentRun/machineConnector.ts +56 -8
  258. package/server/handlers/agentRun/machineRunAudit.ts +3 -2
  259. package/server/handlers/agentRun/modelUsageToolHandlers.ts +13 -10
  260. package/server/handlers/agentRun/requestContext.ts +12 -8
  261. package/server/handlers/agentRun/runtimeExecutionContext.ts +15 -3
  262. package/server/handlers/agentRun/runtimePreparation.ts +26 -24
  263. package/server/handlers/agentRun/runtimeRouting.ts +25 -40
  264. package/server/handlers/agentRun/runtimeSystemMessages.ts +65 -0
  265. package/server/handlers/agentRun/saveDialog.ts +97 -87
  266. package/server/handlers/agentRun/taskRunToolHandler.ts +9 -7
  267. package/server/handlers/agentRun/toolExecutor.ts +42 -78
  268. package/server/handlers/agentRun/types.ts +2 -1
  269. package/server/handlers/appDeployStatusStore.ts +17 -10
  270. package/server/handlers/appDomainHandler.ts +21 -15
  271. package/server/handlers/appLegacyInfraCleanup.ts +5 -2
  272. package/server/handlers/appSandboxHandler.ts +29 -8
  273. package/server/handlers/appSpaceAccess.ts +15 -8
  274. package/server/handlers/chatHandler.ts +22 -2
  275. package/server/handlers/chatUpstreamRetry.ts +225 -2
  276. package/server/handlers/connector/connectorConnectionRegistry.ts +55 -7
  277. package/server/handlers/connector/connectorWebSocket.ts +14 -10
  278. package/server/handlers/desktopAgentRuntimeAdapter.ts +4 -4
  279. package/server/handlers/desktopAgentRuntimeHostCapabilities.ts +25 -0
  280. package/server/handlers/desktopAgentRuntimeReadiness.ts +62 -0
  281. package/server/handlers/desktopAgentRuntimeStatusHandler.ts +38 -30
  282. package/server/handlers/desktopAgentRuntimeTurnHandler.ts +7 -3
  283. package/server/handlers/desktopAgentRuntimeTurnService.ts +39 -45
  284. package/server/handlers/desktopLlamaRuntimeHandler.ts +85 -51
  285. package/server/handlers/desktopUpdaterHandler.ts +132 -24
  286. package/server/handlers/favoriteHandlers.ts +8 -2
  287. package/server/handlers/getDialogBillingHandler.ts +4 -3
  288. package/server/handlers/getTransactionsHandler.ts +5 -2
  289. package/server/handlers/machines/machineBinding.ts +1 -0
  290. package/server/handlers/machines/machineHandlers.ts +0 -14
  291. package/server/handlers/machines/machineInstallAssets.ts +4 -2
  292. package/server/handlers/notificationEmitter.ts +5 -3
  293. package/server/handlers/notificationsHandler.ts +5 -2
  294. package/server/handlers/providerCallsRecentHandler.ts +234 -0
  295. package/server/handlers/providerReconciliationRunHandler.ts +180 -0
  296. package/server/handlers/providerRequestIdsHandler.ts +105 -0
  297. package/server/handlers/tableAccess.ts +6 -2
  298. package/server/handlers/tableToolHandlers.ts +28 -14
  299. package/server/handlers/userSecretsHandler.ts +17 -6
  300. package/server/handlers/versionHandler.ts +9 -4
  301. package/server/handlers/versionStore.ts +18 -10
  302. package/server/html/ssrPreload.ts +5 -3
  303. package/server/payments/crypto/cryptoUsdcBasePaymentProvider.ts +11 -8
  304. package/server/payments/crypto/cryptoUsdcBaseScanner.ts +12 -7
  305. package/server/payments/crypto/cryptoUsdtTronPaymentProvider.ts +11 -8
  306. package/server/payments/crypto/cryptoUsdtTronScanner.ts +9 -7
  307. package/server/payments/waffo/waffoPaymentProvider.ts +12 -9
  308. package/server/runtimeRole.ts +15 -0
  309. package/server/scheduler/scheduledTaskRuntime.ts +4 -2
  310. package/server/scheduler/schedulerService.ts +2 -2
  311. package/server/taskRunBridgeRoutes.ts +8 -5
  312. package/share/server/fetchCommunityShares.ts +1 -1
  313. package/share/server/helpers.ts +19 -17
  314. package/share/server/importShare.ts +9 -13
  315. package/share/server/listCommunityShares.ts +4 -4
  316. package/share/server/purchaseDoc.ts +8 -16
  317. package/share/server/readCommunityShareCover.ts +3 -2
  318. package/share/server/readSharedTable.ts +14 -13
  319. package/share/server/tableReplication.ts +42 -39
  320. package/spaceAttachCommands.ts +135 -0
  321. package/spaceCategoryCommands.ts +6 -6
  322. package/spaceCommands.ts +3 -3
  323. package/spaceDeleteCommands.ts +2 -2
  324. package/spaceInternalCommandEntries.ts +2 -0
  325. package/spaceReadCommands.ts +3 -3
  326. package/tableMetaCommands.ts +2 -2
  327. package/taskRunCommand.ts +11 -0
  328. package/ai/agent/runtimeServerBase.ts +0 -37
  329. package/server/handlers/desktopAgentRuntimeHostFacts.ts +0 -40
@@ -0,0 +1,117 @@
1
+ export type ShellCommandPolicyVerdict = "allowed" | "forbidden";
2
+
3
+ export type ShellCommandPolicyResult =
4
+ | {
5
+ verdict: "allowed";
6
+ }
7
+ | {
8
+ verdict: "forbidden";
9
+ code: "destructive_action_requires_confirmation";
10
+ reason: string;
11
+ policy: {
12
+ capability: "destructive_action";
13
+ target: "shell_command";
14
+ detail: string;
15
+ };
16
+ };
17
+
18
+ const DESTRUCTIVE_NEGATION_PATTERNS = [
19
+ "别删",
20
+ "别删除",
21
+ "不要删",
22
+ "不要删除",
23
+ "别乱删",
24
+ "别动",
25
+ "不要动",
26
+ "不要清理",
27
+ "不要清空",
28
+ "不要重置",
29
+ "don't delete",
30
+ "do not delete",
31
+ "don't remove",
32
+ "do not remove",
33
+ "without deleting",
34
+ ] as const;
35
+
36
+ const EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS = [
37
+ "删除",
38
+ "删掉",
39
+ "移除",
40
+ "清理",
41
+ "清空",
42
+ "重置",
43
+ "drop",
44
+ "delete",
45
+ "remove",
46
+ "erase",
47
+ "clean up",
48
+ "reset",
49
+ ] as const;
50
+
51
+ const SHELL_DESTRUCTIVE_PATTERNS = [
52
+ /\brm\s+(-[^\n\r]*\s+)?/i,
53
+ /\bremove-item\b/i,
54
+ /\bdel\s+\/?[a-z]*\s+/i,
55
+ /\berase\s+/i,
56
+ /\brmdir\s+/i,
57
+ /\brd\s+\/s\b/i,
58
+ /\bgit\s+reset\s+(--hard\b|--merge\b|--keep\b)/i,
59
+ /\bgit\s+clean\s+-[^\n\r]*f/i,
60
+ /\bgit\s+checkout\s+--\b/i,
61
+ /\bgit\s+restore\s+--source=/i,
62
+ ] as const;
63
+
64
+ const normalizeUserInput = (value: unknown): string =>
65
+ typeof value === "string" ? value.trim().toLowerCase() : "";
66
+
67
+ const containsAny = (text: string, patterns: readonly string[]): boolean =>
68
+ patterns.some((pattern) => text.includes(pattern));
69
+
70
+ const hasExplicitDestructivePermission = (userInput: unknown): boolean => {
71
+ const normalized = normalizeUserInput(userInput);
72
+ if (!normalized) return false;
73
+ if (containsAny(normalized, DESTRUCTIVE_NEGATION_PATTERNS)) return false;
74
+ return containsAny(normalized, EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS);
75
+ };
76
+
77
+ const buildCombinedShellInput = (args: {
78
+ command?: unknown;
79
+ input?: unknown;
80
+ }): string =>
81
+ [
82
+ typeof args.command === "string" ? args.command : "",
83
+ typeof args.input === "string" ? args.input : "",
84
+ ]
85
+ .filter(Boolean)
86
+ .join("\n");
87
+
88
+ export function isDestructiveShellCommand(args: {
89
+ command?: unknown;
90
+ input?: unknown;
91
+ }): boolean {
92
+ const combined = buildCombinedShellInput(args);
93
+ if (!combined.trim()) return false;
94
+ return SHELL_DESTRUCTIVE_PATTERNS.some((pattern) => pattern.test(combined));
95
+ }
96
+
97
+ export function evaluateShellCommandPolicy(args: {
98
+ command?: unknown;
99
+ input?: unknown;
100
+ userInput?: unknown;
101
+ }): ShellCommandPolicyResult {
102
+ if (isDestructiveShellCommand(args) && !hasExplicitDestructivePermission(args.userInput)) {
103
+ return {
104
+ verdict: "forbidden",
105
+ code: "destructive_action_requires_confirmation",
106
+ reason:
107
+ "当前运行默认禁止自动执行可能删除用户内容的 shell 命令。只有当用户在当前请求里明确要求删除/清理时,才能继续;否则请停止并先说明限制。",
108
+ policy: {
109
+ capability: "destructive_action",
110
+ target: "shell_command",
111
+ detail: "execShell destructive command",
112
+ },
113
+ };
114
+ }
115
+
116
+ return { verdict: "allowed" };
117
+ }
@@ -0,0 +1,38 @@
1
+ import { canonicalizeToolName } from "../ai/tools/toolNameAliases";
2
+
3
+ export type RuntimeToolGateDecision =
4
+ | { allowed: true; toolName: string }
5
+ | { allowed: false; toolName: string; reason: string };
6
+
7
+ function normalizeExposedToolNames(toolNames?: string[]): Set<string> {
8
+ return new Set(
9
+ (toolNames ?? [])
10
+ .map((toolName) => canonicalizeToolName(String(toolName ?? "").replace(/^functions\./, "").trim()))
11
+ .filter(Boolean),
12
+ );
13
+ }
14
+
15
+ export function resolveRuntimeToolGate(args: {
16
+ toolName: string;
17
+ exposedToolNames?: string[];
18
+ forbiddenReason?: string;
19
+ }): RuntimeToolGateDecision {
20
+ const toolName = canonicalizeToolName(args.toolName.replace(/^functions\./, "").trim());
21
+ if (!toolName) {
22
+ return {
23
+ allowed: false,
24
+ toolName,
25
+ reason: "Tool name is required.",
26
+ };
27
+ }
28
+
29
+ if (normalizeExposedToolNames(args.exposedToolNames).has(toolName)) {
30
+ return { allowed: true, toolName };
31
+ }
32
+
33
+ return {
34
+ allowed: false,
35
+ toolName,
36
+ reason: args.forbiddenReason ?? `${toolName} is not exposed by this runtime turn.`,
37
+ };
38
+ }
@@ -3,6 +3,7 @@ import { createSpaceKey } from "./create/space/spaceKeys";
3
3
  import { readDbRecord, writeDbRecord } from "./agentRecordHelpers";
4
4
  import {
5
5
  parseUserIdFromAuthToken,
6
+ readCliOptionValue,
6
7
  resolveAuthToken,
7
8
  resolveServerUrl,
8
9
  type EnvLike,
@@ -68,11 +69,13 @@ function buildAgentKeys(agentId: string, userId: string) {
68
69
 
69
70
  async function createCustomAgentWithCliAuth(
70
71
  options: CreateCustomCodingAgentOptions,
71
- deps: Pick<AgentCreateCustomDeps, "env" | "fallbackFetchImpl" | "fetchImpl">
72
+ deps: Pick<AgentCreateCustomDeps, "env" | "fallbackFetchImpl" | "fetchImpl"> & {
73
+ cliArgs?: string[];
74
+ }
72
75
  ) {
73
76
  const env = deps.env ?? process.env;
74
77
  const fetchImpl = deps.fetchImpl ?? fetch;
75
- const authToken = resolveAuthToken(env);
78
+ const authToken = readCliOptionValue(deps.cliArgs ?? [], "--token") || resolveAuthToken(env);
76
79
  const userId = parseUserIdFromAuthToken(authToken);
77
80
  if (!authToken || !userId) {
78
81
  throw new Error("agent create-custom requires an auth token with userId. Run `nolo login`.");
@@ -232,9 +235,11 @@ export async function runAgentCreateCustomCommand(
232
235
  }
233
236
 
234
237
  try {
235
- const createCustomAgent = deps.createCustomAgent ?? ((options) => createCustomAgentWithCliAuth(options, deps));
238
+ const createCustomAgent =
239
+ deps.createCustomAgent ??
240
+ ((options) => createCustomAgentWithCliAuth(options, { ...deps, cliArgs: args }));
236
241
  const result = await createCustomAgent({
237
- baseUrl: resolveServerUrl(env),
242
+ baseUrl: resolveServerUrl(args, env),
238
243
  spaceId: readOption(args, "--space-id"),
239
244
  agentId: env.CUSTOM_AGENT_ID,
240
245
  apiKey,
@@ -93,7 +93,7 @@ export async function runAgentDialogsCommand(
93
93
  return agentInput ? 0 : 1;
94
94
  }
95
95
 
96
- const authToken = resolveAuthToken(env);
96
+ const authToken = resolveAuthToken(args, env);
97
97
  if (!authToken) {
98
98
  output.write("[nolo] agent dialogs requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
99
99
  return 1;
@@ -112,12 +112,13 @@ export async function runAgentDialogsCommand(
112
112
  const db = deps.db ?? await getReadableCliDb(output);
113
113
  const fetchImpl = deps.fetchImpl ?? fetch;
114
114
  const fallbackFetchImpl = deps.fallbackFetchImpl;
115
- const serverUrl = resolveServerUrl(env);
116
- const serverCandidates = resolveServerCandidates(env, serverUrl);
115
+ const serverUrl = resolveServerUrl(args, env);
116
+ const serverCandidates = resolveServerCandidates(args, env, serverUrl);
117
117
 
118
118
  try {
119
119
  const resolvedAgent = await resolveAgentRecordFromHybridStore({
120
120
  agentInput,
121
+ cliArgs: args,
121
122
  env,
122
123
  db,
123
124
  fetchImpl,
@@ -45,7 +45,7 @@ export async function runAgentDoctorCommand(
45
45
  return 0;
46
46
  }
47
47
 
48
- const authToken = resolveAuthToken(env);
48
+ const authToken = resolveAuthToken(args, env);
49
49
  if (!authToken) {
50
50
  output.write("[nolo] agent doctor requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
51
51
  return 1;
@@ -60,8 +60,8 @@ export async function runAgentDoctorCommand(
60
60
  const db = deps.db ?? await getReadableCliDb(output);
61
61
  const fetchImpl = deps.fetchImpl ?? fetch;
62
62
  const fallbackFetchImpl = deps.fallbackFetchImpl;
63
- const defaultServerUrl = resolveServerUrl(env);
64
- const serverCandidates = resolveServerCandidates(env, defaultServerUrl);
63
+ const defaultServerUrl = resolveServerUrl(args, env);
64
+ const serverCandidates = resolveServerCandidates(args, env, defaultServerUrl);
65
65
 
66
66
  try {
67
67
  const [profile, settings, agents] = await Promise.all([
@@ -25,7 +25,7 @@ export async function runAgentListCommand(
25
25
  const output = deps.output ?? process.stdout;
26
26
  const { wantJson, publicOnly, idsOnly, includeLegacy } = parseAgentListArgs(args);
27
27
 
28
- const authToken = resolveAuthToken(env);
28
+ const authToken = resolveAuthToken(args, env);
29
29
  if (!authToken) {
30
30
  output.write("[nolo] agent list requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
31
31
  return 1;
@@ -40,8 +40,8 @@ export async function runAgentListCommand(
40
40
  const db = deps.db ?? await getReadableCliDb(output);
41
41
  const fetchImpl = deps.fetchImpl ?? fetch;
42
42
  const fallbackFetchImpl = deps.fallbackFetchImpl;
43
- const serverUrl = resolveServerUrl(env);
44
- const serverCandidates = resolveServerCandidates(env, serverUrl);
43
+ const serverUrl = resolveServerUrl(args, env);
44
+ const serverCandidates = resolveServerCandidates(args, env, serverUrl);
45
45
 
46
46
  try {
47
47
  const loadRemoteAgents = async () => {
@@ -225,7 +225,7 @@ export async function runAgentBindCurrentCommand(
225
225
  return agentKey ? 0 : 1;
226
226
  }
227
227
 
228
- const authToken = resolveAuthToken(env);
228
+ const authToken = resolveAuthToken(args, env);
229
229
  if (!authToken) {
230
230
  output.write("[nolo] agent bind-current requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
231
231
  return 1;
@@ -237,7 +237,7 @@ export async function runAgentBindCurrentCommand(
237
237
  return 1;
238
238
  }
239
239
 
240
- const serverUrl = resolveServerUrl(env);
240
+ const serverUrl = resolveServerUrl(args, env);
241
241
  const fetchImpl = deps.fetchImpl ?? fetch;
242
242
  const fallbackFetchImpl = deps.fallbackFetchImpl;
243
243
  const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
@@ -292,7 +292,7 @@ export async function runAgentSmokeCurrentCommand(
292
292
  }
293
293
  const agentKey = resolveCliAgentKeyInput(agentInput);
294
294
 
295
- const authToken = resolveAuthToken(env);
295
+ const authToken = resolveAuthToken(args, env);
296
296
  if (!authToken) {
297
297
  output.write("[nolo] agent smoke-current requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
298
298
  return 1;
@@ -304,7 +304,7 @@ export async function runAgentSmokeCurrentCommand(
304
304
  }
305
305
 
306
306
  const userInput = readOption(args, "--msg") ?? "Smoke test from nolo connector.";
307
- const serverUrl = resolveServerUrl(env);
307
+ const serverUrl = resolveServerUrl(args, env);
308
308
  const fetchImpl = deps.fetchImpl ?? fetch;
309
309
  const fallbackFetchImpl = deps.fallbackFetchImpl;
310
310
  const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
@@ -415,13 +415,13 @@ export async function runAgentRuntimeDoctorCommand(
415
415
  }
416
416
  const agentKey = resolveCliAgentKeyInput(agentInput);
417
417
 
418
- const authToken = resolveAuthToken(env);
418
+ const authToken = resolveAuthToken(args, env);
419
419
  if (!authToken) {
420
420
  output.write("[nolo] agent runtime-doctor requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
421
421
  return 1;
422
422
  }
423
423
 
424
- const serverUrl = resolveServerUrl(env);
424
+ const serverUrl = resolveServerUrl(args, env);
425
425
  const fetchImpl = deps.fetchImpl ?? fetch;
426
426
  const fallbackFetchImpl = deps.fallbackFetchImpl;
427
427
  const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
@@ -4,8 +4,8 @@ import type { OutputLike } from "./cliIoTypes";
4
4
  import { resolveCliAgentKeyInput } from "./agentAliases";
5
5
  import {
6
6
  readCliOptionValue,
7
- resolveAuthTokenFromEnv,
8
- resolveServerUrlFromEnv,
7
+ resolveAuthToken,
8
+ resolveServerUrl,
9
9
  } from "./cliEnvHelpers";
10
10
 
11
11
  type EnvLike = Record<string, string | undefined>;
@@ -44,14 +44,6 @@ export function parseAgentPullArgs(args: string[]): ParsedAgentPullArgs | null {
44
44
  return { agentKey: resolveCliAgentKeyInput(agentKey) };
45
45
  }
46
46
 
47
- function resolveServerUrl(env: EnvLike) {
48
- return resolveServerUrlFromEnv(env);
49
- }
50
-
51
- function resolveAuthToken(env: EnvLike) {
52
- return resolveAuthTokenFromEnv(env);
53
- }
54
-
55
47
  function extractToolNames(record: any) {
56
48
  if (Array.isArray(record?.toolNames)) return record.toolNames.filter((tool: unknown) => typeof tool === "string");
57
49
  if (!Array.isArray(record?.tools)) return [];
@@ -113,8 +105,8 @@ export async function runAgentPullCommand(args: string[], deps: AgentPullCommand
113
105
  return 1;
114
106
  }
115
107
 
116
- const serverUrl = resolveServerUrl(env);
117
- const authToken = resolveAuthToken(env);
108
+ const serverUrl = resolveServerUrl(args, env);
109
+ const authToken = resolveAuthToken(args, env);
118
110
  const fetchImpl = deps.fetchImpl ?? fetch;
119
111
  const db = deps.db ?? await getDefaultCliLocalRuntimeDb();
120
112
 
@@ -17,11 +17,11 @@ export async function runAgentReadCommand(
17
17
  const output = deps.output ?? process.stdout;
18
18
  const agentInput = args[0]?.trim();
19
19
  if (!agentInput || agentInput === "--help" || agentInput === "-h") {
20
- output.write("Usage: nolo agent read <agent>\n");
20
+ output.write("Usage: nolo agent read <agent> [--server <url>]\n");
21
21
  return agentInput ? 0 : 1;
22
22
  }
23
23
 
24
- const authToken = resolveAuthToken(env);
24
+ const authToken = resolveAuthToken(args, env);
25
25
  if (!authToken) {
26
26
  output.write("[nolo] agent read requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
27
27
  return 1;
@@ -35,6 +35,7 @@ export async function runAgentReadCommand(
35
35
  try {
36
36
  const result = await resolveAgentRecordFromHybridStore({
37
37
  agentInput,
38
+ cliArgs: args,
38
39
  env,
39
40
  db,
40
41
  fetchImpl,
@@ -79,7 +80,7 @@ export async function runAgentUpdateCommand(
79
80
  return args[0] ? 0 : 1;
80
81
  }
81
82
 
82
- const authToken = resolveAuthToken(env);
83
+ const authToken = resolveAuthToken(args, env);
83
84
  if (!authToken) {
84
85
  output.write("[nolo] agent update requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
85
86
  return 1;
@@ -97,6 +98,7 @@ export async function runAgentUpdateCommand(
97
98
 
98
99
  try {
99
100
  const built = await buildUpdatedAgentRecord({
101
+ cliArgs: args,
100
102
  parsed,
101
103
  env,
102
104
  db,
@@ -3,6 +3,7 @@ import { resolveCliAgentKeyInput } from "./agentAliases";
3
3
  import type { CliKvDb } from "./client/hybridRecordStore";
4
4
  import { buildLocalAgentLookupKeys, shouldReadAgentKeyRemotely } from "./client/localAgentRecords";
5
5
  import {
6
+ hasExplicitServerOverride,
6
7
  parseUserIdFromAuthToken,
7
8
  readOption,
8
9
  resolveAuthToken,
@@ -262,34 +263,21 @@ export async function deleteDbRecord(args: {
262
263
 
263
264
  export async function resolveAgentRecordFromHybridStore(args: {
264
265
  agentInput: string;
266
+ cliArgs?: string[];
265
267
  env: EnvLike;
266
268
  db: CliKvDb;
267
269
  fetchImpl: typeof fetch;
268
270
  fallbackFetchImpl?: typeof fetch;
269
271
  }) {
270
272
  const agentKey = resolveCliAgentKeyInput(args.agentInput);
271
- const authToken = resolveAuthToken(args.env);
272
- const defaultServerUrl = resolveServerUrl(args.env);
273
-
274
- for (const key of buildLocalAgentLookupKeys({
275
- agentRef: agentKey,
276
- userId: parseUserIdFromAuthToken(authToken) || "local",
277
- })) {
278
- try {
279
- const record = await args.db.get(key);
280
- if (record && typeof record === "object") {
281
- return {
282
- agentKey: key,
283
- record,
284
- source: record?.serverOrigin ? "remote-cache" : "local-cache",
285
- } as const;
286
- }
287
- } catch {
288
- // local miss
289
- }
290
-
291
- if (!shouldReadAgentKeyRemotely(key)) continue;
292
- for (const serverUrl of resolveServerCandidates(args.env, defaultServerUrl)) {
273
+ const authToken = resolveAuthToken(args.cliArgs ?? [], args.env);
274
+ const cliArgs = args.cliArgs ?? [];
275
+ const defaultServerUrl = resolveServerUrl(cliArgs, args.env);
276
+ const serverCandidates = resolveServerCandidates(cliArgs, args.env, defaultServerUrl);
277
+ const preferRemote = hasExplicitServerOverride(cliArgs);
278
+
279
+ const readRemoteRecord = async (key: string) => {
280
+ for (const serverUrl of serverCandidates) {
293
281
  try {
294
282
  const remoteRecord = await readAgentRecord({
295
283
  agentKey: key,
@@ -309,6 +297,34 @@ export async function resolveAgentRecordFromHybridStore(args: {
309
297
  // try next
310
298
  }
311
299
  }
300
+ return null;
301
+ };
302
+
303
+ for (const key of buildLocalAgentLookupKeys({
304
+ agentRef: agentKey,
305
+ userId: parseUserIdFromAuthToken(authToken) || "local",
306
+ })) {
307
+ if (preferRemote && shouldReadAgentKeyRemotely(key)) {
308
+ const remoteFirst = await readRemoteRecord(key);
309
+ if (remoteFirst) return remoteFirst;
310
+ }
311
+
312
+ try {
313
+ const record = await args.db.get(key);
314
+ if (record && typeof record === "object") {
315
+ return {
316
+ agentKey: key,
317
+ record,
318
+ source: record?.serverOrigin ? "remote-cache" : "local-cache",
319
+ } as const;
320
+ }
321
+ } catch {
322
+ // local miss
323
+ }
324
+
325
+ if (!shouldReadAgentKeyRemotely(key)) continue;
326
+ const remoteFallback = await readRemoteRecord(key);
327
+ if (remoteFallback) return remoteFallback;
312
328
  }
313
329
 
314
330
  return null;
@@ -380,6 +396,7 @@ export function parseAgentUpdateArgs(args: string[]) {
380
396
  }
381
397
 
382
398
  export async function buildUpdatedAgentRecord(args: {
399
+ cliArgs?: string[];
383
400
  parsed: NonNullable<ReturnType<typeof parseAgentUpdateArgs>>;
384
401
  env: EnvLike;
385
402
  db: CliKvDb;
@@ -389,13 +406,14 @@ export async function buildUpdatedAgentRecord(args: {
389
406
  }) {
390
407
  const cached = await resolveAgentRecordFromHybridStore({
391
408
  agentInput: args.parsed.agentInput,
409
+ cliArgs: args.cliArgs,
392
410
  env: args.env,
393
411
  db: args.db,
394
412
  fetchImpl: args.fetchImpl,
395
413
  fallbackFetchImpl: args.fallbackFetchImpl,
396
414
  });
397
415
  const agentKey = cached?.agentKey ?? resolveCliAgentKeyInput(args.parsed.agentInput);
398
- const serverUrl = cached?.record?.serverOrigin ?? resolveServerUrl(args.env);
416
+ const serverUrl = cached?.record?.serverOrigin ?? resolveServerUrl(args.cliArgs ?? [], args.env);
399
417
  const currentRecord = await readAgentRecord({
400
418
  agentKey,
401
419
  authToken: args.authToken,
@@ -407,6 +425,7 @@ export async function buildUpdatedAgentRecord(args: {
407
425
  if (args.parsed.copyProviderFrom) {
408
426
  const providerSource = await resolveAgentRecordFromHybridStore({
409
427
  agentInput: args.parsed.copyProviderFrom,
428
+ cliArgs: args.cliArgs,
410
429
  env: args.env,
411
430
  db: args.db,
412
431
  fetchImpl: args.fetchImpl,
@@ -1,4 +1,3 @@
1
- import { DEFAULT_NOLO_SERVER_URL } from "./defaultServer";
2
1
  import { runAgentTurn, type RunAgentTurnResult } from "./client/agentRun";
3
2
  import type { AgentRuntimeHostAdapter } from "./agentRuntimeLocal";
4
3
  import {
@@ -20,6 +19,7 @@ import {
20
19
  type ParsedAgentRunArgs,
21
20
  type ResolvedWorkflowReference,
22
21
  } from "./agentRunParsing";
22
+ import { resolveServerUrl } from "./cliEnvHelpers";
23
23
 
24
24
  type AgentRunCommandDeps = {
25
25
  env?: EnvLike;
@@ -49,10 +49,6 @@ function shouldPrintLocalRunSummary(args: {
49
49
  return Boolean(args.localRuntimeCwd && args.parsed.runtimeMode === "local");
50
50
  }
51
51
 
52
- function resolveServerUrl(env: EnvLike) {
53
- return (env.NOLO_SERVER || env.BASE_URL || DEFAULT_NOLO_SERVER_URL).replace(/\/+$/, "");
54
- }
55
-
56
52
  function writeUsage(output: OutputLike) {
57
53
  output.write(
58
54
  "Usage: nolo agent run <agent> <message> [--local|--server|--auto] [--continue <dialogId>] [--cwd <path>] [--max-tool-rounds <n>]\n" +
@@ -95,7 +91,7 @@ export async function runAgentRunCommand(args: string[], deps: AgentRunCommandDe
95
91
  const result: RunAgentTurnResult = await runner({
96
92
  agentName: parsed.agentKey,
97
93
  agentKey: parsed.agentKey,
98
- serverUrl: resolveServerUrl(env),
94
+ serverUrl: resolveServerUrl(args, env),
99
95
  message: prependWorkflowReferencePrompt(parsed.message, workflowReference),
100
96
  imageUrls: parsed.imageUrls.map(normalizeCliImageInput),
101
97
  scriptDir: deps.scriptDir,
@@ -1,6 +1,10 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { extname, resolve } from "node:path";
3
3
 
4
+ import {
5
+ buildAgentRunDialogLineageFields,
6
+ normalizeAgentRunDialogLineage,
7
+ } from "./ai/agent/agentRunDialogLineage";
4
8
  import { parseSkillDocProtocol, type WorkflowReferenceConfig } from "./ai/skills/skillDocProtocol";
5
9
 
6
10
  import { resolveCliAgentKeyInput } from "./agentAliases";
@@ -168,7 +172,10 @@ export function parseAgentRunArgs(
168
172
  if (!agentKey || !rawMessage.trim()) return null;
169
173
  const message = rawMessage.trim();
170
174
  const runtimeMode = runtimeModeFromArgs(args);
171
- const continueDialogId = readFlagValue(args, "--continue") ?? readFlagValue(args, "--dialog");
175
+ const rawContinueDialogId = readFlagValue(args, "--continue") ?? readFlagValue(args, "--dialog");
176
+ const continueDialogId = normalizeAgentRunDialogLineage({
177
+ continueDialogId: rawContinueDialogId,
178
+ }).continueDialogId;
172
179
  const spaceId = readFlagValue(args, "--space");
173
180
  const category = readFlagValue(args, "--category");
174
181
  const inheritedFromDialog = readFlagValue(args, "--inherit-from-dialog");
@@ -219,11 +226,17 @@ export function parseAgentRunArgs(
219
226
  background: args.includes("--bg"),
220
227
  noStream: args.includes("--no-stream"),
221
228
  noDefaultTestRoot,
222
- ...(continueDialogId ? { continueDialogId } : {}),
229
+ ...buildAgentRunDialogLineageFields({
230
+ continueDialogId,
231
+ inheritedFromDialogKey: inheritedRef?.dialogKey,
232
+ parentDialogId: inheritedRef?.dialogId,
233
+ }),
223
234
  ...(!continueDialogId && spaceId ? { spaceId } : {}),
224
- ...(category ? { category } : !continueDialogId && !noDefaultTestRoot ? { category: DEFAULT_TEST_DIALOG_CATEGORY_ID } : {}),
225
- ...(inheritedRef?.dialogKey ? { inheritedFromDialogKey: inheritedRef.dialogKey } : {}),
226
- ...(inheritedRef?.dialogId ? { parentDialogId: inheritedRef.dialogId } : {}),
235
+ ...(category
236
+ ? { category }
237
+ : !continueDialogId && !noDefaultTestRoot
238
+ ? { category: DEFAULT_TEST_DIALOG_CATEGORY_ID }
239
+ : {}),
227
240
  ...(cwd ? { cwd } : {}),
228
241
  ...(typeof maxToolRounds === "number" ? { maxToolRounds } : {}),
229
242
  ...(typeof timeoutMs === "number" ? { timeoutMs } : {}),
@@ -1,7 +1,9 @@
1
1
  export {
2
+ createHostRuntimeConfig,
2
3
  buildOpenAiCompatibleChatCompletionRequest,
3
4
  buildPlatformChatCompletionRequest,
4
5
  canUsePlatformChatProvider,
6
+ createHostRuntimeCapabilities,
5
7
  hasDirectOpenAiCompatibleProvider,
6
8
  createHybridRecordStore,
7
9
  executeLocalToolWithPolicy,
@@ -16,9 +18,12 @@ export {
16
18
  parsePlatformChatCompletionData,
17
19
  parsePlatformChatCompletionResponse,
18
20
  resolveAgentRuntimeConfigFromRecord,
21
+ resolveHostRuntimeConfigFromEnv,
22
+ resolveHostRuntimeCapabilitiesFromEnv,
19
23
  resolvePlatformChatProviderConfig,
20
24
  resolveLocalToolPolicy,
21
25
  resolveOpenAiCompatibleProviderConfig,
26
+ resolveRequestedRuntimeToolNames,
22
27
  shouldUsePlatformChatProvider,
23
28
  shouldCacheHybridRemoteRecord,
24
29
  shouldFetchAgentRuntimeRecordRemotely,
@@ -27,6 +32,7 @@ export { runLocalAgentTurn } from "./agent-runtime/localLoop";
27
32
  export {
28
33
  buildLocalWorkspaceOpenAiTools,
29
34
  buildLocalWorkspacePolicyToolNames,
35
+ resolveLocalWorkspaceShellToolExposure,
30
36
  buildLocalWorkspaceToolset,
31
37
  createLocalWorkspaceToolExecutors,
32
38
  } from "./agent-runtime/localWorkspaceTools";
@@ -35,6 +41,10 @@ export type {
35
41
  AgentRuntimeHostAdapter,
36
42
  AgentRuntimeRequestedMode,
37
43
  AgentRuntimeSaveTurnInput,
44
+ HostRuntimeConfig,
45
+ HostRuntimeCapabilities,
46
+ HostRuntimeSurface,
47
+ HostRuntimeWorkspaceBinding,
38
48
  HybridRecordKvDb,
39
49
  HybridRecordStore,
40
50
  LocalToolPolicyDecision,
@@ -36,7 +36,7 @@ export async function runAgentUnpublishCommand(
36
36
  return 1;
37
37
  }
38
38
 
39
- const authToken = resolveAuthToken(env);
39
+ const authToken = resolveAuthToken(args, env);
40
40
  if (!authToken) {
41
41
  output.write("[nolo] agent unpublish requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
42
42
  return 1;
@@ -51,13 +51,14 @@ export async function runAgentUnpublishCommand(
51
51
  const db = deps.db ?? await getReadableCliDb(output);
52
52
  const fetchImpl = deps.fetchImpl ?? fetch;
53
53
  const fallbackFetchImpl = deps.fallbackFetchImpl;
54
- const serverUrl = resolveServerUrl(env);
54
+ const serverUrl = resolveServerUrl(args, env);
55
55
  const privateKey = `agent-${userId}-${agentId}`;
56
56
  const publicKey = `agent-pub-${agentId}`;
57
57
 
58
58
  try {
59
59
  const resolved = await resolveAgentRecordFromHybridStore({
60
60
  agentInput: privateKey,
61
+ cliArgs: args,
61
62
  env,
62
63
  db,
63
64
  fetchImpl,