@spexcode/spec-cli 0.6.5

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 (201) hide show
  1. package/README.md +95 -0
  2. package/bin/spex.mjs +76 -0
  3. package/dist/attach.d.ts +2 -0
  4. package/dist/attach.js +48 -0
  5. package/dist/claude-headless.d.ts +33 -0
  6. package/dist/claude-headless.js +307 -0
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.js +1859 -0
  9. package/dist/client.d.ts +111 -0
  10. package/dist/client.js +476 -0
  11. package/dist/cockpit.d.ts +7 -0
  12. package/dist/cockpit.js +26 -0
  13. package/dist/codex-headless.d.ts +1 -0
  14. package/dist/codex-headless.js +7 -0
  15. package/dist/codex-runtime-generations.d.ts +53 -0
  16. package/dist/codex-runtime-generations.js +686 -0
  17. package/dist/commit-surgery.d.ts +1 -0
  18. package/dist/commit-surgery.js +90 -0
  19. package/dist/contract-filter.d.ts +14 -0
  20. package/dist/contract-filter.js +219 -0
  21. package/dist/dashboard-assets.d.ts +6 -0
  22. package/dist/dashboard-assets.js +50 -0
  23. package/dist/delivery-queue.d.ts +23 -0
  24. package/dist/delivery-queue.js +179 -0
  25. package/dist/doctor.d.ts +9 -0
  26. package/dist/doctor.js +547 -0
  27. package/dist/eval-host.d.ts +1 -0
  28. package/dist/eval-host.js +19 -0
  29. package/dist/execution-trace.d.ts +26 -0
  30. package/dist/execution-trace.js +475 -0
  31. package/dist/file-write.d.ts +2 -0
  32. package/dist/file-write.js +26 -0
  33. package/dist/flat.d.ts +89 -0
  34. package/dist/flat.js +1076 -0
  35. package/dist/gateway-auth.d.ts +56 -0
  36. package/dist/gateway-auth.js +168 -0
  37. package/dist/gateway-hub.d.ts +28 -0
  38. package/dist/gateway-hub.js +361 -0
  39. package/dist/gateway.d.ts +37 -0
  40. package/dist/gateway.js +503 -0
  41. package/dist/graphCache.d.ts +27 -0
  42. package/dist/graphCache.js +716 -0
  43. package/dist/graphSnapshot.d.ts +14 -0
  44. package/dist/graphSnapshot.js +35 -0
  45. package/dist/graphStream.d.ts +85 -0
  46. package/dist/graphStream.js +1195 -0
  47. package/dist/guidance-catalog.d.ts +64 -0
  48. package/dist/guidance-catalog.js +166 -0
  49. package/dist/guide.d.ts +8 -0
  50. package/dist/guide.js +684 -0
  51. package/dist/harness-select.d.ts +18 -0
  52. package/dist/harness-select.js +62 -0
  53. package/dist/harness.d.ts +325 -0
  54. package/dist/harness.js +3026 -0
  55. package/dist/headless-controller.d.ts +9 -0
  56. package/dist/headless-controller.js +47 -0
  57. package/dist/help.d.ts +10 -0
  58. package/dist/help.js +574 -0
  59. package/dist/hook-prompts.d.ts +18 -0
  60. package/dist/hook-prompts.js +122 -0
  61. package/dist/hooks.d.ts +1 -0
  62. package/dist/hooks.js +27 -0
  63. package/dist/host-resources.d.ts +97 -0
  64. package/dist/host-resources.js +795 -0
  65. package/dist/host.d.ts +88 -0
  66. package/dist/host.js +663 -0
  67. package/dist/index.d.ts +1 -0
  68. package/dist/index.js +899 -0
  69. package/dist/init.d.ts +1 -0
  70. package/dist/init.js +284 -0
  71. package/dist/issues-cli.d.ts +6 -0
  72. package/dist/issues-cli.js +334 -0
  73. package/dist/issues.d.ts +69 -0
  74. package/dist/issues.js +189 -0
  75. package/dist/lint.d.ts +34 -0
  76. package/dist/lint.js +476 -0
  77. package/dist/listen.d.ts +7 -0
  78. package/dist/listen.js +24 -0
  79. package/dist/localIssues.d.ts +65 -0
  80. package/dist/localIssues.js +582 -0
  81. package/dist/login-page.d.ts +5 -0
  82. package/dist/login-page.js +86 -0
  83. package/dist/loop-in.d.ts +23 -0
  84. package/dist/loop-in.js +68 -0
  85. package/dist/machine-peer.d.ts +69 -0
  86. package/dist/machine-peer.js +603 -0
  87. package/dist/materialize.d.ts +18 -0
  88. package/dist/materialize.js +468 -0
  89. package/dist/mentions.d.ts +50 -0
  90. package/dist/mentions.js +117 -0
  91. package/dist/opencode-headless.d.ts +4 -0
  92. package/dist/opencode-headless.js +208 -0
  93. package/dist/opencode.d.ts +3 -0
  94. package/dist/opencode.js +142 -0
  95. package/dist/pi-harness.d.ts +3 -0
  96. package/dist/pi-harness.js +129 -0
  97. package/dist/pi-headless.d.ts +25 -0
  98. package/dist/pi-headless.js +196 -0
  99. package/dist/plugin-harness.d.ts +21 -0
  100. package/dist/plugin-harness.js +146 -0
  101. package/dist/pty-bridge.d.ts +10 -0
  102. package/dist/pty-bridge.js +404 -0
  103. package/dist/pty-helper.d.mts +1 -0
  104. package/dist/pty-helper.mjs +101 -0
  105. package/dist/pty-native-helper.d.mts +2 -0
  106. package/dist/pty-native-helper.mjs +23 -0
  107. package/dist/public-graph.d.ts +46 -0
  108. package/dist/public-graph.js +56 -0
  109. package/dist/ranker.d.ts +15 -0
  110. package/dist/ranker.js +188 -0
  111. package/dist/reaper.d.ts +6 -0
  112. package/dist/reaper.js +81 -0
  113. package/dist/reviews.d.ts +189 -0
  114. package/dist/reviews.js +350 -0
  115. package/dist/runtime-guard.d.ts +6 -0
  116. package/dist/runtime-guard.js +37 -0
  117. package/dist/runtime-ownership.d.ts +21 -0
  118. package/dist/runtime-ownership.js +84 -0
  119. package/dist/search.bench.d.mts +1 -0
  120. package/dist/search.bench.mjs +75 -0
  121. package/dist/search.d.ts +20 -0
  122. package/dist/search.js +61 -0
  123. package/dist/session-cursors.d.ts +14 -0
  124. package/dist/session-cursors.js +82 -0
  125. package/dist/session-declarations.d.ts +13 -0
  126. package/dist/session-declarations.js +126 -0
  127. package/dist/session-execution.d.ts +10 -0
  128. package/dist/session-execution.js +70 -0
  129. package/dist/session-files.d.ts +28 -0
  130. package/dist/session-files.js +130 -0
  131. package/dist/session-follow.d.ts +31 -0
  132. package/dist/session-follow.js +179 -0
  133. package/dist/session-reparent.d.ts +10 -0
  134. package/dist/session-reparent.js +33 -0
  135. package/dist/session-timeline.d.ts +51 -0
  136. package/dist/session-timeline.js +233 -0
  137. package/dist/session-web.d.ts +24 -0
  138. package/dist/session-web.js +141 -0
  139. package/dist/sessions.d.ts +412 -0
  140. package/dist/sessions.js +4239 -0
  141. package/dist/sh.d.ts +1 -0
  142. package/dist/sh.js +3 -0
  143. package/dist/shim-runtime.d.ts +1 -0
  144. package/dist/shim-runtime.js +161 -0
  145. package/dist/slash-commands.d.ts +9 -0
  146. package/dist/slash-commands.js +307 -0
  147. package/dist/source-files.d.ts +9 -0
  148. package/dist/source-files.js +113 -0
  149. package/dist/supervise.d.ts +1 -0
  150. package/dist/supervise.js +308 -0
  151. package/dist/tree.d.ts +25 -0
  152. package/dist/tree.js +98 -0
  153. package/dist/tsx-bin.d.ts +3 -0
  154. package/dist/tsx-bin.js +41 -0
  155. package/dist/uninstall.d.ts +3 -0
  156. package/dist/uninstall.js +177 -0
  157. package/dist/uploads.d.ts +36 -0
  158. package/dist/uploads.js +243 -0
  159. package/dist/worktree-sources.d.ts +1 -0
  160. package/dist/worktree-sources.js +47 -0
  161. package/hooks/compat/mark-active-0.5.2-eef1.fixture +53 -0
  162. package/hooks/compat/mark-active-sed-v0.fixture +46 -0
  163. package/hooks/dispatch.sh +105 -0
  164. package/hooks/harness.sh +272 -0
  165. package/package.json +47 -0
  166. package/templates/hooks/commit-msg +14 -0
  167. package/templates/hooks/post-checkout +25 -0
  168. package/templates/hooks/post-merge +34 -0
  169. package/templates/hooks/pre-commit +120 -0
  170. package/templates/hooks/prepare-commit-msg +35 -0
  171. package/templates/hooks/reference-transaction +105 -0
  172. package/templates/spec/project/.plugins/commands/extract/spec.md +66 -0
  173. package/templates/spec/project/.plugins/commands/regroup/spec.md +25 -0
  174. package/templates/spec/project/.plugins/commands/rename/spec.md +11 -0
  175. package/templates/spec/project/.plugins/commands/spec.md +30 -0
  176. package/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
  177. package/templates/spec/project/.plugins/commands/tidy/spec.md +43 -0
  178. package/templates/spec/project/.plugins/core/comment-altitude/spec.md +9 -0
  179. package/templates/spec/project/.plugins/core/idle/idle.sh +15 -0
  180. package/templates/spec/project/.plugins/core/idle/spec.md +13 -0
  181. package/templates/spec/project/.plugins/core/mark-active/mark-active.sh +59 -0
  182. package/templates/spec/project/.plugins/core/mark-active/spec.md +22 -0
  183. package/templates/spec/project/.plugins/core/session-fail/fail.sh +12 -0
  184. package/templates/spec/project/.plugins/core/session-fail/spec.md +15 -0
  185. package/templates/spec/project/.plugins/core/spec-first/spec-first.sh +43 -0
  186. package/templates/spec/project/.plugins/core/spec-first/spec.md +17 -0
  187. package/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +66 -0
  188. package/templates/spec/project/.plugins/core/spec-of-file/spec.md +15 -0
  189. package/templates/spec/project/.plugins/core/spec.md +22 -0
  190. package/templates/spec/project/.plugins/core/stop-gate/spec.md +23 -0
  191. package/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +149 -0
  192. package/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +15 -0
  193. package/templates/spec/project/.plugins/prompts/forge-link/spec.md +10 -0
  194. package/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +13 -0
  195. package/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +12 -0
  196. package/templates/spec/project/.plugins/prompts/spec.md +24 -0
  197. package/templates/spec/project/.plugins/skills/distill/digest.mjs +136 -0
  198. package/templates/spec/project/.plugins/skills/distill/spec.md +67 -0
  199. package/templates/spec/project/.plugins/skills/spec.md +19 -0
  200. package/templates/spec/project/.plugins/spec.md +23 -0
  201. package/templates/spec/project/spec.md +20 -0
