@nyte-ai/host 0.0.0-stage → 0.0.19

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 (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -2
  3. package/THIRD-PARTY-NOTICES.md +866 -0
  4. package/dist/chunks/canvas-preview-0cmbkp2j.js +65 -0
  5. package/dist/chunks/canvas-preview-0nq75h9k.js +7 -0
  6. package/dist/chunks/canvas-preview-11nadadc.js +241 -0
  7. package/dist/chunks/canvas-preview-1sq7z9jq.js +17 -0
  8. package/dist/chunks/canvas-preview-2jwbe14k.js +130 -0
  9. package/dist/chunks/canvas-preview-2zdyh9ny.js +26 -0
  10. package/dist/chunks/canvas-preview-31w7xm8z.js +34 -0
  11. package/dist/chunks/canvas-preview-4b6sayhg.js +295 -0
  12. package/dist/chunks/canvas-preview-4e0pxa32.js +63 -0
  13. package/dist/chunks/canvas-preview-518dh8by.js +169 -0
  14. package/dist/chunks/canvas-preview-55s0y68g.js +387 -0
  15. package/dist/chunks/canvas-preview-5ekjx6sw.js +613 -0
  16. package/dist/chunks/canvas-preview-5mex725c.js +14 -0
  17. package/dist/chunks/canvas-preview-5z63am63.js +295 -0
  18. package/dist/chunks/canvas-preview-65xqjw7f.js +20 -0
  19. package/dist/chunks/canvas-preview-69fkk9yn.js +95 -0
  20. package/dist/chunks/canvas-preview-8xc0vn7v.js +458 -0
  21. package/dist/chunks/canvas-preview-9aqczacs.js +73 -0
  22. package/dist/chunks/canvas-preview-af86jz8t.js +141 -0
  23. package/dist/chunks/canvas-preview-aq5j4p25.js +240 -0
  24. package/dist/chunks/canvas-preview-b2v8wfnz.js +36 -0
  25. package/dist/chunks/canvas-preview-befkjea2.js +60 -0
  26. package/dist/chunks/canvas-preview-bxnqt8cd.js +103 -0
  27. package/dist/chunks/canvas-preview-cawy6vbz.js +352 -0
  28. package/dist/chunks/canvas-preview-crmzxxt8.js +518 -0
  29. package/dist/chunks/canvas-preview-drctegz4.js +591 -0
  30. package/dist/chunks/canvas-preview-e3vnkkc5.js +134 -0
  31. package/dist/chunks/canvas-preview-ec2mt7es.js +108 -0
  32. package/dist/chunks/canvas-preview-fxa0rfb0.js +61 -0
  33. package/dist/chunks/canvas-preview-g5fkjs34.js +598 -0
  34. package/dist/chunks/canvas-preview-jeddjex8.js +166 -0
  35. package/dist/chunks/canvas-preview-k1yg4fgp.js +571 -0
  36. package/dist/chunks/canvas-preview-kdqgrstc.js +194 -0
  37. package/dist/chunks/canvas-preview-kn7kvbfj.js +12 -0
  38. package/dist/chunks/canvas-preview-kp75gb63.js +141 -0
  39. package/dist/chunks/canvas-preview-mgcx2b2p.js +271 -0
  40. package/dist/chunks/canvas-preview-n2a35zv5.js +81 -0
  41. package/dist/chunks/canvas-preview-pkzqg96v.js +63 -0
  42. package/dist/chunks/canvas-preview-rp4x6y1h.js +144 -0
  43. package/dist/chunks/canvas-preview-s94ebwf5.js +112 -0
  44. package/dist/chunks/canvas-preview-skzwvw4d.js +23 -0
  45. package/dist/chunks/canvas-preview-srgfpdmf.js +60 -0
  46. package/dist/chunks/canvas-preview-tjhabynd.js +252 -0
  47. package/dist/chunks/canvas-preview-tnqe7k0b.js +374 -0
  48. package/dist/chunks/canvas-preview-vaatfznm.js +189 -0
  49. package/dist/chunks/canvas-preview-vm9zdp2t.js +398 -0
  50. package/dist/chunks/canvas-preview-w54ymtb3.js +272 -0
  51. package/dist/chunks/canvas-preview-wg80rbc2.js +46 -0
  52. package/dist/chunks/canvas-preview-y5y6ghaw.js +125 -0
  53. package/dist/chunks/canvas-preview-ycepb05s.js +176 -0
  54. package/dist/chunks/canvas-preview-yjz0f7n4.js +50 -0
  55. package/dist/chunks/canvas-preview-zaaj99wd.js +244 -0
  56. package/dist/src/canvas-preview.d.ts +29 -0
  57. package/dist/src/canvas-preview.js +271 -0
  58. package/dist/src/credentials.d.ts +44 -0
  59. package/dist/src/credentials.js +10 -0
  60. package/dist/src/deploy/cloudflare/worker.d.ts +50 -0
  61. package/dist/src/deploy/cloudflare/worker.js +196 -0
  62. package/dist/src/deploy/vercel/nitro.config.d.ts +2 -0
  63. package/dist/src/deploy/vercel/nitro.config.js +30 -0
  64. package/dist/src/deploy/vercel/server/routes/[...].d.ts +2 -0
  65. package/dist/src/deploy/vercel/server/routes/[...].js +18 -0
  66. package/dist/src/deploy/vercel/server/utils/host.d.ts +13 -0
  67. package/dist/src/deploy/vercel/server/utils/host.js +7 -0
  68. package/dist/src/deploy/vercel/server/utils/repair.d.ts +1 -0
  69. package/dist/src/deploy/vercel/server/utils/repair.js +6 -0
  70. package/dist/src/deploy/vercel/server/utils/step.d.ts +10 -0
  71. package/dist/src/deploy/vercel/server/utils/step.js +6 -0
  72. package/dist/src/deploy/vercel/server/workflows/drive.d.ts +14 -0
  73. package/dist/src/deploy/vercel/server/workflows/drive.js +13 -0
  74. package/dist/src/durable-object.d.ts +14 -0
  75. package/dist/src/durable-object.js +231 -0
  76. package/dist/src/hash.d.ts +1 -0
  77. package/dist/src/hash.js +6 -0
  78. package/dist/src/identity-key.d.ts +11 -0
  79. package/dist/src/identity-key.js +9 -0
  80. package/dist/src/identity.d.ts +12 -0
  81. package/dist/src/identity.js +6 -0
  82. package/dist/src/images/exif.d.ts +1 -0
  83. package/dist/src/images/exif.js +6 -0
  84. package/dist/src/images/node.d.ts +37 -0
  85. package/dist/src/images/node.js +12 -0
  86. package/dist/src/images/photon.d.ts +3 -0
  87. package/dist/src/images/photon.js +7 -0
  88. package/dist/src/images/worker.d.ts +1 -0
  89. package/dist/src/images/worker.js +23 -0
  90. package/dist/src/index.d.ts +20 -0
  91. package/dist/src/index.js +121 -0
  92. package/dist/src/key-file.d.ts +1 -0
  93. package/dist/src/key-file.js +7 -0
  94. package/dist/src/listen-fetch.d.ts +8 -0
  95. package/dist/src/listen-fetch.js +9 -0
  96. package/dist/src/listen.d.ts +4 -0
  97. package/dist/src/listen.js +10 -0
  98. package/dist/src/local/command.d.ts +20 -0
  99. package/dist/src/local/command.js +12 -0
  100. package/dist/src/local/feed.d.ts +7 -0
  101. package/dist/src/local/feed.js +6 -0
  102. package/dist/src/local/files.d.ts +18 -0
  103. package/dist/src/local/files.js +13 -0
  104. package/dist/src/local/git-watch.d.ts +15 -0
  105. package/dist/src/local/git-watch.js +7 -0
  106. package/dist/src/local/git.d.ts +5 -0
  107. package/dist/src/local/git.js +13 -0
  108. package/dist/src/local/github.d.ts +30 -0
  109. package/dist/src/local/github.js +9 -0
  110. package/dist/src/local/identity.d.ts +3 -0
  111. package/dist/src/local/identity.js +7 -0
  112. package/dist/src/local/jobs.d.ts +7 -0
  113. package/dist/src/local/jobs.js +7 -0
  114. package/dist/src/local/legacy-trust.d.ts +10 -0
  115. package/dist/src/local/legacy-trust.js +6 -0
  116. package/dist/src/local/patch.d.ts +16 -0
  117. package/dist/src/local/patch.js +17 -0
  118. package/dist/src/local/provider.d.ts +11 -0
  119. package/dist/src/local/provider.js +20 -0
  120. package/dist/src/local/snapshots.d.ts +7 -0
  121. package/dist/src/local/snapshots.js +11 -0
  122. package/dist/src/local/text.d.ts +1 -0
  123. package/dist/src/local/text.js +6 -0
  124. package/dist/src/local/tree.d.ts +50 -0
  125. package/dist/src/local/tree.js +16 -0
  126. package/dist/src/local/workspace-migration.d.ts +2 -0
  127. package/dist/src/local/workspace-migration.js +7 -0
  128. package/dist/src/local/worktrees.d.ts +46 -0
  129. package/dist/src/local/worktrees.js +14 -0
  130. package/dist/src/mcp/config.d.ts +75 -0
  131. package/dist/src/mcp/config.js +12 -0
  132. package/dist/src/mcp/connect.d.ts +15 -0
  133. package/dist/src/mcp/connect.js +9 -0
  134. package/dist/src/mcp/hub.d.ts +19 -0
  135. package/dist/src/mcp/hub.js +11 -0
  136. package/dist/src/mcp/oauth.d.ts +46 -0
  137. package/dist/src/mcp/oauth.js +12 -0
  138. package/dist/src/mcp/tools.d.ts +29 -0
  139. package/dist/src/mcp/tools.js +12 -0
  140. package/dist/src/open.d.ts +14 -0
  141. package/dist/src/open.js +46 -0
  142. package/dist/src/plugins/loader.d.ts +21 -0
  143. package/dist/src/plugins/loader.js +11 -0
  144. package/dist/src/postgres.d.ts +19 -0
  145. package/dist/src/postgres.js +8 -0
  146. package/dist/src/providers.d.ts +16 -0
  147. package/dist/src/providers.js +112 -0
  148. package/dist/src/secrets.d.ts +12 -0
  149. package/dist/src/secrets.js +8 -0
  150. package/dist/src/serve/binding.d.ts +39 -0
  151. package/dist/src/serve/binding.js +6 -0
  152. package/dist/src/serve/handler.d.ts +15 -0
  153. package/dist/src/serve/handler.js +8 -0
  154. package/dist/src/serve/stream-server.d.ts +6 -0
  155. package/dist/src/serve/stream-server.js +6 -0
  156. package/dist/src/session-index.d.ts +11 -0
  157. package/dist/src/session-index.js +11 -0
  158. package/dist/src/shell-env.d.ts +14 -0
  159. package/dist/src/shell-env.js +108 -0
  160. package/dist/src/sqlite-workers.d.ts +6 -0
  161. package/dist/src/sqlite-workers.js +6 -0
  162. package/dist/src/sqlite.d.ts +8 -0
  163. package/dist/src/sqlite.js +11 -0
  164. package/dist/src/store-rows.d.ts +13 -0
  165. package/dist/src/store-rows.js +26 -0
  166. package/dist/src/store-usage.d.ts +25 -0
  167. package/dist/src/store-usage.js +19 -0
  168. package/dist/src/usage-history.d.ts +54 -0
  169. package/dist/src/usage-history.js +14 -0
  170. package/dist/src/usage-scan.d.ts +24 -0
  171. package/dist/src/usage-scan.js +65 -0
  172. package/dist/src/usage-service.d.ts +23 -0
  173. package/dist/src/usage-service.js +16 -0
  174. package/dist/src/usage-summary.d.ts +9 -0
  175. package/dist/src/usage-summary.js +16 -0
  176. package/dist/src/usage-types.d.ts +86 -0
  177. package/dist/src/usage-types.js +0 -0
  178. package/dist/src/usage-worker.d.ts +1 -0
  179. package/dist/src/usage-worker.js +29 -0
  180. package/dist/src/usage.d.ts +195 -0
  181. package/dist/src/usage.js +23 -0
  182. package/package.json +140 -3
  183. package/src/canvas-preview.ts +403 -0
  184. package/src/credentials.ts +294 -0
  185. package/src/deploy/cloudflare/README.md +3 -0
  186. package/src/deploy/cloudflare/worker.ts +306 -0
  187. package/src/deploy/cloudflare/wrangler.jsonc +12 -0
  188. package/src/deploy/vercel/README.md +3 -0
  189. package/src/deploy/vercel/nitro.config.ts +29 -0
  190. package/src/deploy/vercel/server/routes/[...].ts +10 -0
  191. package/src/deploy/vercel/server/utils/host.ts +104 -0
  192. package/src/deploy/vercel/server/utils/repair.ts +35 -0
  193. package/src/deploy/vercel/server/utils/step.ts +25 -0
  194. package/src/deploy/vercel/server/workflows/drive.ts +46 -0
  195. package/src/deploy/vercel/tsconfig.json +9 -0
  196. package/src/deploy/vercel/types/bun.d.ts +2 -0
  197. package/src/durable-object.ts +386 -0
  198. package/src/hash.ts +5 -0
  199. package/src/identity-key.ts +20 -0
  200. package/src/identity.ts +66 -0
  201. package/src/images/exif.ts +69 -0
  202. package/src/images/node.ts +163 -0
  203. package/src/images/photon.ts +141 -0
  204. package/src/images/worker.ts +29 -0
  205. package/src/index.ts +39 -0
  206. package/src/key-file.ts +53 -0
  207. package/src/listen-fetch.ts +409 -0
  208. package/src/listen.ts +228 -0
  209. package/src/local/command.ts +161 -0
  210. package/src/local/feed.ts +70 -0
  211. package/src/local/files.ts +817 -0
  212. package/src/local/git-watch.ts +199 -0
  213. package/src/local/git.ts +919 -0
  214. package/src/local/github.ts +691 -0
  215. package/src/local/identity.ts +21 -0
  216. package/src/local/jobs.ts +573 -0
  217. package/src/local/legacy-trust.ts +105 -0
  218. package/src/local/patch.ts +334 -0
  219. package/src/local/provider.ts +184 -0
  220. package/src/local/snapshots.ts +778 -0
  221. package/src/local/text.ts +9 -0
  222. package/src/local/tree.ts +398 -0
  223. package/src/local/workspace-migration.ts +95 -0
  224. package/src/local/worktrees.ts +239 -0
  225. package/src/mcp/config.ts +330 -0
  226. package/src/mcp/connect.ts +92 -0
  227. package/src/mcp/hub.ts +836 -0
  228. package/src/mcp/oauth.ts +436 -0
  229. package/src/mcp/tools.ts +333 -0
  230. package/src/open.ts +449 -0
  231. package/src/plugins/loader.ts +186 -0
  232. package/src/postgres.ts +492 -0
  233. package/src/providers.ts +135 -0
  234. package/src/secrets.ts +31 -0
  235. package/src/serve/binding.ts +629 -0
  236. package/src/serve/handler.ts +362 -0
  237. package/src/serve/stream-server.ts +176 -0
  238. package/src/session-index.ts +99 -0
  239. package/src/shell-env.ts +153 -0
  240. package/src/sqlite-workers.ts +283 -0
  241. package/src/sqlite.ts +553 -0
  242. package/src/store-rows.ts +110 -0
  243. package/src/store-usage.ts +347 -0
  244. package/src/usage-history.ts +219 -0
  245. package/src/usage-scan.ts +81 -0
  246. package/src/usage-service.ts +82 -0
  247. package/src/usage-summary.ts +79 -0
  248. package/src/usage-types.ts +87 -0
  249. package/src/usage-worker.ts +24 -0
  250. package/src/usage.ts +776 -0
@@ -0,0 +1,271 @@
1
+ import {
2
+ killTree2
3
+ } from "../chunks/canvas-preview-bxnqt8cd.js";
4
+
5
+ // src/canvas-preview.ts
6
+ import { spawn } from "node:child_process";
7
+ import { existsSync, readdirSync } from "node:fs";
8
+ import { mkdtemp, rm } from "node:fs/promises";
9
+ import { homedir, tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+ import process from "node:process";
12
+ import { Readable, Writable } from "node:stream";
13
+ import { runCanvasPreview } from "@nyte-ai/plugin/core/canvas-preview";
14
+ import { Type } from "typebox";
15
+ import { Value } from "typebox/value";
16
+ var ORIGIN = "https://canvas.preview/";
17
+ var SHELL_POLICY = "default-src 'none'; script-src 'self' blob:; style-src 'self' 'unsafe-inline'; img-src data: blob:; font-src 'self'; connect-src 'none'; base-uri 'none'; form-action 'none'; sandbox allow-scripts";
18
+ var SHELL_TYPES = new Map([
19
+ ["html", "text/html; charset=utf-8"],
20
+ ["js", "text/javascript; charset=utf-8"],
21
+ ["css", "text/css; charset=utf-8"],
22
+ ["woff2", "font/woff2"]
23
+ ]);
24
+ function playwrightBrowser(prefix, executables) {
25
+ const cache = process.env["PLAYWRIGHT_BROWSERS_PATH"] ?? (process.platform === "darwin" ? join(homedir(), "Library", "Caches", "ms-playwright") : process.platform === "win32" ? join(process.env["LOCALAPPDATA"] ?? homedir(), "ms-playwright") : join(homedir(), ".cache", "ms-playwright"));
26
+ if (!existsSync(cache))
27
+ return;
28
+ const versions = readdirSync(cache).filter((name) => name.startsWith(`${prefix}-`)).toSorted((left, right) => Number(right.slice(prefix.length + 1)) - Number(left.slice(prefix.length + 1)));
29
+ return versions.flatMap((version) => executables.map((executable) => join(cache, version, executable))).find((path) => existsSync(path));
30
+ }
31
+ function findChromium() {
32
+ const named = process.env["NYTE_CANVAS_CHROMIUM"];
33
+ if (named !== undefined && named !== "")
34
+ return existsSync(named) ? named : undefined;
35
+ const arch = process.arch === "arm64" ? "arm64" : "x64";
36
+ return playwrightBrowser("chromium_headless_shell", [
37
+ `chrome-headless-shell-mac-${arch}/chrome-headless-shell`,
38
+ "chrome-headless-shell-linux64/chrome-headless-shell",
39
+ "chrome-headless-shell-win64/chrome-headless-shell.exe"
40
+ ]) ?? playwrightBrowser("chromium", [
41
+ `chrome-mac-${arch}/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing`,
42
+ "chrome-mac/Chromium.app/Contents/MacOS/Chromium",
43
+ "chrome-linux64/chrome",
44
+ "chrome-linux/chrome",
45
+ "chrome-win64/chrome.exe"
46
+ ]) ?? [
47
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
48
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
49
+ "/usr/bin/google-chrome",
50
+ "/usr/bin/google-chrome-stable",
51
+ "/usr/bin/chromium",
52
+ "/usr/bin/chromium-browser",
53
+ join(process.env["PROGRAMFILES"] ?? "C:\\Program Files", "Google/Chrome/Application/chrome.exe")
54
+ ].find((path) => existsSync(path));
55
+ }
56
+ var Reply = Type.Object({
57
+ id: Type.Number(),
58
+ result: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
59
+ error: Type.Optional(Type.Object({ message: Type.String() }))
60
+ });
61
+ var Event = Type.Object({
62
+ method: Type.String(),
63
+ params: Type.Record(Type.String(), Type.Unknown()),
64
+ sessionId: Type.Optional(Type.String())
65
+ });
66
+ var Paused = Type.Object({
67
+ requestId: Type.String(),
68
+ request: Type.Object({ url: Type.String() })
69
+ });
70
+ function read(schema, value, what) {
71
+ if (!Value.Check(schema, value))
72
+ throw new Error(`Chromium answered ${what} unreadably.`);
73
+ return value;
74
+ }
75
+
76
+ class Pipe {
77
+ #write;
78
+ #waiting = new Map;
79
+ #listeners = new Set;
80
+ #next = 0;
81
+ #buffer = "";
82
+ #closed;
83
+ constructor(write, readable) {
84
+ this.#write = write;
85
+ readable.setEncoding("utf8");
86
+ readable.on("data", (chunk) => this.#receive(chunk));
87
+ readable.on("close", () => this.close(new Error("Chromium closed its DevTools pipe.")));
88
+ write.on("error", (error) => this.close(error));
89
+ }
90
+ send(method, params = {}, sessionId) {
91
+ if (this.#closed !== undefined)
92
+ return Promise.reject(this.#closed);
93
+ this.#next += 1;
94
+ const id = this.#next;
95
+ return new Promise((resolve, reject) => {
96
+ this.#waiting.set(id, { resolve, reject });
97
+ this.#write.write(`${JSON.stringify({ id, method, params, sessionId })}\x00`);
98
+ });
99
+ }
100
+ listen(listener) {
101
+ this.#listeners.add(listener);
102
+ }
103
+ close(error) {
104
+ this.#closed ??= error;
105
+ for (const waiting of this.#waiting.values())
106
+ waiting.reject(error);
107
+ this.#waiting.clear();
108
+ }
109
+ #receive(chunk) {
110
+ this.#buffer += chunk;
111
+ const messages = this.#buffer.split("\x00");
112
+ this.#buffer = messages.pop() ?? "";
113
+ for (const text of messages) {
114
+ const message = JSON.parse(text);
115
+ if (Value.Check(Reply, message)) {
116
+ const waiting = this.#waiting.get(message.id);
117
+ this.#waiting.delete(message.id);
118
+ if (message.error === undefined)
119
+ waiting?.resolve(message.result ?? {});
120
+ else
121
+ waiting?.reject(new Error(message.error.message));
122
+ } else if (Value.Check(Event, message))
123
+ for (const listener of this.#listeners)
124
+ listener(message.method, message.params);
125
+ }
126
+ }
127
+ }
128
+ function serve(pipe, shell, sessionId) {
129
+ pipe.listen((method, params) => {
130
+ if (method !== "Fetch.requestPaused" || !Value.Check(Paused, params))
131
+ return;
132
+ const { requestId, request } = params;
133
+ const requested = request.url.startsWith(ORIGIN) ? request.url.slice(ORIGIN.length).split(/[?#]/u)[0] : undefined;
134
+ const path = requested === "" ? "index.html" : requested;
135
+ const body = path !== undefined && Object.hasOwn(shell, path) ? shell[path] : undefined;
136
+ const type = SHELL_TYPES.get(path?.split(".").at(-1) ?? "");
137
+ if (path === undefined || body === undefined || type === undefined) {
138
+ pipe.send("Fetch.failRequest", { requestId, errorReason: "BlockedByClient" }, sessionId).catch(() => {
139
+ return;
140
+ });
141
+ return;
142
+ }
143
+ pipe.send("Fetch.fulfillRequest", {
144
+ requestId,
145
+ responseCode: 200,
146
+ responseHeaders: [
147
+ { name: "Content-Type", value: type },
148
+ { name: "Access-Control-Allow-Origin", value: "*" },
149
+ ...path === "index.html" ? [{ name: "Content-Security-Policy", value: SHELL_POLICY }] : []
150
+ ],
151
+ body
152
+ }, sessionId).catch(() => {
153
+ return;
154
+ });
155
+ });
156
+ }
157
+ async function previewIn(pipe, shell, request) {
158
+ const target = read(Type.Object({ targetId: Type.String() }), await pipe.send("Target.createTarget", { url: "about:blank" }), "a new page");
159
+ const { sessionId } = read(Type.Object({ sessionId: Type.String() }), await pipe.send("Target.attachToTarget", { targetId: target.targetId, flatten: true }), "an attach");
160
+ const send = (method, params = {}) => pipe.send(method, params, sessionId);
161
+ serve(pipe, shell, sessionId);
162
+ const loaded = new Promise((resolve) => pipe.listen((method) => {
163
+ if (method === "Page.loadEventFired")
164
+ resolve();
165
+ }));
166
+ await send("Fetch.enable", { patterns: [{ urlPattern: "*" }] });
167
+ await send("Page.enable");
168
+ await send("Page.navigate", { url: ORIGIN });
169
+ await loaded;
170
+ const page = {
171
+ async evaluate(expression) {
172
+ const answer = read(Type.Object({
173
+ result: Type.Object({ value: Type.Optional(Type.Unknown()) }),
174
+ exceptionDetails: Type.Optional(Type.Object({ text: Type.String() }))
175
+ }), await send("Runtime.evaluate", { expression, awaitPromise: true, returnByValue: true }), "an evaluation");
176
+ if (answer.exceptionDetails !== undefined)
177
+ throw new Error(`The preview page threw: ${answer.exceptionDetails.text}`);
178
+ return answer.result.value;
179
+ },
180
+ async resize(width, height) {
181
+ await send("Emulation.setDeviceMetricsOverride", {
182
+ width,
183
+ height,
184
+ deviceScaleFactor: 1,
185
+ mobile: false
186
+ });
187
+ },
188
+ async capture() {
189
+ const { data } = read(Type.Object({ data: Type.String() }), await send("Page.captureScreenshot", { format: "png" }), "a screenshot");
190
+ return new Uint8Array(Buffer.from(data, "base64"));
191
+ }
192
+ };
193
+ return { kind: "rendered", report: await runCanvasPreview(page, request) };
194
+ }
195
+ function stop(child) {
196
+ if (child.exitCode !== null || child.signalCode !== null)
197
+ return Promise.resolve();
198
+ return new Promise((resolve) => {
199
+ const kill = setTimeout(() => killTree2(child, "SIGKILL"), 2000);
200
+ child.once("exit", () => {
201
+ clearTimeout(kill);
202
+ resolve();
203
+ });
204
+ killTree2(child, "SIGTERM");
205
+ });
206
+ }
207
+ function chromiumCanvasPreview(shell, executable = findChromium) {
208
+ return async (request, signal) => {
209
+ const path = executable();
210
+ if (path === undefined)
211
+ return {
212
+ kind: "unavailable",
213
+ reason: "No Chrome or Chromium was found on this machine."
214
+ };
215
+ const profile = await mkdtemp(join(tmpdir(), "nyte-canvas-preview-"));
216
+ const child = spawn(path, [
217
+ "--headless",
218
+ "--remote-debugging-pipe",
219
+ `--user-data-dir=${profile}`,
220
+ "--no-first-run",
221
+ "--no-default-browser-check",
222
+ "--disable-extensions",
223
+ "--disable-background-networking",
224
+ "--disable-sync",
225
+ "--mute-audio",
226
+ "--deny-permission-prompts",
227
+ "--force-webrtc-ip-handling-policy=disable_non_proxied_udp",
228
+ "--webrtc-ip-handling-policy=disable_non_proxied_udp",
229
+ "--proxy-server=socks5://127.0.0.1:9",
230
+ "--proxy-bypass-list=<-loopback>",
231
+ "--host-resolver-rules=MAP * ~NOTFOUND",
232
+ "--hide-scrollbars",
233
+ "--enable-unsafe-swiftshader",
234
+ "--use-mock-keychain",
235
+ "--password-store=basic",
236
+ "about:blank"
237
+ ], { stdio: ["ignore", "ignore", "ignore", "pipe", "pipe"] });
238
+ const [, , , input, output] = child.stdio;
239
+ try {
240
+ if (!(input instanceof Writable) || !(output instanceof Readable))
241
+ return { kind: "unavailable", reason: "Chromium did not open its DevTools pipe." };
242
+ const pipe = new Pipe(input, output);
243
+ child.once("error", (error) => pipe.close(error));
244
+ const stopped = Promise.withResolvers();
245
+ const stop = () => stopped.reject(new Error("The preview was stopped."));
246
+ signal.addEventListener("abort", stop, { once: true });
247
+ try {
248
+ signal.throwIfAborted();
249
+ return await Promise.race([previewIn(pipe, shell, request), stopped.promise]);
250
+ } catch (error) {
251
+ return {
252
+ kind: "unavailable",
253
+ reason: `Chromium could not render the preview: ${error instanceof Error ? error.message : String(error)}`
254
+ };
255
+ } finally {
256
+ signal.removeEventListener("abort", stop);
257
+ pipe.send("Browser.close").catch(() => {
258
+ return;
259
+ });
260
+ pipe.close(new Error("The preview finished."));
261
+ }
262
+ } finally {
263
+ await stop(child);
264
+ await rm(profile, { recursive: true, force: true, maxRetries: 10 });
265
+ }
266
+ };
267
+ }
268
+ export {
269
+ chromiumCanvasPreview,
270
+ findChromium
271
+ };
@@ -0,0 +1,44 @@
1
+ import type { CredentialStore } from "@nyte-ai/ai/auth/types";
2
+ import type { Store } from "@nyte-ai/core";
3
+ import { Type } from "typebox";
4
+ import type { Static } from "typebox";
5
+ import type { SecretsSource } from "./secrets.ts";
6
+ declare const SealedCredentialSchema: Type.TUnion<[Type.TObject<{
7
+ type: Type.TUnion<[Type.TLiteral<"api_key">, Type.TLiteral<"oauth">]>;
8
+ iv: Type.TString;
9
+ ciphertext: Type.TString;
10
+ }>, Type.TObject<{
11
+ active: Type.TUnion<[Type.TString, Type.TNull]>;
12
+ accounts: Type.TArray<Type.TObject<{
13
+ id: Type.TString;
14
+ label: Type.TString;
15
+ type: Type.TUnion<[Type.TLiteral<"api_key">, Type.TLiteral<"oauth">]>;
16
+ }>>;
17
+ iv: Type.TString;
18
+ ciphertext: Type.TString;
19
+ }>]>;
20
+ export type SealedCredential = Static<typeof SealedCredentialSchema>;
21
+ /**
22
+ * Returns `@nyte-ai/ai`'s `CredentialStore` over a host `Store`, so a host's
23
+ * model logins live with its sessions and pass to
24
+ * `createModels({ credentials })` (§42e); a Durable Object and a Vercel
25
+ * instance keep theirs.
26
+ *
27
+ * Each call opens a store connection and closes it when done; the `Store` is
28
+ * the caller's. `read` is `unsealCredential` over the record, `list` answers
29
+ * non-secret account metadata per ref under `kv/secret/models/`, `modify` is
30
+ * `modifyCredential`, and `delete` sets the ref to null, serialised as
31
+ * `modify` is. Building it touches nothing, `list` never calls `key()` and
32
+ * `read` calls it only when that provider's record exists (§50b, §55); the
33
+ * imported key is kept once `key()` resolves, a rejection is not (§43k). While `key()` rejects (a deploy
34
+ * without `NYTE_SECRET_KEY`), `read` answers undefined, `list` and `delete`
35
+ * work (they need no key) and `modify` rejects that error, so provider keys
36
+ * from the environment still resolve and logins answer `unavailable`. Web
37
+ * Crypto only, no `node:*` (the `./credentials` subpath).
38
+ */
39
+ export declare function credentialStore(store: Store, secrets: SecretsSource): CredentialStore;
40
+ /** Returns `plain` sealed under the secrets key as `<iv>.<ciphertext>`, both base64; a desktop keeps its account token this way (§55). */
41
+ export declare function sealSecret(secrets: SecretsSource, plain: string): Promise<string>;
42
+ /** Returns the text `sealSecret` sealed; rejects when it was sealed under another key or is not such a text. */
43
+ export declare function openSecret(secrets: SecretsSource, sealed: string): Promise<string>;
44
+ export {};
@@ -0,0 +1,10 @@
1
+ import {
2
+ credentialStore2,
3
+ sealSecret2,
4
+ openSecret2
5
+ } from "../chunks/canvas-preview-518dh8by.js";
6
+ export {
7
+ credentialStore2 as credentialStore,
8
+ openSecret2 as openSecret,
9
+ sealSecret2 as sealSecret
10
+ };
@@ -0,0 +1,50 @@
1
+ import type { AdvanceReport } from "@nyte-ai/schema";
2
+ import type { Models } from "@nyte-ai/ai";
3
+ import type { Host } from "@nyte-ai/core";
4
+ import type { ServerHost } from "@nyte-ai/core/server";
5
+ import type { DurableObjectSql } from "@nyte-ai/host/durable-object";
6
+ /** Returns the parts of a Durable Object's `state` `NyteHost` uses, structurally: the storage `durableObjectStore` reads with the object's one alarm, and `blockConcurrencyWhile` to hold requests until the host is composed. */
7
+ export type WorkerState = {
8
+ readonly storage: DurableObjectSql & {
9
+ getAlarm(): Promise<number | null>;
10
+ setAlarm(scheduledTime: number): Promise<void>;
11
+ deleteAlarm(): Promise<void>;
12
+ };
13
+ blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T>;
14
+ };
15
+ /** Returns the Worker's bindings: the `NyteHost` namespace `wrangler.jsonc` binds, the listener token it requires as a secret (`secrets.required`, set with `wrangler secret put NYTE_TOKEN`, at least 16 characters; §42l), the optional base64 secrets key (decision 10; absent, see `secretsFrom`), and the optional base64 identity seed (§50a; absent, the host answers no identity challenge). */
16
+ export type WorkerEnv = {
17
+ readonly NYTE_HOST: {
18
+ getByName(name: string): {
19
+ fetch(request: Request): Promise<Response>;
20
+ };
21
+ };
22
+ readonly NYTE_TOKEN: string;
23
+ readonly NYTE_SECRET_KEY?: string;
24
+ readonly NYTE_IDENTITY_KEY?: string;
25
+ };
26
+ export type PassBudget = {
27
+ readonly heads: number;
28
+ readonly ms: number;
29
+ readonly repair: boolean;
30
+ };
31
+ export type PassHost = Pick<Host, "execution"> & {
32
+ readonly server: Pick<ServerHost, "tick">;
33
+ };
34
+ export declare function scheduleFrom(report: AdvanceReport, now: number): number | null;
35
+ export declare function pass(host: PassHost, storage: Pick<DurableObjectSql, "sql">, budget: PassBudget): Promise<number | null>;
36
+ /** The Durable Object that is one Nyte host, importing only the node-free subpaths (§41j): composed once per object over its own SQLite storage with a chat-only workspace, served through `listenFetch`, and driven by its alarm. */
37
+ export declare class NyteHost {
38
+ #private;
39
+ constructor(state: WorkerState, env: WorkerEnv, options?: {
40
+ readonly models?: Models;
41
+ });
42
+ /** Answers one request through the listener once the host is composed; an object whose composition failed answers its encoded `SdkError` (`unavailable`, 503) and composes again on the next request. */
43
+ fetch(request: Request): Promise<Response>;
44
+ alarm(): Promise<void>;
45
+ }
46
+ /** The Worker: routes every request to the one `NyteHost` object, `env.NYTE_HOST.getByName("host")`. */
47
+ declare const _default: {
48
+ fetch(request: Request, env: WorkerEnv): Promise<Response>;
49
+ };
50
+ export default _default;
@@ -0,0 +1,196 @@
1
+ import {
2
+ package_default
3
+ } from "../../../chunks/canvas-preview-jeddjex8.js";
4
+
5
+ // src/deploy/cloudflare/worker.ts
6
+ import { asId, SdkError } from "@nyte-ai/schema";
7
+ import { createModels } from "@nyte-ai/ai/models";
8
+ import { composeHost } from "@nyte-ai/core/server";
9
+ import { encodeError, errorStatus } from "@nyte-ai/protocol";
10
+ import { Settings } from "typebox/system";
11
+ import { credentialStore } from "@nyte-ai/host/credentials";
12
+ import { durableObjectStore } from "@nyte-ai/host/durable-object";
13
+ import { seedSigner } from "@nyte-ai/host/identity";
14
+ import { listenFetch } from "@nyte-ai/host/listen-fetch";
15
+ import { chatOnlyProvider } from "@nyte-ai/host/providers";
16
+ Settings.Set({ useAcceleration: false });
17
+ var PASS_BUDGET = { heads: 32, ms: 1e4 };
18
+ var REPAIR_EVERY = 60;
19
+ var RETRY_MS = 30000;
20
+ var PAGE = 100;
21
+ function scheduleFrom(report, now) {
22
+ switch (report.kind) {
23
+ case "continue":
24
+ return now;
25
+ case "waiting":
26
+ return report.until;
27
+ case "retry":
28
+ case "busy":
29
+ return report.until;
30
+ case "idle":
31
+ case "fenced":
32
+ return null;
33
+ }
34
+ }
35
+ async function pass(host, storage, budget) {
36
+ const began = Date.now();
37
+ const schedule = openSchedule(storage);
38
+ await host.server.tick(began);
39
+ if (budget.repair) {
40
+ let cursor;
41
+ do {
42
+ cursor = (await host.execution.repair({ cursor, limit: PAGE })).next ?? undefined;
43
+ } while (cursor !== undefined);
44
+ }
45
+ const advances = [];
46
+ for (const entry of schedule.due(Date.now())) {
47
+ if (advances.length >= budget.heads || Date.now() - began >= budget.ms) {
48
+ schedule.write(entry.session, entry.head, began);
49
+ continue;
50
+ }
51
+ advances.push(host.execution.advance({ session: entry.session, head: entry.head }).then((report) => schedule.settle(entry, scheduleFrom(report, Date.now())), (error) => {
52
+ console.error(`Advancing ${entry.session}/${entry.head} failed:`, error);
53
+ schedule.settle(entry, Date.now() + RETRY_MS);
54
+ }));
55
+ }
56
+ await Promise.all(advances);
57
+ return schedule.earliest();
58
+ }
59
+
60
+ class NyteHost {
61
+ #state;
62
+ #env;
63
+ #models;
64
+ #served = null;
65
+ #passes = 0;
66
+ constructor(state, env, options) {
67
+ this.#state = state;
68
+ this.#env = env;
69
+ this.#models = options?.models;
70
+ state.blockConcurrencyWhile(async () => {
71
+ await this.#serve().catch(() => {
72
+ return;
73
+ });
74
+ });
75
+ }
76
+ async fetch(request) {
77
+ let served;
78
+ try {
79
+ served = await this.#serve();
80
+ } catch (error) {
81
+ const failure = new SdkError("unavailable", `The host did not start: ${error instanceof Error ? error.message : String(error)}`);
82
+ return new Response(JSON.stringify(encodeError(failure)), {
83
+ status: errorStatus[failure.code],
84
+ headers: { "Content-Type": "application/json" }
85
+ });
86
+ }
87
+ return served.listener.fetch(request);
88
+ }
89
+ async alarm() {
90
+ const served = await this.#serve();
91
+ const repair = this.#passes % REPAIR_EVERY === 0;
92
+ this.#passes += 1;
93
+ const next = await pass(served.host, this.#state.storage, { ...PASS_BUDGET, repair });
94
+ if (next === null)
95
+ await this.#state.storage.deleteAlarm();
96
+ else
97
+ await this.#state.storage.setAlarm(next);
98
+ }
99
+ #serve() {
100
+ const served = this.#served ??= compose(this.#state, this.#env, this.#models);
101
+ served.catch(() => {
102
+ if (this.#served === served)
103
+ this.#served = null;
104
+ });
105
+ return served;
106
+ }
107
+ }
108
+ var worker_default = {
109
+ async fetch(request, env) {
110
+ return env.NYTE_HOST.getByName("host").fetch(request);
111
+ }
112
+ };
113
+ async function compose(state, env, models) {
114
+ const { storage } = state;
115
+ const store = durableObjectStore(storage);
116
+ const secrets = secretsFrom(env.NYTE_SECRET_KEY);
117
+ const description = { name: "nyte-host", platform: "cloudflare", version: package_default.version };
118
+ const host = await composeHost({
119
+ store,
120
+ models: models ?? createModels({ credentials: credentialStore(store, secrets) }),
121
+ plugins: [{ id: "chat-only", environment: chatOnlyProvider() }],
122
+ workspace: { kind: "chat-only", locator: null },
123
+ execution: { kind: "admit-only" },
124
+ secrets,
125
+ home: null,
126
+ description
127
+ });
128
+ try {
129
+ const coverage = await host.execution.cover({ kind: "all" });
130
+ const schedule = openSchedule(storage);
131
+ host.server.onWake((session, head) => {
132
+ const now = Date.now();
133
+ schedule.write(session, head, now);
134
+ storage.setAlarm(now);
135
+ });
136
+ const listener = await listenFetch(host, {
137
+ transport: { kind: "fetch" },
138
+ auth: { kind: "token", token: env.NYTE_TOKEN },
139
+ execution: { kind: "admit-only" },
140
+ describe: () => description,
141
+ ...env.NYTE_IDENTITY_KEY === undefined || env.NYTE_IDENTITY_KEY === "" ? {} : {
142
+ identity: await seedSigner(host.hostId, Uint8Array.fromBase64(env.NYTE_IDENTITY_KEY))
143
+ }
144
+ });
145
+ await storage.setAlarm(Date.now());
146
+ return { host, listener, coverage };
147
+ } catch (error) {
148
+ await host.close();
149
+ throw error;
150
+ }
151
+ }
152
+ function secretsFrom(key) {
153
+ if (key === undefined || key === "")
154
+ return {
155
+ key: async () => {
156
+ throw new SdkError("unavailable", "Set NYTE_SECRET_KEY to a base64 32-byte key.");
157
+ }
158
+ };
159
+ const bytes = Uint8Array.from(atob(key), (character) => character.charCodeAt(0));
160
+ return { key: async () => bytes };
161
+ }
162
+ function openSchedule(storage) {
163
+ const rows = (query, ...bindings) => storage.sql.exec(query, ...bindings).toArray();
164
+ rows("CREATE TABLE IF NOT EXISTS nyte_schedule (session TEXT NOT NULL, head TEXT NOT NULL, at INTEGER NOT NULL, PRIMARY KEY (session, head))");
165
+ const readAt = (session, head) => {
166
+ const at = rows("SELECT at FROM nyte_schedule WHERE session = ? AND head = ?", session, head)[0]?.at;
167
+ return typeof at === "number" ? at : null;
168
+ };
169
+ const write = (session, head, at) => {
170
+ rows("INSERT INTO nyte_schedule (session, head, at) VALUES (?, ?, ?) ON CONFLICT (session, head) DO UPDATE SET at = excluded.at", session, head, at);
171
+ };
172
+ return {
173
+ write,
174
+ due(now) {
175
+ return rows("SELECT session, head, at FROM nyte_schedule WHERE at <= ? ORDER BY at", now).flatMap((row) => typeof row.session === "string" && typeof row.head === "string" && typeof row.at === "number" ? [{ session: asId(row.session), head: asId(row.head), at: row.at }] : []);
176
+ },
177
+ settle(entry, next) {
178
+ if (readAt(entry.session, entry.head) !== entry.at)
179
+ return;
180
+ if (next === null)
181
+ rows("DELETE FROM nyte_schedule WHERE session = ? AND head = ?", entry.session, entry.head);
182
+ else
183
+ write(entry.session, entry.head, next);
184
+ },
185
+ earliest() {
186
+ const at = rows("SELECT MIN(at) AS at FROM nyte_schedule")[0]?.at;
187
+ return typeof at === "number" ? at : null;
188
+ }
189
+ };
190
+ }
191
+ export {
192
+ NyteHost,
193
+ worker_default as default,
194
+ pass,
195
+ scheduleFrom
196
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: Omit<import("nitro/types").NitroConfig, "rootDir">;
2
+ export default _default;
@@ -0,0 +1,30 @@
1
+ // src/deploy/vercel/nitro.config.ts
2
+ import process from "node:process";
3
+ import { defineConfig } from "nitro";
4
+ var config = {
5
+ serverDir: "./server",
6
+ modules: ["workflow/nitro"],
7
+ workflow: {
8
+ runtime: "nodejs24.x",
9
+ dirs: ["./server/workflows"]
10
+ },
11
+ vercel: {
12
+ functions: {
13
+ runtime: "nodejs24.x",
14
+ maxDuration: 300
15
+ },
16
+ config: {
17
+ version: 3,
18
+ crons: [
19
+ {
20
+ path: "/.nyte/repair",
21
+ schedule: process.env.NYTE_REPAIR_SCHEDULE ?? "* * * * *"
22
+ }
23
+ ]
24
+ }
25
+ }
26
+ };
27
+ var nitro_config_default = defineConfig(config);
28
+ export {
29
+ nitro_config_default as default
30
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nitro/h3").EventHandlerWithFetch<import("nitro/h3").EventHandlerRequest, Promise<Response>>;
2
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import"../../../../../chunks/canvas-preview-2zdyh9ny.js";
2
+ import {
3
+ vercelHost2
4
+ } from "../../../../../chunks/canvas-preview-n2a35zv5.js";
5
+ import"../../../../../chunks/canvas-preview-65xqjw7f.js";
6
+ import {
7
+ dispatchHead2
8
+ } from "../../../../../chunks/canvas-preview-b2v8wfnz.js";
9
+
10
+ // src/deploy/vercel/server/routes/[...].ts
11
+ import { defineHandler } from "nitro/h3";
12
+ async function serve(event) {
13
+ return (await vercelHost2(dispatchHead2)).listener.fetch(event.req);
14
+ }
15
+ var ___default = defineHandler(serve);
16
+ export {
17
+ ___default as default
18
+ };
@@ -0,0 +1,13 @@
1
+ import type { Listener, OpenOptions } from "@nyte-ai/core";
2
+ import type { ServedHost } from "@nyte-ai/core/server";
3
+ type Served = {
4
+ readonly host: ServedHost;
5
+ readonly listener: Listener;
6
+ };
7
+ /** Starts the workflow that drives a head; the host hands each wake to it. */
8
+ type Dispatch = Extract<NonNullable<OpenOptions["execution"]>, {
9
+ readonly kind: "dispatch";
10
+ }>["dispatch"];
11
+ /** This process's host, composed once, handing each wake to `dispatch`. */
12
+ export declare function vercelHost(dispatch: Dispatch): Promise<Served>;
13
+ export {};
@@ -0,0 +1,7 @@
1
+ import {
2
+ vercelHost2
3
+ } from "../../../../../chunks/canvas-preview-n2a35zv5.js";
4
+ import"../../../../../chunks/canvas-preview-2zdyh9ny.js";
5
+ export {
6
+ vercelHost2 as vercelHost
7
+ };
@@ -0,0 +1 @@
1
+ export declare function answerRepair(request: Request, secret: string | undefined, repair: () => Promise<void>): Promise<Response | undefined>;
@@ -0,0 +1,6 @@
1
+ import {
2
+ answerRepair2
3
+ } from "../../../../../chunks/canvas-preview-2zdyh9ny.js";
4
+ export {
5
+ answerRepair2 as answerRepair
6
+ };
@@ -0,0 +1,10 @@
1
+ import type { AdvanceReport } from "@nyte-ai/schema";
2
+ export type DriveStep = {
3
+ readonly kind: "advance";
4
+ } | {
5
+ readonly kind: "sleep";
6
+ readonly ms: number;
7
+ } | {
8
+ readonly kind: "stop";
9
+ };
10
+ export declare function stepFrom(report: AdvanceReport, now: number): DriveStep;