@cotal-ai/core 0.16.0 → 0.18.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 (145) hide show
  1. package/dist/acls.d.ts +21 -0
  2. package/dist/acls.d.ts.map +1 -1
  3. package/dist/acls.js +44 -1
  4. package/dist/acls.js.map +1 -1
  5. package/dist/artifact.d.ts +45 -0
  6. package/dist/artifact.d.ts.map +1 -0
  7. package/dist/artifact.js +82 -0
  8. package/dist/artifact.js.map +1 -0
  9. package/dist/backup-config.d.ts +9 -2
  10. package/dist/backup-config.d.ts.map +1 -1
  11. package/dist/backup-config.js +6 -2
  12. package/dist/backup-config.js.map +1 -1
  13. package/dist/broker-tls.d.ts +70 -0
  14. package/dist/broker-tls.d.ts.map +1 -0
  15. package/dist/broker-tls.js +195 -0
  16. package/dist/broker-tls.js.map +1 -0
  17. package/dist/canonical.d.ts +14 -1
  18. package/dist/canonical.d.ts.map +1 -1
  19. package/dist/canonical.js +21 -1
  20. package/dist/canonical.js.map +1 -1
  21. package/dist/channels.js +4 -4
  22. package/dist/channels.js.map +1 -1
  23. package/dist/endpoint-action.d.ts +108 -3
  24. package/dist/endpoint-action.d.ts.map +1 -1
  25. package/dist/endpoint-action.js +209 -20
  26. package/dist/endpoint-action.js.map +1 -1
  27. package/dist/endpoint-binding.d.ts +138 -8
  28. package/dist/endpoint-binding.d.ts.map +1 -1
  29. package/dist/endpoint-binding.js +233 -26
  30. package/dist/endpoint-binding.js.map +1 -1
  31. package/dist/endpoint-contract-store.d.ts +30 -1
  32. package/dist/endpoint-contract-store.d.ts.map +1 -1
  33. package/dist/endpoint-contract-store.js +100 -29
  34. package/dist/endpoint-contract-store.js.map +1 -1
  35. package/dist/endpoint-envelope.d.ts +15 -37
  36. package/dist/endpoint-envelope.d.ts.map +1 -1
  37. package/dist/endpoint-envelope.js +93 -44
  38. package/dist/endpoint-envelope.js.map +1 -1
  39. package/dist/endpoint-error.d.ts +33 -0
  40. package/dist/endpoint-error.d.ts.map +1 -0
  41. package/dist/endpoint-error.js +34 -0
  42. package/dist/endpoint-error.js.map +1 -0
  43. package/dist/endpoint-grants.d.ts +63 -7
  44. package/dist/endpoint-grants.d.ts.map +1 -1
  45. package/dist/endpoint-grants.js +118 -9
  46. package/dist/endpoint-grants.js.map +1 -1
  47. package/dist/endpoint-invoke.d.ts +138 -0
  48. package/dist/endpoint-invoke.d.ts.map +1 -0
  49. package/dist/endpoint-invoke.js +393 -0
  50. package/dist/endpoint-invoke.js.map +1 -0
  51. package/dist/endpoint-records.d.ts.map +1 -1
  52. package/dist/endpoint-records.js +17 -0
  53. package/dist/endpoint-records.js.map +1 -1
  54. package/dist/endpoint-serve-kv.d.ts +97 -0
  55. package/dist/endpoint-serve-kv.d.ts.map +1 -0
  56. package/dist/endpoint-serve-kv.js +336 -0
  57. package/dist/endpoint-serve-kv.js.map +1 -0
  58. package/dist/endpoint-serve.d.ts.map +1 -1
  59. package/dist/endpoint-serve.js +21 -1
  60. package/dist/endpoint-serve.js.map +1 -1
  61. package/dist/endpoint-service.d.ts +1 -1
  62. package/dist/endpoint-service.d.ts.map +1 -1
  63. package/dist/endpoint-service.js +34 -10
  64. package/dist/endpoint-service.js.map +1 -1
  65. package/dist/endpoint-session-rail.d.ts +127 -0
  66. package/dist/endpoint-session-rail.d.ts.map +1 -0
  67. package/dist/endpoint-session-rail.js +325 -0
  68. package/dist/endpoint-session-rail.js.map +1 -0
  69. package/dist/endpoint-session.d.ts +1 -115
  70. package/dist/endpoint-session.d.ts.map +1 -1
  71. package/dist/endpoint-session.js +4 -316
  72. package/dist/endpoint-session.js.map +1 -1
  73. package/dist/endpoint-subjects.d.ts +20 -1
  74. package/dist/endpoint-subjects.d.ts.map +1 -1
  75. package/dist/endpoint-subjects.js +20 -1
  76. package/dist/endpoint-subjects.js.map +1 -1
  77. package/dist/endpoint-verbs.d.ts +1 -2
  78. package/dist/endpoint-verbs.d.ts.map +1 -1
  79. package/dist/endpoint-verbs.js +6 -6
  80. package/dist/endpoint-verbs.js.map +1 -1
  81. package/dist/endpoint.d.ts +157 -11
  82. package/dist/endpoint.d.ts.map +1 -1
  83. package/dist/endpoint.js +471 -47
  84. package/dist/endpoint.js.map +1 -1
  85. package/dist/evict.d.ts +47 -0
  86. package/dist/evict.d.ts.map +1 -1
  87. package/dist/evict.js +191 -59
  88. package/dist/evict.js.map +1 -1
  89. package/dist/identity.d.ts +34 -0
  90. package/dist/identity.d.ts.map +1 -1
  91. package/dist/identity.js +46 -0
  92. package/dist/identity.js.map +1 -1
  93. package/dist/index.d.ts +8 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/kv-scan.d.ts +8 -0
  98. package/dist/kv-scan.d.ts.map +1 -1
  99. package/dist/kv-scan.js +8 -0
  100. package/dist/kv-scan.js.map +1 -1
  101. package/dist/lease.d.ts +12 -5
  102. package/dist/lease.d.ts.map +1 -1
  103. package/dist/lease.js.map +1 -1
  104. package/dist/lifecycle-saga.d.ts +174 -0
  105. package/dist/lifecycle-saga.d.ts.map +1 -0
  106. package/dist/lifecycle-saga.js +418 -0
  107. package/dist/lifecycle-saga.js.map +1 -0
  108. package/dist/lifecycle-state.d.ts +202 -0
  109. package/dist/lifecycle-state.d.ts.map +1 -0
  110. package/dist/lifecycle-state.js +347 -0
  111. package/dist/lifecycle-state.js.map +1 -0
  112. package/dist/parts.d.ts +13 -0
  113. package/dist/parts.d.ts.map +1 -0
  114. package/dist/parts.js +17 -0
  115. package/dist/parts.js.map +1 -0
  116. package/dist/provision.d.ts +124 -15
  117. package/dist/provision.d.ts.map +1 -1
  118. package/dist/provision.js +578 -121
  119. package/dist/provision.js.map +1 -1
  120. package/dist/schema-profile.d.ts +3 -2
  121. package/dist/schema-profile.d.ts.map +1 -1
  122. package/dist/schema-profile.js +242 -18
  123. package/dist/schema-profile.js.map +1 -1
  124. package/dist/session-browser.d.ts +15 -0
  125. package/dist/session-browser.d.ts.map +1 -0
  126. package/dist/session-browser.js +14 -0
  127. package/dist/session-browser.js.map +1 -0
  128. package/dist/session-terminal-frames.d.ts +36 -0
  129. package/dist/session-terminal-frames.d.ts.map +1 -0
  130. package/dist/session-terminal-frames.js +149 -0
  131. package/dist/session-terminal-frames.js.map +1 -0
  132. package/dist/spaces.d.ts.map +1 -1
  133. package/dist/spaces.js +6 -1
  134. package/dist/spaces.js.map +1 -1
  135. package/dist/streams.d.ts +168 -1
  136. package/dist/streams.d.ts.map +1 -1
  137. package/dist/streams.js +299 -21
  138. package/dist/streams.js.map +1 -1
  139. package/dist/subjects.d.ts +34 -36
  140. package/dist/subjects.d.ts.map +1 -1
  141. package/dist/subjects.js +46 -35
  142. package/dist/subjects.js.map +1 -1
  143. package/dist/types.d.ts +27 -1
  144. package/dist/types.d.ts.map +1 -1
  145. package/package.json +6 -1
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The BROWSER-SAFE subset of the §13.6 session composite, for the manager console's session-client
3
+ * bundle (P2 item 6): the rails + the terminal-session frame codec, with ZERO node-only
4
+ * dependencies. The console bundle (esbuild) imports ONLY this subpath
5
+ * (`@cotal-ai/core/session-browser`), NEVER the package root — the root pulls `node:crypto` through
6
+ * the grant mint/verify/redeem + the KV ledger, which a browser has no business bundling.
7
+ *
8
+ * This is a re-export barrel over the two already-split node-free modules; it adds no logic, so the
9
+ * SAME core rail + frame codec that runs on the manager runs in the browser (the point of item 6:
10
+ * a remote holder speaks the identical wire).
11
+ */
12
+ export { openSessionRail, encodeSessionFrame, parseSessionFrame, assertWindow, SESSION_WINDOW_DEFAULT, SESSION_WINDOW_MAX, type SessionFrame, type SessionRail, type SessionRailOpts, type SessionRole, } from "./endpoint-session-rail.js";
13
+ export { encodeTerminalData, terminalFrameBytes, decodeTerminalFrame, type TerminalFrame, } from "./session-terminal-frames.js";
14
+ export type { SessionGrant } from "./endpoint-session.js";
15
+ //# sourceMappingURL=session-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-browser.d.ts","sourceRoot":"","sources":["../src/session-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The BROWSER-SAFE subset of the §13.6 session composite, for the manager console's session-client
3
+ * bundle (P2 item 6): the rails + the terminal-session frame codec, with ZERO node-only
4
+ * dependencies. The console bundle (esbuild) imports ONLY this subpath
5
+ * (`@cotal-ai/core/session-browser`), NEVER the package root — the root pulls `node:crypto` through
6
+ * the grant mint/verify/redeem + the KV ledger, which a browser has no business bundling.
7
+ *
8
+ * This is a re-export barrel over the two already-split node-free modules; it adds no logic, so the
9
+ * SAME core rail + frame codec that runs on the manager runs in the browser (the point of item 6:
10
+ * a remote holder speaks the identical wire).
11
+ */
12
+ export { openSessionRail, encodeSessionFrame, parseSessionFrame, assertWindow, SESSION_WINDOW_DEFAULT, SESSION_WINDOW_MAX, } from "./endpoint-session-rail.js";
13
+ export { encodeTerminalData, terminalFrameBytes, decodeTerminalFrame, } from "./session-terminal-frames.js";
14
+ //# sourceMappingURL=session-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-browser.js","sourceRoot":"","sources":["../src/session-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,GAKnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,36 @@
1
+ /** One terminal-session frame carried in a §13.6 rail data payload. `end.reason` is an
2
+ * APPLICATION-defined bounded token (the reference manager uses `process-exit` / `closed` /
3
+ * `expired` / `target-despawn` / `manager-restart`); the vocabulary is not fixed by the wire, so
4
+ * a different endpoint can surface its own terminal causes without a core change. */
5
+ export type TerminalFrame = {
6
+ k: "ready";
7
+ } | {
8
+ k: "data";
9
+ b: string;
10
+ } | {
11
+ k: "resize";
12
+ cols: number;
13
+ rows: number;
14
+ } | {
15
+ k: "end";
16
+ reason: string;
17
+ } | {
18
+ k: "drop";
19
+ bytes: number;
20
+ };
21
+ /** Encode raw terminal bytes as a `data` frame (the ruled base64-in-JSON form). Accepts any
22
+ * Uint8Array (a node Buffer is one). FAIL-LOUD on a non-Uint8Array: a STRING (e.g. xterm's onData
23
+ * keystroke, which is a string, not bytes) would `base64Encode` its chars as NaN→0 and silently
24
+ * ship NUL bytes the pty ignores — the browser must UTF-8-encode first. Throwing turns that trap
25
+ * into an immediate error instead of a byte stream that vanishes into the terminal (§13.6). */
26
+ export declare function encodeTerminalData(bytes: Uint8Array): TerminalFrame;
27
+ /** The bytes carried by a decoded `data` frame, as a Uint8Array (a node Buffer is one; the manager
28
+ * bridge decodes utf8 via TextDecoder, the browser writes the bytes straight to xterm). */
29
+ export declare function terminalFrameBytes(frame: Extract<TerminalFrame, {
30
+ k: "data";
31
+ }>): Uint8Array;
32
+ /** Fail-loud closed-schema parse of a terminal-session frame from a rail's opaque `data`. An
33
+ * unknown kind, an extra field, or a malformed value THROWS — the rail turns that into a protocol
34
+ * error, so a corrupt frame can never reach the terminal as a partial write. */
35
+ export declare function decodeTerminalFrame(data: unknown): TerminalFrame;
36
+ //# sourceMappingURL=session-terminal-frames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-terminal-frames.d.ts","sourceRoot":"","sources":["../src/session-terminal-frames.ts"],"names":[],"mappings":"AA0BA;;;sFAGsF;AACtF,MAAM,MAAM,aAAa,GACrB;IAAE,CAAC,EAAE,OAAO,CAAA;CAAE,GACd;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA+DjC;;;;gGAIgG;AAChG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAMnE;AAED;4FAC4F;AAC5F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,UAAU,CAE3F;AAED;;iFAEiF;AACjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAyBhE"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * The §13.6 TERMINAL-SESSION PROFILE: the normative application framing for streaming an
3
+ * interactive terminal (a PTY) over a §13.6 bidirectional session. It rides inside the session
4
+ * rail's opaque `data` field (`SessionFrame` `{t:"f",seq,data}`); the rail owns ordering, the
5
+ * bounded flow window, credits, and its own `close`, and this profile is what a terminal attach
6
+ * puts on top.
7
+ *
8
+ * This is WIRE, not a client concern: a remote holder on another machine (the whole point of the
9
+ * mesh attach — no `127.0.0.1`) MUST speak exactly this codec to drive or watch the terminal, and
10
+ * an extension attaches through the same frames. It therefore lives in core (extensions peer-depend
11
+ * core only) with ZERO dependency on any implementation, as a tightly-bound vocabulary.
12
+ *
13
+ * The ratified session-plane ruling: raw-binary DATA payloads + structured JSON CONTROL frames.
14
+ * The rail encodes every frame as JSON, so raw terminal bytes cannot ride uninterpreted — they take
15
+ * the ruled base64-in-JSON form (`{k:"data",b:<base64>}`), keeping the bytes on the SAME
16
+ * subject/grant as the control frames rather than weakening the ACL to carry a second binary rail.
17
+ * Control frames (`ready`/`resize`/`end`/`drop`) stay structured, bounded, and authenticated.
18
+ *
19
+ * Directions (the rail already scopes who may send on which subject):
20
+ * caller → serving: `ready` (subscribed — replay backlog + stream live), `data` (keystrokes),
21
+ * `resize` (pty geometry).
22
+ * serving → caller: `data` (pty output, incl. the reconstructed backlog), `drop` (a
23
+ * backpressure drop-notice — never a silent loss), `end` (a terminal reason).
24
+ */
25
+ import { EpEnvelopeError } from "./endpoint-error.js";
26
+ const isRec = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
27
+ function invalid(what) {
28
+ throw new EpEnvelopeError("contract-invalid", `${what} (SPEC 13.6 terminal-session frame)`);
29
+ }
30
+ /** Standard base64 (the rail is JSON; base64 is the compact interop form), validated
31
+ * DETERMINISTICALLY by grammar — `Buffer.from(_, "base64")` is lenient (it drops invalid chars),
32
+ * so a garbled byte payload would decode to silent garbage; a strict grammar + length check
33
+ * rejects it LOUD (a protocol error the rail surfaces), never a partial terminal write. */
34
+ const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
35
+ /** Ceiling for a single data payload's base64 text (well under the rail's 1 MiB default). */
36
+ const MAX_B64_CHARS = 4 * 1024 * 1024;
37
+ function assertBase64(v) {
38
+ if (typeof v !== "string")
39
+ invalid("data payload is not a string");
40
+ if (v.length > MAX_B64_CHARS)
41
+ invalid(`data payload is ${v.length} base64 chars, over the ${MAX_B64_CHARS} ceiling`);
42
+ if (v.length % 4 !== 0 || !BASE64.test(v))
43
+ invalid("data payload is not valid base64");
44
+ return v;
45
+ }
46
+ /** A bounded terminal-cause token: lowercase kebab, 1..48 chars. Keeps `end.reason` generic
47
+ * (no fixed enum) while refusing an unbounded/hostile string. */
48
+ const REASON = /^[a-z][a-z0-9-]{0,47}$/;
49
+ function assertReason(v) {
50
+ if (typeof v !== "string" || !REASON.test(v))
51
+ invalid(`end reason ${JSON.stringify(v)} is not a bounded kebab-case cause token`);
52
+ return v;
53
+ }
54
+ // STANDARD base64 (RFC 4648 §4: the standard alphabet + `=` padding — BYTE-EXACT with node's
55
+ // `Buffer.toString("base64")` / `Buffer.from(_, "base64")`), implemented Buffer-free so the codec
56
+ // runs unchanged in the browser console bundle. NOT url-safe (the rail's JSON carries `+`/`/`
57
+ // fine). Both ends run this same code, so the wire stays identical either way.
58
+ const B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
59
+ const B64_INV = (() => { const m = new Int16Array(128).fill(-1); for (let i = 0; i < B64_ALPHABET.length; i++)
60
+ m[B64_ALPHABET.charCodeAt(i)] = i; return m; })();
61
+ function base64Encode(bytes) {
62
+ let out = "";
63
+ for (let i = 0; i < bytes.length; i += 3) {
64
+ const b0 = bytes[i];
65
+ const has1 = i + 1 < bytes.length, has2 = i + 2 < bytes.length;
66
+ const b1 = has1 ? bytes[i + 1] : 0, b2 = has2 ? bytes[i + 2] : 0;
67
+ out += B64_ALPHABET[b0 >> 2];
68
+ out += B64_ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];
69
+ out += has1 ? B64_ALPHABET[((b1 & 0x0f) << 2) | (b2 >> 6)] : "=";
70
+ out += has2 ? B64_ALPHABET[b2 & 0x3f] : "=";
71
+ }
72
+ return out;
73
+ }
74
+ /** Decode STANDARD base64 (already grammar-validated by {@link assertBase64}) to bytes. */
75
+ function base64Decode(s) {
76
+ const clean = s.endsWith("==") ? s.slice(0, -2) : s.endsWith("=") ? s.slice(0, -1) : s;
77
+ const out = new Uint8Array((clean.length * 6) >> 3);
78
+ let o = 0, acc = 0, bits = 0;
79
+ for (let i = 0; i < clean.length; i++) {
80
+ acc = (acc << 6) | (B64_INV[clean.charCodeAt(i)] & 0x3f);
81
+ bits += 6;
82
+ if (bits >= 8) {
83
+ bits -= 8;
84
+ out[o++] = (acc >> bits) & 0xff;
85
+ }
86
+ }
87
+ return out;
88
+ }
89
+ /** Encode raw terminal bytes as a `data` frame (the ruled base64-in-JSON form). Accepts any
90
+ * Uint8Array (a node Buffer is one). FAIL-LOUD on a non-Uint8Array: a STRING (e.g. xterm's onData
91
+ * keystroke, which is a string, not bytes) would `base64Encode` its chars as NaN→0 and silently
92
+ * ship NUL bytes the pty ignores — the browser must UTF-8-encode first. Throwing turns that trap
93
+ * into an immediate error instead of a byte stream that vanishes into the terminal (§13.6). */
94
+ export function encodeTerminalData(bytes) {
95
+ // ArrayBuffer.isView is cross-realm safe (a browser/vm-sandbox/node Uint8Array all pass; a string
96
+ // or plain object does not) — unlike `instanceof Uint8Array`, which fails across realms.
97
+ if (!ArrayBuffer.isView(bytes))
98
+ invalid(`encodeTerminalData expects raw bytes (Uint8Array); got ${typeof bytes} — UTF-8-encode a string keystroke first`);
99
+ return { k: "data", b: base64Encode(bytes) };
100
+ }
101
+ /** The bytes carried by a decoded `data` frame, as a Uint8Array (a node Buffer is one; the manager
102
+ * bridge decodes utf8 via TextDecoder, the browser writes the bytes straight to xterm). */
103
+ export function terminalFrameBytes(frame) {
104
+ return base64Decode(frame.b);
105
+ }
106
+ /** Fail-loud closed-schema parse of a terminal-session frame from a rail's opaque `data`. An
107
+ * unknown kind, an extra field, or a malformed value THROWS — the rail turns that into a protocol
108
+ * error, so a corrupt frame can never reach the terminal as a partial write. */
109
+ export function decodeTerminalFrame(data) {
110
+ if (!isRec(data))
111
+ invalid("frame is not an object");
112
+ const o = data;
113
+ switch (o.k) {
114
+ case "ready":
115
+ for (const key of Object.keys(o))
116
+ if (key !== "k")
117
+ invalid(`ready frame carries the unknown field "${key}"`);
118
+ return { k: "ready" };
119
+ case "data":
120
+ for (const key of Object.keys(o))
121
+ if (key !== "k" && key !== "b")
122
+ invalid(`data frame carries the unknown field "${key}"`);
123
+ return { k: "data", b: assertBase64(o.b) };
124
+ case "resize":
125
+ for (const key of Object.keys(o))
126
+ if (key !== "k" && key !== "cols" && key !== "rows")
127
+ invalid(`resize frame carries the unknown field "${key}"`);
128
+ if (!Number.isInteger(o.cols) || o.cols < 1 || o.cols > 100_000)
129
+ invalid("resize cols is not a bounded positive integer");
130
+ if (!Number.isInteger(o.rows) || o.rows < 1 || o.rows > 100_000)
131
+ invalid("resize rows is not a bounded positive integer");
132
+ return { k: "resize", cols: o.cols, rows: o.rows };
133
+ case "end":
134
+ for (const key of Object.keys(o))
135
+ if (key !== "k" && key !== "reason")
136
+ invalid(`end frame carries the unknown field "${key}"`);
137
+ return { k: "end", reason: assertReason(o.reason) };
138
+ case "drop":
139
+ for (const key of Object.keys(o))
140
+ if (key !== "k" && key !== "bytes")
141
+ invalid(`drop frame carries the unknown field "${key}"`);
142
+ if (!Number.isInteger(o.bytes) || o.bytes < 1)
143
+ invalid("drop frame bytes is not a positive integer");
144
+ return { k: "drop", bytes: o.bytes };
145
+ default:
146
+ invalid(`unknown terminal-session frame kind ${JSON.stringify(o.k)}`);
147
+ }
148
+ }
149
+ //# sourceMappingURL=session-terminal-frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-terminal-frames.js","sourceRoot":"","sources":["../src/session-terminal-frames.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"spaces.d.ts","sourceRoot":"","sources":["../src/spaces.ts"],"names":[],"mappings":"AA4BA,qCAAqC;AACrC,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;2EAE2E;AAC3E,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAmDnF;AAED;;0FAE0F;AAC1F,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B1G"}
1
+ {"version":3,"file":"spaces.d.ts","sourceRoot":"","sources":["../src/spaces.ts"],"names":[],"mappings":"AA8BA,qCAAqC;AACrC,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;2EAE2E;AAC3E,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAmDnF;AAED;;0FAE0F;AAC1F,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC1G"}
package/dist/spaces.js CHANGED
@@ -7,7 +7,7 @@ import { connect, credsAuthenticator } from "@nats-io/transport-node";
7
7
  import { jetstreamManager } from "@nats-io/jetstream";
