@agimon-ai/po-core 0.0.0-alpha.2 → 0.0.0-alpha.21
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/LICENSE +149 -21
- package/NOTICE +41 -0
- package/dist/agentModel.cjs +1 -1
- package/dist/agentModel.d.mts +2 -2
- package/dist/agentModel.mjs +1 -2
- package/dist/apiContracts.cjs +623 -802
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts +277 -615
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/apiContracts.mjs +617 -794
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/askUser.cjs +2 -2
- package/dist/askUser.d.mts +2 -2
- package/dist/askUser.mjs +1 -2
- package/dist/authorTools.mjs +1 -2
- package/dist/backgroundWork.cjs +3 -3
- package/dist/backgroundWork.d.mts +2 -2
- package/dist/backgroundWork.mjs +1 -2
- package/dist/bundleAssetPolicy.mjs +1 -2
- package/dist/chatgptAuth.cjs +3 -2
- package/dist/chatgptAuth.d.mts +3 -2
- package/dist/chatgptAuth.mjs +2 -1
- package/dist/childProcess.cjs +1 -1
- package/dist/childProcess.d.mts +2 -2
- package/dist/childProcess.mjs +1 -2
- package/dist/childSession.cjs +11 -6
- package/dist/childSession.d.mts +3 -3
- package/dist/childSession.mjs +3 -3
- package/dist/cockpitContainer.mjs +1 -2
- package/dist/config.cjs +1 -1
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -2
- package/dist/contextApi.cjs +1 -0
- package/dist/contextApi.d.mts +2 -2
- package/dist/contextApi.mjs +2 -2
- package/dist/contextContributions.cjs +4 -4
- package/dist/contextContributions.d.mts +3 -3
- package/dist/contextContributions.mjs +3 -3
- package/dist/contextDetailStore.cjs +7 -5
- package/dist/contextDetailStore.cjs.map +1 -1
- package/dist/contextDetailStore.d.mts +2 -1
- package/dist/contextDetailStore.d.mts.map +1 -1
- package/dist/contextDetailStore.mjs +6 -4
- package/dist/contextDetailStore.mjs.map +1 -1
- package/dist/contextProjection.cjs +7 -2
- package/dist/contextProjection.cjs.map +1 -1
- package/dist/contextProjection.d.mts +4 -1
- package/dist/contextProjection.d.mts.map +1 -1
- package/dist/contextProjection.mjs +5 -2
- package/dist/contextProjection.mjs.map +1 -1
- package/dist/cordisHost.cjs +11 -11
- package/dist/cordisHost.d.mts +2 -2
- package/dist/cordisHost.mjs +1 -2
- package/dist/delegation.cjs +8 -8
- package/dist/delegation.d.mts +2 -2
- package/dist/delegation.mjs +1 -2
- package/dist/executionBudget.cjs +4 -3
- package/dist/executionBudget.cjs.map +1 -1
- package/dist/executionBudget.d.mts +2 -2
- package/dist/executionBudget.d.mts.map +1 -1
- package/dist/executionBudget.mjs +4 -3
- package/dist/executionBudget.mjs.map +1 -1
- package/dist/extensionFile.cjs +5 -0
- package/dist/extensionFile.d.mts +4 -2
- package/dist/extensionFile.mjs +4 -2
- package/dist/footer.d.mts +2 -2
- package/dist/footer.mjs +1 -2
- package/dist/headless.cjs +14 -14
- package/dist/headless.d.mts +2 -2
- package/dist/headless.mjs +1 -2
- package/dist/headlessHub.cjs +308 -109
- package/dist/headlessHub.cjs.map +1 -1
- package/dist/headlessHub.d.mts +71 -36
- package/dist/headlessHub.d.mts.map +1 -1
- package/dist/headlessHub.mjs +309 -110
- package/dist/headlessHub.mjs.map +1 -1
- package/dist/headlessProtocol.cjs +327 -0
- package/dist/headlessProtocol.cjs.map +1 -0
- package/dist/headlessProtocol.d.mts +30 -0
- package/dist/headlessProtocol.d.mts.map +1 -0
- package/dist/headlessProtocol.mjs +326 -0
- package/dist/headlessProtocol.mjs.map +1 -0
- package/dist/headlessServer.cjs +166 -151
- package/dist/headlessServer.cjs.map +1 -1
- package/dist/headlessServer.d.mts +13 -5
- package/dist/headlessServer.d.mts.map +1 -1
- package/dist/headlessServer.mjs +166 -151
- package/dist/headlessServer.mjs.map +1 -1
- package/dist/headlessSessionHost.d.mts +58 -21
- package/dist/headlessSessionHost.d.mts.map +1 -1
- package/dist/help.cjs +20 -20
- package/dist/help.d.mts +2 -2
- package/dist/help.mjs +2 -2
- package/dist/history.cjs +16 -20
- package/dist/history.d.mts +9 -7
- package/dist/history.mjs +6 -7
- package/dist/historyOwnership.cjs.map +1 -1
- package/dist/historyOwnership.d.mts +1 -1
- package/dist/historyOwnership.mjs.map +1 -1
- package/dist/hubChannel.cjs +9 -0
- package/dist/hubChannel.d.mts +3 -2
- package/dist/hubChannel.mjs +3 -2
- package/dist/index.cjs +26 -28
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +6 -6
- package/dist/interop/chord.mjs +1 -0
- package/dist/interop/chordContext.mjs +1 -0
- package/dist/json.cjs +11 -5
- package/dist/json.d.mts +4 -2
- package/dist/json.mjs +4 -2
- package/dist/kernel.cjs +1 -1
- package/dist/kernel.d.mts +3 -3
- package/dist/kernel.mjs +1 -2
- package/dist/leader.d.mts +2 -2
- package/dist/leader.mjs +1 -2
- package/dist/logSinkTelemetry.mjs +1 -2
- package/dist/machineApi.cjs +80 -74
- package/dist/machineApi.cjs.map +1 -1
- package/dist/machineApi.d.mts +5 -2
- package/dist/machineApi.d.mts.map +1 -1
- package/dist/machineApi.mjs +78 -71
- package/dist/machineApi.mjs.map +1 -1
- package/dist/main.cjs +2 -1
- package/dist/main.d.mts +2 -1
- package/dist/main.mjs +2 -1
- package/dist/mcpFacet.d.mts +3 -3
- package/dist/mcpProjection.cjs +13 -13
- package/dist/mcpProjection.d.mts +2 -2
- package/dist/mcpProjection.mjs +1 -2
- package/dist/mcpSchemaCost.cjs +4 -4
- package/dist/mcpSchemaCost.cjs.map +1 -1
- package/dist/mcpSchemaCost.d.mts +2 -2
- package/dist/mcpSchemaCost.mjs +4 -4
- package/dist/mcpSchemaCost.mjs.map +1 -1
- package/dist/mcpSession.cjs +7 -7
- package/dist/mcpSession.d.mts +2 -2
- package/dist/mcpSession.mjs +1 -2
- package/dist/mcpStatus.cjs +2 -2
- package/dist/mcpStatus.d.mts +2 -2
- package/dist/mcpStatus.mjs +1 -2
- package/dist/mcpToolResolver.cjs +3 -3
- package/dist/mcpToolResolver.d.mts +2 -2
- package/dist/mcpToolResolver.mjs +1 -2
- package/dist/mcpWidget.d.mts +2 -2
- package/dist/moduleResolution.cjs +43 -8
- package/dist/moduleResolution.cjs.map +1 -1
- package/dist/moduleResolution.d.mts +10 -1
- package/dist/moduleResolution.d.mts.map +1 -1
- package/dist/moduleResolution.mjs +40 -7
- package/dist/moduleResolution.mjs.map +1 -1
- package/dist/narration.cjs +3 -3
- package/dist/narration.d.mts +2 -2
- package/dist/narration.mjs +1 -2
- package/dist/native.cjs +9 -0
- package/dist/native.d.mts +4 -3
- package/dist/native.mjs +3 -2
- package/dist/nodePlatform.cjs +77 -0
- package/dist/nodePlatform.cjs.map +1 -0
- package/dist/nodePlatform.d.mts +17 -0
- package/dist/nodePlatform.d.mts.map +1 -0
- package/dist/nodePlatform.mjs +72 -0
- package/dist/nodePlatform.mjs.map +1 -0
- package/dist/notification.cjs +15 -15
- package/dist/notification.d.mts +2 -2
- package/dist/notification.mjs +1 -2
- package/dist/packageApi.cjs +11 -11
- package/dist/packageApi.d.mts +2 -2
- package/dist/packageApi.mjs +2 -2
- package/dist/packageApiServer.cjs +45 -27
- package/dist/packageApiServer.cjs.map +1 -1
- package/dist/packageApiServer.d.mts +36 -26
- package/dist/packageApiServer.d.mts.map +1 -1
- package/dist/packageApiServer.mjs +44 -26
- package/dist/packageApiServer.mjs.map +1 -1
- package/dist/piSettings.cjs +41 -20
- package/dist/piSettings.d.mts +4 -2
- package/dist/piSettings.mjs +4 -2
- package/dist/platform.cjs +62 -0
- package/dist/platform.d.mts +10 -0
- package/dist/platform.mjs +10 -0
- package/dist/pluginProtocol.cjs +7 -8
- package/dist/pluginProtocol.d.mts +2 -2
- package/dist/pluginProtocol.mjs +1 -2
- package/dist/poPackage.cjs +12 -0
- package/dist/poPackage.d.mts +3 -0
- package/dist/poPackage.mjs +3 -0
- package/dist/profileIdentity.cjs +1 -1
- package/dist/profileIdentity.d.mts +2 -2
- package/dist/profileIdentity.mjs +1 -2
- package/dist/protocol.cjs +3 -3
- package/dist/protocol.d.mts +2 -2
- package/dist/protocol.mjs +1 -2
- package/dist/readiness.cjs +6 -6
- package/dist/readiness.d.mts +2 -2
- package/dist/readiness.mjs +1 -2
- package/dist/remoteApi.cjs.map +1 -1
- package/dist/remoteApi.d.mts +2 -2
- package/dist/remoteApi.mjs.map +1 -1
- package/dist/remoteRuntime.cjs +42 -65
- package/dist/remoteRuntime.cjs.map +1 -1
- package/dist/remoteRuntime.d.mts +3 -2
- package/dist/remoteRuntime.d.mts.map +1 -1
- package/dist/remoteRuntime.mjs +41 -62
- package/dist/remoteRuntime.mjs.map +1 -1
- package/dist/runtimeConfig.cjs +4 -4
- package/dist/runtimeConfig.cjs.map +1 -1
- package/dist/runtimeConfig.d.mts +10 -9
- package/dist/runtimeConfig.d.mts.map +1 -1
- package/dist/runtimeConfig.mjs +4 -4
- package/dist/runtimeConfig.mjs.map +1 -1
- package/dist/runtimeContextApi.cjs +10 -3
- package/dist/runtimeContextApi.cjs.map +1 -1
- package/dist/runtimeContextApi.d.mts +3 -3
- package/dist/runtimeContextApi.d.mts.map +1 -1
- package/dist/runtimeContextApi.mjs +10 -3
- package/dist/runtimeContextApi.mjs.map +1 -1
- package/dist/runtimeCordisHost.cjs +46 -46
- package/dist/runtimeCordisHost.cjs.map +1 -1
- package/dist/runtimeCordisHost.d.mts +29 -28
- package/dist/runtimeCordisHost.d.mts.map +1 -1
- package/dist/runtimeCordisHost.mjs +42 -42
- package/dist/runtimeCordisHost.mjs.map +1 -1
- package/dist/runtimeIdentity.cjs +6 -9
- package/dist/runtimeIdentity.cjs.map +1 -1
- package/dist/runtimeIdentity.d.mts +5 -1
- package/dist/runtimeIdentity.d.mts.map +1 -1
- package/dist/runtimeIdentity.mjs +5 -8
- package/dist/runtimeIdentity.mjs.map +1 -1
- package/dist/runtimeJson.cjs +10 -45
- package/dist/runtimeJson.d.mts +3 -22
- package/dist/runtimeJson.mjs +3 -39
- package/dist/runtimeLogSinkTelemetry.cjs +19 -19
- package/dist/runtimeLogSinkTelemetry.cjs.map +1 -1
- package/dist/runtimeLogSinkTelemetry.d.mts +19 -19
- package/dist/runtimeLogSinkTelemetry.mjs +19 -19
- package/dist/runtimeLogSinkTelemetry.mjs.map +1 -1
- package/dist/runtimePackages.cjs +7 -2
- package/dist/runtimePackages.cjs.map +1 -1
- package/dist/runtimePackages.d.mts +4 -1
- package/dist/runtimePackages.d.mts.map +1 -1
- package/dist/runtimePackages.mjs +7 -2
- package/dist/runtimePackages.mjs.map +1 -1
- package/dist/runtimePiSettings.cjs +40 -263
- package/dist/runtimePiSettings.d.mts +3 -72
- package/dist/runtimePiSettings.mjs +3 -241
- package/dist/runtimeProtocol.cjs +19 -19
- package/dist/runtimeProtocol.cjs.map +1 -1
- package/dist/runtimeProtocol.d.mts +7 -7
- package/dist/runtimeProtocol.d.mts.map +1 -1
- package/dist/runtimeProtocol.mjs +17 -17
- package/dist/runtimeProtocol.mjs.map +1 -1
- package/dist/runtimeTransition.cjs +9 -9
- package/dist/runtimeTransition.cjs.map +1 -1
- package/dist/runtimeTransition.d.mts +10 -10
- package/dist/runtimeTransition.d.mts.map +1 -1
- package/dist/runtimeTransition.mjs +7 -7
- package/dist/runtimeTransition.mjs.map +1 -1
- package/dist/sandboxHarness.mjs +1 -2
- package/dist/server.cjs +3 -7
- package/dist/server.d.mts +6 -6
- package/dist/server.mjs +3 -4
- package/dist/serverPlugin.cjs +39 -0
- package/dist/serverPlugin.d.mts +12 -0
- package/dist/serverPlugin.mjs +11 -0
- package/dist/serverTelemetry.cjs +1 -1
- package/dist/serverTelemetry.cjs.map +1 -1
- package/dist/serverTelemetry.d.mts +2 -2
- package/dist/serverTelemetry.mjs +2 -2
- package/dist/serverTelemetry.mjs.map +1 -1
- package/dist/sessionFilesApi.cjs +41 -37
- package/dist/sessionFilesApi.cjs.map +1 -1
- package/dist/sessionFilesApi.d.mts +6 -3
- package/dist/sessionFilesApi.d.mts.map +1 -1
- package/dist/sessionFilesApi.mjs +41 -36
- package/dist/sessionFilesApi.mjs.map +1 -1
- package/dist/sessionProtocol.cjs +31 -6
- package/dist/sessionProtocol.d.mts +8 -3
- package/dist/sessionProtocol.mjs +8 -2
- package/dist/skills.cjs +5 -5
- package/dist/skills.d.mts +2 -2
- package/dist/skills.mjs +1 -2
- package/dist/sqliteSessionStorage.cjs +28 -50
- package/dist/sqliteSessionStorage.cjs.map +1 -1
- package/dist/sqliteSessionStorage.d.mts +13 -20
- package/dist/sqliteSessionStorage.d.mts.map +1 -1
- package/dist/sqliteSessionStorage.mjs +25 -48
- package/dist/sqliteSessionStorage.mjs.map +1 -1
- package/dist/src/constants/agentSettled.cjs +7 -0
- package/dist/src/constants/agentSettled.cjs.map +1 -0
- package/dist/src/constants/agentSettled.mjs +7 -0
- package/dist/src/constants/agentSettled.mjs.map +1 -0
- package/dist/src/constants/contextApi.cjs +3 -1
- package/dist/src/constants/contextApi.cjs.map +1 -1
- package/dist/src/constants/contextApi.d.mts +2 -1
- package/dist/src/constants/contextApi.d.mts.map +1 -1
- package/dist/src/constants/contextApi.mjs +3 -2
- package/dist/src/constants/contextApi.mjs.map +1 -1
- package/dist/src/constants/voiceTools.cjs +6 -6
- package/dist/src/constants/voiceTools.cjs.map +1 -1
- package/dist/src/constants/voiceTools.d.mts +3 -3
- package/dist/src/constants/voiceTools.mjs +4 -4
- package/dist/src/constants/voiceTools.mjs.map +1 -1
- package/dist/src/extensions/extensionFile.cjs +22 -5
- package/dist/src/extensions/extensionFile.cjs.map +1 -1
- package/dist/src/extensions/extensionFile.d.mts +17 -4
- package/dist/src/extensions/extensionFile.d.mts.map +1 -1
- package/dist/src/extensions/extensionFile.mjs +22 -6
- package/dist/src/extensions/extensionFile.mjs.map +1 -1
- package/dist/src/extensions/serverPlugin.cjs +231 -92
- package/dist/src/extensions/serverPlugin.cjs.map +1 -1
- package/dist/src/extensions/serverPlugin.d.mts +2 -2
- package/dist/src/extensions/serverPlugin.d.mts.map +1 -1
- package/dist/src/extensions/serverPlugin.mjs +232 -93
- package/dist/src/extensions/serverPlugin.mjs.map +1 -1
- package/dist/src/pi/piSessionRuntime.cjs +349 -142
- package/dist/src/pi/piSessionRuntime.cjs.map +1 -1
- package/dist/src/pi/piSessionRuntime.d.mts +18 -17
- package/dist/src/pi/piSessionRuntime.d.mts.map +1 -1
- package/dist/src/pi/piSessionRuntime.mjs +342 -135
- package/dist/src/pi/piSessionRuntime.mjs.map +1 -1
- package/dist/src/schemas/agentModel.cjs +2 -2
- package/dist/src/schemas/agentModel.cjs.map +1 -1
- package/dist/src/schemas/agentModel.d.mts +1 -1
- package/dist/src/schemas/agentModel.mjs +2 -2
- package/dist/src/schemas/agentModel.mjs.map +1 -1
- package/dist/src/schemas/apiContracts.d.mts +2 -2
- package/dist/src/schemas/apiContracts.d.mts.map +1 -1
- package/dist/src/schemas/askUser.cjs +4 -4
- package/dist/src/schemas/askUser.cjs.map +1 -1
- package/dist/src/schemas/askUser.d.mts +4 -4
- package/dist/src/schemas/askUser.d.mts.map +1 -1
- package/dist/src/schemas/askUser.mjs +3 -3
- package/dist/src/schemas/askUser.mjs.map +1 -1
- package/dist/src/schemas/backgroundWork.cjs +10 -10
- package/dist/src/schemas/backgroundWork.cjs.map +1 -1
- package/dist/src/schemas/backgroundWork.d.mts +9 -9
- package/dist/src/schemas/backgroundWork.d.mts.map +1 -1
- package/dist/src/schemas/backgroundWork.mjs +8 -8
- package/dist/src/schemas/backgroundWork.mjs.map +1 -1
- package/dist/src/schemas/childProcess.cjs +5 -5
- package/dist/src/schemas/childProcess.cjs.map +1 -1
- package/dist/src/schemas/childProcess.d.mts +2 -2
- package/dist/src/schemas/childProcess.mjs +5 -5
- package/dist/src/schemas/childProcess.mjs.map +1 -1
- package/dist/src/schemas/contextContributions.cjs +10 -10
- package/dist/src/schemas/contextContributions.cjs.map +1 -1
- package/dist/src/schemas/contextContributions.d.mts +16 -16
- package/dist/src/schemas/contextContributions.d.mts.map +1 -1
- package/dist/src/schemas/contextContributions.mjs +8 -8
- package/dist/src/schemas/contextContributions.mjs.map +1 -1
- package/dist/src/schemas/delegation.cjs +17 -17
- package/dist/src/schemas/delegation.cjs.map +1 -1
- package/dist/src/schemas/delegation.d.mts +16 -16
- package/dist/src/schemas/delegation.d.mts.map +1 -1
- package/dist/src/schemas/delegation.mjs +10 -10
- package/dist/src/schemas/delegation.mjs.map +1 -1
- package/dist/src/schemas/extensionFile.d.mts +23 -19
- package/dist/src/schemas/extensionFile.d.mts.map +1 -1
- package/dist/src/schemas/footer.cjs.map +1 -1
- package/dist/src/schemas/footer.d.mts +5 -5
- package/dist/src/schemas/footer.d.mts.map +1 -1
- package/dist/src/schemas/footer.mjs.map +1 -1
- package/dist/src/schemas/headless.cjs +37 -37
- package/dist/src/schemas/headless.cjs.map +1 -1
- package/dist/src/schemas/headless.d.mts +100 -101
- package/dist/src/schemas/headless.d.mts.map +1 -1
- package/dist/src/schemas/headless.mjs +24 -24
- package/dist/src/schemas/headless.mjs.map +1 -1
- package/dist/src/schemas/help.cjs +60 -60
- package/dist/src/schemas/help.cjs.map +1 -1
- package/dist/src/schemas/help.d.mts +43 -43
- package/dist/src/schemas/help.d.mts.map +1 -1
- package/dist/src/schemas/help.mjs +41 -41
- package/dist/src/schemas/help.mjs.map +1 -1
- package/dist/src/schemas/home.cjs +127 -0
- package/dist/src/schemas/home.cjs.map +1 -0
- package/dist/src/schemas/home.d.mts +63 -0
- package/dist/src/schemas/home.d.mts.map +1 -0
- package/dist/src/schemas/home.mjs +121 -0
- package/dist/src/schemas/home.mjs.map +1 -0
- package/dist/src/schemas/httpApiContracts.cjs +441 -0
- package/dist/src/schemas/httpApiContracts.cjs.map +1 -0
- package/dist/src/schemas/httpApiContracts.d.mts +78 -0
- package/dist/src/schemas/httpApiContracts.d.mts.map +1 -0
- package/dist/src/schemas/httpApiContracts.mjs +434 -0
- package/dist/src/schemas/httpApiContracts.mjs.map +1 -0
- package/dist/src/schemas/hubChannel.cjs +3 -0
- package/dist/src/schemas/hubChannel.cjs.map +1 -1
- package/dist/src/schemas/hubChannel.d.mts +84 -60
- package/dist/src/schemas/hubChannel.d.mts.map +1 -1
- package/dist/src/schemas/hubChannel.mjs +3 -1
- package/dist/src/schemas/hubChannel.mjs.map +1 -1
- package/dist/src/schemas/leader.cjs.map +1 -1
- package/dist/src/schemas/leader.d.mts +3 -3
- package/dist/src/schemas/leader.d.mts.map +1 -1
- package/dist/src/schemas/leader.mjs.map +1 -1
- package/dist/src/schemas/mcpBundle.d.mts +3 -3
- package/dist/src/schemas/mcpFacet.cjs.map +1 -1
- package/dist/src/schemas/mcpFacet.d.mts +22 -22
- package/dist/src/schemas/mcpFacet.d.mts.map +1 -1
- package/dist/src/schemas/mcpFacet.mjs.map +1 -1
- package/dist/src/schemas/mcpProjection.cjs +41 -41
- package/dist/src/schemas/mcpProjection.cjs.map +1 -1
- package/dist/src/schemas/mcpProjection.d.mts +31 -30
- package/dist/src/schemas/mcpProjection.d.mts.map +1 -1
- package/dist/src/schemas/mcpProjection.mjs +29 -29
- package/dist/src/schemas/mcpProjection.mjs.map +1 -1
- package/dist/src/schemas/mcpSession.cjs +23 -23
- package/dist/src/schemas/mcpSession.cjs.map +1 -1
- package/dist/src/schemas/mcpSession.d.mts +12 -12
- package/dist/src/schemas/mcpSession.d.mts.map +1 -1
- package/dist/src/schemas/mcpSession.mjs +18 -18
- package/dist/src/schemas/mcpSession.mjs.map +1 -1
- package/dist/src/schemas/mcpStatus.cjs +5 -5
- package/dist/src/schemas/mcpStatus.cjs.map +1 -1
- package/dist/src/schemas/mcpStatus.d.mts +4 -4
- package/dist/src/schemas/mcpStatus.d.mts.map +1 -1
- package/dist/src/schemas/mcpStatus.mjs +4 -4
- package/dist/src/schemas/mcpStatus.mjs.map +1 -1
- package/dist/src/schemas/mcpToolResolver.cjs +9 -9
- package/dist/src/schemas/mcpToolResolver.cjs.map +1 -1
- package/dist/src/schemas/mcpToolResolver.d.mts +7 -7
- package/dist/src/schemas/mcpToolResolver.d.mts.map +1 -1
- package/dist/src/schemas/mcpToolResolver.mjs +7 -7
- package/dist/src/schemas/mcpToolResolver.mjs.map +1 -1
- package/dist/src/schemas/narration.cjs +9 -9
- package/dist/src/schemas/narration.cjs.map +1 -1
- package/dist/src/schemas/narration.d.mts +5 -5
- package/dist/src/schemas/narration.d.mts.map +1 -1
- package/dist/src/schemas/narration.mjs +7 -7
- package/dist/src/schemas/narration.mjs.map +1 -1
- package/dist/src/schemas/notification.cjs +45 -45
- package/dist/src/schemas/notification.cjs.map +1 -1
- package/dist/src/schemas/notification.d.mts +22 -22
- package/dist/src/schemas/notification.d.mts.map +1 -1
- package/dist/src/schemas/notification.mjs +31 -31
- package/dist/src/schemas/notification.mjs.map +1 -1
- package/dist/src/schemas/packageApi.cjs +28 -28
- package/dist/src/schemas/packageApi.cjs.map +1 -1
- package/dist/src/schemas/packageApi.d.mts +91 -65
- package/dist/src/schemas/packageApi.d.mts.map +1 -1
- package/dist/src/schemas/packageApi.mjs +18 -18
- package/dist/src/schemas/packageApi.mjs.map +1 -1
- package/dist/src/schemas/platform.cjs +34 -0
- package/dist/src/schemas/platform.cjs.map +1 -0
- package/dist/src/schemas/platform.d.mts +75 -0
- package/dist/src/schemas/platform.d.mts.map +1 -0
- package/dist/src/schemas/platform.mjs +27 -0
- package/dist/src/schemas/platform.mjs.map +1 -0
- package/dist/src/schemas/pluginContributions.cjs.map +1 -1
- package/dist/src/schemas/pluginContributions.d.mts +12 -12
- package/dist/src/schemas/pluginContributions.d.mts.map +1 -1
- package/dist/src/schemas/pluginContributions.mjs.map +1 -1
- package/dist/src/schemas/pluginProtocol.cjs +24 -27
- package/dist/src/schemas/pluginProtocol.cjs.map +1 -1
- package/dist/src/schemas/pluginProtocol.d.mts +21 -21
- package/dist/src/schemas/pluginProtocol.d.mts.map +1 -1
- package/dist/src/schemas/pluginProtocol.mjs +18 -20
- package/dist/src/schemas/pluginProtocol.mjs.map +1 -1
- package/dist/src/schemas/profileIdentity.cjs +2 -2
- package/dist/src/schemas/profileIdentity.cjs.map +1 -1
- package/dist/src/schemas/profileIdentity.d.mts +1 -1
- package/dist/src/schemas/profileIdentity.mjs +2 -2
- package/dist/src/schemas/profileIdentity.mjs.map +1 -1
- package/dist/src/schemas/protocolChannelsContract.cjs +27 -0
- package/dist/src/schemas/protocolChannelsContract.cjs.map +1 -0
- package/dist/src/schemas/protocolChannelsContract.d.mts +37 -0
- package/dist/src/schemas/protocolChannelsContract.d.mts.map +1 -0
- package/dist/src/schemas/protocolChannelsContract.mjs +25 -0
- package/dist/src/schemas/protocolChannelsContract.mjs.map +1 -0
- package/dist/src/schemas/protocolContracts.cjs +168 -0
- package/dist/src/schemas/protocolContracts.cjs.map +1 -0
- package/dist/src/schemas/protocolContracts.d.mts +69 -0
- package/dist/src/schemas/protocolContracts.d.mts.map +1 -0
- package/dist/src/schemas/protocolContracts.mjs +164 -0
- package/dist/src/schemas/protocolContracts.mjs.map +1 -0
- package/dist/src/schemas/protocolHubContract.cjs +51 -0
- package/dist/src/schemas/protocolHubContract.cjs.map +1 -0
- package/dist/src/schemas/protocolHubContract.d.mts +218 -0
- package/dist/src/schemas/protocolHubContract.d.mts.map +1 -0
- package/dist/src/schemas/protocolHubContract.mjs +49 -0
- package/dist/src/schemas/protocolHubContract.mjs.map +1 -0
- package/dist/src/schemas/protocolSessionContract.cjs +22 -0
- package/dist/src/schemas/protocolSessionContract.cjs.map +1 -0
- package/dist/src/schemas/protocolSessionContract.d.mts +324 -0
- package/dist/src/schemas/protocolSessionContract.d.mts.map +1 -0
- package/dist/src/schemas/protocolSessionContract.mjs +22 -0
- package/dist/src/schemas/protocolSessionContract.mjs.map +1 -0
- package/dist/src/schemas/protocolThreadContract.cjs +21 -0
- package/dist/src/schemas/protocolThreadContract.cjs.map +1 -0
- package/dist/src/schemas/protocolThreadContract.d.mts +29 -0
- package/dist/src/schemas/protocolThreadContract.d.mts.map +1 -0
- package/dist/src/schemas/protocolThreadContract.mjs +20 -0
- package/dist/src/schemas/protocolThreadContract.mjs.map +1 -0
- package/dist/src/schemas/readiness.cjs +36 -36
- package/dist/src/schemas/readiness.cjs.map +1 -1
- package/dist/src/schemas/readiness.d.mts +37 -37
- package/dist/src/schemas/readiness.d.mts.map +1 -1
- package/dist/src/schemas/readiness.mjs +31 -31
- package/dist/src/schemas/readiness.mjs.map +1 -1
- package/dist/src/schemas/serverBundle.d.mts +5 -5
- package/dist/src/schemas/serverPlugin.cjs +103 -0
- package/dist/src/schemas/serverPlugin.cjs.map +1 -0
- package/dist/src/schemas/serverPlugin.d.mts +176 -0
- package/dist/src/schemas/serverPlugin.d.mts.map +1 -0
- package/dist/src/schemas/serverPlugin.mjs +95 -0
- package/dist/src/schemas/serverPlugin.mjs.map +1 -0
- package/dist/src/schemas/serverScope.cjs +37 -0
- package/dist/src/schemas/serverScope.cjs.map +1 -0
- package/dist/src/schemas/serverScope.d.mts +77 -0
- package/dist/src/schemas/serverScope.d.mts.map +1 -0
- package/dist/src/schemas/serverScope.mjs +33 -0
- package/dist/src/schemas/serverScope.mjs.map +1 -0
- package/dist/src/schemas/sessionApiContracts.cjs +320 -0
- package/dist/src/schemas/sessionApiContracts.cjs.map +1 -0
- package/dist/src/schemas/sessionApiContracts.mjs +318 -0
- package/dist/src/schemas/sessionApiContracts.mjs.map +1 -0
- package/dist/src/schemas/sessionProtocol.cjs +20 -13
- package/dist/src/schemas/sessionProtocol.cjs.map +1 -1
- package/dist/src/schemas/sessionProtocol.d.mts +37 -54
- package/dist/src/schemas/sessionProtocol.d.mts.map +1 -1
- package/dist/src/schemas/sessionProtocol.mjs +17 -8
- package/dist/src/schemas/sessionProtocol.mjs.map +1 -1
- package/dist/src/schemas/skills.cjs +16 -16
- package/dist/src/schemas/skills.cjs.map +1 -1
- package/dist/src/schemas/skills.d.mts +7 -7
- package/dist/src/schemas/skills.d.mts.map +1 -1
- package/dist/src/schemas/skills.mjs +12 -12
- package/dist/src/schemas/skills.mjs.map +1 -1
- package/dist/src/schemas/toolOverrides.cjs +9 -9
- package/dist/src/schemas/toolOverrides.cjs.map +1 -1
- package/dist/src/schemas/toolOverrides.d.mts +8 -8
- package/dist/src/schemas/toolOverrides.d.mts.map +1 -1
- package/dist/src/schemas/toolOverrides.mjs +7 -7
- package/dist/src/schemas/toolOverrides.mjs.map +1 -1
- package/dist/src/schemas/toolSurface.cjs +9 -9
- package/dist/src/schemas/toolSurface.cjs.map +1 -1
- package/dist/src/schemas/toolSurface.d.mts +13 -13
- package/dist/src/schemas/toolSurface.d.mts.map +1 -1
- package/dist/src/schemas/toolSurface.mjs +7 -7
- package/dist/src/schemas/toolSurface.mjs.map +1 -1
- package/dist/src/schemas/uiHub.cjs +9 -9
- package/dist/src/schemas/uiHub.cjs.map +1 -1
- package/dist/src/schemas/uiHub.d.mts +12 -12
- package/dist/src/schemas/uiHub.d.mts.map +1 -1
- package/dist/src/schemas/uiHub.mjs +7 -7
- package/dist/src/schemas/uiHub.mjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.cjs +691 -775
- package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.d.mts +5 -1
- package/dist/src/server/directHarnessRuntime.d.mts.map +1 -0
- package/dist/src/server/directHarnessRuntime.mjs +671 -754
- package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
- package/dist/src/server/largeFrameLink.cjs +47 -0
- package/dist/src/server/largeFrameLink.cjs.map +1 -0
- package/dist/src/server/largeFrameLink.mjs +47 -0
- package/dist/src/server/largeFrameLink.mjs.map +1 -0
- package/dist/src/server/liveImport.cjs +1 -1
- package/dist/src/server/liveImport.cjs.map +1 -1
- package/dist/src/server/liveImport.d.mts +1 -1
- package/dist/src/server/liveImport.mjs +1 -1
- package/dist/src/server/liveImport.mjs.map +1 -1
- package/dist/src/server/mcpBundleLoader.cjs.map +1 -1
- package/dist/src/server/mcpBundleLoader.d.mts +6 -6
- package/dist/src/server/mcpBundleLoader.d.mts.map +1 -1
- package/dist/src/server/mcpBundleLoader.mjs.map +1 -1
- package/dist/src/server/serverPackages.cjs +60 -0
- package/dist/src/server/serverPackages.cjs.map +1 -0
- package/dist/src/server/serverPackages.d.mts +44 -0
- package/dist/src/server/serverPackages.d.mts.map +1 -0
- package/dist/src/server/serverPackages.mjs +59 -0
- package/dist/src/server/serverPackages.mjs.map +1 -0
- package/dist/src/server/serverScope.cjs +510 -0
- package/dist/src/server/serverScope.cjs.map +1 -0
- package/dist/src/server/serverScope.d.mts +123 -0
- package/dist/src/server/serverScope.d.mts.map +1 -0
- package/dist/src/server/serverScope.mjs +510 -0
- package/dist/src/server/serverScope.mjs.map +1 -0
- package/dist/src/server/sessionMcpHandler.cjs +3 -3
- package/dist/src/server/sessionMcpHandler.cjs.map +1 -1
- package/dist/src/server/sessionMcpHandler.mjs +4 -4
- package/dist/src/server/sessionMcpHandler.mjs.map +1 -1
- package/dist/src/server/sessionMcpRoutes.cjs +2 -1
- package/dist/src/server/sessionMcpRoutes.cjs.map +1 -1
- package/dist/src/server/sessionMcpRoutes.mjs +2 -1
- package/dist/src/server/sessionMcpRoutes.mjs.map +1 -1
- package/dist/src/server/threadJournals.cjs +38 -107
- package/dist/src/server/threadJournals.cjs.map +1 -1
- package/dist/src/server/threadJournals.mjs +38 -104
- package/dist/src/server/threadJournals.mjs.map +1 -1
- package/dist/src/services/apiSurfaceAssert/index.cjs +1 -1
- package/dist/src/services/apiSurfaceAssert/index.cjs.map +1 -1
- package/dist/src/services/apiSurfaceAssert/index.d.mts +6 -6
- package/dist/src/services/apiSurfaceAssert/index.mjs +1 -1
- package/dist/src/services/apiSurfaceAssert/index.mjs.map +1 -1
- package/dist/src/services/chatgptAuth/index.cjs +1 -220
- package/dist/src/services/chatgptAuth/index.cjs.map +1 -1
- package/dist/src/services/chatgptAuth/index.d.mts +0 -18
- package/dist/src/services/chatgptAuth/index.d.mts.map +1 -1
- package/dist/src/services/chatgptAuth/index.mjs +1 -217
- package/dist/src/services/chatgptAuth/index.mjs.map +1 -1
- package/dist/src/services/chatgptImages/index.cjs +1 -1
- package/dist/src/services/chatgptImages/index.cjs.map +1 -1
- package/dist/src/services/chatgptImages/index.mjs +1 -1
- package/dist/src/services/chatgptImages/index.mjs.map +1 -1
- package/dist/src/services/chatgptLogin/index.cjs +230 -0
- package/dist/src/services/chatgptLogin/index.cjs.map +1 -0
- package/dist/src/services/chatgptLogin/index.d.mts +21 -0
- package/dist/src/services/chatgptLogin/index.d.mts.map +1 -0
- package/dist/src/services/chatgptLogin/index.mjs +227 -0
- package/dist/src/services/chatgptLogin/index.mjs.map +1 -0
- package/dist/src/services/chatgptWebSearch/index.cjs +1 -1
- package/dist/src/services/chatgptWebSearch/index.cjs.map +1 -1
- package/dist/src/services/chatgptWebSearch/index.mjs +1 -1
- package/dist/src/services/chatgptWebSearch/index.mjs.map +1 -1
- package/dist/src/services/contextContributions/index.cjs +8 -8
- package/dist/src/services/contextContributions/index.cjs.map +1 -1
- package/dist/src/services/contextContributions/index.d.mts +3 -3
- package/dist/src/services/contextContributions/index.d.mts.map +1 -1
- package/dist/src/services/contextContributions/index.mjs +8 -8
- package/dist/src/services/contextContributions/index.mjs.map +1 -1
- package/dist/src/services/devProxyStore/devProxyRecords.cjs +59 -0
- package/dist/src/services/devProxyStore/devProxyRecords.cjs.map +1 -0
- package/dist/src/services/devProxyStore/devProxyRecords.mjs +56 -0
- package/dist/src/services/devProxyStore/devProxyRecords.mjs.map +1 -0
- package/dist/src/services/devProxyStore/index.cjs +7 -101
- package/dist/src/services/devProxyStore/index.cjs.map +1 -1
- package/dist/src/services/devProxyStore/index.mjs +7 -101
- package/dist/src/services/devProxyStore/index.mjs.map +1 -1
- package/dist/src/services/devProxyStore/sync.cjs +66 -0
- package/dist/src/services/devProxyStore/sync.cjs.map +1 -0
- package/dist/src/services/devProxyStore/sync.mjs +63 -0
- package/dist/src/services/devProxyStore/sync.mjs.map +1 -0
- package/dist/src/services/durableNavigation/docs.cjs +15 -0
- package/dist/src/services/durableNavigation/docs.cjs.map +1 -0
- package/dist/src/services/durableNavigation/docs.mjs +16 -0
- package/dist/src/services/durableNavigation/docs.mjs.map +1 -0
- package/dist/src/services/durableNavigation/index.cjs +3 -18
- package/dist/src/services/durableNavigation/index.cjs.map +1 -1
- package/dist/src/services/durableNavigation/index.mjs +2 -17
- package/dist/src/services/durableNavigation/index.mjs.map +1 -1
- package/dist/src/services/durableQueue/docs.cjs +12 -0
- package/dist/src/services/durableQueue/docs.cjs.map +1 -0
- package/dist/src/services/durableQueue/docs.mjs +13 -0
- package/dist/src/services/durableQueue/docs.mjs.map +1 -0
- package/dist/src/services/durableQueue/index.cjs +151 -0
- package/dist/src/services/durableQueue/index.cjs.map +1 -0
- package/dist/src/services/durableQueue/index.mjs +149 -0
- package/dist/src/services/durableQueue/index.mjs.map +1 -0
- package/dist/src/services/durableRequestReceipts/docs.cjs +11 -0
- package/dist/src/services/durableRequestReceipts/docs.cjs.map +1 -0
- package/dist/src/services/durableRequestReceipts/docs.mjs +12 -0
- package/dist/src/services/durableRequestReceipts/docs.mjs.map +1 -0
- package/dist/src/services/{requestReceipts → durableRequestReceipts}/index.cjs +10 -16
- package/dist/src/services/durableRequestReceipts/index.cjs.map +1 -0
- package/dist/src/services/durableRequestReceipts/index.d.mts +12 -0
- package/dist/src/services/durableRequestReceipts/index.d.mts.map +1 -0
- package/dist/src/services/{requestReceipts → durableRequestReceipts}/index.mjs +7 -13
- package/dist/src/services/durableRequestReceipts/index.mjs.map +1 -0
- package/dist/src/services/durableSession/docs.cjs +65 -0
- package/dist/src/services/durableSession/docs.cjs.map +1 -0
- package/dist/src/services/durableSession/docs.d.mts +17 -0
- package/dist/src/services/durableSession/docs.d.mts.map +1 -0
- package/dist/src/services/durableSession/docs.mjs +60 -0
- package/dist/src/services/durableSession/docs.mjs.map +1 -0
- package/dist/src/services/durableSession/index.cjs +21 -0
- package/dist/src/services/durableSession/index.cjs.map +1 -0
- package/dist/src/services/durableSession/index.d.mts +13 -0
- package/dist/src/services/durableSession/index.d.mts.map +1 -0
- package/dist/src/services/durableSession/index.mjs +20 -0
- package/dist/src/services/durableSession/index.mjs.map +1 -0
- package/dist/src/services/durableSubagents/docs.cjs +15 -0
- package/dist/src/services/durableSubagents/docs.cjs.map +1 -0
- package/dist/src/services/durableSubagents/docs.mjs +16 -0
- package/dist/src/services/durableSubagents/docs.mjs.map +1 -0
- package/dist/src/services/durableSubagents/extension.cjs +11 -0
- package/dist/src/services/durableSubagents/extension.cjs.map +1 -0
- package/dist/src/services/durableSubagents/extension.mjs +12 -0
- package/dist/src/services/durableSubagents/extension.mjs.map +1 -0
- package/dist/src/services/durableSubagents/index.cjs +95 -0
- package/dist/src/services/durableSubagents/index.cjs.map +1 -0
- package/dist/src/services/durableSubagents/index.mjs +90 -0
- package/dist/src/services/durableSubagents/index.mjs.map +1 -0
- package/dist/src/services/durableSubagents/tasks.cjs +25 -0
- package/dist/src/services/durableSubagents/tasks.cjs.map +1 -0
- package/dist/src/services/durableSubagents/tasks.mjs +26 -0
- package/dist/src/services/durableSubagents/tasks.mjs.map +1 -0
- package/dist/src/services/headlessClient/index.cjs +20 -13
- package/dist/src/services/headlessClient/index.cjs.map +1 -1
- package/dist/src/services/headlessClient/index.mjs +21 -14
- package/dist/src/services/headlessClient/index.mjs.map +1 -1
- package/dist/src/services/historyOwnership/type.d.mts +15 -0
- package/dist/src/services/historyOwnership/type.d.mts.map +1 -0
- package/dist/src/services/hubChannelHarness/index.cjs +2 -2
- package/dist/src/services/hubChannelHarness/index.cjs.map +1 -1
- package/dist/src/services/hubChannelHarness/index.d.mts +8 -8
- package/dist/src/services/hubChannelHarness/index.d.mts.map +1 -1
- package/dist/src/services/hubChannelHarness/index.mjs +2 -2
- package/dist/src/services/hubChannelHarness/index.mjs.map +1 -1
- package/dist/src/services/json/core.cjs +30 -0
- package/dist/src/services/json/core.cjs.map +1 -0
- package/dist/src/services/json/core.d.mts +21 -0
- package/dist/src/services/json/core.d.mts.map +1 -0
- package/dist/src/services/json/core.mjs +26 -0
- package/dist/src/services/json/core.mjs.map +1 -0
- package/dist/src/services/json/sync.cjs +48 -0
- package/dist/src/services/json/sync.cjs.map +1 -0
- package/dist/src/services/json/sync.d.mts +22 -0
- package/dist/src/services/json/sync.d.mts.map +1 -0
- package/dist/src/services/json/sync.mjs +43 -0
- package/dist/src/services/json/sync.mjs.map +1 -0
- package/dist/src/services/kernel/index.cjs +2 -2
- package/dist/src/services/kernel/index.cjs.map +1 -1
- package/dist/src/services/kernel/index.d.mts +3 -3
- package/dist/src/services/kernel/index.d.mts.map +1 -1
- package/dist/src/services/kernel/index.mjs +2 -2
- package/dist/src/services/kernel/index.mjs.map +1 -1
- package/dist/src/services/nativeChildTools/index.cjs +16 -0
- package/dist/src/services/nativeChildTools/index.cjs.map +1 -0
- package/dist/src/services/nativeChildTools/index.mjs +16 -0
- package/dist/src/services/nativeChildTools/index.mjs.map +1 -0
- package/dist/src/services/nodeHost/index.cjs +30 -0
- package/dist/src/services/nodeHost/index.cjs.map +1 -0
- package/dist/src/services/nodeHost/index.d.mts +16 -0
- package/dist/src/services/nodeHost/index.d.mts.map +1 -0
- package/dist/src/services/nodeHost/index.mjs +27 -0
- package/dist/src/services/nodeHost/index.mjs.map +1 -0
- package/dist/src/services/nodeModelDependencies/index.cjs +89 -0
- package/dist/src/services/nodeModelDependencies/index.cjs.map +1 -0
- package/dist/src/services/nodeModelDependencies/index.mjs +86 -0
- package/dist/src/services/nodeModelDependencies/index.mjs.map +1 -0
- package/dist/src/services/openSessionRegistry/index.cjs +6 -128
- package/dist/src/services/openSessionRegistry/index.cjs.map +1 -1
- package/dist/src/services/openSessionRegistry/index.d.mts +5 -36
- package/dist/src/services/openSessionRegistry/index.mjs +6 -128
- package/dist/src/services/openSessionRegistry/index.mjs.map +1 -1
- package/dist/src/services/openSessionRegistry/openSessionRecords.cjs +87 -0
- package/dist/src/services/openSessionRegistry/openSessionRecords.cjs.map +1 -0
- package/dist/src/services/openSessionRegistry/openSessionRecords.d.mts +30 -0
- package/dist/src/services/openSessionRegistry/openSessionRecords.d.mts.map +1 -0
- package/dist/src/services/openSessionRegistry/openSessionRecords.mjs +81 -0
- package/dist/src/services/openSessionRegistry/openSessionRecords.mjs.map +1 -0
- package/dist/src/services/openSessionRegistry/sync.cjs +71 -0
- package/dist/src/services/openSessionRegistry/sync.cjs.map +1 -0
- package/dist/src/services/openSessionRegistry/sync.d.mts +14 -0
- package/dist/src/services/openSessionRegistry/sync.d.mts.map +1 -0
- package/dist/src/services/openSessionRegistry/sync.mjs +68 -0
- package/dist/src/services/openSessionRegistry/sync.mjs.map +1 -0
- package/dist/src/services/packageApiHarness/index.cjs +1 -1
- package/dist/src/services/packageApiHarness/index.cjs.map +1 -1
- package/dist/src/services/packageApiHarness/index.d.mts +6 -6
- package/dist/src/services/packageApiHarness/index.d.mts.map +1 -1
- package/dist/src/services/packageApiHarness/index.mjs +2 -2
- package/dist/src/services/packageApiHarness/index.mjs.map +1 -1
- package/dist/src/services/piArgs/index.cjs +53 -0
- package/dist/src/services/piArgs/index.cjs.map +1 -0
- package/dist/src/services/piArgs/index.d.mts +6 -0
- package/dist/src/services/piArgs/index.d.mts.map +1 -0
- package/dist/src/services/piArgs/index.mjs +53 -0
- package/dist/src/services/piArgs/index.mjs.map +1 -0
- package/dist/src/services/piExtensionHost/index.cjs +47 -39
- package/dist/src/services/piExtensionHost/index.cjs.map +1 -1
- package/dist/src/services/piExtensionHost/index.d.mts +83 -0
- package/dist/src/services/piExtensionHost/index.d.mts.map +1 -0
- package/dist/src/services/piExtensionHost/index.mjs +47 -38
- package/dist/src/services/piExtensionHost/index.mjs.map +1 -1
- package/dist/src/services/piHelpTools/index.cjs +5 -5
- package/dist/src/services/piHelpTools/index.cjs.map +1 -1
- package/dist/src/services/piHelpTools/index.d.mts.map +1 -1
- package/dist/src/services/piHelpTools/index.mjs +7 -7
- package/dist/src/services/piHelpTools/index.mjs.map +1 -1
- package/dist/src/services/piMessages/index.cjs +106 -0
- package/dist/src/services/piMessages/index.cjs.map +1 -0
- package/dist/src/services/piMessages/index.mjs +105 -0
- package/dist/src/services/piMessages/index.mjs.map +1 -0
- package/dist/src/services/piSessionEntries/index.cjs +4 -4
- package/dist/src/services/piSessionEntries/index.cjs.map +1 -1
- package/dist/src/services/piSessionEntries/index.mjs +3 -3
- package/dist/src/services/piSessionEntries/index.mjs.map +1 -1
- package/dist/src/services/piSettings/core.cjs +308 -0
- package/dist/src/services/piSettings/core.cjs.map +1 -0
- package/dist/src/services/piSettings/core.d.mts +102 -0
- package/dist/src/services/piSettings/core.d.mts.map +1 -0
- package/dist/src/services/piSettings/core.mjs +276 -0
- package/dist/src/services/piSettings/core.mjs.map +1 -0
- package/dist/src/services/piSettings/sync.cjs +119 -0
- package/dist/src/services/piSettings/sync.cjs.map +1 -0
- package/dist/src/services/piSettings/sync.d.mts +44 -0
- package/dist/src/services/piSettings/sync.d.mts.map +1 -0
- package/dist/src/services/piSettings/sync.mjs +110 -0
- package/dist/src/services/piSettings/sync.mjs.map +1 -0
- package/dist/src/services/piSummary/index.cjs +7 -0
- package/dist/src/services/piSummary/index.cjs.map +1 -0
- package/dist/src/services/piSummary/index.mjs +7 -0
- package/dist/src/services/piSummary/index.mjs.map +1 -0
- package/dist/src/services/platformFiles/index.cjs +44 -0
- package/dist/src/services/platformFiles/index.cjs.map +1 -0
- package/dist/src/services/platformFiles/index.d.mts +16 -0
- package/dist/src/services/platformFiles/index.d.mts.map +1 -0
- package/dist/src/services/platformFiles/index.mjs +39 -0
- package/dist/src/services/platformFiles/index.mjs.map +1 -0
- package/dist/src/services/pluginLifecycle/index.cjs +19 -13
- package/dist/src/services/pluginLifecycle/index.cjs.map +1 -1
- package/dist/src/services/pluginLifecycle/index.d.mts +2 -0
- package/dist/src/services/pluginLifecycle/index.d.mts.map +1 -1
- package/dist/src/services/pluginLifecycle/index.mjs +19 -14
- package/dist/src/services/pluginLifecycle/index.mjs.map +1 -1
- package/dist/src/services/poPackage/core.cjs +73 -0
- package/dist/src/services/poPackage/core.cjs.map +1 -0
- package/dist/src/services/poPackage/core.d.mts +32 -0
- package/dist/src/services/poPackage/core.d.mts.map +1 -0
- package/dist/src/services/poPackage/core.mjs +66 -0
- package/dist/src/services/poPackage/core.mjs.map +1 -0
- package/dist/src/services/poPackage/sync.cjs +55 -0
- package/dist/src/services/poPackage/sync.cjs.map +1 -0
- package/dist/src/services/poPackage/sync.d.mts +21 -0
- package/dist/src/services/poPackage/sync.d.mts.map +1 -0
- package/dist/src/services/poPackage/sync.mjs +50 -0
- package/dist/src/services/poPackage/sync.mjs.map +1 -0
- package/dist/src/services/providerAuth/index.cjs +11 -7
- package/dist/src/services/providerAuth/index.cjs.map +1 -1
- package/dist/src/services/providerAuth/index.mjs +11 -7
- package/dist/src/services/providerAuth/index.mjs.map +1 -1
- package/dist/src/services/publicFileShares/index.cjs +1 -1
- package/dist/src/services/publicFileShares/index.cjs.map +1 -1
- package/dist/src/services/publicFileShares/index.d.mts +2 -2
- package/dist/src/services/publicFileShares/index.mjs +2 -2
- package/dist/src/services/publicFileShares/index.mjs.map +1 -1
- package/dist/src/services/remoteAccess/index.d.mts +1 -0
- package/dist/src/services/remoteAccess/index.d.mts.map +1 -1
- package/dist/src/services/remoteAccessStore/index.cjs +8 -190
- package/dist/src/services/remoteAccessStore/index.cjs.map +1 -1
- package/dist/src/services/remoteAccessStore/index.d.mts +2 -0
- package/dist/src/services/remoteAccessStore/index.mjs +7 -187
- package/dist/src/services/remoteAccessStore/index.mjs.map +1 -1
- package/dist/src/services/remoteAccessStore/remoteAccessRecords.cjs +98 -0
- package/dist/src/services/remoteAccessStore/remoteAccessRecords.cjs.map +1 -0
- package/dist/src/services/remoteAccessStore/remoteAccessRecords.mjs +88 -0
- package/dist/src/services/remoteAccessStore/remoteAccessRecords.mjs.map +1 -0
- package/dist/src/services/remoteAccessStore/sync.cjs +111 -0
- package/dist/src/services/remoteAccessStore/sync.cjs.map +1 -0
- package/dist/src/services/remoteAccessStore/sync.mjs +108 -0
- package/dist/src/services/remoteAccessStore/sync.mjs.map +1 -0
- package/dist/src/services/runtimeIdentity/sync.cjs +23 -0
- package/dist/src/services/runtimeIdentity/sync.cjs.map +1 -0
- package/dist/src/services/runtimeIdentity/sync.d.mts +9 -0
- package/dist/src/services/runtimeIdentity/sync.d.mts.map +1 -0
- package/dist/src/services/runtimeIdentity/sync.mjs +20 -0
- package/dist/src/services/runtimeIdentity/sync.mjs.map +1 -0
- package/dist/src/services/serialRunner/index.cjs +25 -0
- package/dist/src/services/serialRunner/index.cjs.map +1 -0
- package/dist/src/services/serialRunner/index.d.mts +10 -0
- package/dist/src/services/serialRunner/index.d.mts.map +1 -0
- package/dist/src/services/serialRunner/index.mjs +25 -0
- package/dist/src/services/serialRunner/index.mjs.map +1 -0
- package/dist/src/services/{serverFacet → serverHost}/index.cjs +5 -5
- package/dist/src/services/serverHost/index.cjs.map +1 -0
- package/dist/src/services/serverHost/index.d.mts +31 -0
- package/dist/src/services/serverHost/index.d.mts.map +1 -0
- package/dist/src/services/{serverFacet → serverHost}/index.mjs +5 -5
- package/dist/src/services/serverHost/index.mjs.map +1 -0
- package/dist/src/services/sessionAttachments/index.cjs +4 -3
- package/dist/src/services/sessionAttachments/index.cjs.map +1 -1
- package/dist/src/services/sessionAttachments/index.d.mts +1 -6
- package/dist/src/services/sessionAttachments/index.d.mts.map +1 -1
- package/dist/src/services/sessionAttachments/index.mjs +3 -2
- package/dist/src/services/sessionAttachments/index.mjs.map +1 -1
- package/dist/src/services/sessionAttachments/type.d.mts +9 -0
- package/dist/src/services/sessionAttachments/type.d.mts.map +1 -0
- package/dist/src/services/sessionFiles/index.cjs +96 -0
- package/dist/src/services/sessionFiles/index.cjs.map +1 -0
- package/dist/src/services/sessionFiles/index.d.mts +33 -0
- package/dist/src/services/sessionFiles/index.d.mts.map +1 -0
- package/dist/src/services/sessionFiles/index.mjs +89 -0
- package/dist/src/services/sessionFiles/index.mjs.map +1 -0
- package/dist/src/services/sessionFiles/sessionDirectory.cjs +66 -0
- package/dist/src/services/sessionFiles/sessionDirectory.cjs.map +1 -0
- package/dist/src/services/sessionFiles/sessionDirectory.mjs +62 -0
- package/dist/src/services/sessionFiles/sessionDirectory.mjs.map +1 -0
- package/dist/src/services/sessionGitStatus/index.cjs +31 -33
- package/dist/src/services/sessionGitStatus/index.cjs.map +1 -1
- package/dist/src/services/sessionGitStatus/index.mjs +31 -33
- package/dist/src/services/sessionGitStatus/index.mjs.map +1 -1
- package/dist/src/services/sessionPresentation/index.cjs +3 -27
- package/dist/src/services/sessionPresentation/index.cjs.map +1 -1
- package/dist/src/services/sessionPresentation/index.mjs +3 -27
- package/dist/src/services/sessionPresentation/index.mjs.map +1 -1
- package/dist/src/services/skillPrompt/index.cjs +11 -0
- package/dist/src/services/skillPrompt/index.cjs.map +1 -0
- package/dist/src/services/skillPrompt/index.mjs +11 -0
- package/dist/src/services/skillPrompt/index.mjs.map +1 -0
- package/dist/src/services/sqliteSessionHistory/index.cjs +44 -30
- package/dist/src/services/sqliteSessionHistory/index.cjs.map +1 -1
- package/dist/src/services/sqliteSessionHistory/index.d.mts +7 -4
- package/dist/src/services/sqliteSessionHistory/index.d.mts.map +1 -1
- package/dist/src/services/sqliteSessionHistory/index.mjs +43 -28
- package/dist/src/services/sqliteSessionHistory/index.mjs.map +1 -1
- package/dist/src/services/sqliteTranscriptReader/index.cjs +21 -45
- package/dist/src/services/sqliteTranscriptReader/index.cjs.map +1 -1
- package/dist/src/services/sqliteTranscriptReader/index.d.mts +3 -2
- package/dist/src/services/sqliteTranscriptReader/index.d.mts.map +1 -1
- package/dist/src/services/sqliteTranscriptReader/index.mjs +16 -38
- package/dist/src/services/sqliteTranscriptReader/index.mjs.map +1 -1
- package/dist/src/services/testMode/index.cjs +162 -0
- package/dist/src/services/testMode/index.cjs.map +1 -0
- package/dist/src/services/testMode/index.d.mts +17 -0
- package/dist/src/services/testMode/index.d.mts.map +1 -0
- package/dist/src/services/testMode/index.mjs +155 -0
- package/dist/src/services/testMode/index.mjs.map +1 -0
- package/dist/src/services/toolOverrides/index.cjs +6 -6
- package/dist/src/services/toolOverrides/index.cjs.map +1 -1
- package/dist/src/services/toolOverrides/index.d.mts +3 -3
- package/dist/src/services/toolOverrides/index.d.mts.map +1 -1
- package/dist/src/services/toolOverrides/index.mjs +6 -6
- package/dist/src/services/toolOverrides/index.mjs.map +1 -1
- package/dist/src/services/toolPrompt/index.d.mts +17 -0
- package/dist/src/services/toolPrompt/index.d.mts.map +1 -0
- package/dist/src/services/toolSurface/index.cjs +3 -3
- package/dist/src/services/toolSurface/index.cjs.map +1 -1
- package/dist/src/services/toolSurface/index.d.mts +3 -3
- package/dist/src/services/toolSurface/index.d.mts.map +1 -1
- package/dist/src/services/toolSurface/index.mjs +4 -4
- package/dist/src/services/toolSurface/index.mjs.map +1 -1
- package/dist/src/services/traceContext/index.cjs.map +1 -1
- package/dist/src/services/traceContext/index.mjs.map +1 -1
- package/dist/src/services/transcriptPages/index.cjs +159 -33
- package/dist/src/services/transcriptPages/index.cjs.map +1 -1
- package/dist/src/services/transcriptPages/index.mjs +158 -34
- package/dist/src/services/transcriptPages/index.mjs.map +1 -1
- package/dist/src/services/voiceToolsContract/index.cjs +7 -7
- package/dist/src/services/voiceToolsContract/index.cjs.map +1 -1
- package/dist/src/services/voiceToolsContract/index.d.mts +4 -4
- package/dist/src/services/voiceToolsContract/index.d.mts.map +1 -1
- package/dist/src/services/voiceToolsContract/index.mjs +7 -7
- package/dist/src/services/voiceToolsContract/index.mjs.map +1 -1
- package/dist/src/services/workspaceRegistry/index.cjs +9 -179
- package/dist/src/services/workspaceRegistry/index.cjs.map +1 -1
- package/dist/src/services/workspaceRegistry/index.d.mts +5 -47
- package/dist/src/services/workspaceRegistry/index.mjs +7 -176
- package/dist/src/services/workspaceRegistry/index.mjs.map +1 -1
- package/dist/src/services/workspaceRegistry/sync.cjs +148 -0
- package/dist/src/services/workspaceRegistry/sync.cjs.map +1 -0
- package/dist/src/services/workspaceRegistry/sync.d.mts +34 -0
- package/dist/src/services/workspaceRegistry/sync.d.mts.map +1 -0
- package/dist/src/services/workspaceRegistry/sync.mjs +140 -0
- package/dist/src/services/workspaceRegistry/sync.mjs.map +1 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.cjs +114 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.cjs.map +1 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.d.mts +31 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.d.mts.map +1 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.mjs +101 -0
- package/dist/src/services/workspaceRegistry/workspaceRecords.mjs.map +1 -0
- package/dist/src/systems/child/adapters/headlessChildSessionService.cjs +339 -202
- package/dist/src/systems/child/adapters/headlessChildSessionService.cjs.map +1 -1
- package/dist/src/systems/child/adapters/headlessChildSessionService.d.mts +16 -21
- package/dist/src/systems/child/adapters/headlessChildSessionService.d.mts.map +1 -1
- package/dist/src/systems/child/adapters/headlessChildSessionService.mjs +329 -191
- package/dist/src/systems/child/adapters/headlessChildSessionService.mjs.map +1 -1
- package/dist/src/systems/child/services/childSession/index.cjs +94 -20
- package/dist/src/systems/child/services/childSession/index.cjs.map +1 -1
- package/dist/src/systems/child/services/childSession/index.d.mts +12 -3
- package/dist/src/systems/child/services/childSession/index.d.mts.map +1 -1
- package/dist/src/systems/child/services/childSession/index.mjs +94 -20
- package/dist/src/systems/child/services/childSession/index.mjs.map +1 -1
- package/dist/src/systems/child/types/childSession.cjs +33 -13
- package/dist/src/systems/child/types/childSession.cjs.map +1 -1
- package/dist/src/systems/child/types/childSession.d.mts +143 -80
- package/dist/src/systems/child/types/childSession.d.mts.map +1 -1
- package/dist/src/systems/child/types/childSession.mjs +24 -9
- package/dist/src/systems/child/types/childSession.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.cjs +30 -27
- package/dist/src/systems/main/adapters/headlessHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.d.mts +22 -22
- package/dist/src/systems/main/adapters/headlessHost.d.mts.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.mjs +33 -30
- package/dist/src/systems/main/adapters/headlessHost.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs +248 -229
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.d.mts +4 -5
- package/dist/src/systems/main/adapters/headlessSessionHost.d.mts.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs +239 -219
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
- package/dist/src/systems/main/types/headlessHost.d.mts +16 -14
- package/dist/src/systems/main/types/headlessHost.d.mts.map +1 -1
- package/dist/src/testing/pi/testHost.cjs +2 -2
- package/dist/src/testing/pi/testHost.cjs.map +1 -1
- package/dist/src/testing/pi/testHost.d.mts +3 -2
- package/dist/src/testing/pi/testHost.mjs +3 -3
- package/dist/src/testing/pi/testHost.mjs.map +1 -1
- package/dist/src/types/config.d.mts +1 -1
- package/dist/src/types/config.d.mts.map +1 -1
- package/dist/src/types/kernel.d.mts +3 -3
- package/dist/src/types/server/directHarnessRuntime.d.mts +54 -25
- package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
- package/dist/src/types/server/sessionToolSurface.d.mts +9 -9
- package/dist/src/web/services/apiClient/index.d.mts +1 -0
- package/dist/src/web/services/apiPaths/index.cjs.map +1 -1
- package/dist/src/web/services/apiPaths/index.d.mts +1 -1
- package/dist/src/web/services/apiPaths/index.mjs.map +1 -1
- package/dist/src/web/services/mcpWidget.cjs.map +1 -1
- package/dist/src/web/services/mcpWidget.d.mts +2 -2
- package/dist/src/web/services/mcpWidget.d.mts.map +1 -1
- package/dist/src/web/services/mcpWidget.mjs.map +1 -1
- package/dist/src/web/services/testing/templateRail.cjs +3 -0
- package/dist/src/web/services/testing/templateRail.cjs.map +1 -1
- package/dist/src/web/services/testing/templateRail.mjs +3 -0
- package/dist/src/web/services/testing/templateRail.mjs.map +1 -1
- package/dist/src/web/types/mcpWidget.d.mts +1 -1
- package/dist/src/web/types/nativeTemplate.d.mts +1 -1
- package/dist/src/web/types/nativeTemplate.d.mts.map +1 -1
- package/dist/src/web/types/template.d.mts +8 -0
- package/dist/src/web/types/template.d.mts.map +1 -1
- package/dist/src/web/types/webPlugin.d.mts +17 -5
- package/dist/src/web/types/webPlugin.d.mts.map +1 -1
- package/dist/testMode.cjs +4 -0
- package/dist/testMode.d.mts +2 -0
- package/dist/testMode.mjs +1 -0
- package/dist/testing.cjs +1 -1
- package/dist/testing.d.mts +2 -2
- package/dist/testing.mjs +2 -2
- package/dist/toolInventory.cjs.map +1 -1
- package/dist/toolInventory.mjs.map +1 -1
- package/dist/toolNames.mjs +1 -2
- package/dist/toolOverrides.cjs +4 -4
- package/dist/toolOverrides.d.mts +3 -3
- package/dist/toolOverrides.mjs +3 -3
- package/dist/toolSurface.cjs +4 -4
- package/dist/toolSurface.d.mts +3 -3
- package/dist/toolSurface.mjs +3 -3
- package/dist/transition.cjs +3 -3
- package/dist/transition.d.cjs +3 -3
- package/dist/transition.d.mts +2 -2
- package/dist/transition.mjs +1 -2
- package/dist/transitionClassifier.cjs.map +1 -1
- package/dist/transitionClassifier.d.mts +2 -2
- package/dist/transitionClassifier.d.mts.map +1 -1
- package/dist/transitionClassifier.mjs.map +1 -1
- package/dist/transitionCoordinator.cjs +3 -3
- package/dist/transitionCoordinator.cjs.map +1 -1
- package/dist/transitionCoordinator.d.mts +4 -4
- package/dist/transitionCoordinator.d.mts.map +1 -1
- package/dist/transitionCoordinator.mjs +3 -3
- package/dist/transitionCoordinator.mjs.map +1 -1
- package/dist/typesContextApi.d.mts +2 -1
- package/dist/typesContextApi.d.mts.map +1 -1
- package/dist/uiHub.cjs +3 -3
- package/dist/uiHub.d.mts +2 -2
- package/dist/uiHub.mjs +1 -2
- package/dist/voiceTools.cjs +5 -5
- package/dist/voiceTools.d.mts +3 -3
- package/dist/voiceTools.mjs +3 -3
- package/dist/web.cjs +8 -0
- package/dist/web.d.mts +3 -2
- package/dist/web.mjs +2 -1
- package/dist/webCompositions.cjs.map +1 -1
- package/dist/webCompositions.d.mts +7 -7
- package/dist/webCompositions.d.mts.map +1 -1
- package/dist/webCompositions.mjs.map +1 -1
- package/licenses/Codex-Apache-2.0.txt +201 -0
- package/package.json +58 -53
- package/dist/doomPackage.cjs +0 -61
- package/dist/doomPackage.cjs.map +0 -1
- package/dist/doomPackage.d.mts +0 -17
- package/dist/doomPackage.d.mts.map +0 -1
- package/dist/doomPackage.mjs +0 -54
- package/dist/doomPackage.mjs.map +0 -1
- package/dist/jsonlSessionRepo.cjs +0 -44
- package/dist/jsonlSessionRepo.cjs.map +0 -1
- package/dist/jsonlSessionRepo.d.mts +0 -7
- package/dist/jsonlSessionRepo.d.mts.map +0 -1
- package/dist/jsonlSessionRepo.mjs +0 -42
- package/dist/jsonlSessionRepo.mjs.map +0 -1
- package/dist/runtimeJson.cjs.map +0 -1
- package/dist/runtimeJson.d.mts.map +0 -1
- package/dist/runtimeJson.mjs.map +0 -1
- package/dist/runtimePiSettings.cjs.map +0 -1
- package/dist/runtimePiSettings.d.mts.map +0 -1
- package/dist/runtimePiSettings.mjs.map +0 -1
- package/dist/serverFacet.cjs +0 -34
- package/dist/serverFacet.d.mts +0 -10
- package/dist/serverFacet.mjs +0 -9
- package/dist/src/pi/piWebSocketListener.cjs +0 -115
- package/dist/src/pi/piWebSocketListener.cjs.map +0 -1
- package/dist/src/pi/piWebSocketListener.mjs +0 -115
- package/dist/src/pi/piWebSocketListener.mjs.map +0 -1
- package/dist/src/schemas/serverFacet.cjs +0 -111
- package/dist/src/schemas/serverFacet.cjs.map +0 -1
- package/dist/src/schemas/serverFacet.d.mts +0 -152
- package/dist/src/schemas/serverFacet.d.mts.map +0 -1
- package/dist/src/schemas/serverFacet.mjs +0 -101
- package/dist/src/schemas/serverFacet.mjs.map +0 -1
- package/dist/src/schemas/sessionUpdates.d.mts +0 -34
- package/dist/src/schemas/sessionUpdates.d.mts.map +0 -1
- package/dist/src/server/headlessProtocol.cjs +0 -382
- package/dist/src/server/headlessProtocol.cjs.map +0 -1
- package/dist/src/server/headlessProtocol.mjs +0 -382
- package/dist/src/server/headlessProtocol.mjs.map +0 -1
- package/dist/src/server/nativeChildTranscriptReader.cjs +0 -20
- package/dist/src/server/nativeChildTranscriptReader.cjs.map +0 -1
- package/dist/src/server/nativeChildTranscriptReader.mjs +0 -18
- package/dist/src/server/nativeChildTranscriptReader.mjs.map +0 -1
- package/dist/src/server/serverFacetLoader.cjs +0 -214
- package/dist/src/server/serverFacetLoader.cjs.map +0 -1
- package/dist/src/server/serverFacetLoader.d.mts +0 -72
- package/dist/src/server/serverFacetLoader.d.mts.map +0 -1
- package/dist/src/server/serverFacetLoader.mjs +0 -212
- package/dist/src/server/serverFacetLoader.mjs.map +0 -1
- package/dist/src/services/acpSessionUpdates/index.cjs +0 -129
- package/dist/src/services/acpSessionUpdates/index.cjs.map +0 -1
- package/dist/src/services/acpSessionUpdates/index.mjs +0 -129
- package/dist/src/services/acpSessionUpdates/index.mjs.map +0 -1
- package/dist/src/services/historyImport/index.cjs +0 -8
- package/dist/src/services/historyImport/index.cjs.map +0 -1
- package/dist/src/services/historyImport/index.d.mts +0 -68
- package/dist/src/services/historyImport/index.d.mts.map +0 -1
- package/dist/src/services/historyImport/index.mjs +0 -8
- package/dist/src/services/historyImport/index.mjs.map +0 -1
- package/dist/src/services/openSessionRegistry/index.d.mts.map +0 -1
- package/dist/src/services/requestReceipts/index.cjs.map +0 -1
- package/dist/src/services/requestReceipts/index.d.mts +0 -11
- package/dist/src/services/requestReceipts/index.d.mts.map +0 -1
- package/dist/src/services/requestReceipts/index.mjs.map +0 -1
- package/dist/src/services/rpcTranscript/index.cjs +0 -633
- package/dist/src/services/rpcTranscript/index.cjs.map +0 -1
- package/dist/src/services/rpcTranscript/index.d.mts +0 -50
- package/dist/src/services/rpcTranscript/index.d.mts.map +0 -1
- package/dist/src/services/rpcTranscript/index.mjs +0 -632
- package/dist/src/services/rpcTranscript/index.mjs.map +0 -1
- package/dist/src/services/serverFacet/index.cjs.map +0 -1
- package/dist/src/services/serverFacet/index.d.mts +0 -31
- package/dist/src/services/serverFacet/index.d.mts.map +0 -1
- package/dist/src/services/serverFacet/index.mjs.map +0 -1
- package/dist/src/services/workspaceRegistry/index.d.mts.map +0 -1
- package/dist/src/systems/child/adapters/nativeChildRuntimes.cjs +0 -28
- package/dist/src/systems/child/adapters/nativeChildRuntimes.cjs.map +0 -1
- package/dist/src/systems/child/adapters/nativeChildRuntimes.mjs +0 -25
- package/dist/src/systems/child/adapters/nativeChildRuntimes.mjs.map +0 -1
- package/dist/terminalPiChildSessionService.cjs +0 -324
- package/dist/terminalPiChildSessionService.cjs.map +0 -1
- package/dist/terminalPiChildSessionService.d.mts +0 -46
- package/dist/terminalPiChildSessionService.d.mts.map +0 -1
- package/dist/terminalPiChildSessionService.mjs +0 -318
- package/dist/terminalPiChildSessionService.mjs.map +0 -1
- package/dist/v3Export.cjs +0 -10
- package/dist/v3Export.cjs.map +0 -1
- package/dist/v3Export.d.mts +0 -35
- package/dist/v3Export.d.mts.map +0 -1
- package/dist/v3Export.mjs +0 -9
- package/dist/v3Export.mjs.map +0 -1
|
@@ -1,197 +1,15 @@
|
|
|
1
1
|
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
-
|
|
2
|
+
require("../platformFiles/index.cjs");
|
|
3
|
+
const require_index$1 = require("../serialRunner/index.cjs");
|
|
3
4
|
require("../../constants/remote.cjs");
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
7
|
-
let node_os = require("node:os");
|
|
8
|
-
node_os = require_runtime.__toESM(node_os, 1);
|
|
5
|
+
const require_remoteAccessRecords = require("./remoteAccessRecords.cjs");
|
|
6
|
+
const require_sync = require("./sync.cjs");
|
|
9
7
|
let node_path = require("node:path");
|
|
10
8
|
node_path = require_runtime.__toESM(node_path, 1);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const STATE_DIRECTORY = "web";
|
|
14
|
-
const SETTINGS_FILE = "remote-access.json";
|
|
15
|
-
const CREDENTIALS_FILE = "credentials.json";
|
|
16
|
-
const TRUSTED_DEVICES_FILE = "trusted-devices.json";
|
|
17
|
-
const TRUSTED_DEVICE_PLATFORMS = /* @__PURE__ */ new Set(["ios", "android"]);
|
|
18
|
-
const STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
19
|
-
const STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;
|
|
20
|
-
const MAX_STORED_LABEL = 200;
|
|
21
|
-
const DIRECTORY_MODE = 448;
|
|
22
|
-
const FILE_MODE = 384;
|
|
23
|
-
/** Any bit set for group or other; a state file readable by another account is worth repairing. */
|
|
24
|
-
const LOOSE_MODE_MASK = 63;
|
|
25
|
-
function defaultRemoteStateDir(homeDir = node_os.default.homedir()) {
|
|
26
|
-
return node_path.default.join(require_runtimePiSettings.poHomeDirectory(homeDir), STATE_DIRECTORY);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Repairs a state file another account can read.
|
|
30
|
-
*
|
|
31
|
-
* Cheap, and it catches the cases a fresh write never would: a file restored
|
|
32
|
-
* from a backup, copied with a permissive umask, or checked out of somewhere it
|
|
33
|
-
* should not have been.
|
|
34
|
-
*/
|
|
35
|
-
function tightenMode(filePath, notice) {
|
|
36
|
-
try {
|
|
37
|
-
if ((node_fs.default.statSync(filePath).mode & LOOSE_MODE_MASK) === 0) return;
|
|
38
|
-
node_fs.default.chmodSync(filePath, FILE_MODE);
|
|
39
|
-
notice(`tightened permissions on ${filePath}`);
|
|
40
|
-
} catch {}
|
|
41
|
-
}
|
|
42
|
-
/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */
|
|
43
|
-
function isTrustedDeviceRecord(value) {
|
|
44
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
45
|
-
const record = value;
|
|
46
|
-
return typeof record.id === "string" && STORED_ID.test(record.id) && typeof record.identityPublicKey === "string" && STORED_KEY.test(record.identityPublicKey) && typeof record.stepUpPublicKey === "string" && STORED_KEY.test(record.stepUpPublicKey) && record.identityPublicKey !== record.stepUpPublicKey && typeof record.label === "string" && record.label.length <= MAX_STORED_LABEL && typeof record.platform === "string" && TRUSTED_DEVICE_PLATFORMS.has(record.platform) && Number.isFinite(record.createdAt) && Number.isFinite(record.lastSeenAt);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Settings and passkeys on disk. Sessions deliberately not.
|
|
50
|
-
*
|
|
51
|
-
* A session is revoked when remote access is switched off, and a hub restart is
|
|
52
|
-
* a switch-off, so persisting one would buy nothing while creating a bearer
|
|
53
|
-
* secret worth stealing. A passkey is the opposite: surviving is its whole
|
|
54
|
-
* point, and what is stored is a public key.
|
|
55
|
-
*/
|
|
56
|
-
function createRemoteAccessStore(options = {}) {
|
|
57
|
-
const directory = options.stateDir ?? defaultRemoteStateDir();
|
|
58
|
-
const notice = options.onNotice ?? (() => {});
|
|
59
|
-
const settingsPath = node_path.default.join(directory, SETTINGS_FILE);
|
|
60
|
-
const credentialsPath = node_path.default.join(directory, CREDENTIALS_FILE);
|
|
61
|
-
const trustedDevicesPath = node_path.default.join(directory, TRUSTED_DEVICES_FILE);
|
|
62
|
-
let current = load();
|
|
63
|
-
let registered = loadCredentials();
|
|
64
|
-
let trusted = loadTrustedDevices();
|
|
65
|
-
function load() {
|
|
66
|
-
let raw;
|
|
67
|
-
try {
|
|
68
|
-
raw = node_fs.default.readFileSync(settingsPath, "utf8");
|
|
69
|
-
} catch {
|
|
70
|
-
return require_index.DEFAULT_REMOTE_SETTINGS;
|
|
71
|
-
}
|
|
72
|
-
tightenMode(settingsPath, notice);
|
|
73
|
-
let parsed;
|
|
74
|
-
try {
|
|
75
|
-
parsed = JSON.parse(raw);
|
|
76
|
-
} catch {
|
|
77
|
-
notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);
|
|
78
|
-
return require_index.DEFAULT_REMOTE_SETTINGS;
|
|
79
|
-
}
|
|
80
|
-
const outcome = require_index.parseRemoteAccessSettings(parsed);
|
|
81
|
-
for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);
|
|
82
|
-
return outcome.settings;
|
|
83
|
-
}
|
|
84
|
-
function loadCredentials() {
|
|
85
|
-
let raw;
|
|
86
|
-
try {
|
|
87
|
-
raw = node_fs.default.readFileSync(credentialsPath, "utf8");
|
|
88
|
-
} catch {
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
tightenMode(credentialsPath, notice);
|
|
92
|
-
try {
|
|
93
|
-
const parsed = JSON.parse(raw);
|
|
94
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
95
|
-
} catch {
|
|
96
|
-
notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);
|
|
97
|
-
return [];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function loadTrustedDevices() {
|
|
101
|
-
let raw;
|
|
102
|
-
try {
|
|
103
|
-
raw = node_fs.default.readFileSync(trustedDevicesPath, "utf8");
|
|
104
|
-
} catch {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
tightenMode(trustedDevicesPath, notice);
|
|
108
|
-
let parsed;
|
|
109
|
-
try {
|
|
110
|
-
parsed = JSON.parse(raw);
|
|
111
|
-
} catch {
|
|
112
|
-
notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
if (!Array.isArray(parsed)) {
|
|
116
|
-
notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);
|
|
117
|
-
return [];
|
|
118
|
-
}
|
|
119
|
-
const loaded = [];
|
|
120
|
-
for (const entry of parsed) {
|
|
121
|
-
if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {
|
|
122
|
-
notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
if (loaded.length >= 32) {
|
|
126
|
-
notice(`dropped trusted devices beyond the limit of ${String(32)} from ${trustedDevicesPath}`);
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
loaded.push({
|
|
130
|
-
id: entry.id,
|
|
131
|
-
identityPublicKey: entry.identityPublicKey,
|
|
132
|
-
stepUpPublicKey: entry.stepUpPublicKey,
|
|
133
|
-
label: entry.label,
|
|
134
|
-
platform: entry.platform,
|
|
135
|
-
createdAt: entry.createdAt,
|
|
136
|
-
lastSeenAt: entry.lastSeenAt
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
return loaded;
|
|
140
|
-
}
|
|
141
|
-
function writeJson(target, body) {
|
|
142
|
-
const temporary = `${target}.${String(process.pid)}.tmp`;
|
|
143
|
-
try {
|
|
144
|
-
node_fs.default.mkdirSync(directory, {
|
|
145
|
-
recursive: true,
|
|
146
|
-
mode: DIRECTORY_MODE
|
|
147
|
-
});
|
|
148
|
-
node_fs.default.writeFileSync(temporary, `${JSON.stringify(body, void 0, 2)}\n`, { mode: FILE_MODE });
|
|
149
|
-
node_fs.default.renameSync(temporary, target);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);
|
|
152
|
-
try {
|
|
153
|
-
node_fs.default.rmSync(temporary, { force: true });
|
|
154
|
-
} catch {}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
directory,
|
|
159
|
-
settings: () => current,
|
|
160
|
-
credentials: () => registered,
|
|
161
|
-
saveCredential(credential) {
|
|
162
|
-
registered = [...registered.filter((held) => held.id !== credential.id), credential];
|
|
163
|
-
writeJson(credentialsPath, registered);
|
|
164
|
-
},
|
|
165
|
-
removeCredential(id) {
|
|
166
|
-
const next = registered.filter((held) => held.id !== id);
|
|
167
|
-
if (next.length === registered.length) return false;
|
|
168
|
-
registered = next;
|
|
169
|
-
writeJson(credentialsPath, registered);
|
|
170
|
-
return true;
|
|
171
|
-
},
|
|
172
|
-
trustedDevices: () => trusted,
|
|
173
|
-
saveTrustedDevice(record) {
|
|
174
|
-
const others = trusted.filter((held) => held.id !== record.id);
|
|
175
|
-
if (others.length === trusted.length && trusted.length >= 32) return false;
|
|
176
|
-
trusted = [...others, record];
|
|
177
|
-
writeJson(trustedDevicesPath, trusted);
|
|
178
|
-
return true;
|
|
179
|
-
},
|
|
180
|
-
removeTrustedDevice(id) {
|
|
181
|
-
const next = trusted.filter((held) => held.id !== id);
|
|
182
|
-
if (next.length === trusted.length) return false;
|
|
183
|
-
trusted = next;
|
|
184
|
-
writeJson(trustedDevicesPath, trusted);
|
|
185
|
-
return true;
|
|
186
|
-
},
|
|
187
|
-
save(settings) {
|
|
188
|
-
current = settings;
|
|
189
|
-
writeJson(settingsPath, require_index.serializeRemoteAccessSettings(settings));
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
}
|
|
9
|
+
require("@earendil-works/pi-durable/env");
|
|
10
|
+
require_index$1.createSerialRunner();
|
|
193
11
|
//#endregion
|
|
194
|
-
exports.createRemoteAccessStore = createRemoteAccessStore;
|
|
195
|
-
exports.defaultRemoteStateDir = defaultRemoteStateDir;
|
|
12
|
+
exports.createRemoteAccessStore = require_sync.createRemoteAccessStore;
|
|
13
|
+
exports.defaultRemoteStateDir = require_remoteAccessRecords.defaultRemoteStateDir;
|
|
196
14
|
|
|
197
15
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["os","path","poHomeDirectory","fs","DEFAULT_REMOTE_SETTINGS","parseRemoteAccessSettings","serializeRemoteAccessSettings"],"sources":["../../../../src/services/remoteAccessStore/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { TRUSTED_DEVICE_LIMIT } from '../../constants/remote';\nimport type { RemoteAccessSettings, TrustedDeviceRecord } from '../../types/remote';\nimport { poHomeDirectory } from '../piSettings';\nimport {\n DEFAULT_REMOTE_SETTINGS,\n parseRemoteAccessSettings,\n serializeRemoteAccessSettings,\n} from '../remoteAccessSettings';\nimport type { StoredCredential } from '../webauthnPolicy';\n\n/** Where the cockpit keeps machine-local state; `po sync` already writes its bundle here. */\nconst STATE_DIRECTORY = 'web';\nconst SETTINGS_FILE = 'remote-access.json';\nconst CREDENTIALS_FILE = 'credentials.json';\nconst TRUSTED_DEVICES_FILE = 'trusted-devices.json';\nconst TRUSTED_DEVICE_PLATFORMS: ReadonlySet<string> = new Set(['ios', 'android']);\nconst STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;\nconst STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;\nconst MAX_STORED_LABEL = 200;\nconst DIRECTORY_MODE = 0o700;\nconst FILE_MODE = 0o600;\n/** Any bit set for group or other; a state file readable by another account is worth repairing. */\nconst LOOSE_MODE_MASK = 0o077;\n\nexport interface RemoteAccessStoreOptions {\n /** Overridden by --state-dir and by tests; the default is ~/.po/web. */\n stateDir?: string;\n onNotice?: (message: string) => void;\n}\n\nexport interface RemoteAccessStore {\n readonly directory: string;\n settings(): RemoteAccessSettings;\n save(settings: RemoteAccessSettings): void;\n /**\n * Registered passkeys. Public keys only, so the file is not a bearer secret\n * and losing it costs a re-enrolment rather than an account.\n */\n credentials(): readonly StoredCredential[];\n saveCredential(credential: StoredCredential): void;\n removeCredential(id: string): boolean;\n /** Registered native devices. Public keys only, at most `TRUSTED_DEVICE_LIMIT`. */\n trustedDevices(): readonly TrustedDeviceRecord[];\n /** Adds or replaces one record by id. False when a new record would exceed the limit. */\n saveTrustedDevice(record: TrustedDeviceRecord): boolean;\n removeTrustedDevice(id: string): boolean;\n}\n\nexport function defaultRemoteStateDir(homeDir: string = os.homedir()): string {\n return path.join(poHomeDirectory(homeDir), STATE_DIRECTORY);\n}\n\n/**\n * Repairs a state file another account can read.\n *\n * Cheap, and it catches the cases a fresh write never would: a file restored\n * from a backup, copied with a permissive umask, or checked out of somewhere it\n * should not have been.\n */\nfunction tightenMode(filePath: string, notice: (message: string) => void): void {\n try {\n if ((fs.statSync(filePath).mode & LOOSE_MODE_MASK) === 0) return;\n fs.chmodSync(filePath, FILE_MODE);\n notice(`tightened permissions on ${filePath}`);\n } catch {\n // The file is missing or unreadable; the caller's own read reports that.\n }\n}\n\n/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */\nfunction isTrustedDeviceRecord(value: unknown): value is TrustedDeviceRecord {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.id === 'string' &&\n STORED_ID.test(record.id) &&\n typeof record.identityPublicKey === 'string' &&\n STORED_KEY.test(record.identityPublicKey) &&\n typeof record.stepUpPublicKey === 'string' &&\n STORED_KEY.test(record.stepUpPublicKey) &&\n record.identityPublicKey !== record.stepUpPublicKey &&\n typeof record.label === 'string' &&\n record.label.length <= MAX_STORED_LABEL &&\n typeof record.platform === 'string' &&\n TRUSTED_DEVICE_PLATFORMS.has(record.platform) &&\n Number.isFinite(record.createdAt) &&\n Number.isFinite(record.lastSeenAt)\n );\n}\n\n/**\n * Settings and passkeys on disk. Sessions deliberately not.\n *\n * A session is revoked when remote access is switched off, and a hub restart is\n * a switch-off, so persisting one would buy nothing while creating a bearer\n * secret worth stealing. A passkey is the opposite: surviving is its whole\n * point, and what is stored is a public key.\n */\nexport function createRemoteAccessStore(options: RemoteAccessStoreOptions = {}): RemoteAccessStore {\n const directory = options.stateDir ?? defaultRemoteStateDir();\n const notice = options.onNotice ?? ((): void => {});\n const settingsPath = path.join(directory, SETTINGS_FILE);\n const credentialsPath = path.join(directory, CREDENTIALS_FILE);\n const trustedDevicesPath = path.join(directory, TRUSTED_DEVICES_FILE);\n\n let current = load();\n let registered = loadCredentials();\n let trusted = loadTrustedDevices();\n\n function load(): RemoteAccessSettings {\n let raw: string;\n try {\n raw = fs.readFileSync(settingsPath, 'utf8');\n } catch {\n // No file is the normal first run, so this is not worth a notice.\n return DEFAULT_REMOTE_SETTINGS;\n }\n tightenMode(settingsPath, notice);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Left in place rather than rewritten: silently overwriting a file\n // somebody hand-edited is worse than ignoring it for this run.\n notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);\n return DEFAULT_REMOTE_SETTINGS;\n }\n const outcome = parseRemoteAccessSettings(parsed);\n for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);\n return outcome.settings;\n }\n\n function loadCredentials(): StoredCredential[] {\n let raw: string;\n try {\n raw = fs.readFileSync(credentialsPath, 'utf8');\n } catch {\n return [];\n }\n tightenMode(credentialsPath, notice);\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as StoredCredential[]) : [];\n } catch {\n // Fails closed: a half-readable credential file means enrolling again,\n // not guessing which entries survived.\n notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);\n return [];\n }\n }\n\n function loadTrustedDevices(): TrustedDeviceRecord[] {\n let raw: string;\n try {\n raw = fs.readFileSync(trustedDevicesPath, 'utf8');\n } catch {\n return [];\n }\n tightenMode(trustedDevicesPath, notice);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Fails closed like passkeys: a device signs in only from a record read whole.\n notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);\n return [];\n }\n if (!Array.isArray(parsed)) {\n notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);\n return [];\n }\n const loaded: TrustedDeviceRecord[] = [];\n for (const entry of parsed) {\n if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {\n notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);\n continue;\n }\n if (loaded.length >= TRUSTED_DEVICE_LIMIT) {\n notice(\n `dropped trusted devices beyond the limit of ${String(TRUSTED_DEVICE_LIMIT)} from ${trustedDevicesPath}`,\n );\n break;\n }\n loaded.push({\n id: entry.id,\n identityPublicKey: entry.identityPublicKey,\n stepUpPublicKey: entry.stepUpPublicKey,\n label: entry.label,\n platform: entry.platform,\n createdAt: entry.createdAt,\n lastSeenAt: entry.lastSeenAt,\n });\n }\n return loaded;\n }\n\n function writeJson(target: string, body: unknown): void {\n const temporary = `${target}.${String(process.pid)}.tmp`;\n try {\n fs.mkdirSync(directory, { recursive: true, mode: DIRECTORY_MODE });\n fs.writeFileSync(temporary, `${JSON.stringify(body, undefined, 2)}\\n`, { mode: FILE_MODE });\n // Rename rather than write in place, so a crash mid-write leaves the\n // previous contents rather than a truncated file.\n fs.renameSync(temporary, target);\n } catch (error) {\n notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);\n try {\n fs.rmSync(temporary, { force: true });\n } catch {\n // Nothing further to do; the temp file is inert either way.\n }\n }\n }\n\n return {\n directory,\n settings: () => current,\n credentials: () => registered,\n\n saveCredential(credential) {\n registered = [...registered.filter((held) => held.id !== credential.id), credential];\n writeJson(credentialsPath, registered);\n },\n\n removeCredential(id) {\n const next = registered.filter((held) => held.id !== id);\n if (next.length === registered.length) return false;\n registered = next;\n writeJson(credentialsPath, registered);\n return true;\n },\n\n trustedDevices: () => trusted,\n\n saveTrustedDevice(record) {\n const others = trusted.filter((held) => held.id !== record.id);\n if (others.length === trusted.length && trusted.length >= TRUSTED_DEVICE_LIMIT) return false;\n trusted = [...others, record];\n writeJson(trustedDevicesPath, trusted);\n return true;\n },\n\n removeTrustedDevice(id) {\n const next = trusted.filter((held) => held.id !== id);\n if (next.length === trusted.length) return false;\n trusted = next;\n writeJson(trustedDevicesPath, trusted);\n return true;\n },\n\n save(settings) {\n current = settings;\n writeJson(settingsPath, serializeRemoteAccessSettings(settings));\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createSerialRunner"],"sources":["../../../../src/services/remoteAccessStore/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { Context } from '@earendil-works/chord';\nimport { getOrThrow, type FileSystem } from '@earendil-works/pi-durable/env';\n\nimport { TRUSTED_DEVICE_LIMIT } from '../../constants/remote';\nimport type { RemoteAccessSettings, TrustedDeviceRecord } from '../../types/remote';\nimport { nodeHost } from '../nodeHost';\nimport { writeFileAtomic } from '../platformFiles';\nimport { DEFAULT_REMOTE_SETTINGS, serializeRemoteAccessSettings } from '../remoteAccessSettings';\nimport { createSerialRunner } from '../serialRunner';\nimport type { StoredCredential } from '../webauthnPolicy';\nimport {\n CREDENTIALS_FILE,\n defaultRemoteStateDir,\n DIRECTORY_MODE,\n FILE_MODE,\n isLooseMode,\n parseCredentialsFile,\n parseSettingsFile,\n parseTrustedDevicesFile,\n serializeStateFile,\n SETTINGS_FILE,\n TRUSTED_DEVICES_FILE,\n type RemoteAccessStoreOptions,\n} from './remoteAccessRecords';\n\nexport type { RemoteAccessStore, RemoteAccessStoreOptions } from './remoteAccessRecords';\nexport { defaultRemoteStateDir } from './remoteAccessRecords';\nexport { createRemoteAccessStore } from './sync';\n\n/** One queue per state file, so concurrent writes in this process never interleave. */\nconst stateWrites = createSerialRunner();\n\n/** The async twin of `RemoteAccessStore`: reads stay in memory, every write resolves once it is on disk. */\nexport interface RemoteAccessStoreAsync {\n readonly directory: string;\n settings(): RemoteAccessSettings;\n save(settings: RemoteAccessSettings): Promise<void>;\n /** Registered passkeys. Public keys only. */\n credentials(): readonly StoredCredential[];\n saveCredential(credential: StoredCredential): Promise<void>;\n removeCredential(id: string): Promise<boolean>;\n /** Registered native devices. Public keys only, at most `TRUSTED_DEVICE_LIMIT`. */\n trustedDevices(): readonly TrustedDeviceRecord[];\n /** Adds or replaces one record by id. False when a new record would exceed the limit. */\n saveTrustedDevice(record: TrustedDeviceRecord): Promise<boolean>;\n removeTrustedDevice(id: string): Promise<boolean>;\n}\n\n/**\n * Settings and passkeys on disk. Sessions deliberately not.\n *\n * A session is revoked when remote access is switched off, and a hub restart is\n * a switch-off, so persisting one would buy nothing while creating a bearer\n * secret worth stealing. A passkey is the opposite: surviving is its whole\n * point, and what is stored is a public key. A failed write is reported and\n * never thrown, as in the sync store.\n */\nexport async function createRemoteAccessStoreAsync(\n fs: FileSystem,\n options: RemoteAccessStoreOptions,\n context: Context,\n): Promise<RemoteAccessStoreAsync> {\n const directory = options.stateDir ?? defaultRemoteStateDir();\n const notice = options.onNotice ?? ((): void => {});\n const settingsPath = path.join(directory, SETTINGS_FILE);\n const credentialsPath = path.join(directory, CREDENTIALS_FILE);\n const trustedDevicesPath = path.join(directory, TRUSTED_DEVICES_FILE);\n\n const readState = async (filePath: string): Promise<string | undefined> => {\n const raw = await fs.readTextFile(filePath, context);\n // No file is the normal first run, so this is not worth a notice.\n if (!raw.ok) return undefined;\n // Repairs a state file another account can read: a file restored from a backup,\n // copied with a permissive umask, or checked out of somewhere it should not have been.\n try {\n const mode = await nodeHost.fileMode(filePath);\n if (mode !== undefined && isLooseMode(mode)) {\n await nodeHost.setMode(filePath, FILE_MODE);\n notice(`tightened permissions on ${filePath}`);\n }\n } catch {\n // The file vanished or is unreadable between the read and the check; the read above already won.\n }\n return raw.value;\n };\n\n const settingsRaw = await readState(settingsPath);\n let current: RemoteAccessSettings =\n settingsRaw === undefined ? DEFAULT_REMOTE_SETTINGS : parseSettingsFile(settingsRaw, settingsPath, notice);\n const credentialsRaw = await readState(credentialsPath);\n let registered = credentialsRaw === undefined ? [] : parseCredentialsFile(credentialsRaw, credentialsPath, notice);\n const devicesRaw = await readState(trustedDevicesPath);\n let trusted = devicesRaw === undefined ? [] : parseTrustedDevicesFile(devicesRaw, trustedDevicesPath, notice);\n\n const writeJson = async (target: string, body: unknown): Promise<void> => {\n try {\n if (!getOrThrow(await fs.exists(directory, context))) {\n getOrThrow(await fs.createDir(directory, { recursive: true }, context));\n await nodeHost.setMode(directory, DIRECTORY_MODE);\n }\n await writeFileAtomic(fs, target, serializeStateFile(body), context);\n await nodeHost.setMode(target, FILE_MODE);\n } catch (error) {\n notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);\n }\n };\n\n return {\n directory,\n settings: () => current,\n credentials: () => registered,\n\n saveCredential: (credential) =>\n stateWrites.forKey(credentialsPath)(async () => {\n registered = [...registered.filter((held) => held.id !== credential.id), credential];\n await writeJson(credentialsPath, registered);\n }),\n\n removeCredential: (id) =>\n stateWrites.forKey(credentialsPath)(async () => {\n const next = registered.filter((held) => held.id !== id);\n if (next.length === registered.length) return false;\n registered = next;\n await writeJson(credentialsPath, registered);\n return true;\n }),\n\n trustedDevices: () => trusted,\n\n saveTrustedDevice: (record) =>\n stateWrites.forKey(trustedDevicesPath)(async () => {\n const others = trusted.filter((held) => held.id !== record.id);\n if (others.length === trusted.length && trusted.length >= TRUSTED_DEVICE_LIMIT) return false;\n trusted = [...others, record];\n await writeJson(trustedDevicesPath, trusted);\n return true;\n }),\n\n removeTrustedDevice: (id) =>\n stateWrites.forKey(trustedDevicesPath)(async () => {\n const next = trusted.filter((held) => held.id !== id);\n if (next.length === trusted.length) return false;\n trusted = next;\n await writeJson(trustedDevicesPath, trusted);\n return true;\n }),\n\n save: (settings) =>\n stateWrites.forKey(settingsPath)(async () => {\n current = settings;\n await writeJson(settingsPath, serializeRemoteAccessSettings(settings));\n }),\n };\n}\n"],"mappings":";;;;;;;;;AAgCoBA,gBAAAA,mBAAmB"}
|
|
@@ -1,191 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../platformFiles/index.mjs";
|
|
2
|
+
import { createSerialRunner } from "../serialRunner/index.mjs";
|
|
2
3
|
import "../../constants/remote.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
/** Where the cockpit keeps machine-local state; `po sync` already writes its bundle here. */
|
|
9
|
-
const STATE_DIRECTORY = "web";
|
|
10
|
-
const SETTINGS_FILE = "remote-access.json";
|
|
11
|
-
const CREDENTIALS_FILE = "credentials.json";
|
|
12
|
-
const TRUSTED_DEVICES_FILE = "trusted-devices.json";
|
|
13
|
-
const TRUSTED_DEVICE_PLATFORMS = /* @__PURE__ */ new Set(["ios", "android"]);
|
|
14
|
-
const STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
15
|
-
const STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;
|
|
16
|
-
const MAX_STORED_LABEL = 200;
|
|
17
|
-
const DIRECTORY_MODE = 448;
|
|
18
|
-
const FILE_MODE = 384;
|
|
19
|
-
/** Any bit set for group or other; a state file readable by another account is worth repairing. */
|
|
20
|
-
const LOOSE_MODE_MASK = 63;
|
|
21
|
-
function defaultRemoteStateDir(homeDir = os.homedir()) {
|
|
22
|
-
return path.join(poHomeDirectory(homeDir), STATE_DIRECTORY);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Repairs a state file another account can read.
|
|
26
|
-
*
|
|
27
|
-
* Cheap, and it catches the cases a fresh write never would: a file restored
|
|
28
|
-
* from a backup, copied with a permissive umask, or checked out of somewhere it
|
|
29
|
-
* should not have been.
|
|
30
|
-
*/
|
|
31
|
-
function tightenMode(filePath, notice) {
|
|
32
|
-
try {
|
|
33
|
-
if ((fs.statSync(filePath).mode & LOOSE_MODE_MASK) === 0) return;
|
|
34
|
-
fs.chmodSync(filePath, FILE_MODE);
|
|
35
|
-
notice(`tightened permissions on ${filePath}`);
|
|
36
|
-
} catch {}
|
|
37
|
-
}
|
|
38
|
-
/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */
|
|
39
|
-
function isTrustedDeviceRecord(value) {
|
|
40
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
41
|
-
const record = value;
|
|
42
|
-
return typeof record.id === "string" && STORED_ID.test(record.id) && typeof record.identityPublicKey === "string" && STORED_KEY.test(record.identityPublicKey) && typeof record.stepUpPublicKey === "string" && STORED_KEY.test(record.stepUpPublicKey) && record.identityPublicKey !== record.stepUpPublicKey && typeof record.label === "string" && record.label.length <= MAX_STORED_LABEL && typeof record.platform === "string" && TRUSTED_DEVICE_PLATFORMS.has(record.platform) && Number.isFinite(record.createdAt) && Number.isFinite(record.lastSeenAt);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Settings and passkeys on disk. Sessions deliberately not.
|
|
46
|
-
*
|
|
47
|
-
* A session is revoked when remote access is switched off, and a hub restart is
|
|
48
|
-
* a switch-off, so persisting one would buy nothing while creating a bearer
|
|
49
|
-
* secret worth stealing. A passkey is the opposite: surviving is its whole
|
|
50
|
-
* point, and what is stored is a public key.
|
|
51
|
-
*/
|
|
52
|
-
function createRemoteAccessStore(options = {}) {
|
|
53
|
-
const directory = options.stateDir ?? defaultRemoteStateDir();
|
|
54
|
-
const notice = options.onNotice ?? (() => {});
|
|
55
|
-
const settingsPath = path.join(directory, SETTINGS_FILE);
|
|
56
|
-
const credentialsPath = path.join(directory, CREDENTIALS_FILE);
|
|
57
|
-
const trustedDevicesPath = path.join(directory, TRUSTED_DEVICES_FILE);
|
|
58
|
-
let current = load();
|
|
59
|
-
let registered = loadCredentials();
|
|
60
|
-
let trusted = loadTrustedDevices();
|
|
61
|
-
function load() {
|
|
62
|
-
let raw;
|
|
63
|
-
try {
|
|
64
|
-
raw = fs.readFileSync(settingsPath, "utf8");
|
|
65
|
-
} catch {
|
|
66
|
-
return DEFAULT_REMOTE_SETTINGS;
|
|
67
|
-
}
|
|
68
|
-
tightenMode(settingsPath, notice);
|
|
69
|
-
let parsed;
|
|
70
|
-
try {
|
|
71
|
-
parsed = JSON.parse(raw);
|
|
72
|
-
} catch {
|
|
73
|
-
notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);
|
|
74
|
-
return DEFAULT_REMOTE_SETTINGS;
|
|
75
|
-
}
|
|
76
|
-
const outcome = parseRemoteAccessSettings(parsed);
|
|
77
|
-
for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);
|
|
78
|
-
return outcome.settings;
|
|
79
|
-
}
|
|
80
|
-
function loadCredentials() {
|
|
81
|
-
let raw;
|
|
82
|
-
try {
|
|
83
|
-
raw = fs.readFileSync(credentialsPath, "utf8");
|
|
84
|
-
} catch {
|
|
85
|
-
return [];
|
|
86
|
-
}
|
|
87
|
-
tightenMode(credentialsPath, notice);
|
|
88
|
-
try {
|
|
89
|
-
const parsed = JSON.parse(raw);
|
|
90
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
91
|
-
} catch {
|
|
92
|
-
notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function loadTrustedDevices() {
|
|
97
|
-
let raw;
|
|
98
|
-
try {
|
|
99
|
-
raw = fs.readFileSync(trustedDevicesPath, "utf8");
|
|
100
|
-
} catch {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
tightenMode(trustedDevicesPath, notice);
|
|
104
|
-
let parsed;
|
|
105
|
-
try {
|
|
106
|
-
parsed = JSON.parse(raw);
|
|
107
|
-
} catch {
|
|
108
|
-
notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
if (!Array.isArray(parsed)) {
|
|
112
|
-
notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
const loaded = [];
|
|
116
|
-
for (const entry of parsed) {
|
|
117
|
-
if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {
|
|
118
|
-
notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (loaded.length >= 32) {
|
|
122
|
-
notice(`dropped trusted devices beyond the limit of ${String(32)} from ${trustedDevicesPath}`);
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
loaded.push({
|
|
126
|
-
id: entry.id,
|
|
127
|
-
identityPublicKey: entry.identityPublicKey,
|
|
128
|
-
stepUpPublicKey: entry.stepUpPublicKey,
|
|
129
|
-
label: entry.label,
|
|
130
|
-
platform: entry.platform,
|
|
131
|
-
createdAt: entry.createdAt,
|
|
132
|
-
lastSeenAt: entry.lastSeenAt
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
return loaded;
|
|
136
|
-
}
|
|
137
|
-
function writeJson(target, body) {
|
|
138
|
-
const temporary = `${target}.${String(process.pid)}.tmp`;
|
|
139
|
-
try {
|
|
140
|
-
fs.mkdirSync(directory, {
|
|
141
|
-
recursive: true,
|
|
142
|
-
mode: DIRECTORY_MODE
|
|
143
|
-
});
|
|
144
|
-
fs.writeFileSync(temporary, `${JSON.stringify(body, void 0, 2)}\n`, { mode: FILE_MODE });
|
|
145
|
-
fs.renameSync(temporary, target);
|
|
146
|
-
} catch (error) {
|
|
147
|
-
notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
-
try {
|
|
149
|
-
fs.rmSync(temporary, { force: true });
|
|
150
|
-
} catch {}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
directory,
|
|
155
|
-
settings: () => current,
|
|
156
|
-
credentials: () => registered,
|
|
157
|
-
saveCredential(credential) {
|
|
158
|
-
registered = [...registered.filter((held) => held.id !== credential.id), credential];
|
|
159
|
-
writeJson(credentialsPath, registered);
|
|
160
|
-
},
|
|
161
|
-
removeCredential(id) {
|
|
162
|
-
const next = registered.filter((held) => held.id !== id);
|
|
163
|
-
if (next.length === registered.length) return false;
|
|
164
|
-
registered = next;
|
|
165
|
-
writeJson(credentialsPath, registered);
|
|
166
|
-
return true;
|
|
167
|
-
},
|
|
168
|
-
trustedDevices: () => trusted,
|
|
169
|
-
saveTrustedDevice(record) {
|
|
170
|
-
const others = trusted.filter((held) => held.id !== record.id);
|
|
171
|
-
if (others.length === trusted.length && trusted.length >= 32) return false;
|
|
172
|
-
trusted = [...others, record];
|
|
173
|
-
writeJson(trustedDevicesPath, trusted);
|
|
174
|
-
return true;
|
|
175
|
-
},
|
|
176
|
-
removeTrustedDevice(id) {
|
|
177
|
-
const next = trusted.filter((held) => held.id !== id);
|
|
178
|
-
if (next.length === trusted.length) return false;
|
|
179
|
-
trusted = next;
|
|
180
|
-
writeJson(trustedDevicesPath, trusted);
|
|
181
|
-
return true;
|
|
182
|
-
},
|
|
183
|
-
save(settings) {
|
|
184
|
-
current = settings;
|
|
185
|
-
writeJson(settingsPath, serializeRemoteAccessSettings(settings));
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
}
|
|
4
|
+
import { defaultRemoteStateDir } from "./remoteAccessRecords.mjs";
|
|
5
|
+
import { createRemoteAccessStore } from "./sync.mjs";
|
|
6
|
+
import "node:path";
|
|
7
|
+
import "@earendil-works/pi-durable/env";
|
|
8
|
+
createSerialRunner();
|
|
189
9
|
//#endregion
|
|
190
10
|
export { createRemoteAccessStore, defaultRemoteStateDir };
|
|
191
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/remoteAccessStore/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { TRUSTED_DEVICE_LIMIT } from '../../constants/remote';\nimport type { RemoteAccessSettings, TrustedDeviceRecord } from '../../types/remote';\nimport { poHomeDirectory } from '../piSettings';\nimport {\n DEFAULT_REMOTE_SETTINGS,\n parseRemoteAccessSettings,\n serializeRemoteAccessSettings,\n} from '../remoteAccessSettings';\nimport type { StoredCredential } from '../webauthnPolicy';\n\n/** Where the cockpit keeps machine-local state; `po sync` already writes its bundle here. */\nconst STATE_DIRECTORY = 'web';\nconst SETTINGS_FILE = 'remote-access.json';\nconst CREDENTIALS_FILE = 'credentials.json';\nconst TRUSTED_DEVICES_FILE = 'trusted-devices.json';\nconst TRUSTED_DEVICE_PLATFORMS: ReadonlySet<string> = new Set(['ios', 'android']);\nconst STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;\nconst STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;\nconst MAX_STORED_LABEL = 200;\nconst DIRECTORY_MODE = 0o700;\nconst FILE_MODE = 0o600;\n/** Any bit set for group or other; a state file readable by another account is worth repairing. */\nconst LOOSE_MODE_MASK = 0o077;\n\nexport interface RemoteAccessStoreOptions {\n /** Overridden by --state-dir and by tests; the default is ~/.po/web. */\n stateDir?: string;\n onNotice?: (message: string) => void;\n}\n\nexport interface RemoteAccessStore {\n readonly directory: string;\n settings(): RemoteAccessSettings;\n save(settings: RemoteAccessSettings): void;\n /**\n * Registered passkeys. Public keys only, so the file is not a bearer secret\n * and losing it costs a re-enrolment rather than an account.\n */\n credentials(): readonly StoredCredential[];\n saveCredential(credential: StoredCredential): void;\n removeCredential(id: string): boolean;\n /** Registered native devices. Public keys only, at most `TRUSTED_DEVICE_LIMIT`. */\n trustedDevices(): readonly TrustedDeviceRecord[];\n /** Adds or replaces one record by id. False when a new record would exceed the limit. */\n saveTrustedDevice(record: TrustedDeviceRecord): boolean;\n removeTrustedDevice(id: string): boolean;\n}\n\nexport function defaultRemoteStateDir(homeDir: string = os.homedir()): string {\n return path.join(poHomeDirectory(homeDir), STATE_DIRECTORY);\n}\n\n/**\n * Repairs a state file another account can read.\n *\n * Cheap, and it catches the cases a fresh write never would: a file restored\n * from a backup, copied with a permissive umask, or checked out of somewhere it\n * should not have been.\n */\nfunction tightenMode(filePath: string, notice: (message: string) => void): void {\n try {\n if ((fs.statSync(filePath).mode & LOOSE_MODE_MASK) === 0) return;\n fs.chmodSync(filePath, FILE_MODE);\n notice(`tightened permissions on ${filePath}`);\n } catch {\n // The file is missing or unreadable; the caller's own read reports that.\n }\n}\n\n/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */\nfunction isTrustedDeviceRecord(value: unknown): value is TrustedDeviceRecord {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.id === 'string' &&\n STORED_ID.test(record.id) &&\n typeof record.identityPublicKey === 'string' &&\n STORED_KEY.test(record.identityPublicKey) &&\n typeof record.stepUpPublicKey === 'string' &&\n STORED_KEY.test(record.stepUpPublicKey) &&\n record.identityPublicKey !== record.stepUpPublicKey &&\n typeof record.label === 'string' &&\n record.label.length <= MAX_STORED_LABEL &&\n typeof record.platform === 'string' &&\n TRUSTED_DEVICE_PLATFORMS.has(record.platform) &&\n Number.isFinite(record.createdAt) &&\n Number.isFinite(record.lastSeenAt)\n );\n}\n\n/**\n * Settings and passkeys on disk. Sessions deliberately not.\n *\n * A session is revoked when remote access is switched off, and a hub restart is\n * a switch-off, so persisting one would buy nothing while creating a bearer\n * secret worth stealing. A passkey is the opposite: surviving is its whole\n * point, and what is stored is a public key.\n */\nexport function createRemoteAccessStore(options: RemoteAccessStoreOptions = {}): RemoteAccessStore {\n const directory = options.stateDir ?? defaultRemoteStateDir();\n const notice = options.onNotice ?? ((): void => {});\n const settingsPath = path.join(directory, SETTINGS_FILE);\n const credentialsPath = path.join(directory, CREDENTIALS_FILE);\n const trustedDevicesPath = path.join(directory, TRUSTED_DEVICES_FILE);\n\n let current = load();\n let registered = loadCredentials();\n let trusted = loadTrustedDevices();\n\n function load(): RemoteAccessSettings {\n let raw: string;\n try {\n raw = fs.readFileSync(settingsPath, 'utf8');\n } catch {\n // No file is the normal first run, so this is not worth a notice.\n return DEFAULT_REMOTE_SETTINGS;\n }\n tightenMode(settingsPath, notice);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Left in place rather than rewritten: silently overwriting a file\n // somebody hand-edited is worse than ignoring it for this run.\n notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);\n return DEFAULT_REMOTE_SETTINGS;\n }\n const outcome = parseRemoteAccessSettings(parsed);\n for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);\n return outcome.settings;\n }\n\n function loadCredentials(): StoredCredential[] {\n let raw: string;\n try {\n raw = fs.readFileSync(credentialsPath, 'utf8');\n } catch {\n return [];\n }\n tightenMode(credentialsPath, notice);\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as StoredCredential[]) : [];\n } catch {\n // Fails closed: a half-readable credential file means enrolling again,\n // not guessing which entries survived.\n notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);\n return [];\n }\n }\n\n function loadTrustedDevices(): TrustedDeviceRecord[] {\n let raw: string;\n try {\n raw = fs.readFileSync(trustedDevicesPath, 'utf8');\n } catch {\n return [];\n }\n tightenMode(trustedDevicesPath, notice);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Fails closed like passkeys: a device signs in only from a record read whole.\n notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);\n return [];\n }\n if (!Array.isArray(parsed)) {\n notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);\n return [];\n }\n const loaded: TrustedDeviceRecord[] = [];\n for (const entry of parsed) {\n if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {\n notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);\n continue;\n }\n if (loaded.length >= TRUSTED_DEVICE_LIMIT) {\n notice(\n `dropped trusted devices beyond the limit of ${String(TRUSTED_DEVICE_LIMIT)} from ${trustedDevicesPath}`,\n );\n break;\n }\n loaded.push({\n id: entry.id,\n identityPublicKey: entry.identityPublicKey,\n stepUpPublicKey: entry.stepUpPublicKey,\n label: entry.label,\n platform: entry.platform,\n createdAt: entry.createdAt,\n lastSeenAt: entry.lastSeenAt,\n });\n }\n return loaded;\n }\n\n function writeJson(target: string, body: unknown): void {\n const temporary = `${target}.${String(process.pid)}.tmp`;\n try {\n fs.mkdirSync(directory, { recursive: true, mode: DIRECTORY_MODE });\n fs.writeFileSync(temporary, `${JSON.stringify(body, undefined, 2)}\\n`, { mode: FILE_MODE });\n // Rename rather than write in place, so a crash mid-write leaves the\n // previous contents rather than a truncated file.\n fs.renameSync(temporary, target);\n } catch (error) {\n notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);\n try {\n fs.rmSync(temporary, { force: true });\n } catch {\n // Nothing further to do; the temp file is inert either way.\n }\n }\n }\n\n return {\n directory,\n settings: () => current,\n credentials: () => registered,\n\n saveCredential(credential) {\n registered = [...registered.filter((held) => held.id !== credential.id), credential];\n writeJson(credentialsPath, registered);\n },\n\n removeCredential(id) {\n const next = registered.filter((held) => held.id !== id);\n if (next.length === registered.length) return false;\n registered = next;\n writeJson(credentialsPath, registered);\n return true;\n },\n\n trustedDevices: () => trusted,\n\n saveTrustedDevice(record) {\n const others = trusted.filter((held) => held.id !== record.id);\n if (others.length === trusted.length && trusted.length >= TRUSTED_DEVICE_LIMIT) return false;\n trusted = [...others, record];\n writeJson(trustedDevicesPath, trusted);\n return true;\n },\n\n removeTrustedDevice(id) {\n const next = trusted.filter((held) => held.id !== id);\n if (next.length === trusted.length) return false;\n trusted = next;\n writeJson(trustedDevicesPath, trusted);\n return true;\n },\n\n save(settings) {\n current = settings;\n writeJson(settingsPath, serializeRemoteAccessSettings(settings));\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/remoteAccessStore/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { Context } from '@earendil-works/chord';\nimport { getOrThrow, type FileSystem } from '@earendil-works/pi-durable/env';\n\nimport { TRUSTED_DEVICE_LIMIT } from '../../constants/remote';\nimport type { RemoteAccessSettings, TrustedDeviceRecord } from '../../types/remote';\nimport { nodeHost } from '../nodeHost';\nimport { writeFileAtomic } from '../platformFiles';\nimport { DEFAULT_REMOTE_SETTINGS, serializeRemoteAccessSettings } from '../remoteAccessSettings';\nimport { createSerialRunner } from '../serialRunner';\nimport type { StoredCredential } from '../webauthnPolicy';\nimport {\n CREDENTIALS_FILE,\n defaultRemoteStateDir,\n DIRECTORY_MODE,\n FILE_MODE,\n isLooseMode,\n parseCredentialsFile,\n parseSettingsFile,\n parseTrustedDevicesFile,\n serializeStateFile,\n SETTINGS_FILE,\n TRUSTED_DEVICES_FILE,\n type RemoteAccessStoreOptions,\n} from './remoteAccessRecords';\n\nexport type { RemoteAccessStore, RemoteAccessStoreOptions } from './remoteAccessRecords';\nexport { defaultRemoteStateDir } from './remoteAccessRecords';\nexport { createRemoteAccessStore } from './sync';\n\n/** One queue per state file, so concurrent writes in this process never interleave. */\nconst stateWrites = createSerialRunner();\n\n/** The async twin of `RemoteAccessStore`: reads stay in memory, every write resolves once it is on disk. */\nexport interface RemoteAccessStoreAsync {\n readonly directory: string;\n settings(): RemoteAccessSettings;\n save(settings: RemoteAccessSettings): Promise<void>;\n /** Registered passkeys. Public keys only. */\n credentials(): readonly StoredCredential[];\n saveCredential(credential: StoredCredential): Promise<void>;\n removeCredential(id: string): Promise<boolean>;\n /** Registered native devices. Public keys only, at most `TRUSTED_DEVICE_LIMIT`. */\n trustedDevices(): readonly TrustedDeviceRecord[];\n /** Adds or replaces one record by id. False when a new record would exceed the limit. */\n saveTrustedDevice(record: TrustedDeviceRecord): Promise<boolean>;\n removeTrustedDevice(id: string): Promise<boolean>;\n}\n\n/**\n * Settings and passkeys on disk. Sessions deliberately not.\n *\n * A session is revoked when remote access is switched off, and a hub restart is\n * a switch-off, so persisting one would buy nothing while creating a bearer\n * secret worth stealing. A passkey is the opposite: surviving is its whole\n * point, and what is stored is a public key. A failed write is reported and\n * never thrown, as in the sync store.\n */\nexport async function createRemoteAccessStoreAsync(\n fs: FileSystem,\n options: RemoteAccessStoreOptions,\n context: Context,\n): Promise<RemoteAccessStoreAsync> {\n const directory = options.stateDir ?? defaultRemoteStateDir();\n const notice = options.onNotice ?? ((): void => {});\n const settingsPath = path.join(directory, SETTINGS_FILE);\n const credentialsPath = path.join(directory, CREDENTIALS_FILE);\n const trustedDevicesPath = path.join(directory, TRUSTED_DEVICES_FILE);\n\n const readState = async (filePath: string): Promise<string | undefined> => {\n const raw = await fs.readTextFile(filePath, context);\n // No file is the normal first run, so this is not worth a notice.\n if (!raw.ok) return undefined;\n // Repairs a state file another account can read: a file restored from a backup,\n // copied with a permissive umask, or checked out of somewhere it should not have been.\n try {\n const mode = await nodeHost.fileMode(filePath);\n if (mode !== undefined && isLooseMode(mode)) {\n await nodeHost.setMode(filePath, FILE_MODE);\n notice(`tightened permissions on ${filePath}`);\n }\n } catch {\n // The file vanished or is unreadable between the read and the check; the read above already won.\n }\n return raw.value;\n };\n\n const settingsRaw = await readState(settingsPath);\n let current: RemoteAccessSettings =\n settingsRaw === undefined ? DEFAULT_REMOTE_SETTINGS : parseSettingsFile(settingsRaw, settingsPath, notice);\n const credentialsRaw = await readState(credentialsPath);\n let registered = credentialsRaw === undefined ? [] : parseCredentialsFile(credentialsRaw, credentialsPath, notice);\n const devicesRaw = await readState(trustedDevicesPath);\n let trusted = devicesRaw === undefined ? [] : parseTrustedDevicesFile(devicesRaw, trustedDevicesPath, notice);\n\n const writeJson = async (target: string, body: unknown): Promise<void> => {\n try {\n if (!getOrThrow(await fs.exists(directory, context))) {\n getOrThrow(await fs.createDir(directory, { recursive: true }, context));\n await nodeHost.setMode(directory, DIRECTORY_MODE);\n }\n await writeFileAtomic(fs, target, serializeStateFile(body), context);\n await nodeHost.setMode(target, FILE_MODE);\n } catch (error) {\n notice(`${target} could not be saved: ${error instanceof Error ? error.message : String(error)}`);\n }\n };\n\n return {\n directory,\n settings: () => current,\n credentials: () => registered,\n\n saveCredential: (credential) =>\n stateWrites.forKey(credentialsPath)(async () => {\n registered = [...registered.filter((held) => held.id !== credential.id), credential];\n await writeJson(credentialsPath, registered);\n }),\n\n removeCredential: (id) =>\n stateWrites.forKey(credentialsPath)(async () => {\n const next = registered.filter((held) => held.id !== id);\n if (next.length === registered.length) return false;\n registered = next;\n await writeJson(credentialsPath, registered);\n return true;\n }),\n\n trustedDevices: () => trusted,\n\n saveTrustedDevice: (record) =>\n stateWrites.forKey(trustedDevicesPath)(async () => {\n const others = trusted.filter((held) => held.id !== record.id);\n if (others.length === trusted.length && trusted.length >= TRUSTED_DEVICE_LIMIT) return false;\n trusted = [...others, record];\n await writeJson(trustedDevicesPath, trusted);\n return true;\n }),\n\n removeTrustedDevice: (id) =>\n stateWrites.forKey(trustedDevicesPath)(async () => {\n const next = trusted.filter((held) => held.id !== id);\n if (next.length === trusted.length) return false;\n trusted = next;\n await writeJson(trustedDevicesPath, trusted);\n return true;\n }),\n\n save: (settings) =>\n stateWrites.forKey(settingsPath)(async () => {\n current = settings;\n await writeJson(settingsPath, serializeRemoteAccessSettings(settings));\n }),\n };\n}\n"],"mappings":";;;;;;;AAgCoB,mBAAmB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_index = require("../nodeHost/index.cjs");
|
|
3
|
+
const require_core = require("../piSettings/core.cjs");
|
|
4
|
+
require("../../../runtimePiSettings.cjs");
|
|
5
|
+
require("../../constants/remote.cjs");
|
|
6
|
+
const require_index$1 = require("../remoteAccessSettings/index.cjs");
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
node_path = require_runtime.__toESM(node_path, 1);
|
|
9
|
+
const SETTINGS_FILE = "remote-access.json";
|
|
10
|
+
const CREDENTIALS_FILE = "credentials.json";
|
|
11
|
+
const TRUSTED_DEVICES_FILE = "trusted-devices.json";
|
|
12
|
+
const TRUSTED_DEVICE_PLATFORMS = /* @__PURE__ */ new Set(["ios", "android"]);
|
|
13
|
+
const STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
14
|
+
const STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;
|
|
15
|
+
const MAX_STORED_LABEL = 200;
|
|
16
|
+
function defaultRemoteStateDir(homeDir = require_index.nodeHost.homeDirectory()) {
|
|
17
|
+
return node_path.default.join(require_core.poHomeDirectory(homeDir), "web");
|
|
18
|
+
}
|
|
19
|
+
/** Whether a file mode lets another account read the file. */
|
|
20
|
+
function isLooseMode(mode) {
|
|
21
|
+
return (mode & 63) !== 0;
|
|
22
|
+
}
|
|
23
|
+
/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */
|
|
24
|
+
function isTrustedDeviceRecord(value) {
|
|
25
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
26
|
+
const record = value;
|
|
27
|
+
return typeof record.id === "string" && STORED_ID.test(record.id) && typeof record.identityPublicKey === "string" && STORED_KEY.test(record.identityPublicKey) && typeof record.stepUpPublicKey === "string" && STORED_KEY.test(record.stepUpPublicKey) && record.identityPublicKey !== record.stepUpPublicKey && typeof record.label === "string" && record.label.length <= MAX_STORED_LABEL && typeof record.platform === "string" && TRUSTED_DEVICE_PLATFORMS.has(record.platform) && Number.isFinite(record.createdAt) && Number.isFinite(record.lastSeenAt);
|
|
28
|
+
}
|
|
29
|
+
function parseSettingsFile(raw, settingsPath, notice) {
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(raw);
|
|
33
|
+
} catch {
|
|
34
|
+
notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);
|
|
35
|
+
return require_index$1.DEFAULT_REMOTE_SETTINGS;
|
|
36
|
+
}
|
|
37
|
+
const outcome = require_index$1.parseRemoteAccessSettings(parsed);
|
|
38
|
+
for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);
|
|
39
|
+
return outcome.settings;
|
|
40
|
+
}
|
|
41
|
+
function parseCredentialsFile(raw, credentialsPath, notice) {
|
|
42
|
+
try {
|
|
43
|
+
const parsed = JSON.parse(raw);
|
|
44
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
45
|
+
} catch {
|
|
46
|
+
notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function parseTrustedDevicesFile(raw, trustedDevicesPath, notice) {
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = JSON.parse(raw);
|
|
54
|
+
} catch {
|
|
55
|
+
notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
if (!Array.isArray(parsed)) {
|
|
59
|
+
notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
const loaded = [];
|
|
63
|
+
for (const entry of parsed) {
|
|
64
|
+
if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {
|
|
65
|
+
notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (loaded.length >= 32) {
|
|
69
|
+
notice(`dropped trusted devices beyond the limit of ${String(32)} from ${trustedDevicesPath}`);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
loaded.push({
|
|
73
|
+
id: entry.id,
|
|
74
|
+
identityPublicKey: entry.identityPublicKey,
|
|
75
|
+
stepUpPublicKey: entry.stepUpPublicKey,
|
|
76
|
+
label: entry.label,
|
|
77
|
+
platform: entry.platform,
|
|
78
|
+
createdAt: entry.createdAt,
|
|
79
|
+
lastSeenAt: entry.lastSeenAt
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return loaded;
|
|
83
|
+
}
|
|
84
|
+
function serializeStateFile(body) {
|
|
85
|
+
return `${JSON.stringify(body, void 0, 2)}\n`;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
exports.CREDENTIALS_FILE = CREDENTIALS_FILE;
|
|
89
|
+
exports.SETTINGS_FILE = SETTINGS_FILE;
|
|
90
|
+
exports.TRUSTED_DEVICES_FILE = TRUSTED_DEVICES_FILE;
|
|
91
|
+
exports.defaultRemoteStateDir = defaultRemoteStateDir;
|
|
92
|
+
exports.isLooseMode = isLooseMode;
|
|
93
|
+
exports.parseCredentialsFile = parseCredentialsFile;
|
|
94
|
+
exports.parseSettingsFile = parseSettingsFile;
|
|
95
|
+
exports.parseTrustedDevicesFile = parseTrustedDevicesFile;
|
|
96
|
+
exports.serializeStateFile = serializeStateFile;
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=remoteAccessRecords.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remoteAccessRecords.cjs","names":["nodeHost","path","poHomeDirectory","DEFAULT_REMOTE_SETTINGS","parseRemoteAccessSettings"],"sources":["../../../../src/services/remoteAccessStore/remoteAccessRecords.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { TRUSTED_DEVICE_LIMIT } from '../../constants/remote';\nimport type { RemoteAccessSettings, TrustedDeviceRecord } from '../../types/remote';\nimport { nodeHost } from '../nodeHost';\nimport { poHomeDirectory } from '../piSettings';\nimport { DEFAULT_REMOTE_SETTINGS, parseRemoteAccessSettings } from '../remoteAccessSettings';\nimport type { StoredCredential } from '../webauthnPolicy';\n\n/** Where the cockpit keeps machine-local state; `po sync` already writes its bundle here. */\nexport const STATE_DIRECTORY = 'web';\nexport const SETTINGS_FILE = 'remote-access.json';\nexport const CREDENTIALS_FILE = 'credentials.json';\nexport const TRUSTED_DEVICES_FILE = 'trusted-devices.json';\nconst TRUSTED_DEVICE_PLATFORMS: ReadonlySet<string> = new Set(['ios', 'android']);\nconst STORED_ID = /^[A-Za-z0-9_-]{1,64}$/u;\nconst STORED_KEY = /^[A-Za-z0-9_-]{1,512}$/u;\nconst MAX_STORED_LABEL = 200;\nexport const DIRECTORY_MODE = 0o700;\nexport const FILE_MODE = 0o600;\n/** Any bit set for group or other; a state file readable by another account is worth repairing. */\nexport const LOOSE_MODE_MASK = 0o077;\n\nexport interface RemoteAccessStoreOptions {\n /** Overridden by --state-dir and by tests; the default is ~/.po/web. */\n stateDir?: string;\n onNotice?: (message: string) => void;\n}\n\nexport interface RemoteAccessStore {\n readonly directory: string;\n settings(): RemoteAccessSettings;\n save(settings: RemoteAccessSettings): void;\n /**\n * Registered passkeys. Public keys only, so the file is not a bearer secret\n * and losing it costs a re-enrolment rather than an account.\n */\n credentials(): readonly StoredCredential[];\n saveCredential(credential: StoredCredential): void;\n removeCredential(id: string): boolean;\n /** Registered native devices. Public keys only, at most `TRUSTED_DEVICE_LIMIT`. */\n trustedDevices(): readonly TrustedDeviceRecord[];\n /** Adds or replaces one record by id. False when a new record would exceed the limit. */\n saveTrustedDevice(record: TrustedDeviceRecord): boolean;\n removeTrustedDevice(id: string): boolean;\n}\n\nexport function defaultRemoteStateDir(homeDir: string = nodeHost.homeDirectory()): string {\n return path.join(poHomeDirectory(homeDir), STATE_DIRECTORY);\n}\n\n/** Whether a file mode lets another account read the file. */\nexport function isLooseMode(mode: number): boolean {\n return (mode & LOOSE_MODE_MASK) !== 0;\n}\n\n/** Whether one parsed entry is a complete trusted-device record; anything else is dropped. */\nfunction isTrustedDeviceRecord(value: unknown): value is TrustedDeviceRecord {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.id === 'string' &&\n STORED_ID.test(record.id) &&\n typeof record.identityPublicKey === 'string' &&\n STORED_KEY.test(record.identityPublicKey) &&\n typeof record.stepUpPublicKey === 'string' &&\n STORED_KEY.test(record.stepUpPublicKey) &&\n record.identityPublicKey !== record.stepUpPublicKey &&\n typeof record.label === 'string' &&\n record.label.length <= MAX_STORED_LABEL &&\n typeof record.platform === 'string' &&\n TRUSTED_DEVICE_PLATFORMS.has(record.platform) &&\n Number.isFinite(record.createdAt) &&\n Number.isFinite(record.lastSeenAt)\n );\n}\n\nexport function parseSettingsFile(\n raw: string,\n settingsPath: string,\n notice: (message: string) => void,\n): RemoteAccessSettings {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Left in place rather than rewritten: silently overwriting a file\n // somebody hand-edited is worse than ignoring it for this run.\n notice(`remote access settings at ${settingsPath} are not valid JSON; using defaults`);\n return DEFAULT_REMOTE_SETTINGS;\n }\n const outcome = parseRemoteAccessSettings(parsed);\n for (const warning of outcome.warnings) notice(`remote access settings: ${warning}`);\n return outcome.settings;\n}\n\nexport function parseCredentialsFile(\n raw: string,\n credentialsPath: string,\n notice: (message: string) => void,\n): StoredCredential[] {\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as StoredCredential[]) : [];\n } catch {\n // Fails closed: a half-readable credential file means enrolling again,\n // not guessing which entries survived.\n notice(`registered passkeys at ${credentialsPath} are not valid JSON; none will load`);\n return [];\n }\n}\n\nexport function parseTrustedDevicesFile(\n raw: string,\n trustedDevicesPath: string,\n notice: (message: string) => void,\n): TrustedDeviceRecord[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Fails closed like passkeys: a device signs in only from a record read whole.\n notice(`trusted devices at ${trustedDevicesPath} are not valid JSON; none will load`);\n return [];\n }\n if (!Array.isArray(parsed)) {\n notice(`trusted devices at ${trustedDevicesPath} are not a list; none will load`);\n return [];\n }\n const loaded: TrustedDeviceRecord[] = [];\n for (const entry of parsed) {\n if (!isTrustedDeviceRecord(entry) || loaded.some((held) => held.id === entry.id)) {\n notice(`dropped an invalid trusted device record from ${trustedDevicesPath}`);\n continue;\n }\n if (loaded.length >= TRUSTED_DEVICE_LIMIT) {\n notice(`dropped trusted devices beyond the limit of ${String(TRUSTED_DEVICE_LIMIT)} from ${trustedDevicesPath}`);\n break;\n }\n loaded.push({\n id: entry.id,\n identityPublicKey: entry.identityPublicKey,\n stepUpPublicKey: entry.stepUpPublicKey,\n label: entry.label,\n platform: entry.platform,\n createdAt: entry.createdAt,\n lastSeenAt: entry.lastSeenAt,\n });\n }\n return loaded;\n}\n\nexport function serializeStateFile(body: unknown): string {\n return `${JSON.stringify(body, undefined, 2)}\\n`;\n}\n"],"mappings":";;;;;;;;AAWA,MAAa,gBAAgB;AAC7B,MAAa,mBAAmB;AAChC,MAAa,uBAAuB;AACpC,MAAM,2CAAgD,IAAI,IAAI,CAAC,OAAO,SAAS,CAAC;AAChF,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,mBAAmB;AA8BzB,SAAgB,sBAAsB,UAAkBA,cAAAA,SAAS,cAAc,GAAW;CACxF,OAAOC,UAAAA,QAAK,KAAKC,aAAAA,gBAAgB,OAAO,GAAA,KAAkB;AAC5D;;AAGA,SAAgB,YAAY,MAAuB;CACjD,QAAQ,OAAA,QAA4B;AACtC;;AAGA,SAAS,sBAAsB,OAA8C;CAC3E,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG,OAAO;CAChF,MAAM,SAAS;CACf,OACE,OAAO,OAAO,OAAO,YACrB,UAAU,KAAK,OAAO,EAAE,KACxB,OAAO,OAAO,sBAAsB,YACpC,WAAW,KAAK,OAAO,iBAAiB,KACxC,OAAO,OAAO,oBAAoB,YAClC,WAAW,KAAK,OAAO,eAAe,KACtC,OAAO,sBAAsB,OAAO,mBACpC,OAAO,OAAO,UAAU,YACxB,OAAO,MAAM,UAAU,oBACvB,OAAO,OAAO,aAAa,YAC3B,yBAAyB,IAAI,OAAO,QAAQ,KAC5C,OAAO,SAAS,OAAO,SAAS,KAChC,OAAO,SAAS,OAAO,UAAU;AAErC;AAEA,SAAgB,kBACd,KACA,cACA,QACsB;CACtB,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,GAAG;CACzB,QAAQ;EAGN,OAAO,6BAA6B,aAAa,oCAAoC;EACrF,OAAOC,gBAAAA;CACT;CACA,MAAM,UAAUC,gBAAAA,0BAA0B,MAAM;CAChD,KAAK,MAAM,WAAW,QAAQ,UAAU,OAAO,2BAA2B,SAAS;CACnF,OAAO,QAAQ;AACjB;AAEA,SAAgB,qBACd,KACA,iBACA,QACoB;CACpB,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,GAAG;EACtC,OAAO,MAAM,QAAQ,MAAM,IAAK,SAAgC,CAAC;CACnE,QAAQ;EAGN,OAAO,0BAA0B,gBAAgB,oCAAoC;EACrF,OAAO,CAAC;CACV;AACF;AAEA,SAAgB,wBACd,KACA,oBACA,QACuB;CACvB,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,GAAG;CACzB,QAAQ;EAEN,OAAO,sBAAsB,mBAAmB,oCAAoC;EACpF,OAAO,CAAC;CACV;CACA,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;EAC1B,OAAO,sBAAsB,mBAAmB,gCAAgC;EAChF,OAAO,CAAC;CACV;CACA,MAAM,SAAgC,CAAC;CACvC,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,sBAAsB,KAAK,KAAK,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,EAAE,GAAG;GAChF,OAAO,iDAAiD,oBAAoB;GAC5E;EACF;EACA,IAAI,OAAO,UAAA,IAAgC;GACzC,OAAO,+CAA+C,OAAA,EAA2B,EAAE,QAAQ,oBAAoB;GAC/G;EACF;EACA,OAAO,KAAK;GACV,IAAI,MAAM;GACV,mBAAmB,MAAM;GACzB,iBAAiB,MAAM;GACvB,OAAO,MAAM;GACb,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,YAAY,MAAM;EACpB,CAAC;CACH;CACA,OAAO;AACT;AAEA,SAAgB,mBAAmB,MAAuB;CACxD,OAAO,GAAG,KAAK,UAAU,MAAM,KAAA,GAAW,CAAC,EAAE;AAC/C"}
|