@@ -0,0 +1,86 @@
1
+ // @@@ login page - the gateway's gate is a DESIGNED page, not the browser's Basic-auth dialog (which can't
2
+ // be styled and feels like a 1998 intranet). Self-contained: inline CSS + SVG, zero external assets, so it
3
+ // renders before anything is authorised. Dark, calm, a single password field; an error state when the
4
+ // password is wrong. The form POSTs to `action` (same-origin), which mints the auth cookie and redirects.
5
+ // One page serves every gate: the single-project gateway's /login (the defaults) and the multi-project
6
+ // hub's admin + per-project logins ([[gateway-hub]] passes action/heading/sub). Every option is
7
+ // HTML-escaped at this sink — projectIds are path-derived, attacker-influencable strings.
8
+ export function loginPage(error = false, opts = {}) {
9
+ const esc = (s) => s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
10
+ const action = esc(opts.action ?? '/login');
11
+ const heading = esc(opts.heading ?? 'Restricted access');
12
+ const sub = esc(opts.sub ?? 'This is a private agent workspace. Enter the access password to continue.');
13
+ return `<!doctype html>
14
+ <html lang="en">
15
+ <head>
16
+ <meta charset="utf-8">
17
+ <meta name="viewport" content="width=device-width, initial-scale=1">
18
+ <title>SpexCode — sign in</title>
19
+ <style>
20
+ :root { color-scheme: dark; }
21
+ * { box-sizing: border-box; }
22
+ body {
23
+ margin: 0; min-height: 100vh; display: grid; place-items: center;
24
+ font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
25
+ color: #e7ecf3;
26
+ background:
27
+ radial-gradient(900px 600px at 50% -10%, #1b2b4d 0%, rgba(27,43,77,0) 60%),
28
+ radial-gradient(700px 500px at 85% 110%, #1d3b39 0%, rgba(29,59,57,0) 55%),
29
+ #080b12;
30
+ }
31
+ .card {
32
+ width: min(92vw, 360px); padding: 38px 34px 30px;
33
+ background: linear-gradient(180deg, rgba(22,28,40,0.92), rgba(15,19,28,0.92));
34
+ border: 1px solid rgba(120,150,200,0.16); border-radius: 18px;
35
+ box-shadow: 0 30px 80px -30px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.04);
36
+ backdrop-filter: blur(8px);
37
+ }
38
+ .mark { display: flex; align-items: center; gap: 11px; margin-bottom: 26px; }
39
+ .mark svg { width: 30px; height: 30px; }
40
+ .mark b { font-size: 17px; font-weight: 650; letter-spacing: 0.2px; }
41
+ .mark b span { color: #6ea0ff; }
42
+ h1 { font-size: 15px; font-weight: 550; margin: 0 0 4px; }
43
+ p.sub { margin: 0 0 22px; font-size: 12.5px; line-height: 1.5; color: #8b97aa; }
44
+ label { display: block; font-size: 11px; letter-spacing: 0.4px; text-transform: uppercase; color: #8b97aa; margin: 0 0 8px; }
45
+ input {
46
+ width: 100%; padding: 12px 14px; font-size: 14px; color: #eef2f8;
47
+ background: #0c1019; border: 1px solid rgba(120,150,200,0.22); border-radius: 11px;
48
+ outline: none; transition: border-color .15s, box-shadow .15s;
49
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 2px;
50
+ }
51
+ input:focus { border-color: #4f7fe0; box-shadow: 0 0 0 3px rgba(79,127,224,0.18); }
52
+ button {
53
+ width: 100%; margin-top: 16px; padding: 12px 14px; font-size: 14px; font-weight: 600;
54
+ color: #fff; cursor: pointer; border: 0; border-radius: 11px;
55
+ background: linear-gradient(180deg, #4f86f7, #3f6fe0);
56
+ box-shadow: 0 8px 22px -8px rgba(63,111,224,0.7); transition: filter .15s, transform .05s;
57
+ }
58
+ button:hover { filter: brightness(1.07); }
59
+ button:active { transform: translateY(1px); }
60
+ .err {
61
+ margin: 0 0 16px; padding: 9px 12px; font-size: 12.5px; border-radius: 9px;
62
+ color: #ffd2cf; background: rgba(220,80,70,0.12); border: 1px solid rgba(220,80,70,0.32);
63
+ }
64
+ .foot { margin-top: 22px; font-size: 11px; color: #69748a; text-align: center; line-height: 1.5; }
65
+ </style>
66
+ </head>
67
+ <body>
68
+ <form class="card" method="POST" action="${action}" autocomplete="off">
69
+ <div class="mark">
70
+ <svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
71
+ <rect x="2" y="2" width="28" height="28" rx="8" fill="#0e1626" stroke="#3f6fe0" stroke-opacity="0.5"/>
72
+ <path d="M11 12.5C11 10.6 12.6 9 14.5 9h3a3.5 3.5 0 0 1 0 7h-3a3.5 3.5 0 0 0 0 7h3c1.9 0 3.5-1.6 3.5-3.5" stroke="#6ea0ff" stroke-width="2" stroke-linecap="round"/>
73
+ </svg>
74
+ <b>Spex<span>Code</span></b>
75
+ </div>
76
+ <h1>${heading}</h1>
77
+ <p class="sub">${sub}</p>
78
+ ${error ? '<div class="err">Incorrect password — try again.</div>' : ''}
79
+ <label for="password">Password</label>
80
+ <input id="password" name="password" type="password" autofocus required placeholder="••••••••••">
81
+ <button type="submit">Sign in</button>
82
+ <div class="foot">Trusted collaborators only.</div>
83
+ </form>
84
+ </body>
85
+ </html>`;
86
+ }
@@ -0,0 +1,23 @@
1
+ import { type LoopIn } from './mentions.js';
2
+ import { replyIssue } from './issues.js';
3
+ import { remarkOnHost } from './localIssues.js';
4
+ /** `issue reply` for every store, with the originator loop-in composed on top. */
5
+ export declare function replyIssueWithLoopIn(id: string, body: string, opts?: {
6
+ author?: string;
7
+ node?: string | null;
8
+ evidence?: string[];
9
+ }): Promise<Awaited<ReturnType<typeof replyIssue>> & {
10
+ loopIn: LoopIn | null;
11
+ }>;
12
+ /** `remark add` on a host, with the same loop-in composed by the same code. */
13
+ export declare function remarkWithLoopIn(host: {
14
+ issue?: string;
15
+ node?: string;
16
+ scenario?: string;
17
+ }, body: string, opts?: {
18
+ codeSha?: string;
19
+ author?: string;
20
+ evidence?: string[];
21
+ }): Promise<Awaited<ReturnType<typeof remarkOnHost>> & {
22
+ loopIn: LoopIn | null;
23
+ }>;
@@ -0,0 +1,68 @@
1
+ import { notifyOriginator } from './mentions.js';
2
+ import { replyIssue } from './issues.js';
3
+ import { parseEvalConcern, remarkOnHost } from './localIssues.js';
4
+ // @@@ loop-in - the originator loop-in's eval-aware half, at the one altitude that can hold it
5
+ // ([[mentions]] / [[remark-substrate]] R3). The MECHANISM never moved: `notifyOriginator`, `summarizeLoopIn` and
6
+ // `LoopIn` live in `mentions.ts`, genuine substrate, and they stay there. What lived at the wrong height was a
7
+ // single INPUT — resolving WHICH candidates to try, which for an eval-remark thread means asking the eval
8
+ // package who filed the reading under judgement. That resolution sat in `localIssues.ts`, a module the eval
9
+ // package imports, so it could only reach eval through a deferred `await import()` whose own comment explained
10
+ // why it had to be wrong. A correct mechanism with one mis-layered input is the hardest shape to see: every
11
+ // piece you read is where it belongs.
12
+ //
13
+ // This module sits above both the store modules and the eval layer, so the import is an ordinary static one.
14
+ // @@@ ONE composer per path - the loop-in is reachable from four call sites: the CLI's `issue reply` and
15
+ // `remark add`, and the HTTP routes for each. If each composed its own chain, the same verb would report
16
+ // different candidates depending on which door it came through, and no gate we have would notice the drift.
17
+ // So the four sites call these two functions, and these two are the only places a chain is built.
18
+ // A node's governing session — the `session` its spec resolves to (the Session: trailer of its latest version,
19
+ // else the frontmatter `session:` fallback; specs.ts owns that derivation). The fallback link when a reading's
20
+ // filer is unreachable. null when the node is unknown or has no governing session.
21
+ async function nodeGoverningSession(nodeId) {
22
+ const { loadSpecs } = await import('@spexcode/spec-core');
23
+ return (await loadSpecs()).find((s) => s.id === nodeId)?.session ?? null;
24
+ }
25
+ // The FALLBACK CHAIN of candidates a reply loops in, tried in order until one is online.
26
+ // A plain thread's only candidate is its author. An EVAL-COMMENT thread (concern `eval: <node> · <scenario>`)
27
+ // chains: the agent who FILED the reading the remark judges FIRST — resolved from the TRUNK sidecar, then from
28
+ // each LIVE session's worktree sidecar (the review-time case, when the filer sits online awaiting review) —
29
+ // then the NODE's governing session, so an unresolved remark still reaches an agent who can act on it. A
30
+ // broken/absent worktree sidecar falls through silently: one bad worktree never fails the remark write.
31
+ // Non-eval threads pay nothing — no eval, specs or sessions module is touched for them.
32
+ async function threadOriginators(thread) {
33
+ const parsed = parseEvalConcern(thread.concern);
34
+ if (!parsed)
35
+ return [thread.by];
36
+ const { node, scenario } = parsed;
37
+ const { evalReadingFiler } = await import('@spexcode/spec-eval/filing');
38
+ const chain = [evalReadingFiler(node, scenario)];
39
+ try {
40
+ const { listSessions } = await import('./sessions.js');
41
+ for (const s of await listSessions()) {
42
+ try {
43
+ if (s.path)
44
+ chain.push(evalReadingFiler(node, scenario, s.path));
45
+ }
46
+ catch { /* one unreadable worktree → next link */ }
47
+ }
48
+ }
49
+ catch { /* sessions unavailable (bare store, no tmux) → trunk-only chain, as before */ }
50
+ chain.push(await nodeGoverningSession(node));
51
+ return chain;
52
+ }
53
+ // the implicit courtesy copy every reply carries: a copy down the fallback chain, delivered to the first online
54
+ // link, notification only — it resolves nothing (R3 keeps resolve a deliberate second-party act).
55
+ const loopInFor = async (thread, author, body, threadId) => notifyOriginator(await threadOriginators(thread), author, body, { threadId, node: thread.nodes[0] || null });
56
+ /** `issue reply` for every store, with the originator loop-in composed on top. */
57
+ export async function replyIssueWithLoopIn(id, body, opts = {}) {
58
+ const r = await replyIssue(id, body, opts);
59
+ // a forge thread's author is a host login, not a live session, so there is no reachable originator and no
60
+ // local thread to read one from — silent by design, exactly as before.
61
+ const loopIn = r.thread ? await loopInFor(r.thread, r.author, body, id) : null;
62
+ return { ...r, loopIn };
63
+ }
64
+ /** `remark add` on a host, with the same loop-in composed by the same code. */
65
+ export async function remarkWithLoopIn(host, body, opts = {}) {
66
+ const r = await remarkOnHost(host, body, opts);
67
+ return { ...r, loopIn: await loopInFor(r.thread, r.author, body, r.thread.id) };
68
+ }
@@ -0,0 +1,69 @@
1
+ export type MachinePeer = {
2
+ machineId: string;
3
+ sshAddress: string;
4
+ inboundPort: number;
5
+ outboundPort: number;
6
+ remoteInboundPort: number;
7
+ remoteOutboundPort: number;
8
+ owner: boolean;
9
+ state: 'connecting' | 'connected';
10
+ createdAt: string;
11
+ lastOkAt: string | null;
12
+ lastError: string | null;
13
+ };
14
+ export declare const peerStorePath: () => string;
15
+ export declare const peerSocketPath: () => string;
16
+ export declare function listMachinePeers(): MachinePeer[];
17
+ export declare function readPeerMachineId(): string;
18
+ export declare function peerSenderRef(machineId: string, sessionId?: string): string;
19
+ export declare function findMachinePeer(sshAddress: string): MachinePeer | null;
20
+ export declare function resolveMachinePeer(sshAddress: string): MachinePeer;
21
+ export type PeerRpcRequest = {
22
+ op: 'list';
23
+ } | {
24
+ op: 'connect';
25
+ sshAddress: string;
26
+ } | {
27
+ op: 'accept';
28
+ sourceMachineId: string;
29
+ sshAddress: string;
30
+ remoteInboundPort: number;
31
+ remoteOutboundPort: number;
32
+ } | {
33
+ op: 'disconnect';
34
+ sshAddress: string;
35
+ } | {
36
+ op: 'drop';
37
+ machineId: string;
38
+ };
39
+ type RpcResponse = {
40
+ ok: true;
41
+ peer?: MachinePeer;
42
+ peers?: MachinePeer[];
43
+ machineId?: string;
44
+ } | {
45
+ ok: false;
46
+ error: string;
47
+ };
48
+ export declare class MachinePeerGateway {
49
+ private readonly inbound;
50
+ private readonly children;
51
+ private control;
52
+ private retry;
53
+ private closing;
54
+ start(): void;
55
+ private startControl;
56
+ private handleRpc;
57
+ private startInbound;
58
+ private stopInbound;
59
+ private ensureTunnel;
60
+ private tunnelEnded;
61
+ private connect;
62
+ private accept;
63
+ private drop;
64
+ private disconnect;
65
+ close(): Promise<void>;
66
+ }
67
+ export declare function peerRpc(request: PeerRpcRequest): Promise<RpcResponse>;
68
+ export declare function peerControlOrThrow(request: PeerRpcRequest): Promise<MachinePeer | MachinePeer[]>;
69
+ export {};