8
8
  import { Kvm } from "@nats-io/kv";
9
9
  import { DEFAULT_SERVER } from "./endpoint.js";
10
- import { parseSubject, chatStream, dmStream, taskStream, inboxStream, dlvStream, presenceBucket, channelBucket, membersBucket, aclBucket, membershipBucket, deliveryBucket, managerBucket, } from "./subjects.js";
10
+ import { parseSubject, chatStream, dmStream, taskStream, inboxStream, dlvStream, presenceBucket, channelBucket, membersBucket, aclBucket, membershipBucket, deliveryBucket, managerBucket, artifactBucket, objectStoreStream, } from "./subjects.js";
11
11
  import { idFromCreds } from "./identity.js";
12
12
  /** Connect opts for a possibly-scoped cred: an authenticator plus the per-id `inboxPrefix` a scoped
13
13
  * cred needs (its `sub.allow` is `_INBOX_<id>.>`, so JS API replies must land there, not the default
@@ -107,6 +107,11 @@ export async function deleteSpace(opts) {
107
107
  `KV_${membershipBucket(opts.space)}`,
108
108
  `KV_${deliveryBucket(opts.space)}`,
109
109
  `KV_${managerBucket(opts.space)}`,
110
+ // The artifact Object Store's backing stream. It must be named HERE and not swept by
111
+ // prefix: `$O.<bucket>.>` lives outside the `cotal.<space>.>` grammar, so a subject-based
112
+ // sweep of the space never sees it. Teardown is the sole STREAM.DELETE holder, so a stream
113
+ // missing from this list is not merely un-deleted - nothing in the system can ever reap it.
114
+ objectStoreStream(artifactBucket(opts.space)),
110
115
  ];
111
116
  for (const s of streams)
112
117
  await jsm.streams.delete(s).catch(() => { });
@@ -1 +1 @@
1
- {"version":3,"file":"spaces.js","sourceRoot":"","sources":["../src/spaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spaces.js","sourceRoot":"","sources":["../src/spaces.ts"],"names":[],"mappings":"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"}
package/dist/streams.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type ConsumerConfig, type JetStreamManager } from "@nats-io/jetstream";
2
+ import { type NatsConnection } from "@nats-io/transport-node";
2
3
  /** Per-(sender,channel)-subject retention cap on the chat stream — the bound past which the
3
4
  * oldest message on a subject is discarded (`DiscardPolicy.Old`). Also the horizon of focus
4
5
  * recall: only the last {@link MAX_MSGS_PER_SUBJECT} per sender-subject are recallable. */
