@decibelsystems/tools 3.0.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.
Files changed (253) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/agentCommands.d.ts +0 -1
  3. package/dist/agentCommands.d.ts.map +1 -1
  4. package/dist/agentCommands.js +19 -8
  5. package/dist/agentCommands.js.map +1 -1
  6. package/dist/agentPresence.d.ts +5 -3
  7. package/dist/agentPresence.d.ts.map +1 -1
  8. package/dist/agentPresence.js +20 -29
  9. package/dist/agentPresence.js.map +1 -1
  10. package/dist/architectAdrs.d.ts +13 -1
  11. package/dist/architectAdrs.d.ts.map +1 -1
  12. package/dist/architectAdrs.js +83 -1
  13. package/dist/architectAdrs.js.map +1 -1
  14. package/dist/artifacts.d.ts +60 -0
  15. package/dist/artifacts.d.ts.map +1 -0
  16. package/dist/artifacts.js +208 -0
  17. package/dist/artifacts.js.map +1 -0
  18. package/dist/asks.d.ts +93 -0
  19. package/dist/asks.d.ts.map +1 -0
  20. package/dist/asks.js +383 -0
  21. package/dist/asks.js.map +1 -0
  22. package/dist/chat.d.ts +47 -0
  23. package/dist/chat.d.ts.map +1 -0
  24. package/dist/chat.js +288 -0
  25. package/dist/chat.js.map +1 -0
  26. package/dist/daemon.d.ts +14 -3
  27. package/dist/daemon.d.ts.map +1 -1
  28. package/dist/daemon.js +44 -14
  29. package/dist/daemon.js.map +1 -1
  30. package/dist/daemonConfig.d.ts +22 -0
  31. package/dist/daemonConfig.d.ts.map +1 -1
  32. package/dist/daemonConfig.js +11 -0
  33. package/dist/daemonConfig.js.map +1 -1
  34. package/dist/domain/issue.d.ts +19 -15
  35. package/dist/domain/issue.d.ts.map +1 -1
  36. package/dist/domain/issue.js +4 -32
  37. package/dist/domain/issue.js.map +1 -1
  38. package/dist/domain/issueCodec.d.ts.map +1 -1
  39. package/dist/domain/issueCodec.js +10 -0
  40. package/dist/domain/issueCodec.js.map +1 -1
  41. package/dist/domain/issueRepository.d.ts +35 -2
  42. package/dist/domain/issueRepository.d.ts.map +1 -1
  43. package/dist/domain/issueRepository.js +40 -1
  44. package/dist/domain/issueRepository.js.map +1 -1
  45. package/dist/domain/uid.d.ts +16 -0
  46. package/dist/domain/uid.d.ts.map +1 -0
  47. package/dist/domain/uid.js +43 -0
  48. package/dist/domain/uid.js.map +1 -0
  49. package/dist/facades/definitions.d.ts.map +1 -1
  50. package/dist/facades/definitions.js +46 -3
  51. package/dist/facades/definitions.js.map +1 -1
  52. package/dist/hq/defineAgent.d.ts.map +1 -1
  53. package/dist/hq/defineAgent.js +7 -11
  54. package/dist/hq/defineAgent.js.map +1 -1
  55. package/dist/httpServer.d.ts.map +1 -1
  56. package/dist/httpServer.js +201 -48
  57. package/dist/httpServer.js.map +1 -1
  58. package/dist/identity.d.ts +123 -0
  59. package/dist/identity.d.ts.map +1 -0
  60. package/dist/identity.js +312 -0
  61. package/dist/identity.js.map +1 -0
  62. package/dist/kernel.d.ts.map +1 -1
  63. package/dist/kernel.js +24 -1
  64. package/dist/kernel.js.map +1 -1
  65. package/dist/killSwitch.d.ts +117 -0
  66. package/dist/killSwitch.d.ts.map +1 -0
  67. package/dist/killSwitch.js +161 -0
  68. package/dist/killSwitch.js.map +1 -0
  69. package/dist/lib/atomicWrite.d.ts +23 -0
  70. package/dist/lib/atomicWrite.d.ts.map +1 -1
  71. package/dist/lib/atomicWrite.js +84 -0
  72. package/dist/lib/atomicWrite.js.map +1 -1
  73. package/dist/lib/recordIdAllocator.d.ts +21 -5
  74. package/dist/lib/recordIdAllocator.d.ts.map +1 -1
  75. package/dist/lib/recordIdAllocator.js +25 -7
  76. package/dist/lib/recordIdAllocator.js.map +1 -1
  77. package/dist/orgId.d.ts +23 -0
  78. package/dist/orgId.d.ts.map +1 -0
  79. package/dist/orgId.js +73 -0
  80. package/dist/orgId.js.map +1 -0
  81. package/dist/pairCli.d.ts +2 -0
  82. package/dist/pairCli.d.ts.map +1 -0
  83. package/dist/pairCli.js +97 -0
  84. package/dist/pairCli.js.map +1 -0
  85. package/dist/peerBroker.d.ts +40 -0
  86. package/dist/peerBroker.d.ts.map +1 -0
  87. package/dist/peerBroker.js +70 -0
  88. package/dist/peerBroker.js.map +1 -0
  89. package/dist/peerBrokerSupervisor.d.ts +21 -0
  90. package/dist/peerBrokerSupervisor.d.ts.map +1 -0
  91. package/dist/peerBrokerSupervisor.js +131 -0
  92. package/dist/peerBrokerSupervisor.js.map +1 -0
  93. package/dist/projectPaths.d.ts.map +1 -1
  94. package/dist/projectPaths.js +1 -19
  95. package/dist/projectPaths.js.map +1 -1
  96. package/dist/projectRegistry.d.ts +22 -0
  97. package/dist/projectRegistry.d.ts.map +1 -1
  98. package/dist/projectRegistry.js +58 -2
  99. package/dist/projectRegistry.js.map +1 -1
  100. package/dist/pty/boundary.d.ts +39 -0
  101. package/dist/pty/boundary.d.ts.map +1 -0
  102. package/dist/pty/boundary.js +100 -0
  103. package/dist/pty/boundary.js.map +1 -0
  104. package/dist/pty/errors.d.ts +6 -0
  105. package/dist/pty/errors.d.ts.map +1 -0
  106. package/dist/pty/errors.js +12 -0
  107. package/dist/pty/errors.js.map +1 -0
  108. package/dist/pty/fleet.d.ts +159 -0
  109. package/dist/pty/fleet.d.ts.map +1 -0
  110. package/dist/pty/fleet.js +543 -0
  111. package/dist/pty/fleet.js.map +1 -0
  112. package/dist/pty/launchProfile.d.ts +45 -0
  113. package/dist/pty/launchProfile.d.ts.map +1 -0
  114. package/dist/pty/launchProfile.js +149 -0
  115. package/dist/pty/launchProfile.js.map +1 -0
  116. package/dist/pty/openTerminal.d.ts +48 -0
  117. package/dist/pty/openTerminal.d.ts.map +1 -0
  118. package/dist/pty/openTerminal.js +185 -0
  119. package/dist/pty/openTerminal.js.map +1 -0
  120. package/dist/pty/pairDialog.d.ts +16 -0
  121. package/dist/pty/pairDialog.d.ts.map +1 -0
  122. package/dist/pty/pairDialog.js +121 -0
  123. package/dist/pty/pairDialog.js.map +1 -0
  124. package/dist/pty/pairing.d.ts +86 -0
  125. package/dist/pty/pairing.d.ts.map +1 -0
  126. package/dist/pty/pairing.js +351 -0
  127. package/dist/pty/pairing.js.map +1 -0
  128. package/dist/pty/routes.d.ts +49 -0
  129. package/dist/pty/routes.d.ts.map +1 -0
  130. package/dist/pty/routes.js +624 -0
  131. package/dist/pty/routes.js.map +1 -0
  132. package/dist/pty/sessions.d.ts +167 -0
  133. package/dist/pty/sessions.d.ts.map +1 -0
  134. package/dist/pty/sessions.js +513 -0
  135. package/dist/pty/sessions.js.map +1 -0
  136. package/dist/pty/tmux.d.ts +109 -0
  137. package/dist/pty/tmux.d.ts.map +1 -0
  138. package/dist/pty/tmux.js +271 -0
  139. package/dist/pty/tmux.js.map +1 -0
  140. package/dist/roster.d.ts +37 -0
  141. package/dist/roster.d.ts.map +1 -0
  142. package/dist/roster.js +126 -0
  143. package/dist/roster.js.map +1 -0
  144. package/dist/runtime/daemonMeta.d.ts +53 -0
  145. package/dist/runtime/daemonMeta.d.ts.map +1 -0
  146. package/dist/runtime/daemonMeta.js +121 -0
  147. package/dist/runtime/daemonMeta.js.map +1 -0
  148. package/dist/runtime/ensureRuntime.d.ts.map +1 -1
  149. package/dist/runtime/ensureRuntime.js +5 -10
  150. package/dist/runtime/ensureRuntime.js.map +1 -1
  151. package/dist/sentinelIssues.d.ts +16 -0
  152. package/dist/sentinelIssues.d.ts.map +1 -1
  153. package/dist/sentinelIssues.js +42 -1
  154. package/dist/sentinelIssues.js.map +1 -1
  155. package/dist/server.js +66 -5
  156. package/dist/server.js.map +1 -1
  157. package/dist/toolConfig.d.ts.map +1 -1
  158. package/dist/toolConfig.js +12 -0
  159. package/dist/toolConfig.js.map +1 -1
  160. package/dist/tools/agentic/agentQueue.d.ts.map +1 -1
  161. package/dist/tools/agentic/agentQueue.js +4 -0
  162. package/dist/tools/agentic/agentQueue.js.map +1 -1
  163. package/dist/tools/architect/index.d.ts +1 -0
  164. package/dist/tools/architect/index.d.ts.map +1 -1
  165. package/dist/tools/architect/index.js +45 -1
  166. package/dist/tools/architect/index.js.map +1 -1
  167. package/dist/tools/architect.d.ts.map +1 -1
  168. package/dist/tools/architect.js +59 -8
  169. package/dist/tools/architect.js.map +1 -1
  170. package/dist/tools/artifacts.d.ts +5 -0
  171. package/dist/tools/artifacts.d.ts.map +1 -0
  172. package/dist/tools/artifacts.js +89 -0
  173. package/dist/tools/artifacts.js.map +1 -0
  174. package/dist/tools/asks.d.ts +6 -0
  175. package/dist/tools/asks.d.ts.map +1 -0
  176. package/dist/tools/asks.js +104 -0
  177. package/dist/tools/asks.js.map +1 -0
  178. package/dist/tools/coordinator/index.d.ts +1 -0
  179. package/dist/tools/coordinator/index.d.ts.map +1 -1
  180. package/dist/tools/coordinator/index.js +42 -2
  181. package/dist/tools/coordinator/index.js.map +1 -1
  182. package/dist/tools/data-inspector.d.ts +1 -1
  183. package/dist/tools/data-inspector.d.ts.map +1 -1
  184. package/dist/tools/data-inspector.js +1 -1
  185. package/dist/tools/data-inspector.js.map +1 -1
  186. package/dist/tools/dojo/index.d.ts.map +1 -1
  187. package/dist/tools/dojo/index.js +52 -3
  188. package/dist/tools/dojo/index.js.map +1 -1
  189. package/dist/tools/dojo.d.ts +62 -1
  190. package/dist/tools/dojo.d.ts.map +1 -1
  191. package/dist/tools/dojo.js +84 -1
  192. package/dist/tools/dojo.js.map +1 -1
  193. package/dist/tools/guardian.d.ts +7 -0
  194. package/dist/tools/guardian.d.ts.map +1 -1
  195. package/dist/tools/guardian.js +146 -9
  196. package/dist/tools/guardian.js.map +1 -1
  197. package/dist/tools/index.d.ts.map +1 -1
  198. package/dist/tools/index.js +6 -0
  199. package/dist/tools/index.js.map +1 -1
  200. package/dist/tools/killswitch/index.d.ts +13 -0
  201. package/dist/tools/killswitch/index.d.ts.map +1 -0
  202. package/dist/tools/killswitch/index.js +138 -0
  203. package/dist/tools/killswitch/index.js.map +1 -0
  204. package/dist/tools/oracle/index.d.ts.map +1 -1
  205. package/dist/tools/oracle/index.js +8 -0
  206. package/dist/tools/oracle/index.js.map +1 -1
  207. package/dist/tools/oracle.d.ts +7 -0
  208. package/dist/tools/oracle.d.ts.map +1 -1
  209. package/dist/tools/oracle.js +22 -6
  210. package/dist/tools/oracle.js.map +1 -1
  211. package/dist/tools/provenance.d.ts +11 -2
  212. package/dist/tools/provenance.d.ts.map +1 -1
  213. package/dist/tools/provenance.js +26 -24
  214. package/dist/tools/provenance.js.map +1 -1
  215. package/dist/tools/registry/index.d.ts.map +1 -1
  216. package/dist/tools/registry/index.js +24 -0
  217. package/dist/tools/registry/index.js.map +1 -1
  218. package/dist/tools/sentinel/index.d.ts.map +1 -1
  219. package/dist/tools/sentinel/index.js +54 -2
  220. package/dist/tools/sentinel/index.js.map +1 -1
  221. package/dist/tools/sentinel.d.ts +50 -0
  222. package/dist/tools/sentinel.d.ts.map +1 -1
  223. package/dist/tools/sentinel.js +72 -7
  224. package/dist/tools/sentinel.js.map +1 -1
  225. package/dist/tools/shared/runTracker.d.ts +2 -0
  226. package/dist/tools/shared/runTracker.d.ts.map +1 -1
  227. package/dist/tools/shared/runTracker.js +38 -0
  228. package/dist/tools/shared/runTracker.js.map +1 -1
  229. package/dist/tools/swarm.d.ts +3 -1
  230. package/dist/tools/swarm.d.ts.map +1 -1
  231. package/dist/tools/swarm.js +6 -12
  232. package/dist/tools/swarm.js.map +1 -1
  233. package/dist/tools/voice/index.d.ts +1 -0
  234. package/dist/tools/voice/index.d.ts.map +1 -1
  235. package/dist/tools/voice/index.js +33 -2
  236. package/dist/tools/voice/index.js.map +1 -1
  237. package/dist/tools/voice.d.ts +48 -1
  238. package/dist/tools/voice.d.ts.map +1 -1
  239. package/dist/tools/voice.js +63 -3
  240. package/dist/tools/voice.js.map +1 -1
  241. package/dist/transports/bridge.d.ts.map +1 -1
  242. package/dist/transports/bridge.js +2 -1
  243. package/dist/transports/bridge.js.map +1 -1
  244. package/dist/transports/mcp.d.ts.map +1 -1
  245. package/dist/transports/mcp.js +2 -1
  246. package/dist/transports/mcp.js.map +1 -1
  247. package/dist/version.d.ts +5 -0
  248. package/dist/version.d.ts.map +1 -0
  249. package/dist/version.js +23 -0
  250. package/dist/version.js.map +1 -0
  251. package/package.json +13 -2
  252. package/templates/AGENT.md +3 -0
  253. package/templates/CLAUDE-decibel.md +11 -0
