@tonyclaw/agent-inspector 3.0.44 → 3.0.46
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/.output/{nitro.json → backend/nitro.json} +3 -3
- package/.output/backend-public/assets/index-D4LX-sw-.js +11 -0
- package/.output/cli.js +22707 -17099
- package/.output/server/_libs/extend.mjs +4 -8
- package/.output/server/_libs/jszip.mjs +9 -35
- package/.output/server/_libs/modelcontextprotocol__core.mjs +25 -25
- package/.output/server/_libs/modelcontextprotocol__server.mjs +2 -2
- package/.output/server/_libs/react-dom.mjs +2 -3
- package/.output/server/_libs/react.mjs +1 -27
- package/.output/server/_libs/tanstack__react-router.mjs +1 -329
- package/.output/server/_libs/tanstack__router-core.mjs +42 -100
- package/.output/server/_libs/use-sync-external-store.mjs +1 -64
- package/.output/server/_libs/ws.mjs +1 -1
- package/.output/server/_libs/zod.mjs +6 -6
- package/.output/server/_ssr/index.mjs +5 -4
- package/.output/server/_ssr/publicBasePathContext-IH2ilOfu.mjs +176 -0
- package/.output/server/_ssr/{router-DWcUFPR3.mjs → router-D18yUq36.mjs} +7877 -5597
- package/.output/server/_ssr/start-COQu_AgD.mjs +57 -0
- package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
- package/.output/server/index.mjs +5 -145
- package/.output/{public/assets/CompareDrawer-DQHjxFO6.js → ui/assets/CompareDrawer-DAUuIJ6G.js} +1 -1
- package/.output/{public/assets/InspectorPet-D1A4505B.js → ui/assets/InspectorPet-BRBVjOWI.js} +1 -1
- package/.output/ui/assets/ProxyViewerContainer-D7Sq0ctc.js +59 -0
- package/.output/{public/assets/ReplayDialog-C5vmbecv.js → ui/assets/ReplayDialog-nDLsjOhs.js} +1 -1
- package/.output/{public/assets/RequestAnatomy-CPGNB8lk.js → ui/assets/RequestAnatomy-zd4BDgL0.js} +1 -1
- package/.output/ui/assets/ResponseView-AdIXGcSn.js +2 -0
- package/.output/ui/assets/StreamingChunkSequence-CesTz8He.js +1 -0
- package/.output/{public/assets/_sessionId-CDhRgzf6.js → ui/assets/_sessionId-BAfzrhSU.js} +1 -1
- package/.output/{public/assets/_sessionId-mw3aA8Bp.js → ui/assets/_sessionId-QnBomgPD.js} +1 -1
- package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
- package/.output/{public/assets/index-B2eoeT-Z.js → ui/assets/index-BcsdxBAd.js} +1 -1
- package/.output/ui/assets/index-BvXp42al.css +1 -0
- package/.output/{public/assets/index-CX7_rf7o.js → ui/assets/index-D0rtCN9V.js} +1 -1
- package/.output/ui/assets/index-DHpwr08Z.js +73 -0
- package/.output/{public/assets/index-BfRhTvOd.js → ui/assets/index-dNuk2dsU.js} +1 -1
- package/.output/ui/assets/json-viewer-BvFHglMb.js +1 -0
- package/.output/{public/assets/jszip.min-C9rCFoU3.js → ui/assets/jszip.min-B5Z7gNZB.js} +1 -1
- package/.output/ui/index.html +229 -0
- package/.output/ui/runtime-config.js +2 -0
- package/.output/workers/logFinalizer.worker.js +983 -414
- package/.output/workers/sessionWorkerEntry.js +983 -414
- package/README.md +363 -35
- package/docs/instance-control.openapi.yaml +361 -0
- package/package.json +28 -5
- package/scripts/generate-theme-scales.mjs +3 -3
- package/src/{router.tsx → backend/router.tsx} +3 -15
- package/src/backend/routes/$.ts +26 -0
- package/src/backend/routes/__root.ts +4 -0
- package/src/backend/routes/api/-instances.ts +109 -0
- package/src/{routes → backend/routes}/api/alerts.summary.ts +3 -3
- package/src/{routes → backend/routes}/api/alerts.ts +4 -4
- package/src/{routes → backend/routes}/api/config.paths.ts +1 -1
- package/src/{routes → backend/routes}/api/config.ts +11 -2
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.help.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.install.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.runner-presets.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.upgrade.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.ts +5 -1
- package/src/{routes → backend/routes}/api/ecosystem.recipes.$recipeId.run.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.tasks.$taskId.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.tasks.ts +1 -1
- package/src/{routes → backend/routes}/api/groups.$groupId.evidence.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.$groupId.sessions.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.$groupId.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.ts +2 -2
- package/src/{routes → backend/routes}/api/health.ts +3 -3
- package/src/backend/routes/api/instances.$name.connection.ts +12 -0
- package/src/backend/routes/api/instances.$name.restart.ts +23 -0
- package/src/backend/routes/api/instances.$name.start.ts +18 -0
- package/src/backend/routes/api/instances.$name.stop.ts +23 -0
- package/src/backend/routes/api/instances.$name.ts +12 -0
- package/src/backend/routes/api/instances.ts +16 -0
- package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.promote.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.candidates.ts +1 -1
- package/src/{routes → backend/routes}/api/knowledge.project-context.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.search.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.sessions.$sessionId.candidates.ts +3 -3
- package/src/{routes → backend/routes}/api/logs.$id.body.ts +6 -6
- package/src/{routes → backend/routes}/api/logs.$id.chunks.ts +5 -4
- package/src/{routes → backend/routes}/api/logs.$id.replay.ts +12 -11
- package/src/{routes → backend/routes}/api/logs.$id.ts +4 -3
- package/src/{routes → backend/routes}/api/logs.import.ts +3 -3
- package/src/{routes → backend/routes}/api/logs.stream.ts +11 -7
- package/src/{routes → backend/routes}/api/logs.ts +17 -9
- package/src/{routes → backend/routes}/api/mcp.ts +1 -1
- package/src/{routes → backend/routes}/api/models.ts +1 -1
- package/src/{routes → backend/routes}/api/pi-agent.ts +2 -2
- package/src/{routes → backend/routes}/api/providers.$providerId.model-metadata.ts +5 -5
- package/src/{routes → backend/routes}/api/providers.$providerId.test.log.ts +7 -7
- package/src/{routes → backend/routes}/api/providers.$providerId.ts +4 -4
- package/src/{routes → backend/routes}/api/providers.export.ts +1 -1
- package/src/{routes → backend/routes}/api/providers.import.ts +3 -3
- package/src/{routes → backend/routes}/api/providers.scan.ts +2 -2
- package/src/{routes → backend/routes}/api/providers.ts +9 -4
- package/src/{routes → backend/routes}/api/runs.$runId.evidence.ts +2 -2
- package/src/{routes → backend/routes}/api/runs.$runId.ts +2 -2
- package/src/{routes → backend/routes}/api/runs.ts +4 -4
- package/src/backend/routes/api/runtime.ts +46 -0
- package/src/{routes → backend/routes}/api/sessions.ts +3 -3
- package/src/{routes → backend/routes}/proxy/$.ts +1 -1
- package/src/{routes → backend/routes}/readyz.ts +1 -1
- package/src/backend/start.ts +10 -0
- package/src/cli/alias.ts +431 -0
- package/src/cli/doctor.ts +32 -9
- package/src/cli/instance.ts +1050 -0
- package/src/cli/instanceArgs.ts +285 -0
- package/src/cli/instanceControl.ts +181 -0
- package/src/cli/instanceModel.ts +267 -0
- package/src/cli/instanceRegistry.ts +731 -0
- package/src/cli/networkHints.ts +27 -14
- package/src/cli/onboard.ts +190 -35
- package/src/cli/onboardTarget.ts +228 -0
- package/src/cli/templates/codex-skill-onboard.ts +109 -31
- package/src/cli/templates/skill-onboard.ts +140 -70
- package/src/cli.ts +338 -77
- package/src/components/ProxyViewer.tsx +20 -10
- package/src/components/ProxyViewerContainer.tsx +12 -11
- package/src/components/pi-agent/PiAgentPanel.tsx +2 -2
- package/src/components/providers/ProviderCard.tsx +1 -1
- package/src/components/providers/ProviderTestResultsView.tsx +1 -1
- package/src/components/providers/SettingsDialog.tsx +160 -140
- package/src/components/proxy-viewer/ApplicationBar.tsx +2 -1
- package/src/components/proxy-viewer/LogEntry.tsx +1 -1
- package/src/components/proxy-viewer/log-formats/index.ts +1 -1
- package/src/contracts/index.ts +5 -0
- package/src/contracts/log.ts +33 -3
- package/src/knowledge/types.ts +3 -2
- package/src/lib/alertContract.ts +2 -2
- package/src/lib/apiClient.ts +30 -7
- package/src/lib/apiFormat.ts +29 -0
- package/src/lib/basePath.ts +31 -7
- package/src/lib/browserRuntimeContract.ts +124 -0
- package/src/lib/browserRuntimeResolver.ts +244 -0
- package/src/{proxy → lib}/claudeCodeStrip.ts +6 -7
- package/src/lib/codingAgentEndpoints.ts +54 -0
- package/src/lib/instanceContract.ts +236 -0
- package/src/lib/managedInstance.ts +104 -0
- package/src/lib/piAgentContract.ts +3 -2
- package/src/lib/publicBasePathContext.ts +137 -0
- package/src/lib/resourceLimits.ts +2 -0
- package/src/lib/runContract.ts +3 -3
- package/src/lib/sessionInfoContract.ts +3 -2
- package/src/mcp/instanceHandlers.ts +150 -0
- package/src/mcp/loopback.ts +16 -5
- package/src/mcp/mode.ts +25 -0
- package/src/mcp/server.ts +274 -39
- package/src/mcp/toolHandlers.ts +2 -2
- package/src/proxy/config.ts +25 -30
- package/src/proxy/dataDir.ts +43 -7
- package/src/proxy/ecosystemTasks.ts +161 -70
- package/src/proxy/formats/registry.ts +6 -21
- package/src/proxy/handler.ts +129 -29
- package/src/proxy/identityProxy.ts +1049 -50
- package/src/proxy/jsonlRecovery.ts +554 -0
- package/src/proxy/logFinalizer.ts +25 -10
- package/src/proxy/logImporter.ts +2 -1
- package/src/proxy/logIndex.ts +191 -95
- package/src/proxy/logger.ts +77 -14
- package/src/proxy/platformCommands.ts +41 -0
- package/src/proxy/privateDataPath.ts +310 -88
- package/src/proxy/rawStreamCapture.ts +194 -13
- package/src/proxy/runtimeAdmission.ts +5 -2
- package/src/proxy/runtimeHealth.ts +14 -1
- package/src/proxy/runtimeShutdown.ts +84 -2
- package/src/proxy/schemas.ts +7 -1
- package/src/proxy/sessionArchive.ts +78 -14
- package/src/proxy/sessionInfo.ts +5 -4
- package/src/proxy/sqliteLogIndex.ts +65 -2
- package/src/proxy/store.ts +141 -34
- package/src/proxy/uiAssetServer.ts +106 -0
- package/src/proxy/upstream.ts +29 -2
- package/src/ui/bootstrap.ts +167 -0
- package/src/ui/index.html +38 -0
- package/src/ui/logsStreamClient.ts +20 -0
- package/src/ui/main.tsx +13 -0
- package/src/ui/public/runtime-config.js +2 -0
- package/src/ui/router.tsx +13 -0
- package/src/ui/routes/__root.tsx +69 -0
- package/src/{routes → ui/routes}/index.tsx +2 -3
- package/src/{routes → ui/routes}/session/$sessionId.tsx +5 -11
- package/src/ui/runtimeDiscovery.ts +50 -0
- package/styles/globals.css +1 -0
- package/.output/public/assets/ProxyViewerContainer-BhpIgfBi.js +0 -126
- package/.output/public/assets/ResponseView-DUfrajCm.js +0 -2
- package/.output/public/assets/StreamingChunkSequence-nbeCQqOz.js +0 -1
- package/.output/public/assets/index-BWjeqxbk.css +0 -1
- package/.output/public/assets/index-C6qZwYlR.js +0 -70
- package/.output/public/assets/json-viewer-BLmF1sOZ.js +0 -1
- package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +0 -1
- package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +0 -344
- package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +0 -11
- package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +0 -69
- package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +0 -1
- package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +0 -28
- package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +0 -6
- package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +0 -34
- package/.output/server/_libs/aria-hidden.mjs +0 -122
- package/.output/server/_libs/bail.mjs +0 -8
- package/.output/server/_libs/character-entities.mjs +0 -2130
- package/.output/server/_libs/class-variance-authority.mjs +0 -44
- package/.output/server/_libs/clsx.mjs +0 -16
- package/.output/server/_libs/comma-separated-tokens.mjs +0 -10
- package/.output/server/_libs/decode-named-character-reference+[...].mjs +0 -8
- package/.output/server/_libs/dequal.mjs +0 -27
- package/.output/server/_libs/detect-node-es.mjs +0 -1
- package/.output/server/_libs/devlop.mjs +0 -8
- package/.output/server/_libs/diff.mjs +0 -320
- package/.output/server/_libs/estree-util-is-identifier-name.mjs +0 -11
- package/.output/server/_libs/floating-ui__core.mjs +0 -725
- package/.output/server/_libs/floating-ui__dom.mjs +0 -622
- package/.output/server/_libs/floating-ui__react-dom.mjs +0 -292
- package/.output/server/_libs/floating-ui__utils.mjs +0 -320
- package/.output/server/_libs/get-nonce.mjs +0 -9
- package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
- package/.output/server/_libs/hast-util-whitespace.mjs +0 -10
- package/.output/server/_libs/html-url-attributes.mjs +0 -26
- package/.output/server/_libs/inline-style-parser.mjs +0 -142
- package/.output/server/_libs/is-plain-obj.mjs +0 -10
- package/.output/server/_libs/lucide-react.mjs +0 -1027
- package/.output/server/_libs/mdast-util-from-markdown.mjs +0 -717
- package/.output/server/_libs/mdast-util-to-hast.mjs +0 -710
- package/.output/server/_libs/mdast-util-to-string.mjs +0 -38
- package/.output/server/_libs/micromark-core-commonmark.mjs +0 -2259
- package/.output/server/_libs/micromark-factory-destination.mjs +0 -94
- package/.output/server/_libs/micromark-factory-label.mjs +0 -63
- package/.output/server/_libs/micromark-factory-space.mjs +0 -24
- package/.output/server/_libs/micromark-factory-title.mjs +0 -65
- package/.output/server/_libs/micromark-factory-whitespace.mjs +0 -22
- package/.output/server/_libs/micromark-util-character.mjs +0 -44
- package/.output/server/_libs/micromark-util-chunked.mjs +0 -36
- package/.output/server/_libs/micromark-util-classify-character+[...].mjs +0 -12
- package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
- package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
- package/.output/server/_libs/micromark-util-decode-string.mjs +0 -21
- package/.output/server/_libs/micromark-util-encode.mjs +0 -1
- package/.output/server/_libs/micromark-util-html-tag-name.mjs +0 -69
- package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
- package/.output/server/_libs/micromark-util-resolve-all.mjs +0 -15
- package/.output/server/_libs/micromark-util-sanitize-uri.mjs +0 -41
- package/.output/server/_libs/micromark-util-subtokenize.mjs +0 -346
- package/.output/server/_libs/micromark.mjs +0 -906
- package/.output/server/_libs/property-information.mjs +0 -1209
- package/.output/server/_libs/radix-ui.mjs +0 -1
- package/.output/server/_libs/radix-ui__number.mjs +0 -6
- package/.output/server/_libs/radix-ui__primitive.mjs +0 -11
- package/.output/server/_libs/radix-ui__react-accordion.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
- package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-avatar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-checkbox.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-collapsible.mjs +0 -144
- package/.output/server/_libs/radix-ui__react-collection.mjs +0 -69
- package/.output/server/_libs/radix-ui__react-compose-refs.mjs +0 -38
- package/.output/server/_libs/radix-ui__react-context-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-context.mjs +0 -64
- package/.output/server/_libs/radix-ui__react-dialog.mjs +0 -280
- package/.output/server/_libs/radix-ui__react-direction.mjs +0 -9
- package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-focus-guards.mjs +0 -39
- package/.output/server/_libs/radix-ui__react-focus-scope.mjs +0 -210
- package/.output/server/_libs/radix-ui__react-form.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-hover-card.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-id.mjs +0 -14
- package/.output/server/_libs/radix-ui__react-label.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-menubar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-popover.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-popper.mjs +0 -340
- package/.output/server/_libs/radix-ui__react-portal.mjs +0 -16
- package/.output/server/_libs/radix-ui__react-presence.mjs +0 -173
- package/.output/server/_libs/radix-ui__react-primitive.mjs +0 -42
- package/.output/server/_libs/radix-ui__react-progress.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-radio-group.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-roving-focus.mjs +0 -235
- package/.output/server/_libs/radix-ui__react-scroll-area.mjs +0 -731
- package/.output/server/_libs/radix-ui__react-select.mjs +0 -1207
- package/.output/server/_libs/radix-ui__react-separator.mjs +0 -28
- package/.output/server/_libs/radix-ui__react-slider.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-slot.mjs +0 -132
- package/.output/server/_libs/radix-ui__react-switch.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-tabs.mjs +0 -194
- package/.output/server/_libs/radix-ui__react-toast.mjs +0 -2
- package/.output/server/_libs/radix-ui__react-toggle-group.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-toggle.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-toolbar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -498
- package/.output/server/_libs/radix-ui__react-use-previous.mjs +0 -14
- package/.output/server/_libs/radix-ui__react-use-size.mjs +0 -39
- package/.output/server/_libs/react-markdown.mjs +0 -235
- package/.output/server/_libs/react-remove-scroll-bar.mjs +0 -82
- package/.output/server/_libs/react-remove-scroll.mjs +0 -328
- package/.output/server/_libs/react-style-singleton.mjs +0 -69
- package/.output/server/_libs/remark-parse.mjs +0 -19
- package/.output/server/_libs/remark-rehype.mjs +0 -21
- package/.output/server/_libs/space-separated-tokens.mjs +0 -6
- package/.output/server/_libs/style-to-js.mjs +0 -72
- package/.output/server/_libs/style-to-object.mjs +0 -38
- package/.output/server/_libs/swr.mjs +0 -947
- package/.output/server/_libs/tailwind-merge.mjs +0 -3255
- package/.output/server/_libs/tanstack__react-virtual.mjs +0 -130
- package/.output/server/_libs/tanstack__virtual-core.mjs +0 -1319
- package/.output/server/_libs/three.mjs +0 -26016
- package/.output/server/_libs/trim-lines.mjs +0 -41
- package/.output/server/_libs/trough.mjs +0 -85
- package/.output/server/_libs/tslib.mjs +0 -1
- package/.output/server/_libs/ungap__structured-clone.mjs +0 -212
- package/.output/server/_libs/unified.mjs +0 -661
- package/.output/server/_libs/unist-util-is.mjs +0 -100
- package/.output/server/_libs/unist-util-position.mjs +0 -27
- package/.output/server/_libs/unist-util-stringify-position.mjs +0 -27
- package/.output/server/_libs/unist-util-visit-parents.mjs +0 -82
- package/.output/server/_libs/unist-util-visit.mjs +0 -24
- package/.output/server/_libs/use-callback-ref.mjs +0 -66
- package/.output/server/_libs/use-sidecar.mjs +0 -106
- package/.output/server/_libs/vfile-message.mjs +0 -138
- package/.output/server/_libs/vfile.mjs +0 -467
- package/.output/server/_sessionId-E_Dmopc-.mjs +0 -144
- package/.output/server/_sessionId-U54BAqdp.mjs +0 -82
- package/.output/server/_ssr/CompareDrawer-CksatPed.mjs +0 -1058
- package/.output/server/_ssr/InspectorPet-DNc4GQ7z.mjs +0 -936
- package/.output/server/_ssr/ProxyViewerContainer-B02Ey0p_.mjs +0 -17607
- package/.output/server/_ssr/ReplayDialog-DdMvHJF1.mjs +0 -723
- package/.output/server/_ssr/RequestAnatomy--vh2Z8__.mjs +0 -835
- package/.output/server/_ssr/ResponseView-Dhxc-cKC.mjs +0 -755
- package/.output/server/_ssr/StreamingChunkSequence-BG0EQmaD.mjs +0 -272
- package/.output/server/_ssr/index-D0At9nfd.mjs +0 -82
- package/.output/server/_ssr/index-lcfulIXa.mjs +0 -133
- package/.output/server/_ssr/json-viewer-My1J1_5R.mjs +0 -481
- package/.output/server/_ssr/start-HYkvq4Ni.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-B2chR8ef.mjs +0 -4
- package/.output/server/node_modules/tslib/modules/index.js +0 -70
- package/.output/server/node_modules/tslib/modules/package.json +0 -3
- package/.output/server/node_modules/tslib/package.json +0 -47
- package/.output/server/node_modules/tslib/tslib.js +0 -484
- package/.output/server/package.json +0 -9
- package/src/routes/__root.tsx +0 -170
- /package/.output/{public → ui}/assets/agent-inspector-58K1_MsC.ico +0 -0
- /package/.output/{public → ui}/assets/alibaba-TTwafVwX.svg +0 -0
- /package/.output/{public → ui}/assets/minimax-BPMzvuL-.jpeg +0 -0
- /package/.output/{public → ui}/assets/qwen-mMn3f5ul.webp +0 -0
- /package/.output/{public → ui}/assets/zhipuai-BPNAnxo-.svg +0 -0
- /package/src/{routes → backend/routes}/livez.ts +0 -0
package/src/mcp/toolHandlers.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
|
20
20
|
import { dirname, join } from "node:path";
|
|
21
21
|
import JSZip from "jszip";
|
|
22
22
|
import { z } from "zod";
|
|
23
|
-
import {
|
|
23
|
+
import { getPublicPort } from "../lib/publicBasePathContext";
|
|
24
24
|
import { LoopbackTimeoutError, type CallApiOptions } from "./loopback";
|
|
25
25
|
import { extractLastUserMessagePreview, extractResponsePreview } from "./previewExtractor";
|
|
26
26
|
import {
|
|
@@ -138,7 +138,7 @@ function redactedProvidersResult(value: unknown): ToolResult {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
function inspectorBaseUrl(): string {
|
|
141
|
-
return `http://127.0.0.1:${String(
|
|
141
|
+
return `http://127.0.0.1:${String(getPublicPort())}`;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
function hasBodyText(value: string | null, byteLength: number | null | undefined): boolean {
|
package/src/proxy/config.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
writeFileSync,
|
|
3
|
-
readFileSync,
|
|
4
|
-
unlinkSync,
|
|
5
|
-
existsSync,
|
|
6
|
-
renameSync,
|
|
7
|
-
copyFileSync,
|
|
8
|
-
} from "node:fs";
|
|
1
|
+
import { writeFileSync, readFileSync, unlinkSync, existsSync, renameSync } from "node:fs";
|
|
9
2
|
import { join } from "node:path";
|
|
10
3
|
import { logger } from "./logger";
|
|
11
4
|
import { getDataDir } from "./dataDir";
|
|
@@ -128,19 +121,19 @@ export function getConfig(): RuntimeConfig {
|
|
|
128
121
|
}
|
|
129
122
|
|
|
130
123
|
/**
|
|
131
|
-
* Applies a partial update
|
|
132
|
-
* Returns the updated full config
|
|
133
|
-
*
|
|
134
|
-
*
|
|
124
|
+
* Applies a partial update after atomically persisting it to disk.
|
|
125
|
+
* Returns the updated full config on success or null when persistence
|
|
126
|
+
* fails. A failed write leaves both the in-memory value and the existing
|
|
127
|
+
* on-disk value unchanged.
|
|
135
128
|
*/
|
|
136
|
-
export function setConfig(patch: Partial<MutableRuntimeConfig>): RuntimeConfig {
|
|
129
|
+
export function setConfig(patch: Partial<MutableRuntimeConfig>): RuntimeConfig | null {
|
|
137
130
|
const next: RuntimeConfig = {
|
|
138
131
|
...currentConfig,
|
|
139
132
|
...patch,
|
|
140
133
|
captureMode: currentConfig.captureMode,
|
|
141
134
|
};
|
|
135
|
+
if (!persistConfig(next)) return null;
|
|
142
136
|
currentConfig = next;
|
|
143
|
-
persistConfig(next);
|
|
144
137
|
return next;
|
|
145
138
|
}
|
|
146
139
|
|
|
@@ -164,8 +157,10 @@ export function _rebootForTests(): void {
|
|
|
164
157
|
// --- Atomic write ---
|
|
165
158
|
|
|
166
159
|
/**
|
|
167
|
-
* Atomic write: temp file + rename
|
|
168
|
-
* Returns true on success, false on failure (logged but not thrown).
|
|
160
|
+
* Atomic write: secure temp file + rename in the same directory.
|
|
161
|
+
* Returns true on success, false on failure (logged but not thrown). There is
|
|
162
|
+
* deliberately no copy fallback because replacing the target through a copy
|
|
163
|
+
* could expose a partially written config after a crash.
|
|
169
164
|
*/
|
|
170
165
|
function persistConfig(value: RuntimeConfig): boolean {
|
|
171
166
|
const dir = getDataDir();
|
|
@@ -181,13 +176,15 @@ function persistConfig(value: RuntimeConfig): boolean {
|
|
|
181
176
|
writeFileSync(tempPath, JSON.stringify(toPersistedConfig(value)), {
|
|
182
177
|
encoding: "utf-8",
|
|
183
178
|
mode: PRIVATE_FILE_MODE,
|
|
179
|
+
flush: true,
|
|
184
180
|
});
|
|
185
181
|
if (!securePrivateFileSync(tempPath)) {
|
|
186
|
-
|
|
182
|
+
removeConfigTempFile(tempPath);
|
|
187
183
|
logger.error(`[config] Failed to secure config temp file ${tempPath}`);
|
|
188
184
|
return false;
|
|
189
185
|
}
|
|
190
186
|
} catch (err) {
|
|
187
|
+
removeConfigTempFile(tempPath);
|
|
191
188
|
logger.error(`[config] Failed to write config temp file: ${String(err)}`);
|
|
192
189
|
return false;
|
|
193
190
|
}
|
|
@@ -196,19 +193,17 @@ function persistConfig(value: RuntimeConfig): boolean {
|
|
|
196
193
|
renameSync(tempPath, targetPath);
|
|
197
194
|
return true;
|
|
198
195
|
} catch (err) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
196
|
+
removeConfigTempFile(tempPath);
|
|
197
|
+
logger.error(`[config] Failed to atomically replace config file: ${String(err)}`);
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function removeConfigTempFile(tempPath: string): void {
|
|
203
|
+
try {
|
|
204
|
+
unlinkSync(tempPath);
|
|
205
|
+
} catch {
|
|
206
|
+
// Best effort. A stale temp path is never read as runtime configuration.
|
|
212
207
|
}
|
|
213
208
|
}
|
|
214
209
|
|
package/src/proxy/dataDir.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { cpSync, existsSync, rmSync } from "node:fs";
|
|
1
|
+
import { cpSync, existsSync, readdirSync, renameSync, rmSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ensurePrivateDirectorySync,
|
|
5
|
+
isPathTreeFreeOfIndirectionSync,
|
|
6
|
+
securePrivateTreeSync,
|
|
7
|
+
} from "./privateDataPath";
|
|
4
8
|
|
|
5
9
|
const CURRENT_DATA_DIR_NAME = ".agent-inspector";
|
|
6
10
|
const LEGACY_DATA_DIR_NAMES = [".llm-inspector", ".llm-agent"];
|
|
@@ -98,14 +102,46 @@ export function migrateLegacyDataDirs(): void {
|
|
|
98
102
|
const legacyDir = join(base, legacyName);
|
|
99
103
|
if (!existsSync(legacyDir)) continue;
|
|
100
104
|
|
|
105
|
+
const stagingDir = join(
|
|
106
|
+
base,
|
|
107
|
+
`${CURRENT_DATA_DIR_NAME}.migration-${String(process.pid)}-${String(Date.now())}`,
|
|
108
|
+
);
|
|
109
|
+
|
|
101
110
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!
|
|
111
|
+
// cpSync may dereference junctions on some Windows runtimes. Reject the source tree before
|
|
112
|
+
// copying and recheck it afterwards so migration never imports through an indirection.
|
|
113
|
+
if (!isPathTreeFreeOfIndirectionSync(legacyDir)) return;
|
|
114
|
+
if (existsSync(currentDir)) {
|
|
115
|
+
// Never merge legacy state into an unknown or partially initialized destination. A caller
|
|
116
|
+
// can inspect it and retry after resolving the conflict; the authoritative legacy source
|
|
117
|
+
// remains untouched.
|
|
118
|
+
if (readdirSync(currentDir).length > 0) return;
|
|
119
|
+
rmSync(currentDir, { recursive: true, force: false });
|
|
120
|
+
}
|
|
121
|
+
if (!ensurePrivateDirectorySync(stagingDir)) return;
|
|
122
|
+
for (const entry of readdirSync(legacyDir)) {
|
|
123
|
+
cpSync(join(legacyDir, entry), join(stagingDir, entry), {
|
|
124
|
+
recursive: true,
|
|
125
|
+
force: false,
|
|
126
|
+
errorOnExist: true,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (!isPathTreeFreeOfIndirectionSync(legacyDir)) {
|
|
130
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!securePrivateTreeSync(stagingDir)) {
|
|
134
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
renameSync(stagingDir, currentDir);
|
|
105
138
|
rmSync(legacyDir, { recursive: true, force: true });
|
|
139
|
+
return;
|
|
106
140
|
} catch {
|
|
107
|
-
//
|
|
108
|
-
//
|
|
141
|
+
// A failed staged migration never deletes the legacy source. Remove only this attempt's
|
|
142
|
+
// private sibling and retry on a later startup.
|
|
143
|
+
if (existsSync(stagingDir)) rmSync(stagingDir, { recursive: true, force: true });
|
|
144
|
+
return;
|
|
109
145
|
}
|
|
110
146
|
}
|
|
111
147
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
2
|
+
import { spawn, type ChildProcess } from "node:child_process";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import type {
|
|
5
5
|
EcosystemExecutionPlan,
|
|
@@ -8,15 +8,31 @@ import type {
|
|
|
8
8
|
EcosystemTaskStatus,
|
|
9
9
|
} from "../lib/ecosystemContract";
|
|
10
10
|
import { findEcosystemPackage, findEcosystemRecipe } from "./ecosystemRegistry";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
npmCommand,
|
|
13
|
+
npmSpawnCommand,
|
|
14
|
+
signalProcessTree,
|
|
15
|
+
type CommandSpec,
|
|
16
|
+
} from "./platformCommands";
|
|
12
17
|
|
|
13
18
|
const MAX_TASKS = 50;
|
|
14
19
|
const OUTPUT_LIMIT = 40_000;
|
|
15
20
|
const INSTALL_TIMEOUT_MS = 120_000;
|
|
16
21
|
const HELP_TIMEOUT_MS = 30_000;
|
|
17
22
|
const RECIPE_TIMEOUT_MS = 90_000;
|
|
23
|
+
const SHUTDOWN_GRACE_MS = 2_000;
|
|
18
24
|
|
|
19
25
|
const tasks = new Map<string, EcosystemTask>();
|
|
26
|
+
type ActiveTask = {
|
|
27
|
+
child: ChildProcess;
|
|
28
|
+
closed: Promise<void>;
|
|
29
|
+
resolveClosed: () => void;
|
|
30
|
+
timeout: ReturnType<typeof setTimeout>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const activeTasks = new Map<string, ActiveTask>();
|
|
34
|
+
let acceptingTasks = true;
|
|
35
|
+
let shutdownForceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
20
36
|
|
|
21
37
|
function nowIso(): string {
|
|
22
38
|
return new Date().toISOString();
|
|
@@ -152,6 +168,77 @@ function completeTask(
|
|
|
152
168
|
task.finishedAt = nowIso();
|
|
153
169
|
}
|
|
154
170
|
|
|
171
|
+
function finishActiveTask(taskId: string): void {
|
|
172
|
+
const active = activeTasks.get(taskId);
|
|
173
|
+
if (active === undefined) return;
|
|
174
|
+
clearTimeout(active.timeout);
|
|
175
|
+
activeTasks.delete(taskId);
|
|
176
|
+
active.resolveClosed();
|
|
177
|
+
if (activeTasks.size === 0 && shutdownForceTimer !== null) {
|
|
178
|
+
clearTimeout(shutdownForceTimer);
|
|
179
|
+
shutdownForceTimer = null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function failTaskForShutdown(task: EcosystemTask): void {
|
|
184
|
+
if (task.status !== "running" && task.status !== "queued") return;
|
|
185
|
+
const error = "Runtime shutdown terminated the ecosystem command";
|
|
186
|
+
appendTaskOutput(task, `\n${error}.\n`);
|
|
187
|
+
completeTask(task, "failed", null, error);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function forceActiveTaskTrees(): void {
|
|
191
|
+
for (const active of activeTasks.values()) {
|
|
192
|
+
const pid = active.child.pid;
|
|
193
|
+
if (pid !== undefined) signalProcessTree(pid, "SIGKILL");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function launchTask(task: EcosystemTask, spawnCommand: CommandSpec, timeoutMs: number): void {
|
|
198
|
+
const child = spawn(spawnCommand.command, spawnCommand.args, {
|
|
199
|
+
detached: process.platform !== "win32",
|
|
200
|
+
windowsHide: true,
|
|
201
|
+
shell: false,
|
|
202
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
203
|
+
});
|
|
204
|
+
let resolveClosed = (): void => {};
|
|
205
|
+
const closed = new Promise<void>((resolve) => {
|
|
206
|
+
resolveClosed = resolve;
|
|
207
|
+
});
|
|
208
|
+
const timeout = setTimeout(() => {
|
|
209
|
+
const pid = child.pid;
|
|
210
|
+
if (pid !== undefined) signalProcessTree(pid, "SIGKILL");
|
|
211
|
+
appendTaskOutput(task, `\nTimed out after ${String(timeoutMs / 1000)}s.\n`);
|
|
212
|
+
}, timeoutMs);
|
|
213
|
+
activeTasks.set(task.id, { child, closed, resolveClosed, timeout });
|
|
214
|
+
|
|
215
|
+
task.status = "running";
|
|
216
|
+
task.startedAt = nowIso();
|
|
217
|
+
appendTaskOutput(task, `$ ${task.command}\n`);
|
|
218
|
+
|
|
219
|
+
child.stdout?.on("data", (chunk: Buffer) => {
|
|
220
|
+
appendTaskOutput(task, chunk.toString("utf8"));
|
|
221
|
+
});
|
|
222
|
+
child.stderr?.on("data", (chunk: Buffer) => {
|
|
223
|
+
appendTaskOutput(task, chunk.toString("utf8"));
|
|
224
|
+
});
|
|
225
|
+
child.on("error", (error) => {
|
|
226
|
+
appendTaskOutput(task, `\n${error.message}\n`);
|
|
227
|
+
if (task.status !== "failed") completeTask(task, "failed", null, error.message);
|
|
228
|
+
finishActiveTask(task.id);
|
|
229
|
+
});
|
|
230
|
+
child.on("close", (code) => {
|
|
231
|
+
if (task.status !== "failed") {
|
|
232
|
+
if (code === 0) {
|
|
233
|
+
completeTask(task, "succeeded", code, null);
|
|
234
|
+
} else {
|
|
235
|
+
completeTask(task, "failed", code, `Command exited with code ${String(code ?? "unknown")}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
finishActiveTask(task.id);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
155
242
|
export function getEcosystemTask(taskId: string): EcosystemTask | null {
|
|
156
243
|
return tasks.get(taskId) ?? null;
|
|
157
244
|
}
|
|
@@ -164,6 +251,7 @@ export function startEcosystemTask(
|
|
|
164
251
|
packageId: string,
|
|
165
252
|
action: EcosystemTaskAction,
|
|
166
253
|
): EcosystemTask | null {
|
|
254
|
+
if (!acceptingTasks) return null;
|
|
167
255
|
if (action === "recipe") return null;
|
|
168
256
|
const definition =
|
|
169
257
|
action === "runner-presets"
|
|
@@ -190,46 +278,13 @@ export function startEcosystemTask(
|
|
|
190
278
|
};
|
|
191
279
|
rememberTask(task);
|
|
192
280
|
|
|
193
|
-
|
|
194
|
-
const child = spawn(spawnCommand.command, spawnCommand.args, {
|
|
195
|
-
windowsHide: true,
|
|
196
|
-
shell: false,
|
|
197
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
198
|
-
});
|
|
199
|
-
const timeout = setTimeout(() => {
|
|
200
|
-
child.kill();
|
|
201
|
-
appendTaskOutput(task, `\nTimed out after ${String(packageActionTimeout(action) / 1000)}s.\n`);
|
|
202
|
-
}, packageActionTimeout(action));
|
|
203
|
-
|
|
204
|
-
task.status = "running";
|
|
205
|
-
task.startedAt = nowIso();
|
|
206
|
-
appendTaskOutput(task, `$ ${task.command}\n`);
|
|
207
|
-
|
|
208
|
-
child.stdout.on("data", (chunk: Buffer) => {
|
|
209
|
-
appendTaskOutput(task, chunk.toString("utf8"));
|
|
210
|
-
});
|
|
211
|
-
child.stderr.on("data", (chunk: Buffer) => {
|
|
212
|
-
appendTaskOutput(task, chunk.toString("utf8"));
|
|
213
|
-
});
|
|
214
|
-
child.on("error", (error) => {
|
|
215
|
-
clearTimeout(timeout);
|
|
216
|
-
appendTaskOutput(task, `\n${error.message}\n`);
|
|
217
|
-
completeTask(task, "failed", null, error.message);
|
|
218
|
-
});
|
|
219
|
-
child.on("close", (code) => {
|
|
220
|
-
clearTimeout(timeout);
|
|
221
|
-
if (task.status === "failed") return;
|
|
222
|
-
if (code === 0) {
|
|
223
|
-
completeTask(task, "succeeded", code, null);
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
completeTask(task, "failed", code, `Command exited with code ${String(code ?? "unknown")}`);
|
|
227
|
-
});
|
|
281
|
+
launchTask(task, npmSpawnCommand(args), packageActionTimeout(action));
|
|
228
282
|
|
|
229
283
|
return task;
|
|
230
284
|
}
|
|
231
285
|
|
|
232
286
|
export function startEcosystemRecipeTask(recipeId: string): EcosystemTask | null {
|
|
287
|
+
if (!acceptingTasks) return null;
|
|
233
288
|
const recipe = findEcosystemRecipe(recipeId);
|
|
234
289
|
if (recipe === null) return null;
|
|
235
290
|
if (!recipe.runnable) return null;
|
|
@@ -255,41 +310,77 @@ export function startEcosystemRecipeTask(recipeId: string): EcosystemTask | null
|
|
|
255
310
|
};
|
|
256
311
|
rememberTask(task);
|
|
257
312
|
|
|
258
|
-
|
|
259
|
-
const child = spawn(spawnCommand.command, spawnCommand.args, {
|
|
260
|
-
windowsHide: true,
|
|
261
|
-
shell: false,
|
|
262
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
263
|
-
});
|
|
264
|
-
const timeout = setTimeout(() => {
|
|
265
|
-
child.kill();
|
|
266
|
-
appendTaskOutput(task, `\nTimed out after ${String(RECIPE_TIMEOUT_MS / 1000)}s.\n`);
|
|
267
|
-
}, RECIPE_TIMEOUT_MS);
|
|
313
|
+
launchTask(task, npmSpawnCommand(args), RECIPE_TIMEOUT_MS);
|
|
268
314
|
|
|
269
|
-
task
|
|
270
|
-
|
|
271
|
-
appendTaskOutput(task, `$ ${task.command}\n`);
|
|
315
|
+
return task;
|
|
316
|
+
}
|
|
272
317
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
318
|
+
/** Stop admitting commands and begin terminating every tracked child process tree. */
|
|
319
|
+
export function beginEcosystemTaskShutdown(): void {
|
|
320
|
+
acceptingTasks = false;
|
|
321
|
+
for (const [taskId, active] of activeTasks) {
|
|
322
|
+
const task = tasks.get(taskId);
|
|
323
|
+
if (task !== undefined) failTaskForShutdown(task);
|
|
324
|
+
clearTimeout(active.timeout);
|
|
325
|
+
const pid = active.child.pid;
|
|
326
|
+
if (pid !== undefined) signalProcessTree(pid, "SIGTERM");
|
|
327
|
+
}
|
|
328
|
+
if (activeTasks.size > 0 && shutdownForceTimer === null) {
|
|
329
|
+
shutdownForceTimer = setTimeout(() => {
|
|
330
|
+
shutdownForceTimer = null;
|
|
331
|
+
forceActiveTaskTrees();
|
|
332
|
+
}, SHUTDOWN_GRACE_MS);
|
|
333
|
+
shutdownForceTimer.unref();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Wait until children signalled by beginEcosystemTaskShutdown have closed. */
|
|
338
|
+
export async function waitForEcosystemTasksToClose(): Promise<void> {
|
|
339
|
+
await Promise.all([...activeTasks.values()].map(async (active) => await active.closed));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** Immediate deadline fallback used by the runtime shutdown coordinator. */
|
|
343
|
+
export function forceCloseEcosystemTasks(): void {
|
|
344
|
+
acceptingTasks = false;
|
|
345
|
+
if (shutdownForceTimer !== null) {
|
|
346
|
+
clearTimeout(shutdownForceTimer);
|
|
347
|
+
shutdownForceTimer = null;
|
|
348
|
+
}
|
|
349
|
+
for (const taskId of activeTasks.keys()) {
|
|
350
|
+
const task = tasks.get(taskId);
|
|
351
|
+
if (task !== undefined) failTaskForShutdown(task);
|
|
352
|
+
}
|
|
353
|
+
forceActiveTaskTrees();
|
|
354
|
+
}
|
|
293
355
|
|
|
356
|
+
export function _startEcosystemTaskForTests(
|
|
357
|
+
spawnCommand: CommandSpec,
|
|
358
|
+
timeoutMs = RECIPE_TIMEOUT_MS,
|
|
359
|
+
): EcosystemTask | null {
|
|
360
|
+
if (!acceptingTasks) return null;
|
|
361
|
+
const task: EcosystemTask = {
|
|
362
|
+
id: randomUUID(),
|
|
363
|
+
packageId: "test-package",
|
|
364
|
+
npmName: "test-package",
|
|
365
|
+
recipeId: null,
|
|
366
|
+
action: "help",
|
|
367
|
+
status: "queued",
|
|
368
|
+
command: `${spawnCommand.command} ${spawnCommand.args.join(" ")}`,
|
|
369
|
+
output: "",
|
|
370
|
+
createdAt: nowIso(),
|
|
371
|
+
startedAt: null,
|
|
372
|
+
finishedAt: null,
|
|
373
|
+
exitCode: null,
|
|
374
|
+
error: null,
|
|
375
|
+
};
|
|
376
|
+
rememberTask(task);
|
|
377
|
+
launchTask(task, spawnCommand, timeoutMs);
|
|
294
378
|
return task;
|
|
295
379
|
}
|
|
380
|
+
|
|
381
|
+
export function _resetEcosystemTasksForTests(): void {
|
|
382
|
+
forceCloseEcosystemTasks();
|
|
383
|
+
tasks.clear();
|
|
384
|
+
activeTasks.clear();
|
|
385
|
+
acceptingTasks = true;
|
|
386
|
+
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { FormatHandler } from "./handler";
|
|
2
2
|
import type { ApiFormat } from "../schemas";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
PATH_V1_RESPONSES,
|
|
7
|
-
PATH_RESPONSES,
|
|
8
|
-
PATH_V1_MESSAGES,
|
|
9
|
-
} from "../constants";
|
|
3
|
+
import { API_FORMAT_PATH_ENTRIES, apiFormatForPath } from "../../lib/apiFormat";
|
|
4
|
+
|
|
5
|
+
export { apiFormatForPath };
|
|
10
6
|
|
|
11
7
|
/**
|
|
12
8
|
* API format registry maps request paths and API formats to their FormatHandler.
|
|
@@ -63,18 +59,7 @@ export function formatForPath(path: string): FormatHandler | null {
|
|
|
63
59
|
return formatRegistry.getByPath(path) ?? null;
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
/**
|
|
67
|
-
* Resolve the API format from the request endpoint. The endpoint is
|
|
68
|
-
* authoritative because Anthropic and OpenAI request bodies overlap for
|
|
69
|
-
* simple message-only calls.
|
|
70
|
-
*/
|
|
71
|
-
export function apiFormatForPath(path: string): ApiFormat {
|
|
72
|
-
return formatRegistry.getApiFormatByPath(path) ?? "unknown";
|
|
73
|
-
}
|
|
74
|
-
|
|
75
62
|
// Register known paths
|
|
76
|
-
|
|
77
|
-
formatRegistry.registerPath(
|
|
78
|
-
|
|
79
|
-
formatRegistry.registerPath(PATH_V1_RESPONSES, "openai");
|
|
80
|
-
formatRegistry.registerPath(PATH_RESPONSES, "openai");
|
|
63
|
+
for (const [path, format] of API_FORMAT_PATH_ENTRIES) {
|
|
64
|
+
formatRegistry.registerPath(path, format);
|
|
65
|
+
}
|