@decibelsystems/tools 2.2.0-beta.0 → 3.1.0
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/CHANGELOG.md +226 -0
- package/dist/agentCommands.d.ts +0 -1
- package/dist/agentCommands.d.ts.map +1 -1
- package/dist/agentCommands.js +19 -8
- package/dist/agentCommands.js.map +1 -1
- package/dist/agentPresence.d.ts +82 -0
- package/dist/agentPresence.d.ts.map +1 -1
- package/dist/agentPresence.js +194 -26
- package/dist/agentPresence.js.map +1 -1
- package/dist/agentic/index.d.ts +18 -8
- package/dist/agentic/index.d.ts.map +1 -1
- package/dist/agentic/index.js +18 -144
- package/dist/agentic/index.js.map +1 -1
- package/dist/agentic/types.d.ts +106 -0
- package/dist/agentic/types.d.ts.map +1 -1
- package/dist/agentic/types.js +77 -1
- package/dist/agentic/types.js.map +1 -1
- package/dist/architectAdrs.d.ts +27 -3
- package/dist/architectAdrs.d.ts.map +1 -1
- package/dist/architectAdrs.js +92 -4
- package/dist/architectAdrs.js.map +1 -1
- package/dist/artifacts.d.ts +60 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +208 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/asks.d.ts +93 -0
- package/dist/asks.d.ts.map +1 -0
- package/dist/asks.js +383 -0
- package/dist/asks.js.map +1 -0
- package/dist/chat.d.ts +47 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +288 -0
- package/dist/chat.js.map +1 -0
- package/dist/client/transports.d.ts.map +1 -1
- package/dist/client/transports.js +13 -3
- package/dist/client/transports.js.map +1 -1
- package/dist/daemon.d.ts +33 -3
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +225 -52
- package/dist/daemon.js.map +1 -1
- package/dist/daemonConfig.d.ts +46 -0
- package/dist/daemonConfig.d.ts.map +1 -1
- package/dist/daemonConfig.js +57 -12
- package/dist/daemonConfig.js.map +1 -1
- package/dist/decibelPaths.d.ts.map +1 -1
- package/dist/decibelPaths.js +39 -6
- package/dist/decibelPaths.js.map +1 -1
- package/dist/domain/issue.d.ts +81 -0
- package/dist/domain/issue.d.ts.map +1 -0
- package/dist/domain/issue.js +106 -0
- package/dist/domain/issue.js.map +1 -0
- package/dist/domain/issueCodec.d.ts +39 -0
- package/dist/domain/issueCodec.d.ts.map +1 -0
- package/dist/domain/issueCodec.js +308 -0
- package/dist/domain/issueCodec.js.map +1 -0
- package/dist/domain/issueRepository.d.ts +124 -0
- package/dist/domain/issueRepository.d.ts.map +1 -0
- package/dist/domain/issueRepository.js +296 -0
- package/dist/domain/issueRepository.js.map +1 -0
- package/dist/domain/uid.d.ts +16 -0
- package/dist/domain/uid.d.ts.map +1 -0
- package/dist/domain/uid.js +43 -0
- package/dist/domain/uid.js.map +1 -0
- package/dist/facades/definitions.d.ts +0 -1
- package/dist/facades/definitions.d.ts.map +1 -1
- package/dist/facades/definitions.js +140 -116
- package/dist/facades/definitions.js.map +1 -1
- package/dist/facades/index.d.ts +2 -1
- package/dist/facades/index.d.ts.map +1 -1
- package/dist/facades/index.js +1 -1
- package/dist/facades/index.js.map +1 -1
- package/dist/facades/types.d.ts +17 -0
- package/dist/facades/types.d.ts.map +1 -1
- package/dist/hq/defineAgent.d.ts.map +1 -1
- package/dist/hq/defineAgent.js +7 -11
- package/dist/hq/defineAgent.js.map +1 -1
- package/dist/httpArgs.d.ts +11 -0
- package/dist/httpArgs.d.ts.map +1 -0
- package/dist/httpArgs.js +39 -0
- package/dist/httpArgs.js.map +1 -0
- package/dist/httpServer.d.ts +1 -12
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +298 -144
- package/dist/httpServer.js.map +1 -1
- package/dist/identity.d.ts +123 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +312 -0
- package/dist/identity.js.map +1 -0
- package/dist/kernel.d.ts +46 -1
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +334 -26
- package/dist/kernel.js.map +1 -1
- package/dist/killSwitch.d.ts +117 -0
- package/dist/killSwitch.d.ts.map +1 -0
- package/dist/killSwitch.js +161 -0
- package/dist/killSwitch.js.map +1 -0
- package/dist/lib/agent-services/assumptions.d.ts.map +1 -1
- package/dist/lib/agent-services/assumptions.js +8 -2
- package/dist/lib/agent-services/assumptions.js.map +1 -1
- package/dist/lib/atomicWrite.d.ts +49 -0
- package/dist/lib/atomicWrite.d.ts.map +1 -0
- package/dist/lib/atomicWrite.js +157 -0
- package/dist/lib/atomicWrite.js.map +1 -0
- package/dist/lib/envelope.d.ts +31 -0
- package/dist/lib/envelope.d.ts.map +1 -0
- package/dist/lib/envelope.js +80 -0
- package/dist/lib/envelope.js.map +1 -0
- package/dist/lib/fileLock.d.ts +38 -0
- package/dist/lib/fileLock.d.ts.map +1 -0
- package/dist/lib/fileLock.js +124 -0
- package/dist/lib/fileLock.js.map +1 -0
- package/dist/lib/recordIdAllocator.d.ts +102 -0
- package/dist/lib/recordIdAllocator.d.ts.map +1 -0
- package/dist/lib/recordIdAllocator.js +179 -0
- package/dist/lib/recordIdAllocator.js.map +1 -0
- package/dist/orgId.d.ts +23 -0
- package/dist/orgId.d.ts.map +1 -0
- package/dist/orgId.js +73 -0
- package/dist/orgId.js.map +1 -0
- package/dist/pairCli.d.ts +2 -0
- package/dist/pairCli.d.ts.map +1 -0
- package/dist/pairCli.js +97 -0
- package/dist/pairCli.js.map +1 -0
- package/dist/peerBroker.d.ts +40 -0
- package/dist/peerBroker.d.ts.map +1 -0
- package/dist/peerBroker.js +70 -0
- package/dist/peerBroker.js.map +1 -0
- package/dist/peerBrokerSupervisor.d.ts +21 -0
- package/dist/peerBrokerSupervisor.d.ts.map +1 -0
- package/dist/peerBrokerSupervisor.js +131 -0
- package/dist/peerBrokerSupervisor.js.map +1 -0
- package/dist/projectPaths.d.ts.map +1 -1
- package/dist/projectPaths.js +1 -19
- package/dist/projectPaths.js.map +1 -1
- package/dist/projectRegistry.d.ts +22 -0
- package/dist/projectRegistry.d.ts.map +1 -1
- package/dist/projectRegistry.js +69 -2
- package/dist/projectRegistry.js.map +1 -1
- package/dist/pty/boundary.d.ts +39 -0
- package/dist/pty/boundary.d.ts.map +1 -0
- package/dist/pty/boundary.js +100 -0
- package/dist/pty/boundary.js.map +1 -0
- package/dist/pty/errors.d.ts +6 -0
- package/dist/pty/errors.d.ts.map +1 -0
- package/dist/pty/errors.js +12 -0
- package/dist/pty/errors.js.map +1 -0
- package/dist/pty/fleet.d.ts +159 -0
- package/dist/pty/fleet.d.ts.map +1 -0
- package/dist/pty/fleet.js +543 -0
- package/dist/pty/fleet.js.map +1 -0
- package/dist/pty/launchProfile.d.ts +45 -0
- package/dist/pty/launchProfile.d.ts.map +1 -0
- package/dist/pty/launchProfile.js +149 -0
- package/dist/pty/launchProfile.js.map +1 -0
- package/dist/pty/openTerminal.d.ts +48 -0
- package/dist/pty/openTerminal.d.ts.map +1 -0
- package/dist/pty/openTerminal.js +185 -0
- package/dist/pty/openTerminal.js.map +1 -0
- package/dist/pty/pairDialog.d.ts +16 -0
- package/dist/pty/pairDialog.d.ts.map +1 -0
- package/dist/pty/pairDialog.js +121 -0
- package/dist/pty/pairDialog.js.map +1 -0
- package/dist/pty/pairing.d.ts +86 -0
- package/dist/pty/pairing.d.ts.map +1 -0
- package/dist/pty/pairing.js +351 -0
- package/dist/pty/pairing.js.map +1 -0
- package/dist/pty/routes.d.ts +49 -0
- package/dist/pty/routes.d.ts.map +1 -0
- package/dist/pty/routes.js +624 -0
- package/dist/pty/routes.js.map +1 -0
- package/dist/pty/sessions.d.ts +167 -0
- package/dist/pty/sessions.d.ts.map +1 -0
- package/dist/pty/sessions.js +513 -0
- package/dist/pty/sessions.js.map +1 -0
- package/dist/pty/tmux.d.ts +109 -0
- package/dist/pty/tmux.d.ts.map +1 -0
- package/dist/pty/tmux.js +271 -0
- package/dist/pty/tmux.js.map +1 -0
- package/dist/roster.d.ts +37 -0
- package/dist/roster.d.ts.map +1 -0
- package/dist/roster.js +126 -0
- package/dist/roster.js.map +1 -0
- package/dist/runtime/circuitBreaker.d.ts +95 -0
- package/dist/runtime/circuitBreaker.d.ts.map +1 -0
- package/dist/runtime/circuitBreaker.js +178 -0
- package/dist/runtime/circuitBreaker.js.map +1 -0
- package/dist/runtime/daemonMeta.d.ts +53 -0
- package/dist/runtime/daemonMeta.d.ts.map +1 -0
- package/dist/runtime/daemonMeta.js +121 -0
- package/dist/runtime/daemonMeta.js.map +1 -0
- package/dist/runtime/ensureRuntime.d.ts +103 -0
- package/dist/runtime/ensureRuntime.d.ts.map +1 -0
- package/dist/runtime/ensureRuntime.js +276 -0
- package/dist/runtime/ensureRuntime.js.map +1 -0
- package/dist/runtime/extensions.d.ts +57 -0
- package/dist/runtime/extensions.d.ts.map +1 -0
- package/dist/runtime/extensions.js +216 -0
- package/dist/runtime/extensions.js.map +1 -0
- package/dist/runtime/localHttp.d.ts +24 -0
- package/dist/runtime/localHttp.d.ts.map +1 -0
- package/dist/runtime/localHttp.js +84 -0
- package/dist/runtime/localHttp.js.map +1 -0
- package/dist/runtime/projectResolution.d.ts +29 -0
- package/dist/runtime/projectResolution.d.ts.map +1 -0
- package/dist/runtime/projectResolution.js +67 -0
- package/dist/runtime/projectResolution.js.map +1 -0
- package/dist/runtime/protocol.d.ts +62 -0
- package/dist/runtime/protocol.d.ts.map +1 -0
- package/dist/runtime/protocol.js +74 -0
- package/dist/runtime/protocol.js.map +1 -0
- package/dist/sentinelIssues.d.ts +42 -2
- package/dist/sentinelIssues.d.ts.map +1 -1
- package/dist/sentinelIssues.js +167 -65
- package/dist/sentinelIssues.js.map +1 -1
- package/dist/server.js +123 -15
- package/dist/server.js.map +1 -1
- package/dist/toolConfig.d.ts.map +1 -1
- package/dist/toolConfig.js +12 -0
- package/dist/toolConfig.js.map +1 -1
- package/dist/tools/agentic/agentQueue.d.ts.map +1 -1
- package/dist/tools/agentic/agentQueue.js +4 -0
- package/dist/tools/agentic/agentQueue.js.map +1 -1
- package/dist/tools/agentic/index.d.ts.map +1 -1
- package/dist/tools/agentic/index.js +28 -2
- package/dist/tools/agentic/index.js.map +1 -1
- package/dist/tools/architect/index.d.ts +1 -0
- package/dist/tools/architect/index.d.ts.map +1 -1
- package/dist/tools/architect/index.js +52 -3
- package/dist/tools/architect/index.js.map +1 -1
- package/dist/tools/architect.d.ts.map +1 -1
- package/dist/tools/architect.js +59 -8
- package/dist/tools/architect.js.map +1 -1
- package/dist/tools/artifacts.d.ts +5 -0
- package/dist/tools/artifacts.d.ts.map +1 -0
- package/dist/tools/artifacts.js +89 -0
- package/dist/tools/artifacts.js.map +1 -0
- package/dist/tools/asks.d.ts +6 -0
- package/dist/tools/asks.d.ts.map +1 -0
- package/dist/tools/asks.js +104 -0
- package/dist/tools/asks.js.map +1 -0
- package/dist/tools/context.d.ts +10 -5
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +45 -18
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
- package/dist/tools/coordinator/coordinator.js +48 -19
- package/dist/tools/coordinator/coordinator.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts +1 -0
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +42 -2
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/crit.d.ts +2 -1
- package/dist/tools/crit.d.ts.map +1 -1
- package/dist/tools/crit.js +19 -4
- package/dist/tools/crit.js.map +1 -1
- package/dist/tools/data-inspector.d.ts +1 -1
- package/dist/tools/data-inspector.d.ts.map +1 -1
- package/dist/tools/data-inspector.js +1 -1
- package/dist/tools/data-inspector.js.map +1 -1
- package/dist/tools/designer/index.d.ts.map +1 -1
- package/dist/tools/designer/index.js +4 -3
- package/dist/tools/designer/index.js.map +1 -1
- package/dist/tools/designer/lateral-tools.d.ts.map +1 -1
- package/dist/tools/designer/lateral-tools.js +4 -2
- package/dist/tools/designer/lateral-tools.js.map +1 -1
- package/dist/tools/designer.d.ts +2 -1
- package/dist/tools/designer.d.ts.map +1 -1
- package/dist/tools/designer.js +24 -12
- package/dist/tools/designer.js.map +1 -1
- package/dist/tools/dojo/index.d.ts.map +1 -1
- package/dist/tools/dojo/index.js +52 -3
- package/dist/tools/dojo/index.js.map +1 -1
- package/dist/tools/dojo.d.ts +65 -3
- package/dist/tools/dojo.d.ts.map +1 -1
- package/dist/tools/dojo.js +148 -23
- package/dist/tools/dojo.js.map +1 -1
- package/dist/tools/friction.d.ts.map +1 -1
- package/dist/tools/friction.js +16 -6
- package/dist/tools/friction.js.map +1 -1
- package/dist/tools/guardian.d.ts +7 -0
- package/dist/tools/guardian.d.ts.map +1 -1
- package/dist/tools/guardian.js +152 -11
- package/dist/tools/guardian.js.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.js +8 -2
- package/dist/tools/hygiene/oracle-hygiene.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +33 -18
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/killswitch/index.d.ts +13 -0
- package/dist/tools/killswitch/index.d.ts.map +1 -0
- package/dist/tools/killswitch/index.js +138 -0
- package/dist/tools/killswitch/index.js.map +1 -0
- package/dist/tools/learnings.d.ts +2 -1
- package/dist/tools/learnings.d.ts.map +1 -1
- package/dist/tools/learnings.js +31 -15
- package/dist/tools/learnings.js.map +1 -1
- package/dist/tools/oracle/index.d.ts.map +1 -1
- package/dist/tools/oracle/index.js +8 -0
- package/dist/tools/oracle/index.js.map +1 -1
- package/dist/tools/oracle.d.ts +7 -0
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +41 -12
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/policy.d.ts +2 -1
- package/dist/tools/policy.d.ts.map +1 -1
- package/dist/tools/policy.js +28 -9
- package/dist/tools/policy.js.map +1 -1
- package/dist/tools/postoffice/index.d.ts +10 -0
- package/dist/tools/postoffice/index.d.ts.map +1 -0
- package/dist/tools/postoffice/index.js +218 -0
- package/dist/tools/postoffice/index.js.map +1 -0
- package/dist/tools/postoffice.d.ts +78 -0
- package/dist/tools/postoffice.d.ts.map +1 -0
- package/dist/tools/postoffice.js +199 -0
- package/dist/tools/postoffice.js.map +1 -0
- package/dist/tools/provenance.d.ts +18 -2
- package/dist/tools/provenance.d.ts.map +1 -1
- package/dist/tools/provenance.js +68 -40
- package/dist/tools/provenance.js.map +1 -1
- package/dist/tools/registry/index.d.ts.map +1 -1
- package/dist/tools/registry/index.js +24 -0
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/sentinel/index.d.ts +1 -0
- package/dist/tools/sentinel/index.d.ts.map +1 -1
- package/dist/tools/sentinel/index.js +142 -6
- package/dist/tools/sentinel/index.js.map +1 -1
- package/dist/tools/sentinel.d.ts +152 -1
- package/dist/tools/sentinel.d.ts.map +1 -1
- package/dist/tools/sentinel.js +609 -328
- package/dist/tools/sentinel.js.map +1 -1
- package/dist/tools/shared/index.d.ts +2 -1
- package/dist/tools/shared/index.d.ts.map +1 -1
- package/dist/tools/shared/index.js +2 -1
- package/dist/tools/shared/index.js.map +1 -1
- package/dist/tools/shared/response.d.ts +24 -0
- package/dist/tools/shared/response.d.ts.map +1 -1
- package/dist/tools/shared/response.js +61 -7
- package/dist/tools/shared/response.js.map +1 -1
- package/dist/tools/shared/runTracker.d.ts +2 -0
- package/dist/tools/shared/runTracker.d.ts.map +1 -1
- package/dist/tools/shared/runTracker.js +38 -0
- package/dist/tools/shared/runTracker.js.map +1 -1
- package/dist/tools/shared/storeRead.d.ts +153 -0
- package/dist/tools/shared/storeRead.d.ts.map +1 -0
- package/dist/tools/shared/storeRead.js +242 -0
- package/dist/tools/shared/storeRead.js.map +1 -0
- package/dist/tools/swarm.d.ts +3 -1
- package/dist/tools/swarm.d.ts.map +1 -1
- package/dist/tools/swarm.js +6 -12
- package/dist/tools/swarm.js.map +1 -1
- package/dist/tools/testSpec.d.ts +3 -2
- package/dist/tools/testSpec.d.ts.map +1 -1
- package/dist/tools/testSpec.js +51 -14
- package/dist/tools/testSpec.js.map +1 -1
- package/dist/tools/vector.d.ts +33 -1
- package/dist/tools/vector.d.ts.map +1 -1
- package/dist/tools/vector.js +31 -5
- package/dist/tools/vector.js.map +1 -1
- package/dist/tools/voice/index.d.ts +1 -0
- package/dist/tools/voice/index.d.ts.map +1 -1
- package/dist/tools/voice/index.js +33 -2
- package/dist/tools/voice/index.js.map +1 -1
- package/dist/tools/voice.d.ts +48 -1
- package/dist/tools/voice.d.ts.map +1 -1
- package/dist/tools/voice.js +63 -3
- package/dist/tools/voice.js.map +1 -1
- package/dist/tools/zoom/index.d.ts +15 -0
- package/dist/tools/zoom/index.d.ts.map +1 -0
- package/dist/tools/zoom/index.js +174 -0
- package/dist/tools/zoom/index.js.map +1 -0
- package/dist/tools/zoom.d.ts +234 -0
- package/dist/tools/zoom.d.ts.map +1 -0
- package/dist/tools/zoom.js +627 -0
- package/dist/tools/zoom.js.map +1 -0
- package/dist/transports/bridge.d.ts +1 -1
- package/dist/transports/bridge.d.ts.map +1 -1
- package/dist/transports/bridge.js +4 -1
- package/dist/transports/bridge.js.map +1 -1
- package/dist/transports/http.d.ts +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +3 -1
- package/dist/transports/http.js.map +1 -1
- package/dist/transports/index.d.ts +1 -0
- package/dist/transports/index.d.ts.map +1 -1
- package/dist/transports/index.js +1 -0
- package/dist/transports/index.js.map +1 -1
- package/dist/transports/mcp.d.ts +1 -1
- package/dist/transports/mcp.d.ts.map +1 -1
- package/dist/transports/mcp.js +9 -4
- package/dist/transports/mcp.js.map +1 -1
- package/dist/transports/stdio.d.ts +1 -1
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +2 -0
- package/dist/transports/stdio.js.map +1 -1
- package/dist/transports/thinStdio.d.ts +22 -0
- package/dist/transports/thinStdio.d.ts.map +1 -0
- package/dist/transports/thinStdio.js +218 -0
- package/dist/transports/thinStdio.js.map +1 -0
- package/dist/transports/types.d.ts +8 -1
- package/dist/transports/types.d.ts.map +1 -1
- package/dist/types/agent-services.d.ts +7 -0
- package/dist/types/agent-services.d.ts.map +1 -1
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/package.json +20 -4
- package/templates/AGENT.md +3 -0
- package/templates/CLAUDE-decibel.md +11 -0
- package/templates/com.decibel.daemon.plist +6 -1
- package/dist/tools/deck.d.ts +0 -11
- package/dist/tools/deck.d.ts.map +0 -1
- package/dist/tools/deck.js +0 -1656
- package/dist/tools/deck.js.map +0 -1
- package/dist/tools/mother.d.ts +0 -11
- package/dist/tools/mother.d.ts.map +0 -1
- package/dist/tools/mother.js +0 -503
- package/dist/tools/mother.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -3
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -189
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/senken.d.ts +0 -11
- package/dist/tools/senken.d.ts.map +0 -1
- package/dist/tools/senken.js +0 -482
- package/dist/tools/senken.js.map +0 -1
- package/dist/tools/terminal.d.ts +0 -17
- package/dist/tools/terminal.d.ts.map +0 -1
- package/dist/tools/terminal.js +0 -968
- package/dist/tools/terminal.js.map +0 -1
- package/dist/tools/toolsIndex.d.ts +0 -5
- package/dist/tools/toolsIndex.d.ts.map +0 -1
- package/dist/tools/toolsIndex.js +0 -37
- package/dist/tools/toolsIndex.js.map +0 -1
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Hosted-session HTTP + WebSocket routes (ADR-0012 / decibel-hq EPIC-0015)
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Productised from the T3 probe (a88c533). The auth shape is unchanged:
|
|
5
|
+
//
|
|
6
|
+
// loopback peer -> exact Origin allowlist -> sessions bearer
|
|
7
|
+
//
|
|
8
|
+
// for every WRITE route (attach-token, control, spawn, restore), and for the WS upgrade
|
|
9
|
+
// the bearer is replaced by a 30s single-use attach token presented as the
|
|
10
|
+
// `attach.<token>` subprotocol — a browser cannot set Authorization on a
|
|
11
|
+
// WebSocket handshake. Every upgrade refusal happens BEFORE handleUpgrade, so
|
|
12
|
+
// an unauthorised peer never becomes a WebSocket.
|
|
13
|
+
//
|
|
14
|
+
// The session bearer is `sessions.token` in ~/.decibel/config.yaml, not the
|
|
15
|
+
// daemon auth_token, which is usually unset on a localhost daemon (the 127.0.0.1
|
|
16
|
+
// bind is its boundary). That boundary is fine for reads and not fine for
|
|
17
|
+
// "start claude and type into it" — any dev server on any localhost port would
|
|
18
|
+
// pass it. With no sessions.token the write routes fail closed (503).
|
|
19
|
+
//
|
|
20
|
+
// Frames on the attach socket: binary = raw PTY bytes both ways. Text = JSON
|
|
21
|
+
// control: client->server {"type":"resize","cols","rows"},
|
|
22
|
+
// {"type":"scroll","lines":n} (n<0 up) and {"type":"scroll","cancel":true}
|
|
23
|
+
// (tmux copy-mode, see scrollPane); server->client
|
|
24
|
+
// {"attached":"<key>"} first and {"exit":code} last. Closing the socket kills
|
|
25
|
+
// the attach CLIENT pty only — the tmux session lives on — and never sends
|
|
26
|
+
// keystrokes into the session.
|
|
27
|
+
// ============================================================================
|
|
28
|
+
import { randomBytes } from 'crypto';
|
|
29
|
+
import { homedir } from 'os';
|
|
30
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
31
|
+
import { loadConfig } from '../daemonConfig.js';
|
|
32
|
+
import { log } from '../config.js';
|
|
33
|
+
import { isLoopbackPeer, isAllowedOrigin, presentedBearer, respondToPnaPreflight, timingSafeTokenCompare, } from './boundary.js';
|
|
34
|
+
import { resolveTmux, sessionTarget, socketArgs, serverFor, cleanEnv } from './tmux.js';
|
|
35
|
+
import { sendChat, ChatError } from '../chat.js';
|
|
36
|
+
import { fleet } from './fleet.js';
|
|
37
|
+
import { pairingOf, hasPairingHeaders, verifyPairedRequest, isPairingActive, requestPairing, pairingStatus, issueNonces, revokePairing, } from './pairing.js';
|
|
38
|
+
import { SessionError, controlSession, loadPty, resolveAttachable, scrollPane, spawnSession, } from './sessions.js';
|
|
39
|
+
import { openTerminal } from './openTerminal.js';
|
|
40
|
+
import { confirmPairingLocally } from './pairDialog.js';
|
|
41
|
+
/** The dialog belongs to the real daemon, never to tests or a plain --http run. */
|
|
42
|
+
function isDaemonProcess() {
|
|
43
|
+
return process.argv.includes('--daemon') && !process.env.VITEST;
|
|
44
|
+
}
|
|
45
|
+
/** How long a minted attach token stays usable. Deliberately short. */
|
|
46
|
+
export const ATTACH_TOKEN_TTL_MS = 30_000;
|
|
47
|
+
const SUBPROTOCOL_PREFIX = 'attach.';
|
|
48
|
+
/** HQ dev server, through the Vite proxy (decibel-hq EPIC-0015 phase 1). */
|
|
49
|
+
export const DEFAULT_SESSION_ORIGINS = ['http://localhost:5733', 'http://127.0.0.1:5733'];
|
|
50
|
+
/**
|
|
51
|
+
* The default allowlist: the dev server, plus the origin of the deployed HQ the
|
|
52
|
+
* daemon already talks to (hq.url in config.yaml). Deployed HQ has no bearer;
|
|
53
|
+
* it can only act through an approved pairing (src/pty/pairing.ts).
|
|
54
|
+
*/
|
|
55
|
+
function defaultOrigins(hqUrl) {
|
|
56
|
+
const out = [...DEFAULT_SESSION_ORIGINS];
|
|
57
|
+
if (hqUrl) {
|
|
58
|
+
try {
|
|
59
|
+
const u = new URL(hqUrl);
|
|
60
|
+
if (u.protocol === 'https:')
|
|
61
|
+
out.push(`${u.protocol}//${u.host}`);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* not a URL; ignore */
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Read per request: the file is small, these routes are rare, and it means a
|
|
71
|
+
* token set in config.yaml takes effect without a daemon restart.
|
|
72
|
+
*/
|
|
73
|
+
let authOverride = null;
|
|
74
|
+
// The rate limiter also reads this, on every request that carries a bearer, so
|
|
75
|
+
// it is cached for a few seconds rather than parsed from YAML each time.
|
|
76
|
+
let authCache = null;
|
|
77
|
+
const AUTH_CACHE_MS = 5_000;
|
|
78
|
+
export function sessionAuthConfig() {
|
|
79
|
+
if (authOverride)
|
|
80
|
+
return authOverride;
|
|
81
|
+
if (authCache && Date.now() - authCache.at < AUTH_CACHE_MS)
|
|
82
|
+
return authCache.value;
|
|
83
|
+
const cfg = loadConfig();
|
|
84
|
+
const s = cfg.sessions;
|
|
85
|
+
const value = {
|
|
86
|
+
token: s?.token || undefined,
|
|
87
|
+
allowedOrigins: s?.allowed_origins?.length ? s.allowed_origins : defaultOrigins(cfg.hq?.url),
|
|
88
|
+
};
|
|
89
|
+
authCache = { at: Date.now(), value };
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
/** Test seam. */
|
|
93
|
+
export function _setSessionAuthConfig(c) {
|
|
94
|
+
authOverride = c;
|
|
95
|
+
authCache = null;
|
|
96
|
+
}
|
|
97
|
+
const tokens = new Map();
|
|
98
|
+
let now = Date.now;
|
|
99
|
+
/** Test seam. */
|
|
100
|
+
export function _setClock(fn) {
|
|
101
|
+
now = fn ?? Date.now;
|
|
102
|
+
}
|
|
103
|
+
export function outstandingTokens() {
|
|
104
|
+
sweep();
|
|
105
|
+
return tokens.size;
|
|
106
|
+
}
|
|
107
|
+
function sweep() {
|
|
108
|
+
const t = now();
|
|
109
|
+
for (const [k, rec] of tokens)
|
|
110
|
+
if (rec.expiresAt <= t)
|
|
111
|
+
tokens.delete(k);
|
|
112
|
+
}
|
|
113
|
+
// ----------------------------------------------------------------------------
|
|
114
|
+
// Routing
|
|
115
|
+
// ----------------------------------------------------------------------------
|
|
116
|
+
const ATTACH_TOKEN_RE = /^\/sessions\/([^/]+)\/attach-token$/;
|
|
117
|
+
const CONTROL_RE = /^\/sessions\/([^/]+)\/control$/;
|
|
118
|
+
const ATTACH_RE = /^\/sessions\/([^/]+)\/attach$/;
|
|
119
|
+
/** The routes this module gates itself. GET /sessions and /sessions/last-fleet are NOT among them. */
|
|
120
|
+
export function isSessionWritePath(path) {
|
|
121
|
+
return path === '/sessions/spawn' || path === '/sessions/restore' || path === '/sessions/open-terminal' ||
|
|
122
|
+
ATTACH_TOKEN_RE.test(path) || CONTROL_RE.test(path);
|
|
123
|
+
}
|
|
124
|
+
export function isSessionAttachPath(path) {
|
|
125
|
+
return ATTACH_RE.test(path);
|
|
126
|
+
}
|
|
127
|
+
function decodeKey(raw) {
|
|
128
|
+
try {
|
|
129
|
+
const k = decodeURIComponent(raw);
|
|
130
|
+
// tmux session names: no ':' or '.' (target syntax), no control chars.
|
|
131
|
+
return /^[^\x00-\x1f:.]{1,128}$/.test(k) ? k : null;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function sendJson(res, status, body, origin) {
|
|
138
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
139
|
+
if (origin) {
|
|
140
|
+
headers['Access-Control-Allow-Origin'] = origin;
|
|
141
|
+
headers.Vary = 'Origin';
|
|
142
|
+
}
|
|
143
|
+
res.writeHead(status, headers).end(JSON.stringify(body));
|
|
144
|
+
}
|
|
145
|
+
async function readJson(req, limit = 64 * 1024) {
|
|
146
|
+
const chunks = [];
|
|
147
|
+
let size = 0;
|
|
148
|
+
for await (const chunk of req) {
|
|
149
|
+
size += chunk.length;
|
|
150
|
+
if (size > limit)
|
|
151
|
+
throw new SessionError(413, 'BODY_TOO_LARGE', 'Request body too large.');
|
|
152
|
+
chunks.push(chunk);
|
|
153
|
+
}
|
|
154
|
+
if (!size)
|
|
155
|
+
return {};
|
|
156
|
+
try {
|
|
157
|
+
const v = JSON.parse(Buffer.concat(chunks).toString('utf-8'));
|
|
158
|
+
return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
throw new SessionError(400, 'BAD_JSON', 'Body is not valid JSON.');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The write-route gate. Returns the origin to echo on success ('' for a
|
|
166
|
+
* request that carried none), or writes the refusal and returns null.
|
|
167
|
+
*
|
|
168
|
+
* A request with NO Origin header is a local CLI (`decibel up`, decibel-hq
|
|
169
|
+
* ADR-0018 D5): admitted on loopback with a valid bearer. The Origin check
|
|
170
|
+
* exists to stop browser CSRF, and browsers always send Origin on a
|
|
171
|
+
* cross-origin POST, so this opens no browser path. An Origin that IS sent
|
|
172
|
+
* must still be allowlisted.
|
|
173
|
+
*/
|
|
174
|
+
function gate(req, res) {
|
|
175
|
+
const cfg = sessionAuthConfig();
|
|
176
|
+
const origin = req.headers.origin;
|
|
177
|
+
// A request already verified under an approved pairing (httpServer.ts ran
|
|
178
|
+
// verifyPairedRequest: loopback, origin allowlist, pairing bound to this
|
|
179
|
+
// origin, fresh single-use nonce, signature). No bearer involved.
|
|
180
|
+
if (pairingOf(req))
|
|
181
|
+
return origin;
|
|
182
|
+
if (!cfg.token) {
|
|
183
|
+
sendJson(res, 503, {
|
|
184
|
+
error: 'Hosted sessions are not configured: set sessions.token in ~/.decibel/config.yaml.',
|
|
185
|
+
code: 'SESSIONS_NOT_CONFIGURED',
|
|
186
|
+
});
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
if (!isLoopbackPeer(req)) {
|
|
190
|
+
sendJson(res, 403, { error: 'not a loopback peer', code: 'FORBIDDEN' });
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if (origin !== undefined && !isAllowedOrigin(origin, cfg.allowedOrigins)) {
|
|
194
|
+
sendJson(res, 403, { error: 'origin not allowed', code: 'FORBIDDEN' });
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const presented = presentedBearer(req);
|
|
198
|
+
if (!presented || !timingSafeTokenCompare(presented, cfg.token)) {
|
|
199
|
+
sendJson(res, 401, { error: 'bad bearer', code: 'UNAUTHORIZED' }, origin);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
return origin ?? '';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Handle a session write route or its preflight. Called by httpServer.ts for
|
|
206
|
+
* any path where isSessionWritePath() is true, before the daemon's own auth
|
|
207
|
+
* gate (which knows nothing of the sessions bearer).
|
|
208
|
+
*/
|
|
209
|
+
export async function handleSessionWrite(req, res, path) {
|
|
210
|
+
if (respondToPnaPreflight(req, res, sessionAuthConfig().allowedOrigins))
|
|
211
|
+
return;
|
|
212
|
+
if (req.method !== 'POST') {
|
|
213
|
+
sendJson(res, 405, { error: 'POST only', code: 'METHOD_NOT_ALLOWED' });
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const origin = gate(req, res);
|
|
217
|
+
if (origin === null)
|
|
218
|
+
return;
|
|
219
|
+
try {
|
|
220
|
+
if (path === '/sessions/spawn') {
|
|
221
|
+
const body = await readJson(req);
|
|
222
|
+
sendJson(res, 200, await spawnSession(body), origin);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// decibel-hq ADR-0018: resume ledger sessions. Never takes a cwd, flags
|
|
226
|
+
// or an arbitrary uuid; every one must be in the daemon's own ledger.
|
|
227
|
+
if (path === '/sessions/restore') {
|
|
228
|
+
const body = await readJson(req);
|
|
229
|
+
sendJson(res, 200, await fleet().restore(body.session_ids), origin);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (path === '/sessions/open-terminal') {
|
|
233
|
+
sendJson(res, 200, await openTerminal(await readJson(req)), origin);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const tokenMatch = path.match(ATTACH_TOKEN_RE);
|
|
237
|
+
if (tokenMatch) {
|
|
238
|
+
const key = decodeKey(tokenMatch[1]);
|
|
239
|
+
if (!key)
|
|
240
|
+
throw new SessionError(400, 'BAD_SESSION_KEY', 'Malformed session key.');
|
|
241
|
+
if (!(await loadPty())) {
|
|
242
|
+
throw new SessionError(503, 'PTY_UNAVAILABLE', 'node-pty is not installed; attach is unavailable on this daemon.');
|
|
243
|
+
}
|
|
244
|
+
await resolveAttachable(key);
|
|
245
|
+
sweep();
|
|
246
|
+
const token = randomBytes(32).toString('hex');
|
|
247
|
+
const expiresAt = now() + ATTACH_TOKEN_TTL_MS;
|
|
248
|
+
tokens.set(token, { sessionKey: key, expiresAt, pairingId: pairingOf(req) });
|
|
249
|
+
sendJson(res, 200, { token, expires_at: new Date(expiresAt).toISOString() }, origin);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const controlMatch = path.match(CONTROL_RE);
|
|
253
|
+
if (controlMatch) {
|
|
254
|
+
const key = decodeKey(controlMatch[1]);
|
|
255
|
+
if (!key)
|
|
256
|
+
throw new SessionError(400, 'BAD_SESSION_KEY', 'Malformed session key.');
|
|
257
|
+
const body = await readJson(req);
|
|
258
|
+
sendJson(res, 200, await controlSession(key, body.action), origin);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
sendJson(res, 404, { error: 'Not found', code: 'NOT_FOUND' }, origin);
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
if (err instanceof SessionError) {
|
|
265
|
+
sendJson(res, err.status, { error: err.message, code: err.code }, origin);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
log(`Sessions: ${path} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
269
|
+
sendJson(res, 500, { error: 'internal error', code: 'INTERNAL' }, origin);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* POST /chat (decibel-hq EPIC-0016): send as the HQ chat peer. Same gate as
|
|
275
|
+
* the session writes: it puts text into other sessions.
|
|
276
|
+
*/
|
|
277
|
+
export async function handleChatWrite(req, res) {
|
|
278
|
+
if (respondToPnaPreflight(req, res, sessionAuthConfig().allowedOrigins))
|
|
279
|
+
return;
|
|
280
|
+
if (req.method !== 'POST') {
|
|
281
|
+
sendJson(res, 405, { error: 'POST only', code: 'METHOD_NOT_ALLOWED' });
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const origin = gate(req, res);
|
|
285
|
+
if (origin === null)
|
|
286
|
+
return;
|
|
287
|
+
try {
|
|
288
|
+
const body = await readJson(req, 16 * 1024);
|
|
289
|
+
sendJson(res, 200, await sendChat(body.to, body.text), origin);
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
if (err instanceof ChatError || err instanceof SessionError) {
|
|
293
|
+
sendJson(res, err.status, { error: err.message, code: err.code }, origin);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
log(`Chat: POST /chat failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
297
|
+
sendJson(res, 500, { error: 'internal error', code: 'INTERNAL' }, origin);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Signed requests from a paired browser (ADR-0012 in this repo). httpServer.ts
|
|
303
|
+
* calls this once per request, before rate limiting and auth. A verified
|
|
304
|
+
* request is marked (pairingOf) and stands in for a bearer everywhere after.
|
|
305
|
+
* A request that CLAIMS a pairing and fails verification is refused outright
|
|
306
|
+
* rather than falling through as anonymous. Returns false when it refused.
|
|
307
|
+
*/
|
|
308
|
+
export function applyPairingAuth(req, res, url) {
|
|
309
|
+
if (!hasPairingHeaders(req))
|
|
310
|
+
return true;
|
|
311
|
+
const allowed = sessionAuthConfig().allowedOrigins;
|
|
312
|
+
const origin = req.headers.origin;
|
|
313
|
+
const echo = isAllowedOrigin(origin, allowed)
|
|
314
|
+
? { 'Access-Control-Allow-Origin': origin, Vary: 'Origin' }
|
|
315
|
+
: {};
|
|
316
|
+
try {
|
|
317
|
+
verifyPairedRequest(req, url.pathname + url.search, allowed);
|
|
318
|
+
for (const [k, v] of Object.entries(echo))
|
|
319
|
+
res.setHeader(k, v);
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
const status = err instanceof SessionError ? err.status : 401;
|
|
324
|
+
const code = err instanceof SessionError ? err.code : 'BAD_SIGNATURE';
|
|
325
|
+
res.writeHead(status, { 'Content-Type': 'application/json', ...echo });
|
|
326
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err), code }));
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// ----------------------------------------------------------------------------
|
|
331
|
+
// Pairing routes
|
|
332
|
+
// ----------------------------------------------------------------------------
|
|
333
|
+
// None of these approves anything: approval is `decibel-tools pair approve
|
|
334
|
+
// <code>` on this machine, and nowhere else.
|
|
335
|
+
const PAIR_STATUS_RE = /^\/pair\/status\/([A-Za-z0-9_]{1,64})$/;
|
|
336
|
+
export function isPairPath(path) {
|
|
337
|
+
return path === '/pair/request' || path === '/pair/challenge' || path === '/pair/revoke' || PAIR_STATUS_RE.test(path);
|
|
338
|
+
}
|
|
339
|
+
export async function handlePair(req, res, path) {
|
|
340
|
+
const cfg = sessionAuthConfig();
|
|
341
|
+
if (respondToPnaPreflight(req, res, cfg.allowedOrigins))
|
|
342
|
+
return;
|
|
343
|
+
const origin = req.headers.origin;
|
|
344
|
+
if (!isLoopbackPeer(req)) {
|
|
345
|
+
sendJson(res, 403, { error: 'not a loopback peer', code: 'FORBIDDEN' });
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (!isAllowedOrigin(origin, cfg.allowedOrigins)) {
|
|
349
|
+
sendJson(res, 403, { error: 'origin not allowed', code: 'FORBIDDEN' });
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
const statusMatch = path.match(PAIR_STATUS_RE);
|
|
354
|
+
if (statusMatch && req.method === 'GET') {
|
|
355
|
+
sendJson(res, 200, pairingStatus(statusMatch[1], origin), origin);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (req.method !== 'POST') {
|
|
359
|
+
sendJson(res, 405, { error: 'method not allowed', code: 'METHOD_NOT_ALLOWED' }, origin);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const body = await readJson(req, 8 * 1024);
|
|
363
|
+
if (path === '/pair/request') {
|
|
364
|
+
const pending = await requestPairing(origin, body.public_key_jwk, body.label);
|
|
365
|
+
sendJson(res, 200, pending, origin);
|
|
366
|
+
// macOS: ask on this screen (ISS-0228). The response never waits on it.
|
|
367
|
+
if (isDaemonProcess())
|
|
368
|
+
void confirmPairingLocally(pending.pairing_id);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (path === '/pair/challenge') {
|
|
372
|
+
sendJson(res, 200, issueNonces(body.pairing_id, origin, body.count), origin);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (path === '/pair/revoke') {
|
|
376
|
+
// Only a pairing can revoke itself over HTTP, and only by a signed request.
|
|
377
|
+
const id = pairingOf(req);
|
|
378
|
+
if (!id)
|
|
379
|
+
throw new SessionError(401, 'NOT_PAIRED', 'Revoke must be a signed request from the pairing being revoked.');
|
|
380
|
+
await revokePairing(id);
|
|
381
|
+
closeRevokedSockets();
|
|
382
|
+
sendJson(res, 200, { ok: true, revoked: id }, origin);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
sendJson(res, 404, { error: 'Not found', code: 'NOT_FOUND' }, origin);
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
if (err instanceof SessionError) {
|
|
389
|
+
sendJson(res, err.status, { error: err.message, code: err.code }, origin);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
log(`Pairing: ${path} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
393
|
+
sendJson(res, 500, { error: 'internal error', code: 'INTERNAL' }, origin);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// ----------------------------------------------------------------------------
|
|
398
|
+
// WebSocket attach
|
|
399
|
+
// ----------------------------------------------------------------------------
|
|
400
|
+
// noServer: the upgrade is authorised by us first, and only an authorised one
|
|
401
|
+
// is handed to ws. handleProtocols echoes the token-bearing subprotocol back,
|
|
402
|
+
// which every engine expects to see in the response.
|
|
403
|
+
let wss = null;
|
|
404
|
+
function getWss() {
|
|
405
|
+
if (!wss) {
|
|
406
|
+
wss = new WebSocketServer({
|
|
407
|
+
noServer: true,
|
|
408
|
+
maxPayload: 1024 * 1024,
|
|
409
|
+
handleProtocols: (protocols) => {
|
|
410
|
+
for (const p of protocols)
|
|
411
|
+
if (p.startsWith(SUBPROTOCOL_PREFIX))
|
|
412
|
+
return p;
|
|
413
|
+
return false;
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
return wss;
|
|
418
|
+
}
|
|
419
|
+
/** Live attach sockets, so shutdown can close them. */
|
|
420
|
+
const liveSockets = new Map();
|
|
421
|
+
/**
|
|
422
|
+
* Revocation reaches live sockets. A CLI revoke edits pairings.yaml in another
|
|
423
|
+
* process, so the daemon checks every paired socket's pairing on a short
|
|
424
|
+
* interval rather than waiting to be told.
|
|
425
|
+
*/
|
|
426
|
+
let revocationTimer = null;
|
|
427
|
+
export function closeRevokedSockets() {
|
|
428
|
+
let closed = 0;
|
|
429
|
+
for (const [ws, pairingId] of liveSockets) {
|
|
430
|
+
if (pairingId && !isPairingActive(pairingId)) {
|
|
431
|
+
try {
|
|
432
|
+
ws.close(4401, 'pairing revoked');
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
/* ignore */
|
|
436
|
+
}
|
|
437
|
+
liveSockets.delete(ws);
|
|
438
|
+
closed++;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (![...liveSockets.values()].some(Boolean) && revocationTimer) {
|
|
442
|
+
clearInterval(revocationTimer);
|
|
443
|
+
revocationTimer = null;
|
|
444
|
+
}
|
|
445
|
+
return closed;
|
|
446
|
+
}
|
|
447
|
+
function watchRevocation() {
|
|
448
|
+
if (revocationTimer)
|
|
449
|
+
return;
|
|
450
|
+
revocationTimer = setInterval(() => {
|
|
451
|
+
try {
|
|
452
|
+
closeRevokedSockets();
|
|
453
|
+
}
|
|
454
|
+
catch (err) {
|
|
455
|
+
log(`Sessions: revocation check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
456
|
+
}
|
|
457
|
+
}, 5_000);
|
|
458
|
+
revocationTimer.unref?.();
|
|
459
|
+
}
|
|
460
|
+
function refuse(socket, status, why) {
|
|
461
|
+
socket.write(`HTTP/1.1 ${status}\r\nContent-Length: 0\r\nConnection: close\r\nX-Attach-Refused: ${why}\r\n\r\n`);
|
|
462
|
+
socket.destroy();
|
|
463
|
+
}
|
|
464
|
+
function clampDim(v, fallback, max) {
|
|
465
|
+
const n = Number(v);
|
|
466
|
+
return Number.isInteger(n) && n > 0 ? Math.min(n, max) : fallback;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Handle an upgrade on /sessions/<key>/attach. The caller (httpServer.ts)
|
|
470
|
+
* routes here only for that path; anything else it refuses itself.
|
|
471
|
+
*/
|
|
472
|
+
export async function handleSessionUpgrade(req, socket, head, url) {
|
|
473
|
+
const cfg = sessionAuthConfig();
|
|
474
|
+
if (!cfg.token)
|
|
475
|
+
return refuse(socket, '503 Service Unavailable', 'not-configured');
|
|
476
|
+
if (!isLoopbackPeer(req))
|
|
477
|
+
return refuse(socket, '403 Forbidden', 'peer');
|
|
478
|
+
if (!isAllowedOrigin(req.headers.origin, cfg.allowedOrigins)) {
|
|
479
|
+
return refuse(socket, '403 Forbidden', 'origin');
|
|
480
|
+
}
|
|
481
|
+
const m = url.pathname.match(ATTACH_RE);
|
|
482
|
+
const key = m ? decodeKey(m[1]) : null;
|
|
483
|
+
if (!key)
|
|
484
|
+
return refuse(socket, '400 Bad Request', 'bad-key');
|
|
485
|
+
const offered = req.headers['sec-websocket-protocol'] ?? '';
|
|
486
|
+
const chosen = offered
|
|
487
|
+
.split(',')
|
|
488
|
+
.map((p) => p.trim())
|
|
489
|
+
.find((p) => p.startsWith(SUBPROTOCOL_PREFIX));
|
|
490
|
+
if (!chosen)
|
|
491
|
+
return refuse(socket, '401 Unauthorized', 'no-token');
|
|
492
|
+
const presented = chosen.slice(SUBPROTOCOL_PREFIX.length);
|
|
493
|
+
sweep();
|
|
494
|
+
const rec = tokens.get(presented);
|
|
495
|
+
if (!rec)
|
|
496
|
+
return refuse(socket, '401 Unauthorized', 'unknown-token');
|
|
497
|
+
// Burn it before anything async, so two concurrent upgrades presenting the
|
|
498
|
+
// same token cannot both win.
|
|
499
|
+
tokens.delete(presented);
|
|
500
|
+
if (rec.expiresAt <= now())
|
|
501
|
+
return refuse(socket, '401 Unauthorized', 'token-expired');
|
|
502
|
+
if (rec.sessionKey !== key)
|
|
503
|
+
return refuse(socket, '403 Forbidden', 'token-session-mismatch');
|
|
504
|
+
const pty = await loadPty();
|
|
505
|
+
if (!pty)
|
|
506
|
+
return refuse(socket, '503 Service Unavailable', 'no-pty');
|
|
507
|
+
try {
|
|
508
|
+
await resolveAttachable(key);
|
|
509
|
+
}
|
|
510
|
+
catch (err) {
|
|
511
|
+
const why = err instanceof SessionError ? err.code.toLowerCase() : 'session';
|
|
512
|
+
return refuse(socket, '409 Conflict', why);
|
|
513
|
+
}
|
|
514
|
+
const cols = clampDim(url.searchParams.get('cols'), 120, 500);
|
|
515
|
+
const rows = clampDim(url.searchParams.get('rows'), 32, 200);
|
|
516
|
+
getWss().handleUpgrade(req, socket, head, (ws) => {
|
|
517
|
+
const env = { ...cleanEnv(), TERM: 'xterm-256color' };
|
|
518
|
+
let term;
|
|
519
|
+
try {
|
|
520
|
+
term = pty.spawn(resolveTmux(), [...socketArgs(serverFor(key)), 'attach-session', '-t', sessionTarget(key)], {
|
|
521
|
+
name: 'xterm-256color',
|
|
522
|
+
cols,
|
|
523
|
+
rows,
|
|
524
|
+
cwd: homedir(),
|
|
525
|
+
env,
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
catch (err) {
|
|
529
|
+
log(`Sessions: attach spawn failed for ${key}: ${err instanceof Error ? err.message : String(err)}`);
|
|
530
|
+
ws.send(JSON.stringify({ exit: -1, error: 'attach failed' }));
|
|
531
|
+
ws.close(1011, 'attach failed');
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
liveSockets.set(ws, rec.pairingId);
|
|
535
|
+
if (rec.pairingId)
|
|
536
|
+
watchRevocation();
|
|
537
|
+
log(`Sessions: attached ${key} (pid ${term.pid})`);
|
|
538
|
+
ws.send(JSON.stringify({ attached: key }));
|
|
539
|
+
let exited = false;
|
|
540
|
+
term.onData((data) => {
|
|
541
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
542
|
+
ws.send(Buffer.from(data, 'utf-8'), { binary: true });
|
|
543
|
+
});
|
|
544
|
+
term.onExit(({ exitCode }) => {
|
|
545
|
+
exited = true;
|
|
546
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
547
|
+
ws.send(JSON.stringify({ exit: exitCode }));
|
|
548
|
+
ws.close(1000, 'detached');
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
// Scroll frames run tmux asynchronously, and a keystroke that overtook
|
|
552
|
+
// HQ's cancel would land in copy-mode as a copy-mode command. So once a
|
|
553
|
+
// scroll is pending, everything after it on this socket waits its turn.
|
|
554
|
+
let pending = null;
|
|
555
|
+
const inOrder = (fn) => {
|
|
556
|
+
if (!pending) {
|
|
557
|
+
const r = fn();
|
|
558
|
+
if (!r)
|
|
559
|
+
return;
|
|
560
|
+
pending = r;
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
pending = pending.then(fn);
|
|
564
|
+
}
|
|
565
|
+
const mine = pending;
|
|
566
|
+
mine.catch(() => { }).finally(() => {
|
|
567
|
+
if (pending === mine)
|
|
568
|
+
pending = null;
|
|
569
|
+
});
|
|
570
|
+
};
|
|
571
|
+
ws.on('message', (data, isBinary) => {
|
|
572
|
+
if (isBinary) {
|
|
573
|
+
inOrder(() => {
|
|
574
|
+
if (!exited)
|
|
575
|
+
term.write(data);
|
|
576
|
+
});
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
let msg;
|
|
580
|
+
try {
|
|
581
|
+
msg = JSON.parse(data.toString('utf-8'));
|
|
582
|
+
}
|
|
583
|
+
catch {
|
|
584
|
+
return; // Ignore malformed control frames; they are never keystrokes.
|
|
585
|
+
}
|
|
586
|
+
if (msg?.type === 'resize') {
|
|
587
|
+
inOrder(() => {
|
|
588
|
+
if (!exited)
|
|
589
|
+
term.resize(clampDim(msg.cols, cols, 500), clampDim(msg.rows, rows, 200));
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
else if (msg?.type === 'scroll') {
|
|
593
|
+
inOrder(() => scrollPane(key, msg));
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
ws.on('close', () => {
|
|
597
|
+
liveSockets.delete(ws);
|
|
598
|
+
// Kill the attach CLIENT only. The tmux session is untouched, and no
|
|
599
|
+
// keystroke (not even the detach prefix) is ever sent into it.
|
|
600
|
+
if (!exited) {
|
|
601
|
+
try {
|
|
602
|
+
term.kill();
|
|
603
|
+
}
|
|
604
|
+
catch {
|
|
605
|
+
/* already gone */
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
log(`Sessions: detached ${key}`);
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
/** Close every live attach socket (daemon shutdown). */
|
|
613
|
+
export function closeAllAttachSockets() {
|
|
614
|
+
for (const ws of liveSockets.keys()) {
|
|
615
|
+
try {
|
|
616
|
+
ws.close(1001, 'daemon shutting down');
|
|
617
|
+
}
|
|
618
|
+
catch {
|
|
619
|
+
/* ignore */
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
liveSockets.clear();
|
|
623
|
+
}
|
|
624
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/pty/routes.ts"],"names":[],"mappings":"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"}
|