nolo-cli 0.1.39 → 0.1.41
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.
- package/README.md +4 -4
- package/agent-runtime/dialogWritePlan.ts +39 -0
- package/agent-runtime/hostAdapter.ts +4 -0
- package/agent-runtime/hybridRecordStore.ts +5 -3
- package/agent-runtime/index.ts +15 -0
- package/agent-runtime/localLoop.ts +87 -7
- package/agent-runtime/localToolPolicy.ts +2 -13
- package/agent-runtime/localWorkspaceTools.ts +42 -110
- package/agent-runtime/runtimeToolPolicy.ts +2 -11
- package/agent-runtime/runtimeToolSurface.ts +198 -0
- package/agent-runtime/types.ts +1 -0
- package/agentAliases.ts +2 -1
- package/agentRunCommand.ts +10 -32
- package/agentRuntimeLocal.ts +1 -0
- package/ai/agent/_executeModel.ts +146 -0
- package/ai/agent/agentSlice.ts +556 -1
- package/ai/agent/appWorkingMemory.ts +126 -0
- package/ai/agent/buildEditingContext.ts +378 -0
- package/ai/agent/buildSystemPrompt.ts +585 -0
- package/ai/agent/canvasEditingContext.ts +49 -0
- package/ai/agent/cleanAgentMessages.ts +140 -0
- package/ai/agent/cliChatClient.ts +153 -0
- package/ai/agent/cliExecutor.ts +314 -40
- package/ai/agent/contextCompiler.ts +107 -0
- package/ai/agent/contextLayerContract.ts +44 -0
- package/ai/agent/createAgentSchema.ts +272 -0
- package/ai/agent/currentTimeContext.ts +65 -0
- package/ai/agent/executeToolCall.ts +58 -0
- package/ai/agent/fetchAgentContexts.ts +42 -0
- package/ai/agent/generatePrompt.ts +3 -0
- package/ai/agent/getFullChatContextKeys.ts +168 -0
- package/ai/agent/guidedCreation/capabilities.ts +84 -0
- package/ai/agent/guidedCreation/types.ts +38 -0
- package/ai/agent/isLiveAudioOnlyAgent.ts +26 -0
- package/ai/agent/liveAudioModel.ts +2 -0
- package/ai/agent/pageBuilderHandoffRules.ts +75 -0
- package/ai/agent/persistMessageWithFixedId.ts +37 -0
- package/ai/agent/planSlice.ts +259 -0
- package/ai/agent/referenceUtils.ts +229 -0
- package/ai/agent/runAgentBackground.ts +310 -0
- package/ai/agent/runAgentClientLoop.ts +164 -0
- package/ai/agent/runtimeGuidance.ts +116 -0
- package/ai/agent/serverOrigin.ts +7 -0
- package/ai/agent/startParallelAgentStreams.ts +424 -0
- package/ai/agent/startupProtocol.ts +53 -0
- package/ai/agent/streamAgentChatTurn.ts +2001 -0
- package/ai/agent/streamAgentChatTurnUtils.ts +860 -0
- package/ai/agent/toolFailureGuard.ts +99 -0
- package/ai/agent/types.ts +73 -0
- package/ai/agent/utils/imageOutput.ts +37 -0
- package/ai/agent/utils/publicImageAgentMode.ts +26 -0
- package/ai/ai.locale.ts +1095 -0
- package/ai/chat/accumulateToolCallChunks.ts +126 -0
- package/ai/chat/fetchUtils.ts +143 -0
- package/ai/chat/inlineImageUrlsForCustomProvider.ts +117 -0
- package/ai/chat/parseApiError.ts +67 -0
- package/ai/chat/parseMultilineSSE.ts +95 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +897 -0
- package/ai/chat/sendOpenAIResponseRequest.ts +720 -0
- package/ai/chat/serverProxyRetry.ts +102 -0
- package/ai/chat/shouldUseServerProxy.ts +18 -0
- package/ai/chat/streamRetry.ts +46 -0
- package/ai/chat/updateTotalUsage.ts +89 -0
- package/ai/context/buildReferenceContext.ts +437 -0
- package/ai/context/retention.ts +165 -0
- package/ai/context/tokenUtils.ts +78 -0
- package/ai/llm/agentCapabilities.ts +74 -0
- package/ai/llm/deepinfra.ts +79 -0
- package/ai/llm/fireworks.ts +68 -0
- package/ai/llm/generateRequestBody.ts +165 -0
- package/ai/llm/getModelContextWindow.ts +93 -0
- package/ai/llm/getPricing.ts +252 -0
- package/ai/llm/imagePricing.ts +66 -0
- package/ai/llm/isResponseAPIModel.ts +13 -0
- package/ai/llm/kimi.ts +23 -0
- package/ai/llm/mimo.ts +99 -0
- package/ai/llm/mistral.ts +21 -0
- package/ai/llm/models.ts +45 -0
- package/ai/llm/openrouterModels.ts +6 -0
- package/ai/llm/providers.ts +313 -0
- package/ai/llm/reasoningModels.ts +27 -0
- package/ai/llm/types.ts +82 -0
- package/ai/llm/usageRequestOptions.ts +59 -0
- package/ai/memory/queryShared.ts +161 -0
- package/ai/memory/recentRelationshipRecap.ts +247 -0
- package/ai/memory/remember.ts +167 -0
- package/ai/memory/store.ts +20 -0
- package/ai/memory/storeShared.ts +76 -0
- package/ai/memory/types.ts +46 -0
- package/ai/memory/understanding.ts +349 -0
- package/ai/memory/understandingGreeting.ts +264 -0
- package/ai/policy/personalizationDialog.ts +333 -0
- package/ai/policy/runtimePolicy.ts +454 -0
- package/ai/policy/selfUpdateFields.ts +48 -0
- package/ai/policy/types.ts +64 -0
- package/ai/skills/referenceRuntime.ts +274 -0
- package/ai/skills/skillDiagnostics.ts +251 -0
- package/ai/skills/skillDocBuilder.ts +139 -0
- package/ai/skills/skillSummaryMarker.ts +26 -0
- package/ai/token/calculatePrice.ts +576 -0
- package/ai/token/missingUsageEstimate.ts +42 -0
- package/ai/token/normalizeUsage.ts +124 -0
- package/ai/token/openaiImageGenerationUsage.ts +56 -0
- package/ai/token/prepareTokenUsageData.ts +93 -0
- package/ai/token/resolveBillingTarget.ts +52 -0
- package/ai/token/saveTokenRecord.ts +53 -0
- package/ai/token/types.ts +103 -0
- package/ai/tools/agent/agentTools.ts +235 -0
- package/ai/tools/agent/agentUpdateShared.ts +311 -0
- package/ai/tools/agent/callAgentTool.ts +139 -0
- package/ai/tools/agent/createAgentTool.ts +512 -0
- package/ai/tools/agent/createDialogTool.ts +69 -0
- package/ai/tools/agent/createSkillAgentTool.ts +62 -0
- package/ai/tools/agent/parallelBudget.ts +221 -0
- package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
- package/ai/tools/agent/presets/appBuilderPreset.ts +154 -0
- package/ai/tools/agent/runLlmTool.ts +96 -0
- package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
- package/ai/tools/agent/skillAgentArgs.ts +106 -0
- package/ai/tools/agent/startAgentDialogTool.ts +53 -0
- package/ai/tools/agent/streamParallelAgentsTool.ts +123 -0
- package/ai/tools/agent/updateAgentTool.ts +96 -0
- package/ai/tools/agent/updateSelfTool.ts +113 -0
- package/ai/tools/amazonProductScraperTool.ts +86 -0
- package/ai/tools/apifyActorClient.ts +45 -0
- package/ai/tools/appEditGuard.ts +372 -0
- package/ai/tools/appReadSnapshot.ts +153 -0
- package/ai/tools/appTools.ts +1549 -0
- package/ai/tools/applyEditTool.ts +259 -0
- package/ai/tools/applyLineEditsTool.ts +315 -0
- package/ai/tools/browserTools/click.ts +33 -0
- package/ai/tools/browserTools/closeSession.ts +29 -0
- package/ai/tools/browserTools/common.ts +27 -0
- package/ai/tools/browserTools/openSession.ts +48 -0
- package/ai/tools/browserTools/readContent.ts +38 -0
- package/ai/tools/browserTools/selectOption.ts +46 -0
- package/ai/tools/browserTools/typeText.ts +42 -0
- package/ai/tools/category/createCategoryTool.ts +66 -0
- package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
- package/ai/tools/category/updateContentCategoryTool.ts +75 -0
- package/ai/tools/cfBrowserTools.ts +319 -0
- package/ai/tools/cfSpeechToTextTool.ts +49 -0
- package/ai/tools/checkEnvTool.ts +102 -0
- package/ai/tools/cloudflareCrawlTool.ts +289 -0
- package/ai/tools/codeSearchTool.ts +123 -0
- package/ai/tools/codeTools.ts +101 -0
- package/ai/tools/convertMarxistsBookTool.ts +103 -0
- package/ai/tools/createDocTool.ts +132 -0
- package/ai/tools/createSkillDocTool.ts +155 -0
- package/ai/tools/createWorkflowTool.ts +154 -0
- package/ai/tools/delayTool.ts +31 -0
- package/ai/tools/deleteSpacesTool.ts +325 -0
- package/ai/tools/deleteSpacesToolModel.ts +159 -0
- package/ai/tools/devReloadUtils.ts +29 -0
- package/ai/tools/dialogMessageSearch.ts +137 -0
- package/ai/tools/doctorSkillTool.ts +72 -0
- package/ai/tools/ecommerceScraperTool.ts +86 -0
- package/ai/tools/emailTools.ts +549 -0
- package/ai/tools/evalSkillTool.ts +92 -0
- package/ai/tools/exaSearchTool.ts +63 -0
- package/ai/tools/execShellTool.ts +266 -0
- package/ai/tools/executeSqlTool.ts +192 -0
- package/ai/tools/fetchWebpageSupport.ts +333 -0
- package/ai/tools/fetchWebpageTool.ts +97 -0
- package/ai/tools/geminiImagePreviewTool.ts +386 -0
- package/ai/tools/generateDocxTool.ts +215 -0
- package/ai/tools/googleSearchScraperTool.ts +106 -0
- package/ai/tools/importDataTool.ts +133 -0
- package/ai/tools/importSkillTool.ts +162 -0
- package/ai/tools/index.ts +2308 -0
- package/ai/tools/jdProductScraperTool.ts +821 -0
- package/ai/tools/listUserSpacesTool.ts +113 -0
- package/ai/tools/localFilesTool.ts +276 -0
- package/ai/tools/marxistsOfflineBook.ts +253 -0
- package/ai/tools/modelUsageTools.ts +206 -0
- package/ai/tools/noloWorkspaceReadTools.ts +467 -0
- package/ai/tools/olmOcrTool.ts +33 -0
- package/ai/tools/openaiImageTool.ts +267 -0
- package/ai/tools/prepareTools.ts +23 -0
- package/ai/tools/readDocTool.ts +88 -0
- package/ai/tools/readFileTool.ts +214 -0
- package/ai/tools/readTool.ts +194 -0
- package/ai/tools/readXPostTool.ts +229 -0
- package/ai/tools/readXhsProfileTool.ts +627 -0
- package/ai/tools/rememberMemoryTool.ts +84 -0
- package/ai/tools/remotionVideoTool.ts +151 -0
- package/ai/tools/searchDialogMessagesTool.ts +222 -0
- package/ai/tools/searchWorkspaceTool.ts +259 -0
- package/ai/tools/skillFollowup.ts +86 -0
- package/ai/tools/surfWeatherTool.ts +169 -0
- package/ai/tools/table/addTableRowTool.ts +217 -0
- package/ai/tools/table/createTableTool.ts +315 -0
- package/ai/tools/table/rowTools.ts +386 -0
- package/ai/tools/table/schemaTools.ts +244 -0
- package/ai/tools/table/shareTableTool.ts +148 -0
- package/ai/tools/table/toolShared.ts +129 -0
- package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
- package/ai/tools/toolApiClient.ts +279 -0
- package/ai/tools/toolResultError.ts +42 -0
- package/ai/tools/toolRunSlice.ts +303 -0
- package/ai/tools/toolSchemaCompatibility.ts +53 -0
- package/ai/tools/uiAskChoiceTool.ts +104 -0
- package/ai/tools/updateContentTitleTool.ts +84 -0
- package/ai/tools/updateDocTool.ts +105 -0
- package/ai/tools/updateUserPreferenceProfileTool.ts +153 -0
- package/ai/tools/wereadGatewayTool.ts +152 -0
- package/ai/tools/whisperTool.ts +76 -0
- package/ai/tools/writeFileTool.ts +213 -0
- package/ai/tools/youtubeScraperTool.ts +116 -0
- package/ai/tools/ziweiChartTool.ts +678 -0
- package/ai/types.ts +55 -0
- package/ai/workflow/workflowExecutor.ts +323 -0
- package/ai/workflow/workflowSlice.ts +73 -0
- package/ai/workflow/workflowTypes.ts +106 -0
- package/app/actions/syncAppRecord.ts +73 -0
- package/app/constants/animationSets.ts +21 -0
- package/app/constants/appEditor.ts +99 -0
- package/app/favorite/favoriteSlice.ts +690 -0
- package/app/favorite/type.ts +43 -0
- package/app/hooks/deleteDbKey.ts +233 -0
- package/app/i18n/client.ts +13 -0
- package/app/i18n/i18n.base.ts +14 -0
- package/app/i18n/i18n.config.ts +77 -0
- package/app/i18n/index.ts +15 -0
- package/app/i18n/mapLanguage.ts +11 -0
- package/app/i18n/translations/appBuilder.locale.ts +453 -0
- package/app/i18n/translations/error.locale.ts +246 -0
- package/app/i18n/translations/interface.locale.ts +2174 -0
- package/app/i18n/translations/pricing.locale.ts +397 -0
- package/app/i18n/translations/privacy.locale.ts +168 -0
- package/app/i18n/translations/seo.locale.ts +129 -0
- package/app/i18n/translations/terms.locale.ts +124 -0
- package/app/i18n/types.ts +6 -0
- package/app/notifications/model.ts +77 -0
- package/app/notifications/notificationSlice.ts +141 -0
- package/app/reducer.ts +36 -0
- package/app/settings/dbActionThunks.ts +34 -0
- package/app/settings/defaultSpacePreference.ts +87 -0
- package/app/settings/settingSlice.tsx +1212 -0
- package/app/settings/settingsRecord.ts +8 -0
- package/app/stateViews/runtime.ts +90 -0
- package/app/store.ts +55 -0
- package/app/theme/colors.ts +280 -0
- package/app/theme/fontPreference.ts +77 -0
- package/app/theme/theme.config.ts +120 -0
- package/app/theme/themeModeBootstrap.ts +123 -0
- package/app/types/appSummary.ts +114 -0
- package/app/types.ts +358 -0
- package/app/utils/appKeys.ts +55 -0
- package/app/utils/async.ts +28 -0
- package/app/utils/desktopAgentRuntimeTurnClient.ts +73 -0
- package/app/utils/env.ts +17 -0
- package/app/utils/fileUtils.ts +229 -0
- package/app/utils/imageUtils.ts +274 -0
- package/app/utils/myContentItems.ts +289 -0
- package/app/utils/retryAfter.ts +36 -0
- package/app/utils/retryFetch.ts +61 -0
- package/app/utils/toast.ts +3 -0
- package/auth/action/signUpAction.ts +227 -0
- package/auth/adminPermissions.ts +18 -0
- package/auth/authSlice.ts +531 -0
- package/auth/client/loginRequest.ts +14 -0
- package/auth/resetAuthScopedClientState.ts +27 -0
- package/auth/routes.ts +178 -0
- package/auth/token.ts +63 -0
- package/auth/types.ts +40 -0
- package/chat/chat.locale.ts +813 -0
- package/chat/dialog/actions/addCybotAction.ts +52 -0
- package/chat/dialog/actions/addReferenceKeysAction.ts +62 -0
- package/chat/dialog/actions/builtinDialogLlm.ts +35 -0
- package/chat/dialog/actions/cleanupCliSession.ts +40 -0
- package/chat/dialog/actions/createDialogAction.ts +379 -0
- package/chat/dialog/actions/createScheduledTaskAction.ts +78 -0
- package/chat/dialog/actions/handleSendMessageAction.ts +197 -0
- package/chat/dialog/actions/handleSendMessageResolver.ts +27 -0
- package/chat/dialog/actions/removeCybotAction.ts +6 -0
- package/chat/dialog/actions/removeDialogAgentAction.ts +44 -0
- package/chat/dialog/actions/replacePrimaryCybotAction.ts +6 -0
- package/chat/dialog/actions/setPrimaryDialogAgentAction.ts +52 -0
- package/chat/dialog/actions/updateDialogSummaryAction.ts +430 -0
- package/chat/dialog/actions/updateDialogTitleAction.ts +151 -0
- package/chat/dialog/actions/updateDialogTitlePolicy.ts +30 -0
- package/chat/dialog/actions/updateTokensAction.ts +233 -0
- package/chat/dialog/dialogAgents.ts +72 -0
- package/chat/dialog/dialogSlice.ts +872 -0
- package/chat/dialog/dialogTitle.ts +81 -0
- package/chat/dialog/dialogTokenStats.ts +12 -0
- package/chat/dialog/dialogUrl.ts +6 -0
- package/chat/dialog/goal.ts +108 -0
- package/chat/dialog/objectAssistantRegistry.ts +286 -0
- package/chat/dialog/schedule.ts +17 -0
- package/chat/messages/fetchAndCacheMessages.ts +119 -0
- package/chat/messages/fetchConvMsgs.ts +51 -0
- package/chat/messages/fileUrl.ts +13 -0
- package/chat/messages/messageAgent.ts +8 -0
- package/chat/messages/messageContent.ts +199 -0
- package/chat/messages/messageContract.ts +88 -0
- package/chat/messages/messageSlice.ts +1367 -0
- package/chat/messages/toolThunks.ts +625 -0
- package/cli/agentAliases.ts +2 -1
- package/cli/agentRunCommand.ts +10 -32
- package/cli/agentRuntimeLocal.ts +1 -0
- package/cli/client/agentRun.ts +67 -95
- package/cli/client/localRuntimeAdapter.ts +323 -54
- package/cli/commandRegistry.ts +2 -2
- package/cli/machineWsRunDispatch.ts +51 -6
- package/cli/offlineMarxistsAgentCommand.ts +6 -4
- package/client/agentConfigResolver.test.ts +2 -2
- package/client/agentRun.test.ts +175 -57
- package/client/agentRun.ts +67 -95
- package/client/localRuntimeAdapter.test.ts +682 -37
- package/client/localRuntimeAdapter.ts +323 -54
- package/client/localRuntimeDryRun.test.ts +23 -9
- package/client/localToolPolicy.test.ts +4 -4
- package/commandRegistry.ts +2 -2
- package/core/builtinAgents.ts +209 -0
- package/core/config.ts +15 -0
- package/core/crypto.ts +51 -0
- package/core/generateKeyPairFromSeedV1.ts +15 -0
- package/core/generateMainKey.ts +22 -0
- package/core/init.ts +41 -0
- package/core/localOrigins.ts +8 -0
- package/core/password.ts +13 -0
- package/core/prefix.ts +23 -0
- package/create/editor/transforms/fromMarkdown/index.ts +260 -0
- package/create/editor/transforms/fromMarkdown/inline.ts +285 -0
- package/create/editor/transforms/fromMarkdown/table.ts +130 -0
- package/create/editor/transforms/markdownToSlate.ts +24 -0
- package/create/editor/transforms/slateToRenderMarkdown.ts +218 -0
- package/create/editor/transforms/slateToSimplifiedMarkdown.ts +224 -0
- package/create/editor/transforms/slateToText.ts +33 -0
- package/create/editor/utils/slateUtils.ts +233 -0
- package/create/space/addSpaceAction.ts +193 -0
- package/create/space/category/categoryActions.ts +427 -0
- package/create/space/changeSpaceAction.ts +36 -0
- package/create/space/constants.ts +8 -0
- package/create/space/content/addContentAction.ts +116 -0
- package/create/space/content/contentThunks.ts +90 -0
- package/create/space/content/deleteContentFromSpaceAction.ts +187 -0
- package/create/space/content/deleteMultipleContentAction.ts +112 -0
- package/create/space/content/moveContentAction.ts +285 -0
- package/create/space/content/updateContentCategoryAction.ts +154 -0
- package/create/space/content/updateContentTitleAction.ts +151 -0
- package/create/space/content/uploadAndAddFileToSpaceAction.ts +98 -0
- package/create/space/contentKeyUtils.ts +117 -0
- package/create/space/deleteSpaceAction.ts +276 -0
- package/create/space/fetchSpaceAction.ts +70 -0
- package/create/space/fetchSpaceSidebarStateAction.ts +26 -0
- package/create/space/loadDefaultSpaceAction.ts +57 -0
- package/create/space/member/addMemberAction.ts +79 -0
- package/create/space/member/fetchUserSpaceMembershipsAction.ts +386 -0
- package/create/space/member/memberThunks.ts +47 -0
- package/create/space/member/removeMemberAction.ts +67 -0
- package/create/space/resolvePreferredSpaceId.ts +113 -0
- package/create/space/sidebarVisibleTypes.ts +241 -0
- package/create/space/space.locale.ts +1087 -0
- package/create/space/spaceAccess.ts +182 -0
- package/create/space/spaceCollapsedState.ts +54 -0
- package/create/space/spaceKeys.ts +65 -0
- package/create/space/spaceSlice.ts +328 -0
- package/create/space/spaceThunks.ts +410 -0
- package/create/space/types.ts +27 -0
- package/create/space/updateSpaceAction.ts +107 -0
- package/create/space/utils/permissions.ts +47 -0
- package/create/types.ts +21 -0
- package/database/actions/agentReadResolution.ts +33 -0
- package/database/actions/common.ts +243 -0
- package/database/actions/deleteFile.ts +40 -0
- package/database/actions/fileContent.ts +125 -0
- package/database/actions/patch.ts +155 -0
- package/database/actions/read.ts +358 -0
- package/database/actions/readAndWait.ts +260 -0
- package/database/actions/readRequestManager.ts +120 -0
- package/database/actions/readResolution.ts +125 -0
- package/database/actions/remove.ts +94 -0
- package/database/actions/replication.ts +477 -0
- package/database/actions/upload.ts +186 -0
- package/database/actions/upsert.ts +56 -0
- package/database/actions/write.ts +146 -0
- package/database/authority/ownerKey.ts +80 -0
- package/database/authority/recordAuthority.ts +67 -0
- package/database/authority/userAuthorityRegistry.ts +54 -0
- package/database/client/fetchUserData.ts +61 -0
- package/database/dbActionThunks.ts +1 -0
- package/database/dbSlice.ts +149 -0
- package/database/fileRing.ts +51 -0
- package/database/fileStorage.ts +232 -0
- package/database/fileUrl.ts +34 -0
- package/database/keys.ts +767 -0
- package/database/queryPrefixes.ts +14 -0
- package/database/requests.ts +443 -0
- package/database/runtimeServerContext.ts +54 -0
- package/database/server/levelAuthorityStore.ts +20 -1
- package/database/tenantPlacement.ts +57 -0
- package/database/userPreferenceRegister.ts +131 -0
- package/database/utils/ulid.ts +1 -0
- package/integrations/anthropic/anthropicModels.ts +47 -0
- package/integrations/deepseek/models.ts +37 -0
- package/integrations/google/models.ts +341 -0
- package/integrations/openai/chatCompletionStreamMode.ts +10 -0
- package/integrations/openai/filterAndCleanMessages.ts +284 -0
- package/integrations/openai/flexTier.ts +102 -0
- package/integrations/openai/generateOpenAIRequestBody.ts +274 -0
- package/integrations/openai/generateResponseRequestBody.ts +77 -0
- package/integrations/openai/models.ts +271 -0
- package/integrations/openai/providerBodyCompatibility.ts +23 -0
- package/integrations/openai/responsesHelpers.ts +297 -0
- package/integrations/x-reader/types.ts +109 -0
- package/integrations/xai/models.ts +13 -0
- package/integrations/xhs-reader/analyze/profileAnalyzer.ts +205 -0
- package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +624 -0
- package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +227 -0
- package/integrations/xhs-reader/client/xhsWebApiClient.ts +229 -0
- package/integrations/xhs-reader/normalize.ts +390 -0
- package/integrations/xhs-reader/orchestrator.ts +178 -0
- package/integrations/xhs-reader/redaction.ts +68 -0
- package/integrations/xhs-reader/types.ts +244 -0
- package/integrations/xhs-reader/url.ts +57 -0
- package/machineWsRunDispatch.ts +51 -6
- package/offlineMarxistsAgentCommand.ts +6 -4
- package/package.json +430 -3
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +468 -0
- package/render/page/types.ts +17 -0
- package/render/table/createTableAction.ts +270 -0
- package/render/table/deleteTableAction.ts +193 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1106 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +252 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/server/handlers/agentRun/types.ts +104 -0
- package/share/action.ts +225 -0
- package/share/helpers.ts +302 -0
- package/share/keys.ts +243 -0
- package/share/publicSharePolicy.ts +27 -0
- package/share/shareSlice.ts +53 -0
- package/share/types.ts +100 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XHS Profile Reader Bridge
|
|
3
|
+
*
|
|
4
|
+
* Uses Playwright persistent context to:
|
|
5
|
+
* - Reuse login state across sessions (via dedicated profile directory)
|
|
6
|
+
* - Collect profile + notes via the XHS orchestrator
|
|
7
|
+
* - Extract cookies for API enrichment (detail/comment fetching)
|
|
8
|
+
*
|
|
9
|
+
* Does NOT store or output cookies/xsecToken in results.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { join, posix, win32 } from "node:path";
|
|
13
|
+
import { homedir, tmpdir } from "node:os";
|
|
14
|
+
import { collectXhsProfile } from "../orchestrator";
|
|
15
|
+
import type { CollectXhsProfileOptions } from "../orchestrator";
|
|
16
|
+
import type { XhsReadResult, XhsProfileCollection } from "../types";
|
|
17
|
+
import { createXhsFailure } from "../types";
|
|
18
|
+
import { redactXhsSensitiveValue } from "../redaction";
|
|
19
|
+
|
|
20
|
+
export type ReadXhsProfileWithBridgeOptions = {
|
|
21
|
+
/** Canonical field name. */
|
|
22
|
+
profileUrl?: string;
|
|
23
|
+
/** Alias accepted from tool args (tool schema uses `url`). */
|
|
24
|
+
url?: string;
|
|
25
|
+
maxScrollPages?: number;
|
|
26
|
+
enrichDetails?: boolean;
|
|
27
|
+
includeComments?: boolean;
|
|
28
|
+
maxCommentPagesPerNote?: number;
|
|
29
|
+
minLikesForDetail?: number;
|
|
30
|
+
minCommentsForCollect?: number;
|
|
31
|
+
extendedCollectionConsent?: boolean;
|
|
32
|
+
profileDir?: string;
|
|
33
|
+
headless?: boolean;
|
|
34
|
+
keepOpen?: boolean;
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
collectionMode?: "conservative" | "assisted";
|
|
37
|
+
assistedAction?: "snapshot" | "read_more_notes" | "read_comments";
|
|
38
|
+
maxAssistedSteps?: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Pure helper: resolve the profile URL from options, supporting both
|
|
43
|
+
* `profileUrl` (canonical) and `url` (tool schema alias).
|
|
44
|
+
* Returns undefined if neither is provided.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveXhsBridgeProfileUrl(
|
|
47
|
+
options: Pick<ReadXhsProfileWithBridgeOptions, "profileUrl" | "url">,
|
|
48
|
+
): string | undefined {
|
|
49
|
+
return options.profileUrl ?? options.url;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const DESKTOP_APP_ID = "chat.nolo.desktop";
|
|
53
|
+
|
|
54
|
+
export function resolveDefaultXhsProfileDir({
|
|
55
|
+
env = process.env,
|
|
56
|
+
platform = process.platform,
|
|
57
|
+
homeDir = homedir(),
|
|
58
|
+
tmpDir = tmpdir(),
|
|
59
|
+
}: {
|
|
60
|
+
env?: NodeJS.ProcessEnv;
|
|
61
|
+
platform?: NodeJS.Platform;
|
|
62
|
+
homeDir?: string;
|
|
63
|
+
tmpDir?: string;
|
|
64
|
+
} = {}): string {
|
|
65
|
+
const configured = env.NOLO_XHS_READER_PROFILE_DIR?.trim();
|
|
66
|
+
if (configured) return configured;
|
|
67
|
+
|
|
68
|
+
if (env.NOLO_DESKTOP === "1") {
|
|
69
|
+
const pathApi = platform === "win32" ? win32 : posix;
|
|
70
|
+
const dataRoot =
|
|
71
|
+
platform === "win32"
|
|
72
|
+
? env.LOCALAPPDATA?.trim() || pathApi.join(homeDir, "AppData", "Local")
|
|
73
|
+
: platform === "darwin"
|
|
74
|
+
? pathApi.join(homeDir, "Library", "Application Support")
|
|
75
|
+
: env.XDG_DATA_HOME?.trim() || pathApi.join(homeDir, ".local", "share");
|
|
76
|
+
const channel = env.NOLO_DESKTOP_CHANNEL?.trim() || "stable";
|
|
77
|
+
return pathApi.join(dataRoot, DESKTOP_APP_ID, channel, "external-readers", "xhs-profile");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return join(tmpDir, "nolo-xhs-reader-profile");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function envFlagEnabled(value: string | undefined): boolean | undefined {
|
|
84
|
+
if (value == null) return undefined;
|
|
85
|
+
return !["0", "false", "no", "off"].includes(value.trim().toLowerCase());
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Read an XHS profile using Playwright persistent context.
|
|
90
|
+
*
|
|
91
|
+
* The profile directory stores browser state including XHS login cookies.
|
|
92
|
+
* First run: user must log in manually (headless=false, keepOpen=true).
|
|
93
|
+
* Subsequent runs: login state is reused automatically.
|
|
94
|
+
*/
|
|
95
|
+
export async function readXhsProfileWithBridge(
|
|
96
|
+
options: ReadXhsProfileWithBridgeOptions,
|
|
97
|
+
): Promise<XhsReadResult<XhsProfileCollection>> {
|
|
98
|
+
const {
|
|
99
|
+
profileUrl: profileUrlRaw,
|
|
100
|
+
url: urlAlias,
|
|
101
|
+
maxScrollPages = 0,
|
|
102
|
+
enrichDetails = false,
|
|
103
|
+
includeComments = false,
|
|
104
|
+
maxCommentPagesPerNote = 1,
|
|
105
|
+
minLikesForDetail,
|
|
106
|
+
minCommentsForCollect,
|
|
107
|
+
extendedCollectionConsent = false,
|
|
108
|
+
headless = envFlagEnabled(process.env.NOLO_XHS_READER_HEADLESS) ?? true,
|
|
109
|
+
keepOpen = false,
|
|
110
|
+
profileDir = resolveDefaultXhsProfileDir(),
|
|
111
|
+
timeoutMs = 120_000,
|
|
112
|
+
} = options;
|
|
113
|
+
|
|
114
|
+
// Support both `profileUrl` (canonical) and `url` (tool schema alias)
|
|
115
|
+
const profileUrl = resolveXhsBridgeProfileUrl({ profileUrl: profileUrlRaw, url: urlAlias });
|
|
116
|
+
if (!profileUrl) {
|
|
117
|
+
return createXhsFailure({
|
|
118
|
+
code: "parse_error",
|
|
119
|
+
message: "readXhsProfileWithBridge requires a profile URL (profileUrl or url).",
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let playwright: any;
|
|
124
|
+
try {
|
|
125
|
+
playwright = await import("playwright");
|
|
126
|
+
} catch {
|
|
127
|
+
return createXhsFailure({
|
|
128
|
+
code: "unknown",
|
|
129
|
+
message:
|
|
130
|
+
"Playwright is not installed. Run `bun add playwright` or `npx playwright install chromium` first.",
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Wrap the entire Playwright + orchestrator operation in a timeout
|
|
135
|
+
// so that browser launch time is also bounded.
|
|
136
|
+
const timeoutPromise = new Promise<XhsReadResult<XhsProfileCollection>>(
|
|
137
|
+
(_, reject) => {
|
|
138
|
+
const timer = setTimeout(() => {
|
|
139
|
+
reject(
|
|
140
|
+
Object.assign(
|
|
141
|
+
new Error(`read_xhs_profile timed out after ${timeoutMs}ms`),
|
|
142
|
+
{ code: "READ_XHS_PROFILE_TIMEOUT" },
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
}, timeoutMs);
|
|
146
|
+
if (typeof timer === "object" && "unref" in timer) timer.unref();
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const workPromise = (async () => {
|
|
151
|
+
let context: any = null;
|
|
152
|
+
try {
|
|
153
|
+
// Use persistent context for login state reuse
|
|
154
|
+
context = await playwright.chromium.launchPersistentContext(profileDir, {
|
|
155
|
+
headless,
|
|
156
|
+
args: [
|
|
157
|
+
"--disable-dev-shm-usage",
|
|
158
|
+
],
|
|
159
|
+
viewport: { width: 1440, height: 900 },
|
|
160
|
+
locale: "zh-CN",
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const page = await context.newPage();
|
|
164
|
+
|
|
165
|
+
// Extract cookies for API enrichment (not exposed in output)
|
|
166
|
+
let cookie: string | undefined;
|
|
167
|
+
if (enrichDetails || includeComments) {
|
|
168
|
+
try {
|
|
169
|
+
const cookies = await context.cookies("https://www.xiaohongshu.com");
|
|
170
|
+
if (cookies.length > 0) {
|
|
171
|
+
cookie = cookies
|
|
172
|
+
.map((c: { name: string; value: string }) => `${c.name}=${c.value}`)
|
|
173
|
+
.join("; ");
|
|
174
|
+
}
|
|
175
|
+
} catch {
|
|
176
|
+
// Cookie extraction failed - proceed without API enrichment
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const orchestratorOptions: CollectXhsProfileOptions = {
|
|
181
|
+
profileUrl,
|
|
182
|
+
maxScrollPages: extendedCollectionConsent ? maxScrollPages : 0,
|
|
183
|
+
enrichDetails: extendedCollectionConsent && enrichDetails && !!cookie,
|
|
184
|
+
includeComments: extendedCollectionConsent && includeComments && !!cookie,
|
|
185
|
+
maxCommentPagesPerNote: extendedCollectionConsent
|
|
186
|
+
? maxCommentPagesPerNote
|
|
187
|
+
: 1,
|
|
188
|
+
cookie,
|
|
189
|
+
page,
|
|
190
|
+
minLikesForDetail: extendedCollectionConsent
|
|
191
|
+
? minLikesForDetail
|
|
192
|
+
: undefined,
|
|
193
|
+
minCommentsForCollect: extendedCollectionConsent
|
|
194
|
+
? minCommentsForCollect
|
|
195
|
+
: undefined,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const result = await collectXhsProfile(orchestratorOptions);
|
|
199
|
+
|
|
200
|
+
// Final redaction pass (cookies should already be stripped by orchestrator)
|
|
201
|
+
return redactXhsSensitiveValue(result) as XhsReadResult<XhsProfileCollection>;
|
|
202
|
+
} finally {
|
|
203
|
+
if (!keepOpen && context) {
|
|
204
|
+
try {
|
|
205
|
+
await context.close();
|
|
206
|
+
} catch {
|
|
207
|
+
// ignore close errors
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
})();
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
return await Promise.race([workPromise, timeoutPromise]);
|
|
215
|
+
} catch (err: any) {
|
|
216
|
+
if (err?.code === "READ_XHS_PROFILE_TIMEOUT") {
|
|
217
|
+
return createXhsFailure({
|
|
218
|
+
code: "network_error",
|
|
219
|
+
message: err.message,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return createXhsFailure({
|
|
223
|
+
code: "network_error",
|
|
224
|
+
message: `XHS profile read failed: ${String(err?.message ?? err)}`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XHS Web API client for note details and top-level comments.
|
|
3
|
+
*
|
|
4
|
+
* Uses the existing desktop browser cookies to make authenticated requests.
|
|
5
|
+
* Supports dependency injection of fetch for testing.
|
|
6
|
+
*
|
|
7
|
+
* Endpoints:
|
|
8
|
+
* - Note detail: POST /api/sns/web/v1/feed
|
|
9
|
+
* - Comments: GET /api/sns/web/v2/comment/page
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT: This client does NOT implement write endpoints.
|
|
12
|
+
* No like, collect, comment, post, delete, or upload actions.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { redactXhsSensitiveValue } from "../redaction";
|
|
16
|
+
import {
|
|
17
|
+
normalizeNoteDetail,
|
|
18
|
+
normalizeCommentPage,
|
|
19
|
+
} from "../normalize";
|
|
20
|
+
import type {
|
|
21
|
+
XhsNoteDetail,
|
|
22
|
+
XhsCommentPage,
|
|
23
|
+
XhsReadResult,
|
|
24
|
+
XhsFailureCode,
|
|
25
|
+
} from "../types";
|
|
26
|
+
import { createXhsFailure, createXhsSuccess } from "../types";
|
|
27
|
+
|
|
28
|
+
const XHS_BASE = "https://edith.xiaohongshu.com";
|
|
29
|
+
|
|
30
|
+
export interface XhsApiClientOptions {
|
|
31
|
+
/** Cookie string to authenticate requests. Not stored in results. */
|
|
32
|
+
cookie: string;
|
|
33
|
+
/** Optional xsecToken for the session. Not stored in results. */
|
|
34
|
+
xsecToken?: string;
|
|
35
|
+
/** Custom fetch implementation for testing. */
|
|
36
|
+
fetchImpl?: typeof fetch;
|
|
37
|
+
/** Base URL override (for testing). */
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create an XHS Web API client instance.
|
|
43
|
+
*/
|
|
44
|
+
export function createXhsApiClient(opts: XhsApiClientOptions) {
|
|
45
|
+
const baseUrl = opts.baseUrl ?? XHS_BASE;
|
|
46
|
+
const fetchFn = opts.fetchImpl ?? fetch;
|
|
47
|
+
|
|
48
|
+
const commonHeaders: Record<string, string> = {
|
|
49
|
+
cookie: opts.cookie,
|
|
50
|
+
"user-agent":
|
|
51
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
52
|
+
origin: "https://www.xiaohongshu.com",
|
|
53
|
+
referer: "https://www.xiaohongshu.com/",
|
|
54
|
+
"content-type": "application/json",
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
if (opts.xsecToken) {
|
|
58
|
+
commonHeaders["x-xsec-token"] = opts.xsecToken;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Fetch note detail by noteId.
|
|
63
|
+
* Requires per-note xsecToken for the signed request to succeed.
|
|
64
|
+
*/
|
|
65
|
+
async function getNoteDetail(
|
|
66
|
+
noteId: string,
|
|
67
|
+
xsecToken?: string,
|
|
68
|
+
xsecSource?: string,
|
|
69
|
+
): Promise<XhsReadResult<XhsNoteDetail>> {
|
|
70
|
+
try {
|
|
71
|
+
const url = `${baseUrl}/api/sns/web/v1/feed`;
|
|
72
|
+
const resp = await fetchFn(url, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: commonHeaders,
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
source_note_id: noteId,
|
|
77
|
+
image_formats: ["jpg", "webp", "avif"],
|
|
78
|
+
extra: { need_body_topic: 1 },
|
|
79
|
+
...(xsecToken ? { xsec_token: xsecToken } : {}),
|
|
80
|
+
...(xsecSource ? { xsec_source: xsecSource } : {}),
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!resp.ok) {
|
|
85
|
+
const code = mapHttpStatus(resp.status);
|
|
86
|
+
return createXhsFailure({
|
|
87
|
+
code,
|
|
88
|
+
message: `Note detail request failed: HTTP ${resp.status}`,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const body = (await resp.json()) as Record<string, unknown>;
|
|
93
|
+
|
|
94
|
+
if (body.code === -1 || body.success === false) {
|
|
95
|
+
return createXhsFailure({
|
|
96
|
+
code: "unknown",
|
|
97
|
+
message: `XHS API error: ${JSON.stringify(
|
|
98
|
+
redactXhsSensitiveValue(body),
|
|
99
|
+
)}`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The items array contains the note data
|
|
104
|
+
const items = (body.data as Record<string, unknown>)?.items as
|
|
105
|
+
| Array<Record<string, unknown>>
|
|
106
|
+
| undefined;
|
|
107
|
+
if (!items || items.length === 0) {
|
|
108
|
+
return createXhsFailure({
|
|
109
|
+
code: "note_not_found",
|
|
110
|
+
message: "No items returned from feed API",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const noteData = items[0];
|
|
115
|
+
const normalized = normalizeNoteDetail(
|
|
116
|
+
noteData as Record<string, unknown>,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return createXhsSuccess(normalized);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
return createXhsFailure({
|
|
122
|
+
code: "network_error",
|
|
123
|
+
message: `Note detail fetch error: ${String(err)}`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Fetch a page of top-level comments for a note.
|
|
130
|
+
* Requires per-note xsecToken for authentication.
|
|
131
|
+
*/
|
|
132
|
+
async function getCommentPage(
|
|
133
|
+
noteId: string,
|
|
134
|
+
cursor?: string,
|
|
135
|
+
xsecToken?: string,
|
|
136
|
+
topCommentId?: string,
|
|
137
|
+
): Promise<XhsReadResult<XhsCommentPage>> {
|
|
138
|
+
try {
|
|
139
|
+
const params = new URLSearchParams({
|
|
140
|
+
note_id: noteId,
|
|
141
|
+
cursor: cursor ?? "",
|
|
142
|
+
top_comment_id: topCommentId ?? "",
|
|
143
|
+
image_formats: "jpg,webp,avif",
|
|
144
|
+
...(xsecToken ? { xsec_token: xsecToken } : {}),
|
|
145
|
+
});
|
|
146
|
+
const url = `${baseUrl}/api/sns/web/v2/comment/page?${params}`;
|
|
147
|
+
|
|
148
|
+
const resp = await fetchFn(url, {
|
|
149
|
+
method: "GET",
|
|
150
|
+
headers: commonHeaders,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
if (!resp.ok) {
|
|
154
|
+
const code = mapHttpStatus(resp.status);
|
|
155
|
+
return createXhsFailure({
|
|
156
|
+
code,
|
|
157
|
+
message: `Comment page request failed: HTTP ${resp.status}`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const body = (await resp.json()) as Record<string, unknown>;
|
|
162
|
+
|
|
163
|
+
if (body.code === -1 || body.success === false) {
|
|
164
|
+
return createXhsFailure({
|
|
165
|
+
code: "unknown",
|
|
166
|
+
message: `XHS comment API error: ${JSON.stringify(
|
|
167
|
+
redactXhsSensitiveValue(body),
|
|
168
|
+
)}`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const normalized = normalizeCommentPage(body);
|
|
173
|
+
|
|
174
|
+
return createXhsSuccess(normalized);
|
|
175
|
+
} catch (err) {
|
|
176
|
+
return createXhsFailure({
|
|
177
|
+
code: "network_error",
|
|
178
|
+
message: `Comment page fetch error: ${String(err)}`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Fetch all top-level comments for a note up to maxPages.
|
|
185
|
+
*/
|
|
186
|
+
async function getAllCommentPages(
|
|
187
|
+
noteId: string,
|
|
188
|
+
xsecToken?: string,
|
|
189
|
+
maxPages: number = 3,
|
|
190
|
+
): Promise<XhsReadResult<XhsCommentPage>> {
|
|
191
|
+
const allComments: XhsCommentPage["comments"] = [];
|
|
192
|
+
let cursor: string | undefined;
|
|
193
|
+
let hasMore = true;
|
|
194
|
+
let pages = 0;
|
|
195
|
+
|
|
196
|
+
while (hasMore && pages < maxPages) {
|
|
197
|
+
const result = await getCommentPage(noteId, cursor, xsecToken);
|
|
198
|
+
if (!result.ok) {
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
allComments.push(...result.data.comments);
|
|
203
|
+
hasMore = result.data.hasMore;
|
|
204
|
+
cursor = result.data.cursor;
|
|
205
|
+
pages++;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return createXhsSuccess({
|
|
209
|
+
comments: allComments,
|
|
210
|
+
hasMore,
|
|
211
|
+
cursor,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
getNoteDetail,
|
|
217
|
+
getCommentPage,
|
|
218
|
+
getAllCommentPages,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export type XhsApiClient = ReturnType<typeof createXhsApiClient>;
|
|
223
|
+
|
|
224
|
+
function mapHttpStatus(status: number): XhsFailureCode {
|
|
225
|
+
if (status === 401 || status === 403) return "not_logged_in";
|
|
226
|
+
if (status === 404) return "note_not_found";
|
|
227
|
+
if (status === 429) return "rate_limited";
|
|
228
|
+
return "network_error";
|
|
229
|
+
}
|