@cotal-ai/manager 0.16.0 → 0.17.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/dist/attach-endpoint.d.ts +53 -59
- package/dist/attach-endpoint.d.ts.map +1 -1
- package/dist/attach-endpoint.js +120 -244
- package/dist/attach-endpoint.js.map +1 -1
- package/dist/commands.js +9 -4
- package/dist/commands.js.map +1 -1
- package/dist/console/app.js +68 -30
- package/dist/console/index.html +3 -2
- package/dist/console/session-bundle.js +9736 -0
- package/dist/console-crypto-shim.d.ts +16 -0
- package/dist/console-crypto-shim.d.ts.map +1 -0
- package/dist/console-crypto-shim.js +20 -0
- package/dist/console-crypto-shim.js.map +1 -0
- package/dist/console-session-entry.d.ts +2 -0
- package/dist/console-session-entry.d.ts.map +1 -0
- package/dist/console-session-entry.js +26 -0
- package/dist/console-session-entry.js.map +1 -0
- package/dist/endpoint-evict.d.ts +29 -0
- package/dist/endpoint-evict.d.ts.map +1 -0
- package/dist/endpoint-evict.js +80 -0
- package/dist/endpoint-evict.js.map +1 -0
- package/dist/manager-service-contract.d.ts +132 -0
- package/dist/manager-service-contract.d.ts.map +1 -0
- package/dist/manager-service-contract.js +332 -0
- package/dist/manager-service-contract.js.map +1 -0
- package/dist/manager.d.ts +504 -22
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +2193 -257
- package/dist/manager.js.map +1 -1
- package/dist/runtime/pty.d.ts.map +1 -1
- package/dist/runtime/pty.js +15 -2
- package/dist/runtime/pty.js.map +1 -1
- package/dist/session/bridge.d.ts +63 -0
- package/dist/session/bridge.d.ts.map +1 -0
- package/dist/session/bridge.js +157 -0
- package/dist/session/bridge.js.map +1 -0
- package/dist/session/establish.d.ts +212 -0
- package/dist/session/establish.d.ts.map +1 -0
- package/dist/session/establish.js +174 -0
- package/dist/session/establish.js.map +1 -0
- package/dist/session/index.d.ts +12 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/plane.d.ts +120 -0
- package/dist/session/plane.d.ts.map +1 -0
- package/dist/session/plane.js +327 -0
- package/dist/session/plane.js.map +1 -0
- package/dist/static-lifecycle.d.ts +97 -0
- package/dist/static-lifecycle.d.ts.map +1 -0
- package/dist/static-lifecycle.js +262 -0
- package/dist/static-lifecycle.js.map +1 -0
- package/package.json +9 -5
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type { AgentHandle } from "./runtime/index.js";
|
|
2
1
|
/**
|
|
3
|
-
* The address the
|
|
4
|
-
* attached to. Keeping the two in step is the whole point — a client that reached the control plane
|
|
5
|
-
* to request an attach URL demonstrably has a route to that address, whereas a hardcoded
|
|
6
|
-
* `127.0.0.1` resolves to the client's own machine.
|
|
2
|
+
* The address the console endpoint binds and advertises, derived from a mesh broker URL.
|
|
7
3
|
*
|
|
8
4
|
* With no server URL there is no mesh address to follow, so this is loopback: the conservative
|
|
9
|
-
* default
|
|
10
|
-
*
|
|
5
|
+
* default. An unparseable URL is a caller bug and throws rather than quietly binding somewhere the
|
|
6
|
+
* operator did not ask for.
|
|
11
7
|
*/
|
|
12
8
|
export declare function attachHost(servers: string | undefined): string;
|
|
13
9
|
/** One Server-Sent-Events frame: a named event carrying JSON data. */
|
|
@@ -15,81 +11,79 @@ export interface FeedEvent {
|
|
|
15
11
|
event: string;
|
|
16
12
|
data: unknown;
|
|
17
13
|
}
|
|
14
|
+
/** What `POST /session/<name>` returns: the console's mesh §13.6 session establishment (P2 item 6).
|
|
15
|
+
* The `grant` is the holder-bound offer (no ws:// URL, non-bearer); `wsUrl` is the broker's
|
|
16
|
+
* localhost websocket listener; `creds` is the per-session, rails-only session-caller credential the
|
|
17
|
+
* browser connects with. NO 127.0.0.1 terminal transport — the terminal rides the mesh session. */
|
|
18
|
+
export interface SessionEstablishment {
|
|
19
|
+
grant: unknown;
|
|
20
|
+
wsUrl: string;
|
|
21
|
+
creds: string;
|
|
22
|
+
}
|
|
23
|
+
/** The manager-injected session establisher (P2 item 6): given a managed agent name, mint the offer
|
|
24
|
+
* through the ONE {@link import("./session/plane.js").ManagerSessionPlane} + the per-session caller
|
|
25
|
+
* credential, and return what the browser needs to connect. INJECTED — the face never constructs a
|
|
26
|
+
* plane; the manager wires the single plane + the cred mint at boot (6b-2). Absent ⇒ the route 503s
|
|
27
|
+
* (an open mesh with no console session client, or the pre-6b-2 stub). */
|
|
28
|
+
export type SessionEstablisher = (name: string) => Promise<SessionEstablishment>;
|
|
18
29
|
/**
|
|
19
|
-
* The manager's local HTTP
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* agent's PTY may sit on another host than the operator running `cotal attach`. Hardcoding
|
|
26
|
-
* `127.0.0.1` made every remote attach fail with ECONNREFUSED against the *client's own* loopback.
|
|
27
|
-
* The bind address is therefore an explicit option (default loopback, so nothing is exposed by
|
|
28
|
-
* accident); `cotal up` passes the address it bound the broker to. A broker DIAL address is
|
|
29
|
-
* deliberately NOT used as the bind: a manager may supervise a broker on another host and could not
|
|
30
|
-
* bind that address at all. Where the manager can only name loopback (a wildcard bind), the CLIENT
|
|
31
|
-
* substitutes the broker address its own control connection reached.
|
|
30
|
+
* The manager's local HTTP face. It serves the **console** (a lightweight xterm.js page + its
|
|
31
|
+
* assets) and is the browser's credential broker: `POST /session/<name>` mints a mesh §13.6 session
|
|
32
|
+
* for the console to drive the terminal over the broker's WebSocket listener. The terminal never
|
|
33
|
+
* rides a manager-hosted socket (P2 item 6 replaced the loopback `ws://.../attach/` transport with
|
|
34
|
+
* the mesh session, closing the bearer-less-local hole) — `cotal attach` reaches a manager on
|
|
35
|
+
* another machine over the mesh, not by dialing this face.
|
|
32
36
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
37
|
+
* **Where it binds, and why it is credentialed.** The bind address is an explicit option (default
|
|
38
|
+
* loopback, so nothing is exposed by accident); `cotal up` passes the address it bound the broker
|
|
39
|
+
* to when the operator asked for an exposed console. A broker DIAL address is deliberately NOT used
|
|
40
|
+
* as the bind: a manager may supervise a broker on another host and could not bind that address at
|
|
41
|
+
* all. Where the manager can only name loopback (a wildcard bind), it advertises loopback.
|
|
36
42
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
43
|
+
* Reachability is why the surface is credentialed. It carries the managed roster, the live mesh
|
|
44
|
+
* feed, and — through `POST /session/<name>` — the mint of a real §13.6 session grant plus its
|
|
45
|
+
* per-session caller credential. Once the face can leave the box, "unauthenticated but
|
|
46
|
+
* loopback-only" stops being a safe position, so every DATA route requires the manager's console
|
|
47
|
+
* token. The console SHELL (its HTML, its script, the vendored xterm assets) is static and carries
|
|
48
|
+
* nothing about this mesh, so it stays open — that is what lets the page load and then present the
|
|
49
|
+
* token, held in memory from its own URL, on the requests that do matter.
|
|
44
50
|
*
|
|
45
|
-
*
|
|
51
|
+
* The credential travels in `?t=` or a bearer header, never a cookie: cookies are host-scoped, not
|
|
46
52
|
* port-scoped, so one set here would be sent to every other HTTP service on this host and would
|
|
47
53
|
* collide between two managers on one box. The console URL carries its token in the FRAGMENT, which
|
|
48
54
|
* a browser never sends to a server.
|
|
49
55
|
*
|
|
50
|
-
* Routes: `GET /` console page
|
|
51
|
-
* `GET /feed` the live mesh feed (SSE: presence roster + comms)
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Attach protocol: server → client sends raw terminal bytes (binary). client →
|
|
55
|
-
* server: binary frames are keystrokes; a text frame `r:<cols>,<rows>` resizes.
|
|
56
|
+
* Routes: `GET /` console page + `/app.js` + `/session-bundle.js` + `/assets/*`; `GET /agents` the
|
|
57
|
+
* managed roster (JSON); `GET /feed` the live mesh feed (SSE: presence roster + comms);
|
|
58
|
+
* `POST /session/<name>` the mesh session establishment.
|
|
56
59
|
*/
|
|
57
60
|
export declare class AttachEndpoint {
|
|
58
61
|
#private;
|
|
59
|
-
private readonly lookup;
|
|
60
62
|
private readonly list;
|
|
61
63
|
/** Events replayed to each console as it connects to `/feed` (e.g. the current roster). */
|
|
62
64
|
private readonly snapshot;
|
|
63
|
-
/**
|
|
65
|
+
/** P2 item 6: the manager-injected mesh-session establisher backing `POST /session/<name>`
|
|
66
|
+
* (the console's session-client transport). Absent ⇒ the route 503s. Wired at 6b-2. */
|
|
67
|
+
private readonly establishSession?;
|
|
68
|
+
/** The endpoint credential. Generated per manager process; required on every data route. */
|
|
64
69
|
private readonly token;
|
|
65
|
-
constructor(
|
|
70
|
+
constructor(list: () => unknown,
|
|
66
71
|
/** Events replayed to each console as it connects to `/feed` (e.g. the current roster). */
|
|
67
72
|
snapshot: () => FeedEvent[], port?: number,
|
|
68
|
-
/**
|
|
69
|
-
*
|
|
70
|
-
|
|
73
|
+
/** P2 item 6: the manager-injected mesh-session establisher backing `POST /session/<name>`
|
|
74
|
+
* (the console's session-client transport). Absent ⇒ the route 503s. Wired at 6b-2. */
|
|
75
|
+
establishSession?: SessionEstablisher | undefined,
|
|
76
|
+
/** Bind address, and the host advertised in {@link consoleUrl}. Defaults to loopback; the
|
|
77
|
+
* manager passes an operator-chosen address when the console is meant to be reachable from
|
|
78
|
+
* another machine. A wildcard bind still advertises loopback, since a wildcard is not a
|
|
79
|
+
* dialable name. */
|
|
71
80
|
host?: string,
|
|
72
|
-
/** The endpoint credential. Generated per manager process; required on every route. */
|
|
81
|
+
/** The endpoint credential. Generated per manager process; required on every data route. */
|
|
73
82
|
token?: string);
|
|
74
83
|
start(): Promise<void>;
|
|
75
84
|
stop(): Promise<void>;
|
|
76
85
|
/** Push a named event to every connected console (SSE). */
|
|
77
86
|
publish(event: string, data: unknown): void;
|
|
78
|
-
/**
|
|
79
|
-
* The ws URL a client uses to attach to `name`, carrying a capability bound to THAT agent.
|
|
80
|
-
*
|
|
81
|
-
* Called once per authorized control-plane `attach` request, so the ticket inherits exactly the
|
|
82
|
-
* authorization the manager just performed for this caller and this agent. It is single-use and
|
|
83
|
-
* short-lived: the client redeems it immediately, and a leaked URL (shell history, a log, a
|
|
84
|
-
* `Referer`) is spent or expired rather than a standing key to someone's terminal.
|
|
85
|
-
*
|
|
86
|
-
* `expected` is the handle the caller actually authorized, and it is REQUIRED. A name is a reusable
|
|
87
|
-
* slot, and authorization is async (a user-mode ledger read), so between the caller resolving the
|
|
88
|
-
* name and arriving here the slot can have been stopped and refilled by a same-name successor.
|
|
89
|
-
* Re-resolving the name would then mint a valid ticket for an agent nobody authorized. Binding to
|
|
90
|
-
* the caller's own handle closes that window: if the slot moved, there is no capability to issue.
|
|
91
|
-
*/
|
|
92
|
-
url(name: string, expected: AgentHandle): string;
|
|
93
87
|
/** The console page URL. The token rides the FRAGMENT, which a browser never sends to a server:
|
|
94
88
|
* it stays out of this endpoint's request handling, out of any proxy's logs, and out of the
|
|
95
89
|
* `Referer` a click on the page would otherwise leak. The page reads it from `location.hash` and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach-endpoint.d.ts","sourceRoot":"","sources":["../src/attach-endpoint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"attach-endpoint.d.ts","sourceRoot":"","sources":["../src/attach-endpoint.ts"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAW9D;AAED,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;oGAGoG;AACpG,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;2EAI2E;AAC3E,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,cAAc;;IAQvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB;4FACwF;IACxF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAMlC,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAbL,IAAI,EAAE,MAAM,OAAO;IACpC,2FAA2F;IAC1E,QAAQ,EAAE,MAAM,SAAS,EAAE,EAC5C,IAAI,SAAI;IACR;4FACwF;IACvE,gBAAgB,CAAC,EAAE,kBAAkB,YAAA;IACtD;;;yBAGqB;IACrB,IAAI,SAAc;IAClB,4FAA4F;IAC3E,KAAK,GAAE,MAAwC;IAsC5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,2DAA2D;IAC3D,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAW3C;;;;sCAIkC;IAClC,UAAU,IAAI,MAAM;CA8IrB"}
|