@kdonev/termscape 0.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/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/agents/env.d.ts +36 -0
- package/dist/agents/env.d.ts.map +1 -0
- package/dist/agents/env.js +61 -0
- package/dist/agents/env.js.map +1 -0
- package/dist/agents/profiles.d.ts +45 -0
- package/dist/agents/profiles.d.ts.map +1 -0
- package/dist/agents/profiles.js +123 -0
- package/dist/agents/profiles.js.map +1 -0
- package/dist/agents/resolve.d.ts +16 -0
- package/dist/agents/resolve.d.ts.map +1 -0
- package/dist/agents/resolve.js +71 -0
- package/dist/agents/resolve.js.map +1 -0
- package/dist/agents/router.d.ts +29 -0
- package/dist/agents/router.d.ts.map +1 -0
- package/dist/agents/router.js +83 -0
- package/dist/agents/router.js.map +1 -0
- package/dist/agents/tokens.d.ts +21 -0
- package/dist/agents/tokens.d.ts.map +1 -0
- package/dist/agents/tokens.js +39 -0
- package/dist/agents/tokens.js.map +1 -0
- package/dist/agents/wiring.d.ts +30 -0
- package/dist/agents/wiring.d.ts.map +1 -0
- package/dist/agents/wiring.js +110 -0
- package/dist/agents/wiring.js.map +1 -0
- package/dist/browser.d.ts +13 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +34 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +200 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/index.d.ts +14 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +24 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +15 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +176 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/store.d.ts +71 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +341 -0
- package/dist/db/store.js.map +1 -0
- package/dist/hub.d.ts +188 -0
- package/dist/hub.d.ts.map +1 -0
- package/dist/hub.js +636 -0
- package/dist/hub.js.map +1 -0
- package/dist/hub.tgz +0 -0
- package/dist/mcp/server.d.ts +31 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +66 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/paths.d.ts +27 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/protocol/address.d.ts +15 -0
- package/dist/protocol/address.d.ts.map +1 -0
- package/dist/protocol/address.js +39 -0
- package/dist/protocol/address.js.map +1 -0
- package/dist/protocol/domain.d.ts +151 -0
- package/dist/protocol/domain.d.ts.map +1 -0
- package/dist/protocol/domain.js +104 -0
- package/dist/protocol/domain.js.map +1 -0
- package/dist/protocol/index.d.ts +7 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +7 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/inject.d.ts +29 -0
- package/dist/protocol/inject.d.ts.map +1 -0
- package/dist/protocol/inject.js +40 -0
- package/dist/protocol/inject.js.map +1 -0
- package/dist/protocol/mcp-tools.d.ts +45 -0
- package/dist/protocol/mcp-tools.d.ts.map +1 -0
- package/dist/protocol/mcp-tools.js +46 -0
- package/dist/protocol/mcp-tools.js.map +1 -0
- package/dist/protocol/peer.d.ts +304 -0
- package/dist/protocol/peer.d.ts.map +1 -0
- package/dist/protocol/peer.js +183 -0
- package/dist/protocol/peer.js.map +1 -0
- package/dist/protocol/ws.d.ts +416 -0
- package/dist/protocol/ws.d.ts.map +1 -0
- package/dist/protocol/ws.js +119 -0
- package/dist/protocol/ws.js.map +1 -0
- package/dist/remote/deployer.d.ts +78 -0
- package/dist/remote/deployer.d.ts.map +1 -0
- package/dist/remote/deployer.js +216 -0
- package/dist/remote/deployer.js.map +1 -0
- package/dist/remote/enroll.d.ts +14 -0
- package/dist/remote/enroll.d.ts.map +1 -0
- package/dist/remote/enroll.js +244 -0
- package/dist/remote/enroll.js.map +1 -0
- package/dist/remote/join-script.d.ts +29 -0
- package/dist/remote/join-script.d.ts.map +1 -0
- package/dist/remote/join-script.js +709 -0
- package/dist/remote/join-script.js.map +1 -0
- package/dist/remote/join.d.ts +19 -0
- package/dist/remote/join.d.ts.map +1 -0
- package/dist/remote/join.js +195 -0
- package/dist/remote/join.js.map +1 -0
- package/dist/remote/lan.d.ts +45 -0
- package/dist/remote/lan.d.ts.map +1 -0
- package/dist/remote/lan.js +105 -0
- package/dist/remote/lan.js.map +1 -0
- package/dist/remote/peer-serve.d.ts +27 -0
- package/dist/remote/peer-serve.d.ts.map +1 -0
- package/dist/remote/peer-serve.js +274 -0
- package/dist/remote/peer-serve.js.map +1 -0
- package/dist/remote/peer.d.ts +62 -0
- package/dist/remote/peer.d.ts.map +1 -0
- package/dist/remote/peer.js +250 -0
- package/dist/remote/peer.js.map +1 -0
- package/dist/remote/registry.d.ts +104 -0
- package/dist/remote/registry.d.ts.map +1 -0
- package/dist/remote/registry.js +359 -0
- package/dist/remote/registry.js.map +1 -0
- package/dist/remote/tarball.d.ts +9 -0
- package/dist/remote/tarball.d.ts.map +1 -0
- package/dist/remote/tarball.js +22 -0
- package/dist/remote/tarball.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +438 -0
- package/dist/server.js.map +1 -0
- package/dist/session/manager.d.ts +104 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +421 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/pty.d.ts +114 -0
- package/dist/session/pty.d.ts.map +1 -0
- package/dist/session/pty.js +300 -0
- package/dist/session/pty.js.map +1 -0
- package/package.json +49 -0
- package/web/assets/index-B2JtCtHa.css +1 -0
- package/web/assets/index-BOqZOoep.js +107 -0
- package/web/index.html +13 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encoding for text written into another agent's PTY.
|
|
3
|
+
*
|
|
4
|
+
* Two properties matter here and both are security-relevant:
|
|
5
|
+
*
|
|
6
|
+
* 1. Attribution cannot be forged. The `from` address is supplied by the hub
|
|
7
|
+
* from the sender's bearer token, never by the sending agent.
|
|
8
|
+
*
|
|
9
|
+
* 2. A message cannot break out of its own paste. Bracketed paste is framed
|
|
10
|
+
* by ESC[200~ ... ESC[201~; a body containing the terminator would end the
|
|
11
|
+
* paste early and let the remainder be interpreted as keystrokes. We strip
|
|
12
|
+
* the terminator (and bare ESC) from the body before framing.
|
|
13
|
+
*/
|
|
14
|
+
export const PASTE_START = '\x1b[200~';
|
|
15
|
+
export const PASTE_END = '\x1b[201~';
|
|
16
|
+
/** Strip anything that would let a body escape its paste framing. */
|
|
17
|
+
export function sanitizeMessageBody(text) {
|
|
18
|
+
return text
|
|
19
|
+
.replace(/\x1b/g, '') // no escape sequences of any kind survive
|
|
20
|
+
.replace(/\r\n?/g, '\n') // normalize newlines; CR would submit early
|
|
21
|
+
.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ''); // other control chars
|
|
22
|
+
}
|
|
23
|
+
/** The visible, unspoofable prefix a receiving agent sees. */
|
|
24
|
+
export function formatMessage(from, text) {
|
|
25
|
+
return `[from ${from}] ${sanitizeMessageBody(text)}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Wire bytes for injecting `body` into a PTY.
|
|
29
|
+
*
|
|
30
|
+
* Bracketed paste makes a multi-line body arrive as one atomic paste rather
|
|
31
|
+
* than as a line-by-line keystroke stream, so a CLI that reads line-at-a-time
|
|
32
|
+
* does not act on a half-delivered message. The trailing CR submits it.
|
|
33
|
+
*/
|
|
34
|
+
export function encodeInjection(body, mode) {
|
|
35
|
+
const clean = sanitizeMessageBody(body);
|
|
36
|
+
if (mode === 'raw')
|
|
37
|
+
return `${clean}\r`;
|
|
38
|
+
return `${PASTE_START}${clean}${PASTE_END}\r`;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.js","sourceRoot":"","sources":["../src/inject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AAIrC,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,0CAA0C;SAC/D,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,4CAA4C;SACpE,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;AAC7E,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,IAAY;IACtD,OAAO,SAAS,IAAI,KAAK,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAgB;IAC5D,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACxC,OAAO,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool schemas. The *caller* is never a parameter: the hub derives the
|
|
4
|
+
* sender from the per-agent bearer token, so `from` cannot be spoofed by an
|
|
5
|
+
* agent that has been talked into lying about who it is.
|
|
6
|
+
*/
|
|
7
|
+
export declare const WhoamiInput: z.ZodObject<{}, z.core.$strip>;
|
|
8
|
+
export declare const ListAgentsInput: z.ZodObject<{
|
|
9
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const SendMessageInput: z.ZodObject<{
|
|
12
|
+
to: z.ZodString;
|
|
13
|
+
text: z.ZodString;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
export declare const SpawnAgentInput: z.ZodObject<{
|
|
16
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
17
|
+
name: z.ZodOptional<z.ZodString>;
|
|
18
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
19
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
export declare const ReadScreenInput: z.ZodObject<{
|
|
22
|
+
address: z.ZodString;
|
|
23
|
+
lines: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
export declare const SetStatusInput: z.ZodObject<{
|
|
26
|
+
text: z.ZodString;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export declare const StopAgentInput: z.ZodObject<{
|
|
29
|
+
address: z.ZodString;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
export type WhoamiInput = z.infer<typeof WhoamiInput>;
|
|
32
|
+
export type ListAgentsInput = z.infer<typeof ListAgentsInput>;
|
|
33
|
+
export type SendMessageInput = z.infer<typeof SendMessageInput>;
|
|
34
|
+
export type SpawnAgentInput = z.infer<typeof SpawnAgentInput>;
|
|
35
|
+
export type ReadScreenInput = z.infer<typeof ReadScreenInput>;
|
|
36
|
+
export type SetStatusInput = z.infer<typeof SetStatusInput>;
|
|
37
|
+
export type StopAgentInput = z.infer<typeof StopAgentInput>;
|
|
38
|
+
/** Max bytes accepted in a single send_message body (mirrors the zod cap). */
|
|
39
|
+
export declare const MAX_MESSAGE_BYTES = 8000;
|
|
40
|
+
/** Per-sender delivery budget, enforced by the router. */
|
|
41
|
+
export declare const MESSAGE_RATE_LIMIT: {
|
|
42
|
+
readonly windowMs: 10000;
|
|
43
|
+
readonly max: 20;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=mcp-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AAEH,eAAO,MAAM,WAAW,gCAAe,CAAC;AAExC,eAAO,MAAM,eAAe;;iBAK1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;iBAK3B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;iBAW1B,CAAC;AAEH,eAAO,MAAM,eAAe;;;iBAG1B,CAAC;AAEH,eAAO,MAAM,cAAc;;iBAEzB,CAAC;AAEH,eAAO,MAAM,cAAc;;iBAEzB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB;;;CAAyC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool schemas. The *caller* is never a parameter: the hub derives the
|
|
4
|
+
* sender from the per-agent bearer token, so `from` cannot be spoofed by an
|
|
5
|
+
* agent that has been talked into lying about who it is.
|
|
6
|
+
*/
|
|
7
|
+
export const WhoamiInput = z.object({});
|
|
8
|
+
export const ListAgentsInput = z.object({
|
|
9
|
+
workspace: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Limit to one workspace. Defaults to all workspaces on all hosts.'),
|
|
13
|
+
});
|
|
14
|
+
export const SendMessageInput = z.object({
|
|
15
|
+
to: z
|
|
16
|
+
.string()
|
|
17
|
+
.describe('Target agent address, "workspace/name". Use list_agents to discover.'),
|
|
18
|
+
text: z.string().min(1).max(8000).describe('Message body, injected into the target terminal.'),
|
|
19
|
+
});
|
|
20
|
+
export const SpawnAgentInput = z.object({
|
|
21
|
+
profile: z.string().optional().describe('Agent profile id. Defaults to your own profile.'),
|
|
22
|
+
name: z.string().optional().describe('Name for the new agent. Auto-generated if omitted.'),
|
|
23
|
+
workspace: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Workspace to spawn into. Defaults to your own workspace.'),
|
|
27
|
+
prompt: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('First instruction, injected once the new agent is ready.'),
|
|
31
|
+
});
|
|
32
|
+
export const ReadScreenInput = z.object({
|
|
33
|
+
address: z.string().describe('Agent address to inspect.'),
|
|
34
|
+
lines: z.number().int().positive().max(200).optional().describe('Trailing lines to return (default 40).'),
|
|
35
|
+
});
|
|
36
|
+
export const SetStatusInput = z.object({
|
|
37
|
+
text: z.string().max(120).describe('Short status shown under your window title on the canvas.'),
|
|
38
|
+
});
|
|
39
|
+
export const StopAgentInput = z.object({
|
|
40
|
+
address: z.string().describe('Agent to stop. You may only stop agents you spawned.'),
|
|
41
|
+
});
|
|
42
|
+
/** Max bytes accepted in a single send_message body (mirrors the zod cap). */
|
|
43
|
+
export const MAX_MESSAGE_BYTES = 8000;
|
|
44
|
+
/** Per-sender delivery budget, enforced by the router. */
|
|
45
|
+
export const MESSAGE_RATE_LIMIT = { windowMs: 10_000, max: 20 };
|
|
46
|
+
//# sourceMappingURL=mcp-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAExC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,kEAAkE,CAAC;CAChF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,CAAC;SACF,MAAM,EAAE;SACR,QAAQ,CAAC,sEAAsE,CAAC;IACnF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,kDAAkD,CAAC;CAC/F,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;IAC1F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;IAC1F,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;IACvE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IACzD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;CAC1G,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,2DAA2D,CAAC;CAChG,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;CACrF,CAAC,CAAC;AAUH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AACtC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAW,CAAC"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Hub-to-hub RPC.
|
|
4
|
+
*
|
|
5
|
+
* The local hub is the only thing that ever speaks this; agents never see it.
|
|
6
|
+
* A remote agent messaging a local one calls send_message on its own hub,
|
|
7
|
+
* which forwards here.
|
|
8
|
+
*
|
|
9
|
+
* Two things are asymmetric about the link and they are independent: which
|
|
10
|
+
* side opens the socket, and which side issues requests. The hub that owns the
|
|
11
|
+
* canvas always issues requests. It dials an SSH-deployed host through the
|
|
12
|
+
* tunnel, and is dialled by a host that ran the join installer. The frames
|
|
13
|
+
* below are the same in both cases.
|
|
14
|
+
*
|
|
15
|
+
* Knowledge, though, has to travel both ways, or an agent on an attached
|
|
16
|
+
* machine cannot see or reach the agents on the canvas machine. Two frames
|
|
17
|
+
* carry it without disturbing who asks whom: `directory` is the canvas telling
|
|
18
|
+
* a host who else is on the canvas, and `relay` is a host asking the canvas to
|
|
19
|
+
* act on an address it cannot resolve itself — because only the canvas knows
|
|
20
|
+
* where every address on it lives.
|
|
21
|
+
*/
|
|
22
|
+
/** One agent as another hub needs to see it: enough to list and address it. */
|
|
23
|
+
export declare const PeerAgent: z.ZodObject<{
|
|
24
|
+
address: z.ZodString;
|
|
25
|
+
workspace: z.ZodNullable<z.ZodString>;
|
|
26
|
+
profile: z.ZodString;
|
|
27
|
+
state: z.ZodEnum<{
|
|
28
|
+
starting: "starting";
|
|
29
|
+
running: "running";
|
|
30
|
+
stopped: "stopped";
|
|
31
|
+
exited: "exited";
|
|
32
|
+
failed: "failed";
|
|
33
|
+
}>;
|
|
34
|
+
status: z.ZodEnum<{
|
|
35
|
+
idle: "idle";
|
|
36
|
+
busy: "busy";
|
|
37
|
+
unknown: "unknown";
|
|
38
|
+
}>;
|
|
39
|
+
statusText: z.ZodNullable<z.ZodString>;
|
|
40
|
+
host: z.ZodString;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type PeerAgent = z.infer<typeof PeerAgent>;
|
|
43
|
+
/**
|
|
44
|
+
* Opens the link, in either direction.
|
|
45
|
+
*
|
|
46
|
+
* The dialer always sends this and always receives `welcome`; what flips
|
|
47
|
+
* between the two attach models is only who dials. An SSH-deployed hub is
|
|
48
|
+
* dialled by us and `enroll` is absent. A host that ran the join installer
|
|
49
|
+
* dials us, and introduces itself here — we have never seen it before, so this
|
|
50
|
+
* frame is the only place its identity can come from.
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* What an attached hub asks its canvas to do for it.
|
|
54
|
+
*
|
|
55
|
+
* Everything here is something it could do unaided for its own agents and
|
|
56
|
+
* cannot do for anyone else's: the address belongs to a machine it has no link
|
|
57
|
+
* to. The canvas resolves the address and performs it, wherever that lands.
|
|
58
|
+
*/
|
|
59
|
+
export declare const PeerRelayAsk: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
60
|
+
t: z.ZodLiteral<"deliver">;
|
|
61
|
+
from: z.ZodString;
|
|
62
|
+
to: z.ZodString;
|
|
63
|
+
body: z.ZodString;
|
|
64
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
65
|
+
t: z.ZodLiteral<"readScreen">;
|
|
66
|
+
address: z.ZodString;
|
|
67
|
+
lines: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
}, z.core.$strip>], "t">;
|
|
69
|
+
export type PeerRelayAsk = z.infer<typeof PeerRelayAsk>;
|
|
70
|
+
export declare const PeerHello: z.ZodObject<{
|
|
71
|
+
t: z.ZodLiteral<"hello">;
|
|
72
|
+
token: z.ZodString;
|
|
73
|
+
hubVersion: z.ZodString;
|
|
74
|
+
schemaVersion: z.ZodNumber;
|
|
75
|
+
enroll: z.ZodOptional<z.ZodObject<{
|
|
76
|
+
label: z.ZodString;
|
|
77
|
+
platform: z.ZodString;
|
|
78
|
+
arch: z.ZodString;
|
|
79
|
+
homeDir: z.ZodString;
|
|
80
|
+
}, z.core.$strip>>;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
export declare const PeerRequest: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
83
|
+
t: z.ZodLiteral<"hello">;
|
|
84
|
+
token: z.ZodString;
|
|
85
|
+
hubVersion: z.ZodString;
|
|
86
|
+
schemaVersion: z.ZodNumber;
|
|
87
|
+
enroll: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
label: z.ZodString;
|
|
89
|
+
platform: z.ZodString;
|
|
90
|
+
arch: z.ZodString;
|
|
91
|
+
homeDir: z.ZodString;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
94
|
+
t: z.ZodLiteral<"listSessions">;
|
|
95
|
+
id: z.ZodString;
|
|
96
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
97
|
+
t: z.ZodLiteral<"startSession">;
|
|
98
|
+
id: z.ZodString;
|
|
99
|
+
workspaceName: z.ZodString;
|
|
100
|
+
rootPath: z.ZodString;
|
|
101
|
+
profile: z.ZodString;
|
|
102
|
+
name: z.ZodOptional<z.ZodString>;
|
|
103
|
+
spawnedByAddress: z.ZodNullable<z.ZodString>;
|
|
104
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
105
|
+
t: z.ZodLiteral<"stopSession">;
|
|
106
|
+
id: z.ZodString;
|
|
107
|
+
address: z.ZodString;
|
|
108
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
109
|
+
t: z.ZodLiteral<"removeSession">;
|
|
110
|
+
id: z.ZodString;
|
|
111
|
+
address: z.ZodString;
|
|
112
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
113
|
+
t: z.ZodLiteral<"shutdown">;
|
|
114
|
+
id: z.ZodString;
|
|
115
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
116
|
+
t: z.ZodLiteral<"resumeSession">;
|
|
117
|
+
id: z.ZodString;
|
|
118
|
+
address: z.ZodString;
|
|
119
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
120
|
+
t: z.ZodLiteral<"directory">;
|
|
121
|
+
id: z.ZodString;
|
|
122
|
+
agents: z.ZodArray<z.ZodObject<{
|
|
123
|
+
address: z.ZodString;
|
|
124
|
+
workspace: z.ZodNullable<z.ZodString>;
|
|
125
|
+
profile: z.ZodString;
|
|
126
|
+
state: z.ZodEnum<{
|
|
127
|
+
starting: "starting";
|
|
128
|
+
running: "running";
|
|
129
|
+
stopped: "stopped";
|
|
130
|
+
exited: "exited";
|
|
131
|
+
failed: "failed";
|
|
132
|
+
}>;
|
|
133
|
+
status: z.ZodEnum<{
|
|
134
|
+
idle: "idle";
|
|
135
|
+
busy: "busy";
|
|
136
|
+
unknown: "unknown";
|
|
137
|
+
}>;
|
|
138
|
+
statusText: z.ZodNullable<z.ZodString>;
|
|
139
|
+
host: z.ZodString;
|
|
140
|
+
}, z.core.$strip>>;
|
|
141
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
142
|
+
t: z.ZodLiteral<"relayResult">;
|
|
143
|
+
id: z.ZodString;
|
|
144
|
+
relayId: z.ZodString;
|
|
145
|
+
ok: z.ZodBoolean;
|
|
146
|
+
result: z.ZodUnknown;
|
|
147
|
+
error: z.ZodNullable<z.ZodString>;
|
|
148
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
149
|
+
t: z.ZodLiteral<"deliver">;
|
|
150
|
+
id: z.ZodString;
|
|
151
|
+
from: z.ZodString;
|
|
152
|
+
to: z.ZodString;
|
|
153
|
+
body: z.ZodString;
|
|
154
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
155
|
+
t: z.ZodLiteral<"readScreen">;
|
|
156
|
+
id: z.ZodString;
|
|
157
|
+
address: z.ZodString;
|
|
158
|
+
lines: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
160
|
+
t: z.ZodLiteral<"attach">;
|
|
161
|
+
id: z.ZodString;
|
|
162
|
+
address: z.ZodString;
|
|
163
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
164
|
+
t: z.ZodLiteral<"detach">;
|
|
165
|
+
id: z.ZodString;
|
|
166
|
+
address: z.ZodString;
|
|
167
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
168
|
+
t: z.ZodLiteral<"input">;
|
|
169
|
+
id: z.ZodString;
|
|
170
|
+
address: z.ZodString;
|
|
171
|
+
data: z.ZodString;
|
|
172
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
173
|
+
t: z.ZodLiteral<"resize">;
|
|
174
|
+
id: z.ZodString;
|
|
175
|
+
address: z.ZodString;
|
|
176
|
+
cols: z.ZodNumber;
|
|
177
|
+
rows: z.ZodNumber;
|
|
178
|
+
}, z.core.$strip>], "t">;
|
|
179
|
+
export type PeerRequest = z.infer<typeof PeerRequest>;
|
|
180
|
+
export declare const PeerResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
181
|
+
t: z.ZodLiteral<"welcome">;
|
|
182
|
+
hubVersion: z.ZodString;
|
|
183
|
+
schemaVersion: z.ZodNumber;
|
|
184
|
+
hostToken: z.ZodOptional<z.ZodString>;
|
|
185
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
186
|
+
t: z.ZodLiteral<"ok">;
|
|
187
|
+
id: z.ZodString;
|
|
188
|
+
result: z.ZodUnknown;
|
|
189
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
190
|
+
t: z.ZodLiteral<"err">;
|
|
191
|
+
id: z.ZodString;
|
|
192
|
+
message: z.ZodString;
|
|
193
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
194
|
+
t: z.ZodLiteral<"sessions">;
|
|
195
|
+
sessions: z.ZodArray<z.ZodObject<{
|
|
196
|
+
id: z.ZodString;
|
|
197
|
+
workspaceId: z.ZodString;
|
|
198
|
+
name: z.ZodString;
|
|
199
|
+
address: z.ZodString;
|
|
200
|
+
profile: z.ZodString;
|
|
201
|
+
cwd: z.ZodString;
|
|
202
|
+
agentSessionUuid: z.ZodNullable<z.ZodString>;
|
|
203
|
+
spawnedBy: z.ZodNullable<z.ZodString>;
|
|
204
|
+
state: z.ZodEnum<{
|
|
205
|
+
starting: "starting";
|
|
206
|
+
running: "running";
|
|
207
|
+
stopped: "stopped";
|
|
208
|
+
exited: "exited";
|
|
209
|
+
failed: "failed";
|
|
210
|
+
}>;
|
|
211
|
+
status: z.ZodEnum<{
|
|
212
|
+
idle: "idle";
|
|
213
|
+
busy: "busy";
|
|
214
|
+
unknown: "unknown";
|
|
215
|
+
}>;
|
|
216
|
+
statusText: z.ZodNullable<z.ZodString>;
|
|
217
|
+
title: z.ZodNullable<z.ZodString>;
|
|
218
|
+
pid: z.ZodNullable<z.ZodNumber>;
|
|
219
|
+
exitCode: z.ZodNullable<z.ZodNumber>;
|
|
220
|
+
cols: z.ZodNumber;
|
|
221
|
+
rows: z.ZodNumber;
|
|
222
|
+
resumable: z.ZodBoolean;
|
|
223
|
+
createdAt: z.ZodNumber;
|
|
224
|
+
exitedAt: z.ZodNullable<z.ZodNumber>;
|
|
225
|
+
lastActiveAt: z.ZodNumber;
|
|
226
|
+
window: z.ZodObject<{
|
|
227
|
+
x: z.ZodNumber;
|
|
228
|
+
y: z.ZodNumber;
|
|
229
|
+
w: z.ZodNumber;
|
|
230
|
+
h: z.ZodNumber;
|
|
231
|
+
z: z.ZodNumber;
|
|
232
|
+
collapsed: z.ZodBoolean;
|
|
233
|
+
}, z.core.$strip>;
|
|
234
|
+
}, z.core.$strip>>;
|
|
235
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
236
|
+
t: z.ZodLiteral<"sessionUpserted">;
|
|
237
|
+
session: z.ZodObject<{
|
|
238
|
+
id: z.ZodString;
|
|
239
|
+
workspaceId: z.ZodString;
|
|
240
|
+
name: z.ZodString;
|
|
241
|
+
address: z.ZodString;
|
|
242
|
+
profile: z.ZodString;
|
|
243
|
+
cwd: z.ZodString;
|
|
244
|
+
agentSessionUuid: z.ZodNullable<z.ZodString>;
|
|
245
|
+
spawnedBy: z.ZodNullable<z.ZodString>;
|
|
246
|
+
state: z.ZodEnum<{
|
|
247
|
+
starting: "starting";
|
|
248
|
+
running: "running";
|
|
249
|
+
stopped: "stopped";
|
|
250
|
+
exited: "exited";
|
|
251
|
+
failed: "failed";
|
|
252
|
+
}>;
|
|
253
|
+
status: z.ZodEnum<{
|
|
254
|
+
idle: "idle";
|
|
255
|
+
busy: "busy";
|
|
256
|
+
unknown: "unknown";
|
|
257
|
+
}>;
|
|
258
|
+
statusText: z.ZodNullable<z.ZodString>;
|
|
259
|
+
title: z.ZodNullable<z.ZodString>;
|
|
260
|
+
pid: z.ZodNullable<z.ZodNumber>;
|
|
261
|
+
exitCode: z.ZodNullable<z.ZodNumber>;
|
|
262
|
+
cols: z.ZodNumber;
|
|
263
|
+
rows: z.ZodNumber;
|
|
264
|
+
resumable: z.ZodBoolean;
|
|
265
|
+
createdAt: z.ZodNumber;
|
|
266
|
+
exitedAt: z.ZodNullable<z.ZodNumber>;
|
|
267
|
+
lastActiveAt: z.ZodNumber;
|
|
268
|
+
window: z.ZodObject<{
|
|
269
|
+
x: z.ZodNumber;
|
|
270
|
+
y: z.ZodNumber;
|
|
271
|
+
w: z.ZodNumber;
|
|
272
|
+
h: z.ZodNumber;
|
|
273
|
+
z: z.ZodNumber;
|
|
274
|
+
collapsed: z.ZodBoolean;
|
|
275
|
+
}, z.core.$strip>;
|
|
276
|
+
}, z.core.$strip>;
|
|
277
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
278
|
+
t: z.ZodLiteral<"sessionRemoved">;
|
|
279
|
+
address: z.ZodString;
|
|
280
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
281
|
+
t: z.ZodLiteral<"output">;
|
|
282
|
+
address: z.ZodString;
|
|
283
|
+
data: z.ZodString;
|
|
284
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
285
|
+
t: z.ZodLiteral<"relay">;
|
|
286
|
+
relayId: z.ZodString;
|
|
287
|
+
ask: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
288
|
+
t: z.ZodLiteral<"deliver">;
|
|
289
|
+
from: z.ZodString;
|
|
290
|
+
to: z.ZodString;
|
|
291
|
+
body: z.ZodString;
|
|
292
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
293
|
+
t: z.ZodLiteral<"readScreen">;
|
|
294
|
+
address: z.ZodString;
|
|
295
|
+
lines: z.ZodOptional<z.ZodNumber>;
|
|
296
|
+
}, z.core.$strip>], "t">;
|
|
297
|
+
}, z.core.$strip>], "t">;
|
|
298
|
+
export type PeerResponse = z.infer<typeof PeerResponse>;
|
|
299
|
+
/**
|
|
300
|
+
* Bumped whenever the peer protocol or the DB schema changes shape. Hubs
|
|
301
|
+
* refuse to connect across a mismatch rather than corrupting each other.
|
|
302
|
+
*/
|
|
303
|
+
export declare const PEER_SCHEMA_VERSION = 5;
|
|
304
|
+
//# sourceMappingURL=peer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;iBASpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;;;;;;;;;wBAcvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,SAAS;;;;;;;;;;;iBAkBpB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAqEtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAuBvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AgentStatus, Session, SessionState } from './domain.js';
|
|
3
|
+
/**
|
|
4
|
+
* Hub-to-hub RPC.
|
|
5
|
+
*
|
|
6
|
+
* The local hub is the only thing that ever speaks this; agents never see it.
|
|
7
|
+
* A remote agent messaging a local one calls send_message on its own hub,
|
|
8
|
+
* which forwards here.
|
|
9
|
+
*
|
|
10
|
+
* Two things are asymmetric about the link and they are independent: which
|
|
11
|
+
* side opens the socket, and which side issues requests. The hub that owns the
|
|
12
|
+
* canvas always issues requests. It dials an SSH-deployed host through the
|
|
13
|
+
* tunnel, and is dialled by a host that ran the join installer. The frames
|
|
14
|
+
* below are the same in both cases.
|
|
15
|
+
*
|
|
16
|
+
* Knowledge, though, has to travel both ways, or an agent on an attached
|
|
17
|
+
* machine cannot see or reach the agents on the canvas machine. Two frames
|
|
18
|
+
* carry it without disturbing who asks whom: `directory` is the canvas telling
|
|
19
|
+
* a host who else is on the canvas, and `relay` is a host asking the canvas to
|
|
20
|
+
* act on an address it cannot resolve itself — because only the canvas knows
|
|
21
|
+
* where every address on it lives.
|
|
22
|
+
*/
|
|
23
|
+
/** One agent as another hub needs to see it: enough to list and address it. */
|
|
24
|
+
export const PeerAgent = z.object({
|
|
25
|
+
address: z.string(),
|
|
26
|
+
workspace: z.string().nullable(),
|
|
27
|
+
profile: z.string(),
|
|
28
|
+
state: SessionState,
|
|
29
|
+
status: AgentStatus,
|
|
30
|
+
statusText: z.string().nullable(),
|
|
31
|
+
/** Label of the machine it runs on, as the canvas knows that machine. */
|
|
32
|
+
host: z.string(),
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Opens the link, in either direction.
|
|
36
|
+
*
|
|
37
|
+
* The dialer always sends this and always receives `welcome`; what flips
|
|
38
|
+
* between the two attach models is only who dials. An SSH-deployed hub is
|
|
39
|
+
* dialled by us and `enroll` is absent. A host that ran the join installer
|
|
40
|
+
* dials us, and introduces itself here — we have never seen it before, so this
|
|
41
|
+
* frame is the only place its identity can come from.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* What an attached hub asks its canvas to do for it.
|
|
45
|
+
*
|
|
46
|
+
* Everything here is something it could do unaided for its own agents and
|
|
47
|
+
* cannot do for anyone else's: the address belongs to a machine it has no link
|
|
48
|
+
* to. The canvas resolves the address and performs it, wherever that lands.
|
|
49
|
+
*/
|
|
50
|
+
export const PeerRelayAsk = z.discriminatedUnion('t', [
|
|
51
|
+
// `from` was authenticated by the asking hub from the sender's own bearer
|
|
52
|
+
// token, exactly as `deliver` is trusted in the other direction.
|
|
53
|
+
z.object({
|
|
54
|
+
t: z.literal('deliver'),
|
|
55
|
+
from: z.string(),
|
|
56
|
+
to: z.string(),
|
|
57
|
+
body: z.string(),
|
|
58
|
+
}),
|
|
59
|
+
z.object({
|
|
60
|
+
t: z.literal('readScreen'),
|
|
61
|
+
address: z.string(),
|
|
62
|
+
lines: z.number().int().positive().optional(),
|
|
63
|
+
}),
|
|
64
|
+
]);
|
|
65
|
+
export const PeerHello = z.object({
|
|
66
|
+
t: z.literal('hello'),
|
|
67
|
+
/**
|
|
68
|
+
* For an SSH host, the token we minted for the deploy. For an enrolling
|
|
69
|
+
* host, its single-use enrollment token on the first connection and its
|
|
70
|
+
* durable host token on every one after.
|
|
71
|
+
*/
|
|
72
|
+
token: z.string(),
|
|
73
|
+
hubVersion: z.string(),
|
|
74
|
+
schemaVersion: z.number().int(),
|
|
75
|
+
enroll: z
|
|
76
|
+
.object({
|
|
77
|
+
label: z.string(),
|
|
78
|
+
platform: z.string(),
|
|
79
|
+
arch: z.string(),
|
|
80
|
+
homeDir: z.string(),
|
|
81
|
+
})
|
|
82
|
+
.optional(),
|
|
83
|
+
});
|
|
84
|
+
export const PeerRequest = z.discriminatedUnion('t', [
|
|
85
|
+
PeerHello,
|
|
86
|
+
z.object({ t: z.literal('listSessions'), id: z.string() }),
|
|
87
|
+
z.object({
|
|
88
|
+
t: z.literal('startSession'),
|
|
89
|
+
id: z.string(),
|
|
90
|
+
workspaceName: z.string(),
|
|
91
|
+
rootPath: z.string(),
|
|
92
|
+
profile: z.string(),
|
|
93
|
+
name: z.string().optional(),
|
|
94
|
+
spawnedByAddress: z.string().nullable(),
|
|
95
|
+
}),
|
|
96
|
+
z.object({ t: z.literal('stopSession'), id: z.string(), address: z.string() }),
|
|
97
|
+
// Closing a window has to reach the hub that owns the PTY. Handled locally
|
|
98
|
+
// it would only hide the session until that peer's next resync, which is
|
|
99
|
+
// exactly what a restart triggers. Idempotent on purpose: a removal deferred
|
|
100
|
+
// while the host was down may replay one that already went through.
|
|
101
|
+
z.object({ t: z.literal('removeSession'), id: z.string(), address: z.string() }),
|
|
102
|
+
// Sent when the canvas drops this host: the hub over there is a daemon we
|
|
103
|
+
// asked someone to start, so removing it here has to stop it there too,
|
|
104
|
+
// otherwise it lingers holding its files open and its next install fails.
|
|
105
|
+
z.object({ t: z.literal('shutdown'), id: z.string() }),
|
|
106
|
+
z.object({ t: z.literal('resumeSession'), id: z.string(), address: z.string() }),
|
|
107
|
+
// The canvas telling a host who else is on it. Sent whenever that set
|
|
108
|
+
// changes, and it is the whole set minus the receiving host's own agents,
|
|
109
|
+
// which it already knows about and would otherwise list twice.
|
|
110
|
+
z.object({ t: z.literal('directory'), id: z.string(), agents: z.array(PeerAgent) }),
|
|
111
|
+
// The answer to a `relay`, matched by the id the host chose for it. A
|
|
112
|
+
// separate frame rather than an `ok`, because the two ends do not share a
|
|
113
|
+
// request channel: the canvas asks, the host answers, and this is the canvas
|
|
114
|
+
// answering something the host asked.
|
|
115
|
+
z.object({
|
|
116
|
+
t: z.literal('relayResult'),
|
|
117
|
+
id: z.string(),
|
|
118
|
+
relayId: z.string(),
|
|
119
|
+
ok: z.boolean(),
|
|
120
|
+
result: z.unknown(),
|
|
121
|
+
error: z.string().nullable(),
|
|
122
|
+
}),
|
|
123
|
+
// The forwarded delivery: `from` is the *originating agent's* address, which
|
|
124
|
+
// the sending hub already authenticated. A peer is trusted to report it.
|
|
125
|
+
z.object({
|
|
126
|
+
t: z.literal('deliver'),
|
|
127
|
+
id: z.string(),
|
|
128
|
+
from: z.string(),
|
|
129
|
+
to: z.string(),
|
|
130
|
+
body: z.string(),
|
|
131
|
+
}),
|
|
132
|
+
z.object({
|
|
133
|
+
t: z.literal('readScreen'),
|
|
134
|
+
id: z.string(),
|
|
135
|
+
address: z.string(),
|
|
136
|
+
lines: z.number().int().positive().optional(),
|
|
137
|
+
}),
|
|
138
|
+
z.object({ t: z.literal('attach'), id: z.string(), address: z.string() }),
|
|
139
|
+
z.object({ t: z.literal('detach'), id: z.string(), address: z.string() }),
|
|
140
|
+
z.object({
|
|
141
|
+
t: z.literal('input'),
|
|
142
|
+
id: z.string(),
|
|
143
|
+
address: z.string(),
|
|
144
|
+
data: z.string(),
|
|
145
|
+
}),
|
|
146
|
+
z.object({
|
|
147
|
+
t: z.literal('resize'),
|
|
148
|
+
id: z.string(),
|
|
149
|
+
address: z.string(),
|
|
150
|
+
cols: z.number().int().positive(),
|
|
151
|
+
rows: z.number().int().positive(),
|
|
152
|
+
}),
|
|
153
|
+
]);
|
|
154
|
+
export const PeerResponse = z.discriminatedUnion('t', [
|
|
155
|
+
z.object({
|
|
156
|
+
t: z.literal('welcome'),
|
|
157
|
+
hubVersion: z.string(),
|
|
158
|
+
schemaVersion: z.number().int(),
|
|
159
|
+
/**
|
|
160
|
+
* Issued once, in reply to a hello carrying an enrollment token. The
|
|
161
|
+
* enrolling host stores it and presents it on every later connection, so a
|
|
162
|
+
* reboot rejoins without another trip to the download page.
|
|
163
|
+
*/
|
|
164
|
+
hostToken: z.string().optional(),
|
|
165
|
+
}),
|
|
166
|
+
z.object({ t: z.literal('ok'), id: z.string(), result: z.unknown() }),
|
|
167
|
+
z.object({ t: z.literal('err'), id: z.string(), message: z.string() }),
|
|
168
|
+
// Unsolicited: the peer pushing state changes and terminal output.
|
|
169
|
+
z.object({ t: z.literal('sessions'), sessions: z.array(Session) }),
|
|
170
|
+
z.object({ t: z.literal('sessionUpserted'), session: Session }),
|
|
171
|
+
z.object({ t: z.literal('sessionRemoved'), address: z.string() }),
|
|
172
|
+
z.object({ t: z.literal('output'), address: z.string(), data: z.string() }),
|
|
173
|
+
// A host asking the canvas to act on an address it cannot resolve itself.
|
|
174
|
+
// Its own agents it handles directly; anything else it can only reach
|
|
175
|
+
// through the hub that knows where addresses live.
|
|
176
|
+
z.object({ t: z.literal('relay'), relayId: z.string(), ask: PeerRelayAsk }),
|
|
177
|
+
]);
|
|
178
|
+
/**
|
|
179
|
+
* Bumped whenever the peer protocol or the DB schema changes shape. Hubs
|
|
180
|
+
* refuse to connect across a mismatch rather than corrupting each other.
|
|
181
|
+
*/
|
|
182
|
+
export const PEER_SCHEMA_VERSION = 5;
|
|
183
|
+
//# sourceMappingURL=peer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"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"}
|