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,58 @@
1
+ import type {
2
+ AuthorityBatchOperation,
3
+ AuthorityBatchWriter,
4
+ AuthorityIteratorOptions,
5
+ AuthorityStore,
6
+ } from "./authorityStoreTypes";
7
+
8
+ export type LegacyServerDb = {
9
+ readonly location?: string;
10
+ readonly status?: string;
11
+ open(): Promise<void>;
12
+ close(): Promise<void>;
13
+ get<T = any>(key: string): Promise<T>;
14
+ put(key: string, value: unknown): Promise<void>;
15
+ del(key: string): Promise<void>;
16
+ batch(ops: AuthorityBatchOperation[]): Promise<void>;
17
+ batch(): AuthorityBatchWriter;
18
+ iterator(
19
+ options?: AuthorityIteratorOptions
20
+ ): AsyncIterableIterator<[string, unknown]>;
21
+ };
22
+
23
+ export function createLegacyServerDb(store: AuthorityStore): LegacyServerDb {
24
+ const batch = (ops?: AuthorityBatchOperation[]) => {
25
+ if (Array.isArray(ops)) {
26
+ return store.batchWrite(ops);
27
+ }
28
+ return store.createBatch();
29
+ };
30
+
31
+ return {
32
+ get location() {
33
+ return store.location;
34
+ },
35
+ get status() {
36
+ return store.status;
37
+ },
38
+ async open() {
39
+ await store.open();
40
+ },
41
+ async close() {
42
+ await store.close();
43
+ },
44
+ async get<T = any>(key: string) {
45
+ return store.get<T>(key);
46
+ },
47
+ async put(key: string, value: unknown) {
48
+ await store.put(key, value);
49
+ },
50
+ async del(key: string) {
51
+ await store.del(key);
52
+ },
53
+ batch: batch as LegacyServerDb["batch"],
54
+ iterator(options: AuthorityIteratorOptions = {}) {
55
+ return store.iterator(options);
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,75 @@
1
+ import type {
2
+ AuthorityBatchOperation,
3
+ AuthorityBatchWriter,
4
+ AuthorityIteratorOptions,
5
+ AuthorityStore,
6
+ } from "./authorityStoreTypes";
7
+
8
+ type LevelBatchWriterLike = {
9
+ put(key: string, value: unknown): unknown;
10
+ del(key: string): unknown;
11
+ write(): Promise<void>;
12
+ };
13
+
14
+ type LevelLike = {
15
+ readonly location?: string;
16
+ readonly status?: string;
17
+ open?(): Promise<void>;
18
+ close?(): Promise<void>;
19
+ get<T = any>(key: string): Promise<T>;
20
+ put(key: string, value: unknown): Promise<void>;
21
+ del(key: string): Promise<void>;
22
+ batch(ops: AuthorityBatchOperation[]): Promise<void>;
23
+ batch(): LevelBatchWriterLike;
24
+ iterator(
25
+ options?: AuthorityIteratorOptions
26
+ ): AsyncIterableIterator<[string, unknown]>;
27
+ };
28
+
29
+ export function createLevelAuthorityStore(levelDb: LevelLike): AuthorityStore {
30
+ const createBatch = (): AuthorityBatchWriter => {
31
+ const batch = levelDb.batch();
32
+ return {
33
+ put(key: string, value: unknown) {
34
+ batch.put(key, value);
35
+ },
36
+ del(key: string) {
37
+ batch.del(key);
38
+ },
39
+ async write() {
40
+ await batch.write();
41
+ },
42
+ };
43
+ };
44
+
45
+ return {
46
+ get location() {
47
+ return levelDb.location;
48
+ },
49
+ get status() {
50
+ return levelDb.status;
51
+ },
52
+ async open() {
53
+ await levelDb.open?.();
54
+ },
55
+ async close() {
56
+ await levelDb.close?.();
57
+ },
58
+ async get<T = any>(key: string) {
59
+ return levelDb.get<T>(key);
60
+ },
61
+ async put(key: string, value: unknown) {
62
+ await levelDb.put(key, value);
63
+ },
64
+ async del(key: string) {
65
+ await levelDb.del(key);
66
+ },
67
+ async batchWrite(ops: AuthorityBatchOperation[]) {
68
+ await levelDb.batch(ops);
69
+ },
70
+ createBatch,
71
+ iterator(options: AuthorityIteratorOptions = {}) {
72
+ return levelDb.iterator(options);
73
+ },
74
+ };
75
+ }
@@ -0,0 +1,133 @@
1
+ import type {
2
+ AuthorityBatchOperation,
3
+ AuthorityBatchWriter,
4
+ AuthorityIteratorOptions,
5
+ AuthorityStore,
6
+ } from "./authorityStoreTypes";
7
+
8
+ type MemoryEntry = {
9
+ key: string;
10
+ value: unknown;
11
+ };
12
+
13
+ const createNotFoundError = () => {
14
+ const error = new Error("NotFound") as Error & { notFound: true };
15
+ error.notFound = true;
16
+ return error;
17
+ };
18
+
19
+ class MemoryAuthorityBacking {
20
+ readonly location: string;
21
+ status: "closed" | "open" = "closed";
22
+ private readonly data = new Map<string, unknown>();
23
+
24
+ constructor(location: string) {
25
+ this.location = location;
26
+ }
27
+
28
+ async open() {
29
+ this.status = "open";
30
+ }
31
+
32
+ async close() {
33
+ this.status = "closed";
34
+ }
35
+
36
+ async get<T = any>(key: string): Promise<T> {
37
+ if (!this.data.has(key)) {
38
+ throw createNotFoundError();
39
+ }
40
+ return this.data.get(key) as T;
41
+ }
42
+
43
+ async put(key: string, value: unknown) {
44
+ this.data.set(key, value);
45
+ }
46
+
47
+ async del(key: string) {
48
+ this.data.delete(key);
49
+ }
50
+
51
+ async batchWrite(ops: AuthorityBatchOperation[]) {
52
+ for (const op of ops) {
53
+ if (op.type === "put") {
54
+ this.data.set(op.key, op.value);
55
+ } else {
56
+ this.data.delete(op.key);
57
+ }
58
+ }
59
+ }
60
+
61
+ createBatch(): AuthorityBatchWriter {
62
+ const buffered: AuthorityBatchOperation[] = [];
63
+ return {
64
+ put(key: string, value: unknown) {
65
+ buffered.push({ type: "put", key, value });
66
+ },
67
+ del(key: string) {
68
+ buffered.push({ type: "del", key });
69
+ },
70
+ write: async () => {
71
+ await this.batchWrite(buffered);
72
+ },
73
+ };
74
+ }
75
+
76
+ async *iterator(
77
+ options: AuthorityIteratorOptions = {}
78
+ ): AsyncIterableIterator<[string, unknown]> {
79
+ const entries: MemoryEntry[] = Array.from(this.data.entries())
80
+ .sort(([left], [right]) => left.localeCompare(right))
81
+ .map(([key, value]) => ({ key, value }));
82
+
83
+ if (options.reverse) {
84
+ entries.reverse();
85
+ }
86
+
87
+ for (const entry of entries) {
88
+ if (options.gte && entry.key < options.gte) continue;
89
+ if (options.lte && entry.key > options.lte) continue;
90
+ if (options.lt && entry.key >= options.lt) continue;
91
+ yield [entry.key, entry.value];
92
+ }
93
+ }
94
+ }
95
+
96
+ export function createMemoryAuthorityStore(
97
+ location = ":memory:"
98
+ ): AuthorityStore {
99
+ const backing = new MemoryAuthorityBacking(location);
100
+
101
+ return {
102
+ get location() {
103
+ return backing.location;
104
+ },
105
+ get status() {
106
+ return backing.status;
107
+ },
108
+ async open() {
109
+ await backing.open();
110
+ },
111
+ async close() {
112
+ await backing.close();
113
+ },
114
+ async get<T = any>(key: string) {
115
+ return backing.get<T>(key);
116
+ },
117
+ async put(key: string, value: unknown) {
118
+ await backing.put(key, value);
119
+ },
120
+ async del(key: string) {
121
+ await backing.del(key);
122
+ },
123
+ async batchWrite(ops: AuthorityBatchOperation[]) {
124
+ await backing.batchWrite(ops);
125
+ },
126
+ createBatch() {
127
+ return backing.createBatch();
128
+ },
129
+ iterator(options: AuthorityIteratorOptions = {}) {
130
+ return backing.iterator(options);
131
+ },
132
+ };
133
+ }
@@ -1,8 +1,8 @@
1
1
  // patch.js (或你的 patch 处理文件名)
2
- import { pino } from "pino";
3
- import { DataType } from "../../create/types";
4
- import serverDb from "./db"; // 确认路径正确
5
- import { handleToken } from "../../auth/server/token";
2
+ import { pino } from "pino";
3
+ import { DataType } from "../../create/types";
4
+ import { getServerAuthorityStore } from "./db"; // 确认路径正确
5
+ import { handleToken } from "../../auth/server/token";
6
6
  import {
7
7
  CYBOT_READONLY_MESSAGE,
8
8
  isCybotReadOnlyMutation,
@@ -63,8 +63,9 @@ const deepMerge = (target, source) => {
63
63
  return output;
64
64
  };
65
65
 
66
- export const handlePatch = async (req, res) => {
67
- req.user = await handleToken(req, res);
66
+ export const handlePatch = async (req, res) => {
67
+ const store = getServerAuthorityStore();
68
+ req.user = await handleToken(req, res);
68
69
 
69
70
  // --- 修改:变量名改为 dbKey,但仍然从 req.params.id 获取值 ---
70
71
  // (路由中仍然是 :id, 所以这里还是 req.params.id)
@@ -112,8 +113,8 @@ export const handlePatch = async (req, res) => {
112
113
  }
113
114
 
114
115
  try {
115
- // --- 修改:使用 dbKey 变量与数据库交互 ---
116
- const exist = await serverDb.get(dbKey);
116
+ // --- 修改:使用 dbKey 变量与数据库交互 ---
117
+ const exist = await store.get(dbKey);
117
118
  if (!exist) {
118
119
  // 使用 404 Not Found 更合适
119
120
  return res
@@ -152,10 +153,10 @@ export const handlePatch = async (req, res) => {
152
153
  });
153
154
  }
154
155
 
155
- // 深度合并现有数据和变更 (保持不变)
156
- const final = deepMerge(exist, changes);
157
-
158
- await serverDb.put(dbKey, final);
156
+ // 深度合并现有数据和变更 (保持不变)
157
+ const final = deepMerge(exist, changes);
158
+
159
+ await store.put(dbKey, final);
159
160
 
160
161
  if (
161
162
  (final?.type === "table" || final?.type === "table_row") &&
@@ -1,5 +1,5 @@
1
1
  // database/server/handler.ts
2
- import serverDb from "./db";
2
+ import { getServerAuthorityStore } from "./db";
3
3
  import { getUserDataPrefixes } from "../queryPrefixes";
4
4
 
5
5
  interface BaseItem {
@@ -102,6 +102,7 @@ async function fetchUserData(
102
102
  userId: string,
103
103
  options: { includeDeleted?: boolean } = {}
104
104
  ): Promise<Record<string, BaseItem[]>> {
105
+ const store = getServerAuthorityStore();
105
106
  const results: Record<string, BaseItem[]> = {};
106
107
  if (!userId || userId === "local" || userId === "undefined") return results;
107
108
  const typeArray = Array.isArray(types) ? types : [types];
@@ -109,7 +110,7 @@ async function fetchUserData(
109
110
  for (const type of typeArray) {
110
111
  const prefixes = getUserDataPrefixes(type, userId);
111
112
  for (const prefix of prefixes) {
112
- for await (const [key, value] of serverDb.iterator({
113
+ for await (const [key, value] of store.iterator({
113
114
  gte: prefix,
114
115
  lte: `${prefix}\uffff`,
115
116
  })) {
@@ -1,7 +1,7 @@
1
1
  // 文件路径: packages/database/server/read.ts
2
2
 
3
- import serverDb, { ensureServerDbOpen } from "./db";
4
- import { DB_PREFIX, shareKey } from "../keys";
3
+ import { getServerAuthorityStore } from "./db";
4
+ import { DB_PREFIX, shareKey } from "../keys";
5
5
  import { parseToken, verifyToken } from "../../auth/token";
6
6
  import { assertSessionTokenVersion } from "../../auth/sessionTokenVersion";
7
7
  import { hasActiveEntitlement } from "../../auth/server/productEntitlements";
@@ -11,6 +11,7 @@ import { authorizeActorRecordAccess } from "./actorAccess";
11
11
  import {
12
12
  resolveSharePaidAccess,
13
13
  } from "../../share/paidAccess";
14
+ import { ensureDbOpen } from "./ensureDbOpen";
14
15
 
15
16
  const isLevelNotFoundError = (error: any): boolean => {
16
17
  const code = error?.code;
@@ -33,17 +34,18 @@ const isPublicAgentKey = (dbKey: string): boolean =>
33
34
  const getUserIdFromProfileKey = (dbKey: string): string =>
34
35
  dbKey.slice(0, -PROFILE_KEY_SUFFIX.length);
35
36
 
36
- const getAuthorizedUserId = async (req: any): Promise<string | null> => {
37
- const authHeader = req.headers?.get?.("authorization");
38
- const token = typeof authHeader === "string" ? authHeader.split(" ")[1] : "";
39
- if (!token) return null;
37
+ const getAuthorizedUserId = async (req: any): Promise<string | null> => {
38
+ const store = getServerAuthorityStore();
39
+ const authHeader = req.headers?.get?.("authorization");
40
+ const token = typeof authHeader === "string" ? authHeader.split(" ")[1] : "";
41
+ if (!token) return null;
40
42
 
41
43
  const parsed = parseToken(token);
42
44
  const userId = parsed?.userId;
43
45
  if (!userId || typeof userId !== "string") return null;
44
-
45
- try {
46
- const user = await serverDb.get(`${DB_PREFIX.USER}${userId}`);
46
+
47
+ try {
48
+ const user = await store.get(`${DB_PREFIX.USER}${userId}`);
47
49
  if (!user?.publicKey || user?.isDisabled) return null;
48
50
 
49
51
  const payload = verifyToken(token, user.publicKey);
@@ -116,8 +118,9 @@ const isAgentOwner = (agent: any, userId: string | null): boolean =>
116
118
  agent?.userId === userId ||
117
119
  agent?.tenantId === userId)
118
120
  );
119
- export const handleReadSingle = async (req: any) => {
120
- const corsHeaders = {
121
+ export const handleReadSingle = async (req: any) => {
122
+ const store = getServerAuthorityStore();
123
+ const corsHeaders = {
121
124
  "Access-Control-Allow-Origin": "*",
122
125
  "Content-Type": "application/json",
123
126
  };
@@ -132,9 +135,9 @@ export const handleReadSingle = async (req: any) => {
132
135
  const dbKey = req.params.id;
133
136
  const isShareDataKey = dbKey.startsWith("share-") || shareKey.isShareKey(dbKey);
134
137
 
135
- try {
136
- // ⭐ 确保 LevelDB 已打开,避免 LEVEL_DATABASE_NOT_OPEN
137
- await ensureServerDbOpen();
138
+ try {
139
+ // ⭐ 确保 LevelDB 已打开,避免 LEVEL_DATABASE_NOT_OPEN
140
+ await ensureDbOpen(store);
138
141
 
139
142
  const authedUserId = await getAuthorizedUserId(req);
140
143
  const isPublicAgentDataKey = isPublicAgentKey(dbKey);
@@ -156,19 +159,19 @@ export const handleReadSingle = async (req: any) => {
156
159
  if (!authedUserId && isPublicProfileKey(dbKey)) {
157
160
  const inviterId = getUserIdFromProfileKey(dbKey);
158
161
 
159
- let profile: any = null;
160
- try {
161
- profile = await serverDb.get(dbKey);
162
- } catch (error: any) {
163
- if (!isLevelNotFoundError(error)) throw error;
164
- }
165
-
166
- let user: any = null;
167
- try {
168
- user = await serverDb.get(`${DB_PREFIX.USER}${inviterId}`);
169
- } catch (error: any) {
170
- if (!isLevelNotFoundError(error)) throw error;
171
- }
162
+ let profile: any = null;
163
+ try {
164
+ profile = await store.get(dbKey);
165
+ } catch (error: any) {
166
+ if (!isLevelNotFoundError(error)) throw error;
167
+ }
168
+
169
+ let user: any = null;
170
+ try {
171
+ user = await store.get(`${DB_PREFIX.USER}${inviterId}`);
172
+ } catch (error: any) {
173
+ if (!isLevelNotFoundError(error)) throw error;
174
+ }
172
175
 
173
176
  if (user?.isDisabled) {
174
177
  return new Response(
@@ -195,8 +198,8 @@ export const handleReadSingle = async (req: any) => {
195
198
  headers: corsHeaders,
196
199
  });
197
200
  }
198
-
199
- const result = await serverDb.get(dbKey);
201
+
202
+ const result = await store.get(dbKey);
200
203
  if (
201
204
  result === null ||
202
205
  typeof result === "undefined" ||
@@ -236,7 +239,7 @@ export const handleReadSingle = async (req: any) => {
236
239
  const paidAccess = resolveSharePaidAccess(result);
237
240
  if (paidAccess.mode === "product" && !owner) {
238
241
  const purchased = await hasActiveEntitlement({
239
- store: serverDb,
242
+ store,
240
243
  userId: authedUserId,
241
244
  productId: paidAccess.productId,
242
245
  });
@@ -1,6 +1,6 @@
1
1
  import { isSystemAdmin } from "../../core/init";
2
2
  import { shareKey } from "../keys";
3
- import serverDb from "./db";
3
+ import { getServerAuthorityStore } from "./db";
4
4
  import { resolveKeyOwnerId } from "./writeAuthority";
5
5
 
6
6
  export type AccessAction = "read" | "write" | "delete" | "manage";
@@ -73,11 +73,12 @@ const hasSpaceMembership = async (
73
73
  userId: string,
74
74
  spaceId: string | null
75
75
  ): Promise<boolean> => {
76
+ const store = getServerAuthorityStore();
76
77
  const normalized = normalizeSpaceId(spaceId);
77
78
  if (!userId || !normalized) return false;
78
79
 
79
80
  try {
80
- const membership = await serverDb.get(
81
+ const membership = await store.get(
81
82
  `${SPACE_MEMBER_PREFIX}${userId}-${normalized}`
82
83
  );
83
84
  if (membership) return true;
@@ -86,7 +87,7 @@ const hasSpaceMembership = async (
86
87
  }
87
88
 
88
89
  try {
89
- const space = await serverDb.get(`${SPACE_PREFIX}${normalized}`);
90
+ const space = await store.get(`${SPACE_PREFIX}${normalized}`);
90
91
  return (
91
92
  space?.ownerId === userId ||
92
93
  (Array.isArray(space?.members) && space.members.includes(userId))
@@ -112,13 +113,14 @@ const isRecordLinkedFromMemberSpace = async (
112
113
  dbKey: string,
113
114
  record: any
114
115
  ): Promise<string | null> => {
116
+ const store = getServerAuthorityStore();
115
117
  if (!userId || !dbKey) return null;
116
118
 
117
119
  const contentKeys = getContentKeyCandidates(dbKey, record);
118
120
  const prefix = `${SPACE_MEMBER_PREFIX}${userId}-`;
119
121
 
120
122
  try {
121
- for await (const [, membership] of serverDb.iterator({
123
+ for await (const [, membership] of store.iterator({
122
124
  gte: prefix,
123
125
  lte: prefix + "\uffff",
124
126
  })) {
@@ -126,7 +128,7 @@ const isRecordLinkedFromMemberSpace = async (
126
128
  if (!spaceId) continue;
127
129
 
128
130
  try {
129
- const space = await serverDb.get(`${SPACE_PREFIX}${spaceId}`);
131
+ const space = await store.get(`${SPACE_PREFIX}${spaceId}`);
130
132
  const contents = space?.contents;
131
133
  if (!contents || typeof contents !== "object") continue;
132
134
 
@@ -0,0 +1,124 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Level } from "level";
4
+
5
+ import type { AuthorityStore } from "./authorityStoreTypes";
6
+ import { createLegacyServerDb, type LegacyServerDb } from "./legacyServerDb";
7
+ import { createLevelAuthorityStore } from "./levelAuthorityStore";
8
+ import { createMemoryAuthorityStore } from "./memoryAuthorityStore";
9
+
10
+ // Keep the storage seam local-first. Cross-process sharing stays in the
11
+ // existing core/proxy runtime layer; this factory is only for embedded drivers.
12
+ export type ServerStoreDriver = "level" | "memory";
13
+
14
+ export type ServerStoreFactoryEnv = {
15
+ NOLO_SERVER_AUTHORITY_DRIVER?: string | undefined;
16
+ };
17
+
18
+ export const safeJsonEncoding = {
19
+ name: "safe-json",
20
+ format: "utf8" as const,
21
+ encode: (data: any) => JSON.stringify(data),
22
+ decode: (data: string) => {
23
+ try {
24
+ return JSON.parse(data);
25
+ } catch {
26
+ console.warn("[LevelDB] Corrupted value:", data?.substring?.(0, 60));
27
+ return null;
28
+ }
29
+ },
30
+ };
31
+
32
+ export type ServerStoreRuntime = {
33
+ authorityStore: AuthorityStore;
34
+ serverDb: LegacyServerDb;
35
+ };
36
+
37
+ export type ServerStoreFactoryOptions = {
38
+ driver?: ServerStoreDriver;
39
+ env?: ServerStoreFactoryEnv;
40
+ globalScope?: Record<string, unknown>;
41
+ };
42
+
43
+ export function ensureServerDbDirectory(dbPath: string) {
44
+ const dir = path.dirname(dbPath);
45
+ if (!fs.existsSync(dir)) {
46
+ fs.mkdirSync(dir, { recursive: true });
47
+ }
48
+ }
49
+
50
+ export function createLevelBackedAuthorityStore(dbPath: string): AuthorityStore {
51
+ const levelDb = new Level<string, any>(dbPath, {
52
+ valueEncoding: safeJsonEncoding,
53
+ });
54
+ return createLevelAuthorityStore(levelDb);
55
+ }
56
+
57
+ export function resolveServerStoreDriver(
58
+ env: ServerStoreFactoryEnv = process.env
59
+ ): ServerStoreDriver {
60
+ const rawDriver = env.NOLO_SERVER_AUTHORITY_DRIVER?.trim().toLowerCase();
61
+ if (!rawDriver) return "level";
62
+ if (rawDriver === "level") return "level";
63
+ if (rawDriver === "memory") return "memory";
64
+ throw new Error(`Unsupported server authority store driver: ${rawDriver}`);
65
+ }
66
+
67
+ export function createAuthorityStoreForDriver(
68
+ driver: ServerStoreDriver,
69
+ dbPath: string,
70
+ env: ServerStoreFactoryEnv = process.env
71
+ ): AuthorityStore {
72
+ switch (driver) {
73
+ case "level":
74
+ return createLevelBackedAuthorityStore(dbPath);
75
+ case "memory":
76
+ // Test/dev-only driver that exercises the seam without changing the
77
+ // production single-writer runtime model.
78
+ return createMemoryAuthorityStore(dbPath);
79
+ }
80
+ }
81
+
82
+ export function getOrCreateServerStoreRuntime(
83
+ dbPath: string,
84
+ options: ServerStoreFactoryOptions = {}
85
+ ): ServerStoreRuntime {
86
+ const globalScope =
87
+ options.globalScope ?? (globalThis as Record<string, unknown>);
88
+ const driver = options.driver ?? resolveServerStoreDriver(options.env);
89
+ const cachedDriver = globalScope.__serverAuthorityStoreDriver;
90
+
91
+ ensureServerDbDirectory(dbPath);
92
+
93
+ if (
94
+ globalScope.__serverAuthorityStore &&
95
+ typeof cachedDriver === "string" &&
96
+ cachedDriver !== driver
97
+ ) {
98
+ throw new Error(
99
+ `Server authority store already initialized with driver ${cachedDriver}, cannot reuse it for ${driver}`
100
+ );
101
+ }
102
+
103
+ if (!globalScope.__serverAuthorityStore) {
104
+ globalScope.__serverAuthorityStore = createAuthorityStoreForDriver(
105
+ driver,
106
+ dbPath,
107
+ options.env
108
+ );
109
+ globalScope.__serverAuthorityStoreDriver = driver;
110
+ } else if (!cachedDriver) {
111
+ globalScope.__serverAuthorityStoreDriver = driver;
112
+ }
113
+
114
+ const authorityStore = globalScope.__serverAuthorityStore as AuthorityStore;
115
+
116
+ if (!globalScope.__serverDb) {
117
+ globalScope.__serverDb = createLegacyServerDb(authorityStore);
118
+ }
119
+
120
+ return {
121
+ authorityStore,
122
+ serverDb: globalScope.__serverDb as LegacyServerDb,
123
+ };
124
+ }
@@ -1,4 +1,4 @@
1
- import serverDb from "./db";
1
+ import { getServerAuthorityStore } from "./db";
2
2
 
3
3
  const SPACE_MEMBER_PREFIX = "space-member-";
4
4
  const SPACE_PREFIX = "space-";
@@ -23,8 +23,9 @@ export const parseSpaceMemberKey = (
23
23
  };
24
24
 
25
25
  const loadSpaceRecord = async (spaceId: string): Promise<any | null> => {
26
+ const store = getServerAuthorityStore();
26
27
  try {
27
- return await serverDb.get(`${SPACE_PREFIX}${spaceId}`);
28
+ return await store.get(`${SPACE_PREFIX}${spaceId}`);
28
29
  } catch {
29
30
  return null;
30
31
  }
@@ -0,0 +1,37 @@
1
+ import type {
2
+ AuthorityBatchOperation,
3
+ AuthorityBatchWriter,
4
+ } from "./authorityStoreTypes";
5
+
6
+ type BatchArrayStoreLike = {
7
+ batchWrite?(ops: AuthorityBatchOperation[]): Promise<void>;
8
+ batch?(ops: AuthorityBatchOperation[]): Promise<void>;
9
+ };
10
+
11
+ type BatchBuilderStoreLike = {
12
+ createBatch?(): AuthorityBatchWriter;
13
+ batch?(): AuthorityBatchWriter;
14
+ };
15
+
16
+ export function writeStoreOps(
17
+ store: BatchArrayStoreLike,
18
+ ops: AuthorityBatchOperation[]
19
+ ): Promise<void> {
20
+ if (typeof store.batchWrite === "function") {
21
+ return store.batchWrite(ops);
22
+ }
23
+ if (typeof store.batch === "function") {
24
+ return store.batch(ops);
25
+ }
26
+ throw new Error("Store does not support batch array writes");
27
+ }
28
+
29
+ export function createStoreBatch(store: BatchBuilderStoreLike): AuthorityBatchWriter {
30
+ if (typeof store.createBatch === "function") {
31
+ return store.createBatch();
32
+ }
33
+ if (typeof store.batch === "function") {
34
+ return store.batch();
35
+ }
36
+ throw new Error("Store does not support batch builder writes");
37
+ }