@@ -0,0 +1,86 @@
1
+ import type { IncomingMessage } from 'http';
2
+ export declare const PENDING_TTL_MS: number;
3
+ /** Approved pairings idle this long expire (Ben, 2026-09-25). */
4
+ export declare const IDLE_EXPIRY_MS: number;
5
+ export declare const NONCE_TTL_MS = 60000;
6
+ /** Signed requests must be this fresh, in either direction. */
7
+ export declare const IAT_SKEW_MS = 60000;
8
+ export interface PublicJwk {
9
+ kty: 'EC';
10
+ crv: 'P-256';
11
+ x: string;
12
+ y: string;
13
+ }
14
+ export interface Pairing {
15
+ id: string;
16
+ origin: string;
17
+ label: string;
18
+ public_key_jwk: PublicJwk;
19
+ status: 'pending' | 'approved';
20
+ /** pending only: what HQ shows and the human types. */
21
+ code?: string;
22
+ requested_at: string;
23
+ approved_at?: string;
24
+ last_used?: string;
25
+ }
26
+ export declare function pairingsPath(): string;
27
+ export declare function listPairings(): Pairing[];
28
+ export declare function isPairingActive(id: string): boolean;
29
+ /**
30
+ * A P-256 PUBLIC key and nothing else. A JWK carrying `d` is a private key: the
31
+ * page is supposed to hold a non-extractable key, so receiving one means
32
+ * something is badly wrong, and it is refused rather than stored.
33
+ */
34
+ export declare function validatePublicJwk(v: unknown): PublicJwk;
35
+ /** RFC 7638 thumbprint. */
36
+ export declare function thumbprint(jwk: PublicJwk): string;
37
+ /**
38
+ * The code both sides show. Derived from the key AND a daemon nonce: from the
39
+ * key alone, an attacker could grind keys offline until one lands on a chosen
40
+ * code (cheap at 10^6); with the daemon's nonce mixed in, there is nothing to
41
+ * grind against before asking.
42
+ */
43
+ export declare function pairingCode(jwk: PublicJwk, daemonNonce: string): string;
44
+ export declare function requestPairing(origin: string, jwkIn: unknown, labelIn: unknown): Promise<{
45
+ pairing_id: string;
46
+ code: string;
47
+ expires_at: string;
48
+ }>;
49
+ export declare function pairingStatus(id: string, origin: string): {
50
+ status: 'pending' | 'approved' | 'unknown';
51
+ };
52
+ /** CLI only. Never reachable over HTTP. */
53
+ export declare function approveByCode(code: string): Promise<Pairing>;
54
+ /**
55
+ * The native macOS dialog's Allow (pairDialog.ts). Never reachable over HTTP:
56
+ * it is called only from the daemon after a local click. It approves the exact
57
+ * request the dialog showed, by id AND code, so a request that was replaced
58
+ * while the dialog was open is not approved by it.
59
+ */
60
+ export declare function approvePendingLocally(id: string, code: string): Promise<Pairing>;
61
+ /** CLI, or a signed request from the pairing itself. */
62
+ export declare function revokePairing(id: string): Promise<boolean>;
63
+ /** Test seam. */
64
+ export declare function _setPairingClock(fn: (() => number) | null): void;
65
+ export declare function issueNonces(pairingId: unknown, origin: string, countIn: unknown): {
66
+ nonces: string[];
67
+ expires_at: string;
68
+ };
69
+ /**
70
+ * Exactly what the browser signs. The body is not included: replay is stopped
71
+ * by the single-use nonce, and anything able to rewrite a loopback request in
72
+ * flight is already past every boundary this could add.
73
+ */
74
+ export declare function signingPayload(method: string, pathAndQuery: string, origin: string, pairingId: string, nonce: string, iat: number): string;
75
+ /** The pairing id a request was verified under, if it was. */
76
+ export declare function pairingOf(req: IncomingMessage): string | undefined;
77
+ export declare function hasPairingHeaders(req: IncomingMessage): boolean;
78
+ /**
79
+ * Verify a signed request. Order is the ADR's: loopback, origin allowlist,
80
+ * pairing approved and bound to this origin, freshness, nonce (burned before
81
+ * the signature check, so a bad signature still spends it), signature.
82
+ */
83
+ export declare function verifyPairedRequest(req: IncomingMessage, pathAndQuery: string, allowedOrigins: string[]): string;
84
+ /** Test seam. */
85
+ export declare function _resetPairing(): void;
86
+ //# sourceMappingURL=pairing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/pty/pairing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,351 @@
1
+ // ============================================================================
2
+ // Browser pairing (ADR-0012 in this repo; decibel-hq ADR-0012 / EPIC-0015 ph 2)
3
+ // ============================================================================
4
+ // Deployed HQ is an https page with no server of its own on this machine, so
5
+ // nothing can inject the daemon's bearer for it, and POL-0002 forbids putting
6
+ // one in the page. Instead the page holds a NON-EXTRACTABLE ECDSA P-256 key
7
+ // and signs each request; the daemon holds only public keys.
8
+ //
9
+ // 1. POST /pair/request {public_key_jwk, label} → pending, with a 6-digit
10
+ // code = H(thumbprint(pubkey) || daemon_nonce). HQ shows the code.
11
+ // 2. The human approves on this machine: on macOS a native dialog showing
12
+ // the same code (pairDialog.ts, ISS-0228), elsewhere
13
+ // `decibel-tools pair approve <code>`. NO HTTP ROUTE APPROVES — that is
14
+ // the whole gate. A compromised HQ can ask to pair; it cannot say yes.
15
+ // 3. POST /pair/challenge → single-use daemon nonces. Each request is then
16
+ // signed over (method, path, origin, pairing id, nonce, iat) and carried
17
+ // in X-Pairing-* headers.
18
+ //
19
+ // Store: ~/.decibel/pairings.yaml, mode 0600, public keys only. The CLI and the
20
+ // daemon are different processes and both write it, so every write is locked
21
+ // and atomic, and the daemon re-reads it when its mtime changes — which is how
22
+ // a CLI revoke reaches the daemon without any HTTP route.
23
+ // ============================================================================
24
+ import { createHash, createPublicKey, randomBytes, verify as cryptoVerify } from 'crypto';
25
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'fs';
26
+ import { homedir } from 'os';
27
+ import { join } from 'path';
28
+ import YAML from 'yaml';
29
+ import { writeFileAtomic } from '../lib/atomicWrite.js';
30
+ import { withFileLock } from '../lib/fileLock.js';
31
+ import { SessionError } from './errors.js';
32
+ import { isAllowedOrigin, isLoopbackPeer } from './boundary.js';
33
+ export const PENDING_TTL_MS = 10 * 60_000;
34
+ /** Approved pairings idle this long expire (Ben, 2026-09-25). */
35
+ export const IDLE_EXPIRY_MS = 30 * 24 * 60 * 60_000;
36
+ export const NONCE_TTL_MS = 60_000;
37
+ /** Signed requests must be this fresh, in either direction. */
38
+ export const IAT_SKEW_MS = 60_000;
39
+ const MAX_PENDING_PER_ORIGIN = 3;
40
+ const MAX_PENDING_TOTAL = 10;
41
+ const MAX_NONCES_PER_CHALLENGE = 20;
42
+ /** last_used is written at most this often per pairing. */
43
+ const LAST_USED_WRITE_MS = 10 * 60_000;
44
+ // ----------------------------------------------------------------------------
45
+ // Paths (per call, so tests can move HOME)
46
+ // ----------------------------------------------------------------------------
47
+ export function pairingsPath() {
48
+ return join(homedir(), '.decibel', 'pairings.yaml');
49
+ }
50
+ function lockPath() {
51
+ return pairingsPath() + '.lock';
52
+ }
53
+ // ----------------------------------------------------------------------------
54
+ // Store I/O
55
+ // ----------------------------------------------------------------------------
56
+ /**
57
+ * Cache key: inode + size + mtime, never mtime alone. $HOME here is HFS+, whose
58
+ * mtime has ONE-SECOND resolution, so a CLI approve landing in the same second
59
+ * as the daemon's last read left the daemon holding a stale "pending" — found
60
+ * live, not in tests. Every writer replaces the file by atomic rename, which
61
+ * always yields a new inode, so the inode alone would do; size and mtime also
62
+ * catch an in-place edit.
63
+ */
64
+ let cache = null;
65
+ function readStore() {
66
+ const p = pairingsPath();
67
+ if (!existsSync(p)) {
68
+ cache = null;
69
+ return { pairings: [] };
70
+ }
71
+ const st = statSync(p);
72
+ const key = `${st.ino}:${st.size}:${st.mtimeMs}`;
73
+ if (cache && cache.key === key)
74
+ return cache.store;
75
+ // An unparseable store must fail loudly, not read as "no pairings": the
76
+ // latter would silently un-pair every browser and hide the damage.
77
+ const parsed = YAML.parse(readFileSync(p, 'utf-8'));
78
+ const store = { pairings: Array.isArray(parsed?.pairings) ? parsed.pairings : [] };
79
+ cache = { key, store };
80
+ return store;
81
+ }
82
+ async function mutate(fn) {
83
+ const p = pairingsPath();
84
+ mkdirSync(join(homedir(), '.decibel'), { recursive: true });
85
+ return withFileLock(lockPath(), async () => {
86
+ cache = null;
87
+ const store = prune(readStore());
88
+ const result = fn(store);
89
+ if (!existsSync(p))
90
+ writeFileSync(p, '', { mode: 0o600 });
91
+ await writeFileAtomic(p, YAML.stringify(store));
92
+ cache = null;
93
+ return result;
94
+ });
95
+ }
96
+ /** Drop expired pending requests and idle approved pairings. */
97
+ function prune(store, now = Date.now()) {
98
+ store.pairings = store.pairings.filter((p) => {
99
+ if (p.status === 'pending')
100
+ return now - Date.parse(p.requested_at) < PENDING_TTL_MS;
101
+ const last = Date.parse(p.last_used ?? p.approved_at ?? p.requested_at);
102
+ return now - last < IDLE_EXPIRY_MS;
103
+ });
104
+ return store;
105
+ }
106
+ export function listPairings() {
107
+ return prune({ pairings: [...readStore().pairings] }).pairings;
108
+ }
109
+ function activePairing(id) {
110
+ return listPairings().find((p) => p.id === id && p.status === 'approved');
111
+ }
112
+ export function isPairingActive(id) {
113
+ return !!activePairing(id);
114
+ }
115
+ // ----------------------------------------------------------------------------
116
+ // Keys and codes
117
+ // ----------------------------------------------------------------------------
118
+ const B64URL = /^[A-Za-z0-9_-]{43}$/;
119
+ /**
120
+ * A P-256 PUBLIC key and nothing else. A JWK carrying `d` is a private key: the
121
+ * page is supposed to hold a non-extractable key, so receiving one means
122
+ * something is badly wrong, and it is refused rather than stored.
123
+ */
124
+ export function validatePublicJwk(v) {
125
+ const j = v;
126
+ if (!j || typeof j !== 'object')
127
+ throw new SessionError(400, 'BAD_KEY', 'public_key_jwk is required.');
128
+ if ('d' in j)
129
+ throw new SessionError(400, 'BAD_KEY', 'That is a PRIVATE key. Send only the public half; the private key must never leave the browser.');
130
+ if (j.kty !== 'EC' || j.crv !== 'P-256')
131
+ throw new SessionError(400, 'BAD_KEY', 'Only ECDSA P-256 keys are accepted.');
132
+ if (typeof j.x !== 'string' || typeof j.y !== 'string' || !B64URL.test(j.x) || !B64URL.test(j.y)) {
133
+ throw new SessionError(400, 'BAD_KEY', 'Malformed EC coordinates.');
134
+ }
135
+ const jwk = { kty: 'EC', crv: 'P-256', x: j.x, y: j.y };
136
+ try {
137
+ createPublicKey({ key: jwk, format: 'jwk' });
138
+ }
139
+ catch {
140
+ throw new SessionError(400, 'BAD_KEY', 'Not a valid P-256 point.');
141
+ }
142
+ return jwk;
143
+ }
144
+ /** RFC 7638 thumbprint. */
145
+ export function thumbprint(jwk) {
146
+ return createHash('sha256')
147
+ .update(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }))
148
+ .digest('base64url');
149
+ }
150
+ /**
151
+ * The code both sides show. Derived from the key AND a daemon nonce: from the
152
+ * key alone, an attacker could grind keys offline until one lands on a chosen
153
+ * code (cheap at 10^6); with the daemon's nonce mixed in, there is nothing to
154
+ * grind against before asking.
155
+ */
156
+ export function pairingCode(jwk, daemonNonce) {
157
+ const h = createHash('sha256').update(thumbprint(jwk)).update(daemonNonce).digest();
158
+ return String(h.readUInt32BE(0) % 1_000_000).padStart(6, '0');
159
+ }
160
+ // ----------------------------------------------------------------------------
161
+ // Request / status / approve / revoke
162
+ // ----------------------------------------------------------------------------
163
+ export async function requestPairing(origin, jwkIn, labelIn) {
164
+ const jwk = validatePublicJwk(jwkIn);
165
+ const label = typeof labelIn === 'string' ? labelIn.replace(/[\r\n\t]/g, ' ').trim().slice(0, 80) : '';
166
+ return mutate((store) => {
167
+ const pending = store.pairings.filter((p) => p.status === 'pending');
168
+ if (pending.length >= MAX_PENDING_TOTAL || pending.filter((p) => p.origin === origin).length >= MAX_PENDING_PER_ORIGIN) {
169
+ throw new SessionError(429, 'TOO_MANY_PENDING', 'Too many pairing requests are waiting. Approve or let them expire (10 min) first.');
170
+ }
171
+ // Re-requesting with the same key replaces the old pending request.
172
+ const tp = thumbprint(jwk);
173
+ store.pairings = store.pairings.filter((p) => !(p.status === 'pending' && thumbprint(p.public_key_jwk) === tp));
174
+ const taken = new Set(store.pairings.filter((p) => p.status === 'pending').map((p) => p.code));
175
+ let code = '';
176
+ for (let i = 0; i < 20 && (!code || taken.has(code)); i++)
177
+ code = pairingCode(jwk, randomBytes(16).toString('hex'));
178
+ if (taken.has(code))
179
+ throw new SessionError(503, 'CODE_COLLISION', 'Could not allocate a pairing code; try again.');
180
+ const now = new Date();
181
+ const p = {
182
+ id: `pr_${randomBytes(9).toString('hex')}`,
183
+ origin,
184
+ label: label || 'HQ',
185
+ public_key_jwk: jwk,
186
+ status: 'pending',
187
+ code,
188
+ requested_at: now.toISOString(),
189
+ };
190
+ store.pairings.push(p);
191
+ return { pairing_id: p.id, code, expires_at: new Date(now.getTime() + PENDING_TTL_MS).toISOString() };
192
+ });
193
+ }
194
+ export function pairingStatus(id, origin) {
195
+ const p = listPairings().find((x) => x.id === id);
196
+ // A pairing is only reported to the origin it belongs to.
197
+ if (!p || p.origin !== origin)
198
+ return { status: 'unknown' };
199
+ return { status: p.status };
200
+ }
201
+ /** CLI only. Never reachable over HTTP. */
202
+ export async function approveByCode(code) {
203
+ if (!/^\d{6}$/.test(code))
204
+ throw new Error('A pairing code is 6 digits.');
205
+ return mutate((store) => {
206
+ const p = store.pairings.find((x) => x.status === 'pending' && x.code === code);
207
+ if (!p)
208
+ throw new Error(`No pending pairing request with code ${code} (requests expire after 10 minutes).`);
209
+ p.status = 'approved';
210
+ p.approved_at = new Date().toISOString();
211
+ delete p.code;
212
+ return { ...p };
213
+ });
214
+ }
215
+ /**
216
+ * The native macOS dialog's Allow (pairDialog.ts). Never reachable over HTTP:
217
+ * it is called only from the daemon after a local click. It approves the exact
218
+ * request the dialog showed, by id AND code, so a request that was replaced
219
+ * while the dialog was open is not approved by it.
220
+ */
221
+ export async function approvePendingLocally(id, code) {
222
+ return mutate((store) => {
223
+ const p = store.pairings.find((x) => x.id === id && x.status === 'pending' && x.code === code);
224
+ if (!p)
225
+ throw new Error('That pairing request is no longer pending (expired, replaced or already answered).');
226
+ p.status = 'approved';
227
+ p.approved_at = new Date().toISOString();
228
+ delete p.code;
229
+ return { ...p };
230
+ });
231
+ }
232
+ /** CLI, or a signed request from the pairing itself. */
233
+ export async function revokePairing(id) {
234
+ return mutate((store) => {
235
+ const before = store.pairings.length;
236
+ store.pairings = store.pairings.filter((p) => p.id !== id);
237
+ return store.pairings.length < before;
238
+ });
239
+ }
240
+ // ----------------------------------------------------------------------------
241
+ // Nonces and signed requests
242
+ // ----------------------------------------------------------------------------
243
+ const nonces = new Map();
244
+ let clock = Date.now;
245
+ /** Test seam. */
246
+ export function _setPairingClock(fn) {
247
+ clock = fn ?? Date.now;
248
+ }
249
+ function sweepNonces() {
250
+ const t = clock();
251
+ for (const [n, rec] of nonces)
252
+ if (rec.expiresAt <= t)
253
+ nonces.delete(n);
254
+ }
255
+ export function issueNonces(pairingId, origin, countIn) {
256
+ if (typeof pairingId !== 'string')
257
+ throw new SessionError(400, 'BAD_REQUEST', 'pairing_id is required.');
258
+ const p = activePairing(pairingId);
259
+ if (!p || p.origin !== origin)
260
+ throw new SessionError(403, 'NOT_PAIRED', 'No approved pairing with that id for this origin.');
261
+ const count = Math.min(Math.max(1, Math.floor(Number(countIn) || 1)), MAX_NONCES_PER_CHALLENGE);
262
+ sweepNonces();
263
+ const expiresAt = clock() + NONCE_TTL_MS;
264
+ const out = [];
265
+ for (let i = 0; i < count; i++) {
266
+ const n = randomBytes(24).toString('base64url');
267
+ nonces.set(n, { pairingId, expiresAt });
268
+ out.push(n);
269
+ }
270
+ return { nonces: out, expires_at: new Date(expiresAt).toISOString() };
271
+ }
272
+ /**
273
+ * Exactly what the browser signs. The body is not included: replay is stopped
274
+ * by the single-use nonce, and anything able to rewrite a loopback request in
275
+ * flight is already past every boundary this could add.
276
+ */
277
+ export function signingPayload(method, pathAndQuery, origin, pairingId, nonce, iat) {
278
+ return ['decibel-pair-v1', method.toUpperCase(), pathAndQuery, origin, pairingId, nonce, String(iat)].join('\n');
279
+ }
280
+ const pairedRequests = new WeakMap();
281
+ /** The pairing id a request was verified under, if it was. */
282
+ export function pairingOf(req) {
283
+ return pairedRequests.get(req);
284
+ }
285
+ export function hasPairingHeaders(req) {
286
+ return typeof req.headers['x-pairing-id'] === 'string';
287
+ }
288
+ /**
289
+ * Verify a signed request. Order is the ADR's: loopback, origin allowlist,
290
+ * pairing approved and bound to this origin, freshness, nonce (burned before
291
+ * the signature check, so a bad signature still spends it), signature.
292
+ */
293
+ export function verifyPairedRequest(req, pathAndQuery, allowedOrigins) {
294
+ const h = (k) => (typeof req.headers[k] === 'string' ? req.headers[k] : '');
295
+ const origin = h('origin');
296
+ if (!isLoopbackPeer(req))
297
+ throw new SessionError(403, 'FORBIDDEN', 'not a loopback peer');
298
+ if (!isAllowedOrigin(origin, allowedOrigins))
299
+ throw new SessionError(403, 'FORBIDDEN', 'origin not allowed');
300
+ const pairingId = h('x-pairing-id');
301
+ const nonce = h('x-pairing-nonce');
302
+ const iat = Number(h('x-pairing-iat'));
303
+ const sig = h('x-pairing-sig');
304
+ if (!pairingId || !nonce || !Number.isFinite(iat) || !sig) {
305
+ throw new SessionError(401, 'BAD_SIGNATURE', 'X-Pairing-Id, -Nonce, -Iat and -Sig are all required.');
306
+ }
307
+ const p = activePairing(pairingId);
308
+ if (!p || p.origin !== origin)
309
+ throw new SessionError(401, 'NOT_PAIRED', 'No approved pairing with that id for this origin.');
310
+ if (Math.abs(clock() - iat) > IAT_SKEW_MS)
311
+ throw new SessionError(401, 'STALE_REQUEST', 'X-Pairing-Iat is outside the allowed window.');
312
+ sweepNonces();
313
+ const rec = nonces.get(nonce);
314
+ nonces.delete(nonce);
315
+ if (!rec || rec.pairingId !== pairingId)
316
+ throw new SessionError(401, 'BAD_NONCE', 'Unknown, reused or expired nonce.');
317
+ const payload = signingPayload(req.method || 'GET', pathAndQuery, origin, pairingId, nonce, iat);
318
+ let ok = false;
319
+ try {
320
+ ok = cryptoVerify('sha256', Buffer.from(payload, 'utf-8'), { key: createPublicKey({ key: p.public_key_jwk, format: 'jwk' }), dsaEncoding: 'ieee-p1363' }, Buffer.from(sig, 'base64url'));
321
+ }
322
+ catch {
323
+ ok = false;
324
+ }
325
+ if (!ok)
326
+ throw new SessionError(401, 'BAD_SIGNATURE', 'Signature does not verify.');
327
+ pairedRequests.set(req, pairingId);
328
+ touch(p);
329
+ return pairingId;
330
+ }
331
+ const lastTouched = new Map();
332
+ function touch(p) {
333
+ const now = clock();
334
+ const last = lastTouched.get(p.id) ?? Date.parse(p.last_used ?? '') ?? 0;
335
+ if (now - (Number.isFinite(last) ? last : 0) < LAST_USED_WRITE_MS)
336
+ return;
337
+ lastTouched.set(p.id, now);
338
+ mutate((store) => {
339
+ const q = store.pairings.find((x) => x.id === p.id);
340
+ if (q)
341
+ q.last_used = new Date(now).toISOString();
342
+ }).catch(() => undefined);
343
+ }
344
+ /** Test seam. */
345
+ export function _resetPairing() {
346
+ nonces.clear();
347
+ lastTouched.clear();
348
+ cache = null;
349
+ clock = Date.now;
350
+ }
351
+ //# sourceMappingURL=pairing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/pty/pairing.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,6DAA6D;AAC7D,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,4EAA4E;AAC5E,0DAA0D;AAC1D,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,8EAA8E;AAC9E,+BAA+B;AAC/B,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,0DAA0D;AAC1D,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,IAAI,YAAY,EAAmB,MAAM,QAAQ,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM,CAAC;AAC1C,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;AACpD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AACnC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAClC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,2DAA2D;AAC3D,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,CAAC;AA0BvC,+EAA+E;AAC/E,2CAA2C;AAC3C,+EAA+E;AAE/E,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AACD,SAAS,QAAQ;IACf,OAAO,YAAY,EAAE,GAAG,OAAO,CAAC;AAClC,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;GAOG;AACH,IAAI,KAAK,GAAyC,IAAI,CAAC;AAEvD,SAAS,SAAS;IAChB,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACnB,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IACjD,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IACnD,wEAAwE;IACxE,mEAAmE;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAA0B,CAAC;IAC7E,MAAM,KAAK,GAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3F,KAAK,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,MAAM,CAAI,EAAuB;IAC9C,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE;QACzC,KAAK,GAAG,IAAI,CAAC;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,MAAM,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChD,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gEAAgE;AAChE,SAAS,KAAK,CAAC,KAAY,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC3C,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3C,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,cAAc,CAAC;QACrF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC;QACxE,OAAO,GAAG,GAAG,IAAI,GAAG,cAAc,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC;AACjE,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,OAAO,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,MAAM,GAAG,qBAAqB,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAU;IAC1C,MAAM,CAAC,GAAG,CAAmC,CAAC;IAC9C,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACvG,IAAI,GAAG,IAAI,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,iGAAiG,CAAC,CAAC;IACxJ,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,qCAAqC,CAAC,CAAC;IACvH,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,GAAG,GAAc,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,IAAI,CAAC;QACH,eAAe,CAAC,EAAE,GAAG,EAAE,GAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,UAAU,CAAC,GAAc;IACvC,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;SAC1E,MAAM,CAAC,WAAW,CAAC,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAc,EAAE,WAAmB;IAC7D,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC;IACpF,OAAO,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAChE,CAAC;AAED,+EAA+E;AAC/E,sCAAsC;AACtC,+EAA+E;AAE/E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,KAAc,EAAE,OAAgB;IACnF,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvG,OAAO,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,MAAM,IAAI,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,IAAI,sBAAsB,EAAE,CAAC;YACvH,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,kBAAkB,EAAE,mFAAmF,CAAC,CAAC;QACvI,CAAC;QACD,oEAAoE;QACpE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC3B,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAEhH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/F,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE;YAAE,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACpH,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE,+CAA+C,CAAC,CAAC;QAEpH,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAY;YACjB,EAAE,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;YAC1C,MAAM;YACN,KAAK,EAAE,KAAK,IAAI,IAAI;YACpB,cAAc,EAAE,GAAG;YACnB,MAAM,EAAE,SAAS;YACjB,IAAI;YACJ,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE;SAChC,CAAC;QACF,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IACxG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU,EAAE,MAAc;IACtD,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,0DAA0D;IAC1D,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC5D,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,2CAA2C;AAC3C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC1E,OAAO,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAChF,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,sCAAsC,CAAC,CAAC;QAC5G,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,IAAI,CAAC;QACd,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAAU,EAAE,IAAY;IAClE,OAAO,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC/F,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QAC9G,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,IAAI,CAAC;QACd,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAU;IAC5C,OAAO,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoD,CAAC;AAC3E,IAAI,KAAK,GAAiB,IAAI,CAAC,GAAG,CAAC;AACnC,iBAAiB;AACjB,MAAM,UAAU,gBAAgB,CAAC,EAAyB;IACxD,KAAK,GAAG,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC;AACzB,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;IAClB,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM;QAAE,IAAI,GAAG,CAAC,SAAS,IAAI,CAAC;YAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAkB,EAAE,MAAc,EAAE,OAAgB;IAC9E,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,yBAAyB,CAAC,CAAC;IACzG,MAAM,CAAC,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,mDAAmD,CAAC,CAAC;IAC9H,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAChG,WAAW,EAAE,CAAC;IACd,MAAM,SAAS,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;IACzC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACxC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,YAAoB,EAAE,MAAc,EAAE,SAAiB,EAAE,KAAa,EAAE,GAAW;IAChI,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnH,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,OAAO,EAA2B,CAAC;AAE9D,8DAA8D;AAC9D,MAAM,UAAU,SAAS,CAAC,GAAoB;IAC5C,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,OAAO,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAoB,EAAE,YAAoB,EAAE,cAAwB;IACtG,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChG,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAC1F,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,cAAc,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAE7G,MAAM,SAAS,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC;IAC/B,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1D,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,uDAAuD,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,CAAC,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,mDAAmD,CAAC,CAAC;IAC9H,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,GAAG,WAAW;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,8CAA8C,CAAC,CAAC;IAExI,WAAW,EAAE,CAAC;IACd,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,mCAAmC,CAAC,CAAC;IAEvH,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACjG,IAAI,EAAE,GAAG,KAAK,CAAC;IACf,IAAI,CAAC;QACH,EAAE,GAAG,YAAY,CACf,QAAQ,EACR,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7B,EAAE,GAAG,EAAE,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,cAA4B,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAC3G,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAC9B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,GAAG,KAAK,CAAC;IACb,CAAC;IACD,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,4BAA4B,CAAC,CAAC;IAEpF,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,CAAC,CAAC,CAAC;IACT,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC9C,SAAS,KAAK,CAAC,CAAU;IACvB,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IACpB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IACzE,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,kBAAkB;QAAE,OAAO;IAC1E,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC;YAAE,CAAC,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,CAAC;IACpB,KAAK,GAAG,IAAI,CAAC;IACb,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC;AACnB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { IncomingMessage, ServerResponse } from 'http';
2
+ import type { Duplex } from 'stream';
3
+ /** How long a minted attach token stays usable. Deliberately short. */
4
+ export declare const ATTACH_TOKEN_TTL_MS = 30000;
5
+ /** HQ dev server, through the Vite proxy (decibel-hq EPIC-0015 phase 1). */
6
+ export declare const DEFAULT_SESSION_ORIGINS: string[];
7
+ export interface SessionAuthConfig {
8
+ token?: string;
9
+ allowedOrigins: string[];
10
+ }
11
+ export declare function sessionAuthConfig(): SessionAuthConfig;
12
+ /** Test seam. */
13
+ export declare function _setSessionAuthConfig(c: SessionAuthConfig | null): void;
14
+ /** Test seam. */
15
+ export declare function _setClock(fn: (() => number) | null): void;
16
+ export declare function outstandingTokens(): number;
17
+ /** The routes this module gates itself. GET /sessions and /sessions/last-fleet are NOT among them. */
18
+ export declare function isSessionWritePath(path: string): boolean;
19
+ export declare function isSessionAttachPath(path: string): boolean;
20
+ /**
21
+ * Handle a session write route or its preflight. Called by httpServer.ts for
22
+ * any path where isSessionWritePath() is true, before the daemon's own auth
23
+ * gate (which knows nothing of the sessions bearer).
24
+ */
25
+ export declare function handleSessionWrite(req: IncomingMessage, res: ServerResponse, path: string): Promise<void>;
26
+ /**
27
+ * POST /chat (decibel-hq EPIC-0016): send as the HQ chat peer. Same gate as
28
+ * the session writes: it puts text into other sessions.
29
+ */
30
+ export declare function handleChatWrite(req: IncomingMessage, res: ServerResponse): Promise<void>;
31
+ /**
32
+ * Signed requests from a paired browser (ADR-0012 in this repo). httpServer.ts
33
+ * calls this once per request, before rate limiting and auth. A verified
34
+ * request is marked (pairingOf) and stands in for a bearer everywhere after.
35
+ * A request that CLAIMS a pairing and fails verification is refused outright
36
+ * rather than falling through as anonymous. Returns false when it refused.
37
+ */
38
+ export declare function applyPairingAuth(req: IncomingMessage, res: ServerResponse, url: URL): boolean;
39
+ export declare function isPairPath(path: string): boolean;
40
+ export declare function handlePair(req: IncomingMessage, res: ServerResponse, path: string): Promise<void>;
41
+ export declare function closeRevokedSockets(): number;
42
+ /**
43
+ * Handle an upgrade on /sessions/<key>/attach. The caller (httpServer.ts)
44
+ * routes here only for that path; anything else it refuses itself.
45
+ */
46
+ export declare function handleSessionUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, url: URL): Promise<void>;
47
+ /** Close every live attach socket (daemon shutdown). */
48
+ export declare function closeAllAttachSockets(): void;
49
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/pty/routes.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AA0CrC,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAG1C,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,UAAqD,CAAC;AAoB1F,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAWD,wBAAgB,iBAAiB,IAAI,iBAAiB,CAWrD;AACD,iBAAiB;AACjB,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAGvE;AAcD,iBAAiB;AACjB,wBAAgB,SAAS,CAAC,EAAE,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAEzD;AACD,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAcD,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AA8ED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+D/G;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9F;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAkB7F;AAUD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDvG;AAiCD,wBAAgB,mBAAmB,IAAI,MAAM,CAkB5C;AAuBD;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAkItH;AAED,wDAAwD;AACxD,wBAAgB,qBAAqB,IAAI,IAAI,CAS5C"}