@tonyclaw/agent-inspector 3.0.45 → 3.0.47
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 +8018 -5451
- package/.output/server/_libs/extend.mjs +4 -8
- package/.output/server/_libs/jszip.mjs +9 -35
- 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/_ssr/index.mjs +4 -4
- package/.output/server/_ssr/{publicBasePathContext-5264L3rX.mjs → publicBasePathContext-IH2ilOfu.mjs} +52 -24
- package/.output/server/_ssr/{router-BJ_ltLim.mjs → router-BwZEsYfS.mjs} +19794 -19444
- package/.output/server/_ssr/{start-C6MjPjxp.mjs → start-COQu_AgD.mjs} +1 -1
- package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
- package/.output/server/index.mjs +5 -145
- package/.output/{public/assets/CompareDrawer-B3_TLTJh.js → ui/assets/CompareDrawer-V-8lPASC.js} +1 -1
- package/.output/{public/assets/InspectorPet-Cpn6hv4P.js → ui/assets/InspectorPet-D4CVnfdf.js} +1 -1
- package/.output/ui/assets/ProxyViewerContainer-CO3ZVHLX.js +59 -0
- package/.output/{public/assets/ReplayDialog-B3EKVdJk.js → ui/assets/ReplayDialog-CpGyTLtt.js} +1 -1
- package/.output/{public/assets/RequestAnatomy-COOQjyUC.js → ui/assets/RequestAnatomy-BLuJL9dZ.js} +1 -1
- package/.output/ui/assets/ResponseView-BuSC-CH7.js +2 -0
- package/.output/ui/assets/StreamingChunkSequence-DeA-JJKa.js +1 -0
- package/.output/{public/assets/_sessionId-zbgYl7ZJ.js → ui/assets/_sessionId-8HuHFhjo.js} +1 -1
- package/.output/{public/assets/_sessionId-BJlM3nmt.js → ui/assets/_sessionId-Chp67th6.js} +1 -1
- package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
- package/.output/ui/assets/index-BvXp42al.css +1 -0
- package/.output/{public/assets/index-xF_NY8Yb.js → ui/assets/index-DPmKK_5d.js} +5 -5
- package/.output/{public/assets/index-BIK4bPTv.js → ui/assets/index-atoQrlb8.js} +1 -1
- package/.output/ui/assets/index-nY3E1vxV.js +73 -0
- package/.output/{public/assets/index-D2Qw6Ri2.js → ui/assets/index-nl9-dpZn.js} +1 -1
- package/.output/ui/assets/json-viewer-B9kIzqeX.js +1 -0
- package/.output/{public/assets/jszip.min-B_rfAUCe.js → ui/assets/jszip.min-B7tfyE-I.js} +1 -1
- package/.output/ui/index.html +229 -0
- package/.output/ui/runtime-config.js +2 -0
- package/.output/workers/logFinalizer.worker.js +979 -414
- package/.output/workers/sessionWorkerEntry.js +979 -414
- package/README.md +182 -43
- package/docs/instance-control.openapi.yaml +59 -4
- package/package.json +40 -6
- 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 +7 -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/{routes → backend/routes}/api/instances.$name.connection.ts +1 -1
- package/src/{routes → backend/routes}/api/instances.$name.restart.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.start.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.stop.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.ts +1 -1
- package/src/{routes → backend/routes}/api/instances.ts +1 -1
- 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/{start.ts → backend/start.ts} +1 -1
- package/src/cli/alias.ts +2 -11
- package/src/cli/doctor.ts +32 -9
- package/src/cli/instance.ts +36 -13
- package/src/cli/instanceApi.ts +213 -0
- package/src/cli/instanceArgs.ts +46 -11
- package/src/cli/instanceControl.ts +10 -2
- package/src/cli/instanceModel.ts +18 -17
- package/src/cli/instanceRegistry.ts +0 -9
- package/src/cli/networkHints.ts +27 -14
- package/src/cli/onboard.ts +69 -2
- package/src/cli/onboardTarget.ts +89 -40
- package/src/cli/rustBackendPackage.ts +450 -0
- package/src/cli/templates/codex-skill-onboard.ts +44 -14
- package/src/cli/templates/skill-onboard.ts +64 -28
- package/src/cli.ts +341 -75
- package/src/components/ProxyViewer.tsx +11 -9
- 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 +159 -144
- 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/backendImplementation.ts +16 -0
- package/src/lib/basePath.ts +29 -11
- 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 +38 -0
- package/src/lib/instanceContract.ts +30 -11
- package/src/lib/managedInstance.ts +9 -1
- package/src/lib/piAgentContract.ts +3 -2
- package/src/lib/publicBasePathContext.ts +40 -10
- 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 +2 -0
- package/src/mcp/server.ts +19 -24
- 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 +567 -39
- 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 +11 -1
- package/src/proxy/schemas.ts +7 -1
- package/src/proxy/sessionArchive.ts +70 -14
- package/src/proxy/sqliteLogIndex.ts +65 -42
- 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-BEAhuGOJ.js +0 -126
- package/.output/public/assets/ResponseView-DBCjkwye.js +0 -2
- package/.output/public/assets/StreamingChunkSequence-CuXhDgMo.js +0 -1
- package/.output/public/assets/index-BZo_8koU.js +0 -70
- package/.output/public/assets/index-ZWschkCh.css +0 -1
- package/.output/public/assets/json-viewer-B-Ao6pwW.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-CJ99gZFV.mjs +0 -84
- package/.output/server/_sessionId-DEjScBpK.mjs +0 -146
- package/.output/server/_ssr/CompareDrawer-DtOIMeQB.mjs +0 -1060
- package/.output/server/_ssr/InspectorPet-CXc4oCBQ.mjs +0 -938
- package/.output/server/_ssr/ProxyViewerContainer-DVPlwfkt.mjs +0 -17632
- package/.output/server/_ssr/ReplayDialog-BQEA95qC.mjs +0 -725
- package/.output/server/_ssr/RequestAnatomy-BMyd8B7Q.mjs +0 -837
- package/.output/server/_ssr/ResponseView-qrTaEIM8.mjs +0 -757
- package/.output/server/_ssr/StreamingChunkSequence-BFTL8mIy.mjs +0 -274
- package/.output/server/_ssr/index-Bcj1Hcy4.mjs +0 -135
- package/.output/server/_ssr/index-DW-M7XUG.mjs +0 -84
- package/.output/server/_ssr/json-viewer-DiI0Yjsn.mjs +0 -483
- package/.output/server/_tanstack-start-manifest_v-C6pXXX9R.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/src/routes/api/-instances.ts +0 -109
- /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
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
closeSync,
|
|
4
|
+
constants,
|
|
5
|
+
fchmodSync,
|
|
6
|
+
fstatSync,
|
|
7
|
+
lstatSync,
|
|
8
|
+
mkdirSync,
|
|
9
|
+
openSync,
|
|
10
|
+
readdirSync,
|
|
11
|
+
realpathSync,
|
|
12
|
+
} from "node:fs";
|
|
13
|
+
import { join, parse, resolve, sep } from "node:path";
|
|
4
14
|
|
|
5
15
|
export const PRIVATE_DIRECTORY_MODE = 0o700;
|
|
6
16
|
export const PRIVATE_FILE_MODE = 0o600;
|
|
@@ -17,15 +27,35 @@ export type WindowsCommandRunner = (
|
|
|
17
27
|
args: readonly string[],
|
|
18
28
|
) => WindowsCommandResult;
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
type PathEntry = {
|
|
31
|
+
path: string;
|
|
32
|
+
kind: PrivateDataPathKind;
|
|
33
|
+
identity: string;
|
|
34
|
+
mode: number;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type PathChainSnapshot = {
|
|
38
|
+
absolutePath: string;
|
|
39
|
+
complete: boolean;
|
|
40
|
+
entries: readonly PathEntry[];
|
|
41
|
+
missingParts: readonly string[];
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type TreeEntry = {
|
|
45
|
+
path: string;
|
|
46
|
+
kind: PrivateDataPathKind;
|
|
47
|
+
fingerprint: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type PathEntryRead =
|
|
51
|
+
| { status: "ok"; entry: PathEntry }
|
|
52
|
+
| { status: "missing" }
|
|
53
|
+
| { status: "unsafe" };
|
|
54
|
+
|
|
55
|
+
const securedPathFingerprints = new Map<string, string>();
|
|
22
56
|
let cachedWindowsSid: string | null = null;
|
|
23
57
|
|
|
24
|
-
// Always invoke the system copies of
|
|
25
|
-
// of PATH ordering. Git Bash and similar shells ship stub binaries (e.g.
|
|
26
|
-
// `/usr/bin/whoami.exe`) that take precedence on the inherited PATH and do
|
|
27
|
-
// not understand Windows ACL arguments, which makes `ensurePrivate*` fail
|
|
28
|
-
// in environments where `C:\Windows\System32` is not first.
|
|
58
|
+
// Always invoke the system copies of Windows security utilities regardless of PATH ordering.
|
|
29
59
|
function windowsSystemPath(executable: string): string {
|
|
30
60
|
const systemRoot = process.env["SystemRoot"] ?? "C:\\Windows";
|
|
31
61
|
return `${systemRoot}\\System32\\${executable}`;
|
|
@@ -62,19 +92,12 @@ function windowsBroadGroupRemovalArgs(): readonly string[] {
|
|
|
62
92
|
return ["/remove:g", "*S-1-1-0", "*S-1-5-11", "*S-1-5-32-545"];
|
|
63
93
|
}
|
|
64
94
|
|
|
65
|
-
|
|
66
|
-
* Remove inherited Windows permissions and grant full control only to the
|
|
67
|
-
* account that owns the current process. Commands are executed directly,
|
|
68
|
-
* never through a shell, and no path content is interpreted as command text.
|
|
69
|
-
*/
|
|
70
|
-
export function applyWindowsUserOnlyAcl(
|
|
95
|
+
function applyWindowsAclWithSid(
|
|
71
96
|
path: string,
|
|
72
97
|
kind: PrivateDataPathKind,
|
|
73
|
-
|
|
98
|
+
sid: string,
|
|
99
|
+
run: WindowsCommandRunner,
|
|
74
100
|
): boolean {
|
|
75
|
-
const sid = resolveWindowsUserSid(run);
|
|
76
|
-
if (sid === null) return false;
|
|
77
|
-
|
|
78
101
|
const access = kind === "directory" ? `(OI)(CI)F` : "F";
|
|
79
102
|
const result = run("icacls.exe", [
|
|
80
103
|
path,
|
|
@@ -87,111 +110,310 @@ export function applyWindowsUserOnlyAcl(
|
|
|
87
110
|
return result.status === 0;
|
|
88
111
|
}
|
|
89
112
|
|
|
90
|
-
/**
|
|
91
|
-
export function
|
|
92
|
-
|
|
113
|
+
/** Remove inherited Windows permissions and grant access only to the current process user. */
|
|
114
|
+
export function applyWindowsUserOnlyAcl(
|
|
115
|
+
path: string,
|
|
116
|
+
kind: PrivateDataPathKind,
|
|
93
117
|
run: WindowsCommandRunner = runWindowsCommand,
|
|
94
118
|
): boolean {
|
|
95
119
|
const sid = resolveWindowsUserSid(run);
|
|
96
|
-
|
|
97
|
-
const result = run("icacls.exe", [
|
|
98
|
-
root,
|
|
99
|
-
"/inheritance:r",
|
|
100
|
-
"/grant:r",
|
|
101
|
-
`*${sid}:(OI)(CI)F`,
|
|
102
|
-
`*${sid}:F`,
|
|
103
|
-
...windowsBroadGroupRemovalArgs(),
|
|
104
|
-
"/T",
|
|
105
|
-
"/C",
|
|
106
|
-
"/Q",
|
|
107
|
-
]);
|
|
108
|
-
return result.status === 0;
|
|
120
|
+
return sid !== null && applyWindowsAclWithSid(path, kind, sid, run);
|
|
109
121
|
}
|
|
110
122
|
|
|
111
|
-
function
|
|
123
|
+
function comparablePath(path: string): string {
|
|
124
|
+
let normalized = path;
|
|
112
125
|
if (process.platform === "win32") {
|
|
113
|
-
|
|
126
|
+
if (normalized.startsWith("\\\\?\\UNC\\")) {
|
|
127
|
+
normalized = `\\\\${normalized.slice(8)}`;
|
|
128
|
+
} else if (normalized.startsWith("\\\\?\\")) {
|
|
129
|
+
normalized = normalized.slice(4);
|
|
130
|
+
}
|
|
114
131
|
}
|
|
132
|
+
const absolute = resolve(normalized);
|
|
133
|
+
return process.platform === "win32" ? absolute.toLowerCase() : absolute;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
type PathStats = NonNullable<ReturnType<typeof lstatSync>>;
|
|
115
137
|
|
|
138
|
+
function pathIdentity(stats: PathStats): string {
|
|
139
|
+
return `${String(stats.dev)}:${String(stats.ino)}:${String(stats.birthtimeMs)}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function readPathEntry(path: string): PathEntryRead {
|
|
143
|
+
let stats: PathStats;
|
|
116
144
|
try {
|
|
117
|
-
|
|
118
|
-
return
|
|
145
|
+
const observed = lstatSync(path);
|
|
146
|
+
if (observed === undefined) return { status: "missing" };
|
|
147
|
+
stats = observed;
|
|
119
148
|
} catch {
|
|
120
|
-
return
|
|
149
|
+
return { status: "missing" };
|
|
121
150
|
}
|
|
122
|
-
}
|
|
123
151
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
152
|
+
// On Windows, junctions and the supported reparse indirections are surfaced as symbolic links.
|
|
153
|
+
// The realpath equality check also rejects path aliases whose target differs from the lexical path.
|
|
154
|
+
if (stats.isSymbolicLink()) return { status: "unsafe" };
|
|
155
|
+
const kind: PrivateDataPathKind | null = stats.isDirectory()
|
|
156
|
+
? "directory"
|
|
157
|
+
: stats.isFile()
|
|
158
|
+
? "file"
|
|
159
|
+
: null;
|
|
160
|
+
if (kind === null) return { status: "unsafe" };
|
|
131
161
|
|
|
132
|
-
|
|
162
|
+
let canonical: string;
|
|
133
163
|
try {
|
|
134
|
-
|
|
164
|
+
canonical = realpathSync.native(path);
|
|
135
165
|
} catch {
|
|
136
|
-
return
|
|
166
|
+
return { status: "unsafe" };
|
|
137
167
|
}
|
|
138
|
-
|
|
168
|
+
if (comparablePath(canonical) !== comparablePath(path)) return { status: "unsafe" };
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
status: "ok",
|
|
172
|
+
entry: {
|
|
173
|
+
path,
|
|
174
|
+
kind,
|
|
175
|
+
identity: pathIdentity(stats),
|
|
176
|
+
mode: stats.mode & 0o777,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
139
179
|
}
|
|
140
180
|
|
|
141
|
-
|
|
142
|
-
|
|
181
|
+
function snapshotPathChain(path: string): PathChainSnapshot | null {
|
|
182
|
+
const absolutePath = resolve(path);
|
|
183
|
+
const root = parse(absolutePath).root;
|
|
184
|
+
const suffix = absolutePath.slice(root.length);
|
|
185
|
+
const parts = suffix === "" ? [] : suffix.split(sep).filter((part) => part !== "");
|
|
186
|
+
const entries: PathEntry[] = [];
|
|
187
|
+
let current = root;
|
|
188
|
+
|
|
189
|
+
const rootRead = readPathEntry(root);
|
|
190
|
+
if (rootRead.status !== "ok" || rootRead.entry.kind !== "directory") return null;
|
|
191
|
+
entries.push(rootRead.entry);
|
|
192
|
+
|
|
193
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
194
|
+
const part = parts[index];
|
|
195
|
+
if (part === undefined) return null;
|
|
196
|
+
current = join(current, part);
|
|
197
|
+
const read = readPathEntry(current);
|
|
198
|
+
if (read.status === "unsafe") return null;
|
|
199
|
+
if (read.status === "missing") {
|
|
200
|
+
return {
|
|
201
|
+
absolutePath,
|
|
202
|
+
complete: false,
|
|
203
|
+
entries,
|
|
204
|
+
missingParts: parts.slice(index),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (index < parts.length - 1 && read.entry.kind !== "directory") return null;
|
|
208
|
+
entries.push(read.entry);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return { absolutePath, complete: true, entries, missingParts: [] };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function chainFingerprint(snapshot: PathChainSnapshot): string {
|
|
215
|
+
return snapshot.entries.map((entry) => `${entry.path}:${entry.identity}`).join("|");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function snapshotsRetainPrefix(before: PathChainSnapshot, after: PathChainSnapshot): boolean {
|
|
219
|
+
if (after.entries.length < before.entries.length) return false;
|
|
220
|
+
return before.entries.every((entry, index) => {
|
|
221
|
+
const next = after.entries[index];
|
|
222
|
+
return next !== undefined && next.path === entry.path && next.identity === entry.identity;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function completeSnapshotForKind(
|
|
227
|
+
path: string,
|
|
228
|
+
kind: PrivateDataPathKind,
|
|
229
|
+
): PathChainSnapshot | null {
|
|
230
|
+
const snapshot = snapshotPathChain(path);
|
|
231
|
+
if (snapshot === null || !snapshot.complete) return null;
|
|
232
|
+
const leaf = snapshot.entries.at(-1);
|
|
233
|
+
return leaf !== undefined && leaf.kind === kind ? snapshot : null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function applyPosixPermissions(
|
|
237
|
+
path: string,
|
|
238
|
+
kind: PrivateDataPathKind,
|
|
239
|
+
expectedIdentity: string,
|
|
240
|
+
): boolean {
|
|
241
|
+
let descriptor: number | null = null;
|
|
143
242
|
try {
|
|
144
|
-
const
|
|
145
|
-
|
|
243
|
+
const directoryFlag = kind === "directory" ? constants.O_DIRECTORY : 0;
|
|
244
|
+
descriptor = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | directoryFlag);
|
|
245
|
+
const before = fstatSync(descriptor);
|
|
246
|
+
if (pathIdentity(before) !== expectedIdentity) return false;
|
|
247
|
+
fchmodSync(descriptor, kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
|
|
248
|
+
const after = fstatSync(descriptor);
|
|
249
|
+
return (
|
|
250
|
+
pathIdentity(after) === expectedIdentity &&
|
|
251
|
+
(after.mode & 0o777) === (kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE)
|
|
252
|
+
);
|
|
146
253
|
} catch {
|
|
147
254
|
return false;
|
|
255
|
+
} finally {
|
|
256
|
+
if (descriptor !== null) {
|
|
257
|
+
try {
|
|
258
|
+
closeSync(descriptor);
|
|
259
|
+
} catch {
|
|
260
|
+
// The permission result already fails closed; descriptor cleanup is best effort here.
|
|
261
|
+
}
|
|
262
|
+
}
|
|
148
263
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function permissionsArePrivate(entry: PathEntry): boolean {
|
|
267
|
+
if (process.platform === "win32") return true;
|
|
268
|
+
return entry.mode === (entry.kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function secureExistingPath(
|
|
272
|
+
path: string,
|
|
273
|
+
kind: PrivateDataPathKind,
|
|
274
|
+
forcePermissions = false,
|
|
275
|
+
): boolean {
|
|
276
|
+
const before = completeSnapshotForKind(path, kind);
|
|
277
|
+
if (before === null) return false;
|
|
278
|
+
const leaf = before.entries.at(-1);
|
|
279
|
+
if (leaf === undefined) return false;
|
|
280
|
+
const cacheKey = `${kind}:${before.absolutePath}`;
|
|
281
|
+
const beforeFingerprint = chainFingerprint(before);
|
|
282
|
+
if (
|
|
283
|
+
!forcePermissions &&
|
|
284
|
+
securedPathFingerprints.get(cacheKey) === beforeFingerprint &&
|
|
285
|
+
permissionsArePrivate(leaf)
|
|
286
|
+
) {
|
|
287
|
+
const cachedCheck = completeSnapshotForKind(path, kind);
|
|
288
|
+
return cachedCheck !== null && chainFingerprint(cachedCheck) === beforeFingerprint;
|
|
153
289
|
}
|
|
154
|
-
|
|
155
|
-
|
|
290
|
+
|
|
291
|
+
const applied =
|
|
292
|
+
process.platform === "win32"
|
|
293
|
+
? applyWindowsUserOnlyAcl(path, kind)
|
|
294
|
+
: applyPosixPermissions(path, kind, leaf.identity);
|
|
295
|
+
if (!applied) return false;
|
|
296
|
+
|
|
297
|
+
const after = completeSnapshotForKind(path, kind);
|
|
298
|
+
if (after === null || !snapshotsRetainPrefix(before, after)) return false;
|
|
299
|
+
const afterLeaf = after.entries.at(-1);
|
|
300
|
+
if (afterLeaf === undefined || afterLeaf.identity !== leaf.identity) return false;
|
|
301
|
+
if (!permissionsArePrivate(afterLeaf)) return false;
|
|
302
|
+
securedPathFingerprints.set(cacheKey, chainFingerprint(after));
|
|
156
303
|
return true;
|
|
157
304
|
}
|
|
158
305
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (
|
|
306
|
+
export function ensurePrivateDirectorySync(path: string): boolean {
|
|
307
|
+
const before = snapshotPathChain(path);
|
|
308
|
+
if (before === null) return false;
|
|
162
309
|
|
|
163
|
-
let
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
310
|
+
let current = before.entries.at(-1)?.path;
|
|
311
|
+
if (current === undefined) return false;
|
|
312
|
+
for (const part of before.missingParts) {
|
|
313
|
+
const next = join(current, part);
|
|
314
|
+
try {
|
|
315
|
+
mkdirSync(next, { mode: PRIVATE_DIRECTORY_MODE });
|
|
316
|
+
} catch {
|
|
317
|
+
const raced = readPathEntry(next);
|
|
318
|
+
if (raced.status !== "ok" || raced.entry.kind !== "directory") return false;
|
|
319
|
+
}
|
|
320
|
+
if (!secureExistingPath(next, "directory", true)) return false;
|
|
321
|
+
current = next;
|
|
168
322
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
323
|
+
|
|
324
|
+
const complete = completeSnapshotForKind(path, "directory");
|
|
325
|
+
if (complete === null || !snapshotsRetainPrefix(before, complete)) return false;
|
|
326
|
+
return secureExistingPath(path, "directory");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export function securePrivateFileSync(path: string, forceAcl = false): boolean {
|
|
330
|
+
return secureExistingPath(path, "file", forceAcl);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function collectSafeTree(root: string): TreeEntry[] | null {
|
|
334
|
+
const collected: TreeEntry[] = [];
|
|
335
|
+
|
|
336
|
+
const visit = (path: string): boolean => {
|
|
337
|
+
const snapshot = snapshotPathChain(path);
|
|
338
|
+
if (snapshot === null || !snapshot.complete) return false;
|
|
339
|
+
const leaf = snapshot.entries.at(-1);
|
|
340
|
+
if (leaf === undefined) return false;
|
|
341
|
+
const fingerprint = chainFingerprint(snapshot);
|
|
342
|
+
collected.push({ path: snapshot.absolutePath, kind: leaf.kind, fingerprint });
|
|
343
|
+
if (leaf.kind === "file") return true;
|
|
344
|
+
|
|
345
|
+
let entries: string[];
|
|
346
|
+
try {
|
|
347
|
+
entries = readdirSync(path);
|
|
348
|
+
} catch {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
const afterRead = completeSnapshotForKind(path, "directory");
|
|
352
|
+
if (afterRead === null || chainFingerprint(afterRead) !== fingerprint) return false;
|
|
353
|
+
for (const entry of entries) {
|
|
354
|
+
if (!visit(join(path, entry))) return false;
|
|
355
|
+
}
|
|
174
356
|
return true;
|
|
175
|
-
}
|
|
176
|
-
if (!ensurePrivateDirectorySync(root)) return false;
|
|
357
|
+
};
|
|
177
358
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
359
|
+
return visit(root) ? collected : null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function treeFingerprintsMatch(
|
|
363
|
+
expected: readonly TreeEntry[],
|
|
364
|
+
observed: readonly TreeEntry[] | null,
|
|
365
|
+
): boolean {
|
|
366
|
+
if (observed === null || observed.length !== expected.length) return false;
|
|
367
|
+
return expected.every((entry, index) => {
|
|
368
|
+
const next = observed[index];
|
|
369
|
+
return (
|
|
370
|
+
next !== undefined &&
|
|
371
|
+
next.path === entry.path &&
|
|
372
|
+
next.kind === entry.kind &&
|
|
373
|
+
next.fingerprint === entry.fingerprint
|
|
374
|
+
);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Read-only preflight used before copy/import operations that must not follow indirection. */
|
|
379
|
+
export function isPathTreeFreeOfIndirectionSync(root: string): boolean {
|
|
380
|
+
return collectSafeTree(root) !== null;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Apply ACLs item by item after a no-follow scan; never use icacls /T across a reparse point. */
|
|
384
|
+
export function applyWindowsUserOnlyTreeAcl(
|
|
385
|
+
root: string,
|
|
386
|
+
run: WindowsCommandRunner = runWindowsCommand,
|
|
387
|
+
): boolean {
|
|
388
|
+
const entries = collectSafeTree(root);
|
|
389
|
+
if (entries === null) return false;
|
|
390
|
+
const sid = resolveWindowsUserSid(run);
|
|
391
|
+
if (sid === null) return false;
|
|
392
|
+
|
|
393
|
+
for (const entry of entries) {
|
|
394
|
+
const before = completeSnapshotForKind(entry.path, entry.kind);
|
|
395
|
+
if (before === null || chainFingerprint(before) !== entry.fingerprint) return false;
|
|
396
|
+
if (!applyWindowsAclWithSid(entry.path, entry.kind, sid, run)) return false;
|
|
397
|
+
const after = completeSnapshotForKind(entry.path, entry.kind);
|
|
398
|
+
if (after === null || chainFingerprint(after) !== entry.fingerprint) return false;
|
|
399
|
+
securedPathFingerprints.set(`${entry.kind}:${entry.path}`, entry.fingerprint);
|
|
183
400
|
}
|
|
401
|
+
return treeFingerprintsMatch(entries, collectSafeTree(root));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/** Secure an existing tree while refusing every symlink, junction, or reparse indirection. */
|
|
405
|
+
export function securePrivateTreeSync(root: string): boolean {
|
|
406
|
+
const entries = collectSafeTree(root);
|
|
407
|
+
if (entries === null) return false;
|
|
408
|
+
if (process.platform === "win32") return applyWindowsUserOnlyTreeAcl(root);
|
|
184
409
|
|
|
185
|
-
let secured = true;
|
|
186
410
|
for (const entry of entries) {
|
|
187
|
-
|
|
188
|
-
if (!securePrivateTreeSync(childPath)) secured = false;
|
|
411
|
+
if (!secureExistingPath(entry.path, entry.kind, true)) return false;
|
|
189
412
|
}
|
|
190
|
-
return
|
|
413
|
+
return treeFingerprintsMatch(entries, collectSafeTree(root));
|
|
191
414
|
}
|
|
192
415
|
|
|
193
416
|
export function _resetPrivateDataPathCacheForTests(): void {
|
|
194
|
-
|
|
195
|
-
securedFileIdentities.clear();
|
|
417
|
+
securedPathFingerprints.clear();
|
|
196
418
|
cachedWindowsSid = null;
|
|
197
419
|
}
|