@@ -34,6 +35,19 @@ export declare const MANAGER_LEASE_TTL_MS = 10000;
34
35
  * far above any realistic readership while keeping the bucket from growing unbounded. A deliberate cap,
35
36
  * not a guess at scale — the design is cap-safe by construction (per-agent, store-patterns-not-expanded). */
36
37
  export declare const MEMBERSHIP_MAX_BYTES: number;
38
+ /** Bucket-level `max_bytes` cap on the per-space artifact Object Store (`cotal_artifacts_<space>`).
39
+ *
40
+ * THIS NUMBER IS THE ONLY THING BOUNDING ARTIFACT STORAGE, so it is a decision rather than a
41
+ * default. A fresh Object Store bucket ships `max_bytes: -1`, and the space account is provisioned
42
+ * `disk_storage: -1`, so nothing above it says no: without this cap an artifact flood grows until
43
+ * the disk does, starving the chat/DM/delivery streams that share it.
44
+ *
45
+ * 4 GiB is roughly sixteen artifacts at the 256 MiB per-artifact ceiling, which is generous for the
46
+ * transfer use case (screenshots, reports, build outputs) and small enough that filling it is a
47
+ * visible event rather than a silent disk exhaustion. `discard: new` on the bucket means hitting it
48
+ * REFUSES the write rather than evicting older artifacts — the loud failure, not the silent one
49
+ * where a reference published yesterday quietly stops resolving. */
50
+ export declare const ARTIFACT_STORE_MAX_BYTES: number;
37
51
  export interface ClearSpaceHistoryResult {
38
52
  chat: number;
39
53
  dm?: number;
@@ -45,6 +59,24 @@ export interface StandaloneAuth {
45
59
  creds?: string;
46
60
  bearer?: string;
47
61
  sentinelCreds?: string;
62
+ /** Whether this connection must REQUIRE TLS rather than merely tolerate it.
63
+ *
64
+ * REQUIRED, and it is the point of the field. This helper is the STANDALONE connect path, and it
65
+ * was derived from the endpoint path's auth half without its transport half: `authOpts`,
66
+ * `probeConnect` and `RawAuth` all carry a TLS requirement, and this one did not. Every caller
67
+ * of it therefore built connect options that carried the credentials and dropped the thing that
68
+ * protects them in transit.
69
+ *
70
+ * Made required rather than optional because the omitted case is the dangerous one. A client
71
+ * with no TLS requirement still connects to a TLS broker — it upgrades the same socket once it
72
+ * reads `tls_required` in the server's unauthenticated INFO — so nothing looks wrong until an
73
+ * on-path attacker forges an INFO without it and collects the credentials in the clear. An
74
+ * optional field would leave the seam LOOKING transport-aware while callers kept omitting it.
75
+ *
76
+ * Note the honest limit of the compile error: smoke files are outside the tsconfigs, so the type
77
+ * forces every TYPECHECKED caller to state a transport, not every caller. That is why
78
+ * `standaloneConnectOpts` also throws at runtime — see there. */
79
+ tls: boolean;
48
80
  }
49
81
  /** Connection options for a privileged STANDALONE helper (`setupSpaceStreams`, `clearSpaceHistory`,
50
82
  * `clearChannel`, the channel-registry helpers): pin the reply inbox to the connection's own
@@ -56,7 +88,7 @@ export interface StandaloneAuth {
56
88
  * sentinel creds land the connection in the callout account, the bearer rides `auth_token`, and a
57
89
  * client-chosen inbox NONCE goes out as the connect `name` — the callout scopes `_INBOX_<nonce>.>`
58
90
  * from it (the client cannot know its nkey pre-connect). Open mode (no auth) connects bare. */
59
- export declare function standaloneConnectOpts(auth?: StandaloneAuth): Record<string, unknown>;
91
+ export declare function standaloneConnectOpts(auth: StandaloneAuth): Record<string, unknown>;
60
92
  /**
61
93
  * Create (idempotently) the five message streams for a space.
62
94
  *
@@ -124,6 +156,141 @@ export declare function fanoutDurableConfig(space: string, opts?: {
124
156
  }): Partial<ConsumerConfig>;
125
157
  /** Connect with the given (privileged) creds, create the space's streams, and disconnect.
126
158
  * Used by `cotal up` to pre-create streams once at setup. */
159
+ /** #286: reconcile a TTL'd KV bucket's `max_age` to `ttlMs`. `kvm.create` NEVER updates an existing
160
+ * bucket's config, so a presence/lease bucket created by a cotal that predated the TTL (or created
161
+ * without it) keeps NO expiry forever — dead presence records and stale leases never age out, and a
162
+ * raw-KV reader (a dashboard) shows a crashed agent as live indefinitely. Run at every `cotal up`, this
163
+ * `STREAM.UPDATE`s the backing stream when its `max_age` has drifted. Lowering `max_age` immediately
164
+ * ages out already-expired messages (the intended liveness effect; active leases are younger than their
165
+ * TTL and survive, a stale one dies and its holder self-fences on its next failed renewal). NATS requires
166
+ * `duplicate_window <= max_age`; an old unlimited bucket's 120s window would otherwise reject the update,
167
+ * so the window is lowered in the SAME update. Idempotent (a matching bucket is skipped). The `provisioner`
168
+ * cred holds `STREAM.UPDATE` on exactly these three streams (see provision.ts).
169
+ *
170
+ * WHAT THE READ-BACK PROVES, AND WHAT IT CANNOT. It verifies exactly two things: **`max_age` came back
171
+ * EXACTLY as intended**, and **`duplicate_window` does not violate the NATS constraint** (it is not
172
+ * above `max_age`). A no-op update, a `max_age` that came back other than intended, or a server that
173
+ * answers OK without changing anything is caught here and throws.
174
+ *
175
+ * Note what that does NOT include: the update sends a computed `dupNs`, but the read-back never checks
176
+ * the window came back as sent — omitted, zeroed, or clamped smaller all pass. Deliberate: any window
177
+ * `<= max_age` is legal and harmless for a liveness bucket, and demanding equality would turn a
178
+ * legitimate server-side clamp into a failed `cotal up`. (Confirmed by probe: the real function accepts
179
+ * a read-back with exact `max_age` and the window OMITTED.) It does NOT prove that file-store expiry is
180
+ * in force either, and the distinction is
181
+ * not theoretical — on the supported floor (nats-server 2.12.1) the effect is applied in two places and
182
+ * only one of them is visible to us:
183
+ * - `stream.go` assigns the new in-memory `mset.cfg`, then calls `mset.store.UpdateConfig(cfg)` and
184
+ * IGNORES its returned error;
185
+ * - `filestore.go`'s `UpdateConfig` restores the previous config and returns early when
186
+ * `writeStreamMeta()` fails — BEFORE `expireMsgs()`/age enforcement is ever started;
187
+ * - `STREAM.INFO` is answered from `mset.config()`, i.e. the in-memory copy.
188
+ * So a metadata-write fault (EACCES, ENOSPC) yields UPDATE OK, a read-back showing the intended
189
+ * `max_age`, and a backing store still running unlimited with no expiry timer. **This check cannot see
190
+ * that**, because both fields it reads come from the config that DID get updated.
191
+ *
192
+ * It is NOT, however, invisible everywhere — an earlier version of this comment said no check at this
193
+ * seam could see it, and that was false. `$JS.API.STREAM.SNAPSHOT` splits the useful way: the snapshot
194
+ * INITIATION response copies `mset.config()` and false-greens like INFO, but the STREAMED archive's
195
+ * first `meta.inf` entry marshals `fs.cfg` — the file store's own, rolled-back config. Reproduced live
196
+ * against an EACCES split: INFO and the initiation response both reported the requested TTL while the
197
+ * streamed `meta.inf` reported the old one. So a store-side detector EXISTS in the protocol, and this
198
+ * codebase has `downloadStreamSnapshot` plus a per-stream-scoped snapshot grant MODEL (`backup.ts`).
199
+ *
200
+ * **It is NOT available under current authority, and that — not the cost — is what blocks it.**
201
+ * `assertBackupStream` runs every scope through `canonicalBackupStreamConfig`, which accepts only the
202
+ * durable registries (channel / acl / members) among KV buckets and THROWS for presence, delivery and
203
+ * manager. So wiring this in needs a NEW EXACT SCOPE, or a widening of the reconcile credential to
204
+ * whole-body snapshot authority over liveness data — an unsettled authority question on the credential
205
+ * this change otherwise keeps to three `STREAM.UPDATE` subjects. The cost is real too (it scales with
206
+ * bucket size, and a snapshot carries the bucket's records), but quoting only the cost would read as
207
+ * "available but expensive", which is the wrong summary. See the tracking issue for the full spec.
208
+ *
209
+ * Stated here rather than left implied: this guard is a drift detector, not proof of enforcement — and
210
+ * "cannot be detected here" is the stronger claim it does NOT license.
211
+ *
212
+ * CONSEQUENCE OF READING FIRST, which follows from the same split and is worth naming because the
213
+ * skip is deliberate: once `STREAM.INFO` reports the intended `max_age`, later reconciles see no
214
+ * drift and issue no update, so a bucket left unenforced by a metadata-write fault is not retried
215
+ * for as long as that server process lives.
216
+ *
217
+ * WHERE THAT GOES depends on WHEN the write failed, and an earlier version of this comment got it
218
+ * wrong by generalising from one case. `writeStreamMeta` performs TWO writes — `meta.inf`, then
219
+ * `meta.sum` — and `UpdateConfig` rolls `fs.cfg` back if either fails:
220
+ * - **Failure BEFORE the first write commits** (the original EACCES reproduction): persisted state
221
+ * is coherent and old, so a restart makes `INFO` report the old value again and the next
222
+ * reconcile repairs it. Here the skip DEFERS a repair.
223
+ * - **Failure BETWEEN the two** (reproduced live by pointing `meta.sum.tmp` at `/dev/full`):
224
+ * `meta.inf` commits NEW while `meta.sum` stays OLD — a torn pair. On restart the server logs
225
+ * `checksums do not match` and recovery `continue`s past the stream, so it is SKIPPED: `INFO`
226
+ * returns **stream not found**, and the reconcile cannot repair it because its own first `INFO`
227
+ * gets not-found. **That case does not defer a repair, it loses the stream until an operator
228
+ * intervenes.**
229
+ * So "the persisted metadata is ground truth, restart repairs it" is TRUE ONLY of the
230
+ * before-first-atomic case, and "defers, never loses" is false in general. The read-first skip is
231
+ * still right — it keeps a healthy repeat `cotal up` to reads and no writes — but its worst case is
232
+ * worse than a deferred repair. Both branches reproduced live against 2.12.1 during review; see the
233
+ * tracking issue. */
234
+ export declare function reconcileBucketTtl(jsm: JetStreamManager, streamName: string, ttlMs: number): Promise<TtlReconciled | undefined>;
235
+ /** The TTL'd buckets and their intended `max_age`, in ONE place — and the ONLY place any of them is
236
+ * created.
237
+ *
238
+ * Creation is DRIVEN from this list, not merely checked against it. That distinction is the whole
239
+ * point: an earlier version had the reconcile paths read the list while `setupSpaceStreams` still
240
+ * named each `kvm.create(..., { ttl })` separately, and claimed in this comment that a bucket could
241
+ * therefore "never" be TTL'd on one path and forgotten on the other. It could — a fourth bucket
242
+ * added at a create site would have been created with a TTL and never reconciled, which is #286's
243
+ * shape exactly, recreated by the fix for it. (Caught in review; the claim was false when written.)
244
+ * Now a TTL'd bucket cannot be created without appearing here, so it cannot be missed on upgrade.
245
+ *
246
+ * NOT mode-gated: an open mesh carries the same buckets and drifts identically. */
247
+ export declare function ttlBuckets(space: string): ReadonlyArray<readonly [string, number]>;
248
+ /** What a reconcile actually CHANGED. Returned (rather than logged inside) so the caller can report
249
+ * it: a `cotal up` against a running mesh now performs a config write, and a write the operator
250
+ * cannot see is the kind of silent behaviour this change exists to remove. `undefined` means the
251
+ * bucket already carried the intended TTL and nothing was written. */
252
+ export type TtlReconciled = {
253
+ stream: string;
254
+ fromMs: number;
255
+ toMs: number;
256
+ };
257
+ /** #286: reconcile all three TTL'd buckets for a space, over a connection of its own.
258
+ *
259
+ * Exists because `setupSpaceStreams` is only reachable on the CREATE path (`cotal up` starting a
260
+ * mesh), while the drifted-bucket case this fixes is by definition a mesh that is ALREADY RUNNING —
261
+ * an old deployment being upgraded in place. That path starts nothing and so must not run the
262
+ * create-everything routine; it needs exactly the reconcile and nothing else.
263
+ *
264
+ * Read-first by construction: each bucket is skipped when its `max_age` already matches, so a
265
+ * steady-state repeat `cotal up` issues three `STREAM.INFO` reads and ZERO writes. Returns only the
266
+ * buckets it actually changed. `creds` is omitted on an open mesh, exactly as `setupSpaceStreams`
267
+ * documents — the TTL'd buckets are NOT mode-gated, so an open mesh drifts identically. */
268
+ export declare function reconcileSpaceTtls(opts: {
269
+ servers: string;
270
+ space: string;
271
+ /** Privileged creds for an authed mesh; omit on an open mesh (a bare connection has the rights). */
272
+ creds?: string;
273
+ }): Promise<TtlReconciled[]>;
274
+ /**
275
+ * Create the space's artifact Object Store, or VERIFY an existing one — never silently adopt it.
276
+ *
277
+ * `Objm.create(bucket, { max_bytes })` is create-if-MISSING. Measured on nats-server 2.14.4 with
278
+ * `@nats-io/obj` 3.4.0: creating at `max_bytes: 1024`, then calling create again with `4096`, leaves
279
+ * the stream at **1024** — it neither updates the config nor refuses. A bare `create()` with no
280
+ * options does the same.
281
+ *
282
+ * That makes create-alone actively dangerous here, because {@link setupSpaceStreams} is idempotent
283
+ * and re-runs on every `cotal up`. A store that predates this cap, or that an operator widened by
284
+ * hand, would be adopted forever: the code would look like it enforces a 4 GiB ceiling while the
285
+ * broker enforced whatever was there first, and nothing would ever say so. The cap is the ONLY thing
286
+ * bounding artifact storage (account disk is provisioned unlimited), so an unenforced cap is not a
287
+ * smaller cap — it is no cap.
288
+ *
289
+ * So: create, then read the config back and refuse loudly on drift. Same create-or-verify discipline
290
+ * `ensureAuthorityStores` already uses, and the same reason: an idempotent setup path must either
291
+ * converge the resource or report that it cannot.
292
+ */
293
+ export declare function ensureArtifactStore(nc: NatsConnection, space: string): Promise<void>;
127
294
  export declare function setupSpaceStreams(opts: {
128
295
  servers: string;
129
296
  space: string;
@@ -1 +1 @@
1
- {"version":3,"file":"streams.d.ts","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streams.d.ts","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"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"}