@nyte-ai/host 0.0.0-stage → 0.0.18

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 (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -2
  3. package/THIRD-PARTY-NOTICES.md +800 -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-0nrnbt76.js +497 -0
  7. package/dist/chunks/canvas-preview-1sq7z9jq.js +17 -0
  8. package/dist/chunks/canvas-preview-1ta3avah.js +56 -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-5hxat7hh.js +239 -0
  15. package/dist/chunks/canvas-preview-5mex725c.js +14 -0
  16. package/dist/chunks/canvas-preview-5z63am63.js +295 -0
  17. package/dist/chunks/canvas-preview-65xqjw7f.js +20 -0
  18. package/dist/chunks/canvas-preview-69fkk9yn.js +95 -0
  19. package/dist/chunks/canvas-preview-75db60xy.js +457 -0
  20. package/dist/chunks/canvas-preview-76fwvd6e.js +272 -0
  21. package/dist/chunks/canvas-preview-8xgt67ka.js +598 -0
  22. package/dist/chunks/canvas-preview-98aj5p34.js +176 -0
  23. package/dist/chunks/canvas-preview-9aqczacs.js +73 -0
  24. package/dist/chunks/canvas-preview-a3yw0j70.js +72 -0
  25. package/dist/chunks/canvas-preview-azg56359.js +68 -0
  26. package/dist/chunks/canvas-preview-d9wwhbtz.js +240 -0
  27. package/dist/chunks/canvas-preview-ehf3vp31.js +411 -0
  28. package/dist/chunks/canvas-preview-evh92ywd.js +369 -0
  29. package/dist/chunks/canvas-preview-ewgspmsd.js +81 -0
  30. package/dist/chunks/canvas-preview-g3qj3y3k.js +156 -0
  31. package/dist/chunks/canvas-preview-h8hshnff.js +63 -0
  32. package/dist/chunks/canvas-preview-j1tnf51w.js +36 -0
  33. package/dist/chunks/canvas-preview-kdqgrstc.js +194 -0
  34. package/dist/chunks/canvas-preview-kn7kvbfj.js +12 -0
  35. package/dist/chunks/canvas-preview-m02v4yy6.js +386 -0
  36. package/dist/chunks/canvas-preview-mgcx2b2p.js +271 -0
  37. package/dist/chunks/canvas-preview-rp4x6y1h.js +144 -0
  38. package/dist/chunks/canvas-preview-rp6fz0w5.js +130 -0
  39. package/dist/chunks/canvas-preview-s94ebwf5.js +112 -0
  40. package/dist/chunks/canvas-preview-senpjwep.js +518 -0
  41. package/dist/chunks/canvas-preview-skzwvw4d.js +23 -0
  42. package/dist/chunks/canvas-preview-srgfpdmf.js +60 -0
  43. package/dist/chunks/canvas-preview-tjhabynd.js +252 -0
  44. package/dist/chunks/canvas-preview-vaatfznm.js +189 -0
  45. package/dist/chunks/canvas-preview-vax9ne4e.js +341 -0
  46. package/dist/chunks/canvas-preview-wg80rbc2.js +46 -0
  47. package/dist/chunks/canvas-preview-xn10d4f8.js +608 -0
  48. package/dist/chunks/canvas-preview-yjz0f7n4.js +50 -0
  49. package/dist/chunks/canvas-preview-ymgz0937.js +587 -0
  50. package/dist/chunks/canvas-preview-yrfz2ak6.js +134 -0
  51. package/dist/chunks/canvas-preview-zaaj99wd.js +244 -0
  52. package/dist/chunks/canvas-preview-zn2d0k9d.js +133 -0
  53. package/dist/src/canvas-preview.d.ts +29 -0
  54. package/dist/src/canvas-preview.js +267 -0
  55. package/dist/src/credentials.d.ts +44 -0
  56. package/dist/src/credentials.js +10 -0
  57. package/dist/src/deploy/cloudflare/worker.d.ts +50 -0
  58. package/dist/src/deploy/cloudflare/worker.js +196 -0
  59. package/dist/src/deploy/vercel/nitro.config.d.ts +2 -0
  60. package/dist/src/deploy/vercel/nitro.config.js +30 -0
  61. package/dist/src/deploy/vercel/server/routes/[...].d.ts +2 -0
  62. package/dist/src/deploy/vercel/server/routes/[...].js +18 -0
  63. package/dist/src/deploy/vercel/server/utils/host.d.ts +13 -0
  64. package/dist/src/deploy/vercel/server/utils/host.js +7 -0
  65. package/dist/src/deploy/vercel/server/utils/repair.d.ts +1 -0
  66. package/dist/src/deploy/vercel/server/utils/repair.js +6 -0
  67. package/dist/src/deploy/vercel/server/utils/step.d.ts +10 -0
  68. package/dist/src/deploy/vercel/server/utils/step.js +6 -0
  69. package/dist/src/deploy/vercel/server/workflows/drive.d.ts +14 -0
  70. package/dist/src/deploy/vercel/server/workflows/drive.js +13 -0
  71. package/dist/src/durable-object.d.ts +14 -0
  72. package/dist/src/durable-object.js +231 -0
  73. package/dist/src/hash.d.ts +1 -0
  74. package/dist/src/hash.js +6 -0
  75. package/dist/src/identity-key.d.ts +11 -0
  76. package/dist/src/identity-key.js +9 -0
  77. package/dist/src/identity.d.ts +12 -0
  78. package/dist/src/identity.js +6 -0
  79. package/dist/src/index.d.ts +21 -0
  80. package/dist/src/index.js +120 -0
  81. package/dist/src/key-file.d.ts +1 -0
  82. package/dist/src/key-file.js +7 -0
  83. package/dist/src/listen-fetch.d.ts +8 -0
  84. package/dist/src/listen-fetch.js +9 -0
  85. package/dist/src/listen.d.ts +4 -0
  86. package/dist/src/listen.js +10 -0
  87. package/dist/src/local/command.d.ts +15 -0
  88. package/dist/src/local/command.js +8 -0
  89. package/dist/src/local/feed.d.ts +7 -0
  90. package/dist/src/local/feed.js +6 -0
  91. package/dist/src/local/files.d.ts +18 -0
  92. package/dist/src/local/files.js +13 -0
  93. package/dist/src/local/git-watch.d.ts +15 -0
  94. package/dist/src/local/git-watch.js +7 -0
  95. package/dist/src/local/git.d.ts +5 -0
  96. package/dist/src/local/git.js +13 -0
  97. package/dist/src/local/github.d.ts +30 -0
  98. package/dist/src/local/github.js +9 -0
  99. package/dist/src/local/identity.d.ts +3 -0
  100. package/dist/src/local/identity.js +7 -0
  101. package/dist/src/local/jobs.d.ts +7 -0
  102. package/dist/src/local/jobs.js +6 -0
  103. package/dist/src/local/legacy-trust.d.ts +10 -0
  104. package/dist/src/local/legacy-trust.js +6 -0
  105. package/dist/src/local/patch.d.ts +16 -0
  106. package/dist/src/local/patch.js +17 -0
  107. package/dist/src/local/provider.d.ts +11 -0
  108. package/dist/src/local/provider.js +20 -0
  109. package/dist/src/local/snapshots.d.ts +7 -0
  110. package/dist/src/local/snapshots.js +11 -0
  111. package/dist/src/local/text.d.ts +1 -0
  112. package/dist/src/local/text.js +6 -0
  113. package/dist/src/local/tree.d.ts +50 -0
  114. package/dist/src/local/tree.js +16 -0
  115. package/dist/src/local/workspace-migration.d.ts +2 -0
  116. package/dist/src/local/workspace-migration.js +7 -0
  117. package/dist/src/local/worktrees.d.ts +46 -0
  118. package/dist/src/local/worktrees.js +14 -0
  119. package/dist/src/mcp/config.d.ts +75 -0
  120. package/dist/src/mcp/config.js +12 -0
  121. package/dist/src/mcp/connect.d.ts +28 -0
  122. package/dist/src/mcp/connect.js +9 -0
  123. package/dist/src/mcp/hub.d.ts +19 -0
  124. package/dist/src/mcp/hub.js +11 -0
  125. package/dist/src/mcp/oauth.d.ts +46 -0
  126. package/dist/src/mcp/oauth.js +12 -0
  127. package/dist/src/mcp/tools.d.ts +29 -0
  128. package/dist/src/mcp/tools.js +12 -0
  129. package/dist/src/open.d.ts +42 -0
  130. package/dist/src/open.js +44 -0
  131. package/dist/src/plugins/loader.d.ts +21 -0
  132. package/dist/src/plugins/loader.js +11 -0
  133. package/dist/src/postgres.d.ts +19 -0
  134. package/dist/src/postgres.js +8 -0
  135. package/dist/src/providers.d.ts +16 -0
  136. package/dist/src/providers.js +112 -0
  137. package/dist/src/secrets.d.ts +12 -0
  138. package/dist/src/secrets.js +8 -0
  139. package/dist/src/serve/binding.d.ts +39 -0
  140. package/dist/src/serve/binding.js +6 -0
  141. package/dist/src/serve/handler.d.ts +15 -0
  142. package/dist/src/serve/handler.js +8 -0
  143. package/dist/src/serve/stream-server.d.ts +6 -0
  144. package/dist/src/serve/stream-server.js +6 -0
  145. package/dist/src/session-index.d.ts +11 -0
  146. package/dist/src/session-index.js +11 -0
  147. package/dist/src/shell-env.d.ts +14 -0
  148. package/dist/src/shell-env.js +108 -0
  149. package/dist/src/sqlite-workers.d.ts +6 -0
  150. package/dist/src/sqlite-workers.js +6 -0
  151. package/dist/src/sqlite.d.ts +7 -0
  152. package/dist/src/sqlite.js +10 -0
  153. package/dist/src/store-owner.d.ts +15 -0
  154. package/dist/src/store-owner.js +9 -0
  155. package/dist/src/store-rows.d.ts +13 -0
  156. package/dist/src/store-rows.js +26 -0
  157. package/dist/src/store-usage.d.ts +25 -0
  158. package/dist/src/store-usage.js +16 -0
  159. package/dist/src/usage-scan.d.ts +24 -0
  160. package/dist/src/usage-scan.js +65 -0
  161. package/dist/src/usage-service.d.ts +22 -0
  162. package/dist/src/usage-service.js +12 -0
  163. package/dist/src/usage-summary.d.ts +9 -0
  164. package/dist/src/usage-summary.js +16 -0
  165. package/dist/src/usage-types.d.ts +86 -0
  166. package/dist/src/usage-types.js +0 -0
  167. package/dist/src/usage-worker.d.ts +1 -0
  168. package/dist/src/usage-worker.js +25 -0
  169. package/dist/src/usage.d.ts +72 -0
  170. package/dist/src/usage.js +13 -0
  171. package/package.json +132 -3
  172. package/src/canvas-preview.ts +402 -0
  173. package/src/credentials.ts +294 -0
  174. package/src/deploy/cloudflare/README.md +3 -0
  175. package/src/deploy/cloudflare/worker.ts +306 -0
  176. package/src/deploy/cloudflare/wrangler.jsonc +12 -0
  177. package/src/deploy/vercel/README.md +3 -0
  178. package/src/deploy/vercel/nitro.config.ts +29 -0
  179. package/src/deploy/vercel/server/routes/[...].ts +10 -0
  180. package/src/deploy/vercel/server/utils/host.ts +104 -0
  181. package/src/deploy/vercel/server/utils/repair.ts +35 -0
  182. package/src/deploy/vercel/server/utils/step.ts +25 -0
  183. package/src/deploy/vercel/server/workflows/drive.ts +46 -0
  184. package/src/deploy/vercel/tsconfig.json +9 -0
  185. package/src/deploy/vercel/types/bun.d.ts +2 -0
  186. package/src/durable-object.ts +386 -0
  187. package/src/hash.ts +5 -0
  188. package/src/identity-key.ts +20 -0
  189. package/src/identity.ts +66 -0
  190. package/src/index.ts +21 -0
  191. package/src/key-file.ts +53 -0
  192. package/src/listen-fetch.ts +409 -0
  193. package/src/listen.ts +228 -0
  194. package/src/local/command.ts +109 -0
  195. package/src/local/feed.ts +70 -0
  196. package/src/local/files.ts +812 -0
  197. package/src/local/git-watch.ts +189 -0
  198. package/src/local/git.ts +914 -0
  199. package/src/local/github.ts +692 -0
  200. package/src/local/identity.ts +21 -0
  201. package/src/local/jobs.ts +587 -0
  202. package/src/local/legacy-trust.ts +105 -0
  203. package/src/local/patch.ts +334 -0
  204. package/src/local/provider.ts +184 -0
  205. package/src/local/snapshots.ts +776 -0
  206. package/src/local/text.ts +9 -0
  207. package/src/local/tree.ts +398 -0
  208. package/src/local/workspace-migration.ts +95 -0
  209. package/src/local/worktrees.ts +239 -0
  210. package/src/mcp/config.ts +330 -0
  211. package/src/mcp/connect.ts +105 -0
  212. package/src/mcp/hub.ts +836 -0
  213. package/src/mcp/oauth.ts +436 -0
  214. package/src/mcp/tools.ts +333 -0
  215. package/src/open.ts +469 -0
  216. package/src/plugins/loader.ts +186 -0
  217. package/src/postgres.ts +492 -0
  218. package/src/providers.ts +135 -0
  219. package/src/secrets.ts +31 -0
  220. package/src/serve/binding.ts +628 -0
  221. package/src/serve/handler.ts +362 -0
  222. package/src/serve/stream-server.ts +176 -0
  223. package/src/session-index.ts +99 -0
  224. package/src/shell-env.ts +153 -0
  225. package/src/sqlite-workers.ts +283 -0
  226. package/src/sqlite.ts +528 -0
  227. package/src/store-owner.ts +98 -0
  228. package/src/store-rows.ts +110 -0
  229. package/src/store-usage.ts +344 -0
  230. package/src/usage-scan.ts +81 -0
  231. package/src/usage-service.ts +73 -0
  232. package/src/usage-summary.ts +79 -0
  233. package/src/usage-types.ts +87 -0
  234. package/src/usage-worker.ts +24 -0
  235. package/src/usage.ts +701 -0
@@ -0,0 +1,176 @@
1
+ import {
2
+ listenFetch2
3
+ } from "./canvas-preview-76fwvd6e.js";
4
+
5
+ // src/listen.ts
6
+ import { createServer } from "node:http";
7
+ import { SdkError } from "@nyte-ai/schema";
8
+ import { encodeError, errorStatus } from "@nyte-ai/protocol";
9
+ async function listen2(host, options) {
10
+ const inner = await listenFetch2(host, { ...options, transport: { kind: "fetch" } });
11
+ if (options.transport.kind === "fetch")
12
+ return inner;
13
+ const responses = new Set;
14
+ const bound = await bind(options.transport, (request) => inner.fetch(request), responses).catch(async (error) => {
15
+ await inner.close();
16
+ throw new SdkError("unavailable", `Cannot listen: ${error instanceof Error ? error.message : String(error)}`);
17
+ });
18
+ const disconnectClients = () => {
19
+ inner.disconnectClients();
20
+ for (const response of responses)
21
+ response.destroy();
22
+ };
23
+ let closing = null;
24
+ const close = () => {
25
+ closing ??= (async () => {
26
+ disconnectClients();
27
+ await inner.close();
28
+ await new Promise((done) => {
29
+ bound.server.close(() => done());
30
+ bound.server.closeAllConnections();
31
+ });
32
+ })();
33
+ return closing;
34
+ };
35
+ return {
36
+ address: bound.address,
37
+ fetch: (request) => inner.fetch(request),
38
+ disconnectClients,
39
+ close,
40
+ [Symbol.asyncDispose]: close
41
+ };
42
+ }
43
+ async function bind(transport, fetch, responses) {
44
+ let origin = "http://127.0.0.1";
45
+ const server = createServer({ noDelay: true }, (incoming, outgoing) => {
46
+ respond(incoming, outgoing, origin, fetch, responses);
47
+ });
48
+ await new Promise((listening, failed) => {
49
+ server.once("error", failed);
50
+ server.listen(transport.port ?? 0, transport.hostname ?? "127.0.0.1", () => {
51
+ server.off("error", failed);
52
+ listening();
53
+ });
54
+ });
55
+ const info = server.address();
56
+ if (info === null || typeof info === "string") {
57
+ server.close();
58
+ throw new Error("the socket has no address");
59
+ }
60
+ const hostname = info.address.includes(":") ? `[${info.address}]` : info.address;
61
+ origin = `http://${hostname}:${info.port}`;
62
+ return { server, address: origin };
63
+ }
64
+ async function respond(incoming, outgoing, origin, fetch, responses) {
65
+ const controller = new AbortController;
66
+ responses.add(outgoing);
67
+ outgoing.on("close", () => {
68
+ responses.delete(outgoing);
69
+ if (!outgoing.writableFinished)
70
+ controller.abort();
71
+ });
72
+ let request;
73
+ try {
74
+ request = readRequest(incoming, origin, controller.signal);
75
+ } catch (error) {
76
+ await write(failure(new SdkError("invalid", error instanceof Error ? error.message : String(error))), outgoing);
77
+ return;
78
+ }
79
+ await write(await fetch(request), outgoing);
80
+ }
81
+ function readRequest(incoming, origin, signal) {
82
+ const headers = new Headers;
83
+ for (const [name, value] of Object.entries(incoming.headers)) {
84
+ if (name.startsWith(":") || value === undefined)
85
+ continue;
86
+ if (Array.isArray(value))
87
+ for (const each of value)
88
+ headers.append(name, each);
89
+ else
90
+ headers.set(name, value);
91
+ }
92
+ const host = incoming.headers.host;
93
+ const url = new URL(incoming.url ?? "/", host === undefined ? origin : `http://${host}`);
94
+ const method = incoming.method ?? "GET";
95
+ const body = method === "GET" || method === "HEAD" ? {} : { body: streamBody(incoming), duplex: "half" };
96
+ return new Request(url.href, { method, headers, signal, ...body });
97
+ }
98
+ function streamBody(incoming) {
99
+ return new ReadableStream({
100
+ start(controller) {
101
+ incoming.on("data", (chunk) => {
102
+ controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
103
+ if ((controller.desiredSize ?? 0) <= 0)
104
+ incoming.pause();
105
+ });
106
+ incoming.on("end", () => controller.close());
107
+ incoming.on("error", (error) => controller.error(error));
108
+ },
109
+ pull() {
110
+ incoming.resume();
111
+ },
112
+ cancel() {
113
+ incoming.destroy();
114
+ }
115
+ });
116
+ }
117
+ async function write(response, outgoing) {
118
+ if (outgoing.destroyed) {
119
+ await response.body?.cancel().catch(() => {
120
+ return;
121
+ });
122
+ return;
123
+ }
124
+ const headers = {};
125
+ response.headers.forEach((value, name) => {
126
+ headers[name] = value;
127
+ });
128
+ const cookies = response.headers.getSetCookie();
129
+ if (cookies.length > 0)
130
+ headers["set-cookie"] = cookies;
131
+ outgoing.writeHead(response.status, headers);
132
+ outgoing.flushHeaders();
133
+ if (response.body === null) {
134
+ outgoing.end();
135
+ return;
136
+ }
137
+ const reader = response.body.getReader();
138
+ const cancel = () => {
139
+ reader.cancel().catch(() => {
140
+ return;
141
+ });
142
+ };
143
+ outgoing.on("close", cancel);
144
+ try {
145
+ for (;; ) {
146
+ const read = await reader.read();
147
+ if (read.done)
148
+ break;
149
+ if (!outgoing.write(read.value))
150
+ await new Promise((drained) => {
151
+ const done = () => {
152
+ outgoing.off("drain", done);
153
+ outgoing.off("close", done);
154
+ drained();
155
+ };
156
+ outgoing.on("drain", done);
157
+ outgoing.on("close", done);
158
+ });
159
+ if (outgoing.destroyed)
160
+ return;
161
+ }
162
+ outgoing.end();
163
+ } catch {
164
+ outgoing.destroy();
165
+ } finally {
166
+ outgoing.off("close", cancel);
167
+ }
168
+ }
169
+ function failure(error) {
170
+ return new Response(JSON.stringify(encodeError(error)), {
171
+ status: errorStatus[error.code],
172
+ headers: { "Content-Type": "application/json" }
173
+ });
174
+ }
175
+
176
+ export { listen2 };
@@ -0,0 +1,73 @@
1
+ // src/local/legacy-trust.ts
2
+ import { readFile, realpath, stat } from "node:fs/promises";
3
+ import { isAbsolute, join } from "node:path";
4
+ import { envelope, trustRef } from "@nyte-ai/core/store";
5
+ import { SdkError } from "@nyte-ai/schema";
6
+ import { Type } from "typebox";
7
+ import { Value } from "typebox/value";
8
+ var MIGRATION = "host/migrations/legacy-folder-trust-v1";
9
+ var WorkspacesFile = Type.Record(Type.String(), Type.Object({ trusted: Type.Boolean() }));
10
+ var TrustFile = Type.Record(Type.String(), Type.Literal(true));
11
+ async function importLegacyTrust2(connection, home) {
12
+ for (let attempt = 0;attempt < 3; attempt += 1) {
13
+ if (await connection.refs.get(MIGRATION) !== null)
14
+ return;
15
+ const folders = await legacyFolders(home);
16
+ const updates = [];
17
+ for (const path of folders) {
18
+ const target = { kind: "local", path };
19
+ const name = await trustRef(target);
20
+ if (await connection.refs.get(name) !== null)
21
+ continue;
22
+ updates.push({
23
+ name,
24
+ expect: "absent",
25
+ target: await connection.objects.put(envelope("trust", { target, trusted: true }, Date.now()))
26
+ });
27
+ }
28
+ updates.push({
29
+ name: MIGRATION,
30
+ expect: "absent",
31
+ target: await connection.objects.put({ imported: folders })
32
+ });
33
+ if ((await connection.refs.set(updates)).kind === "set")
34
+ return;
35
+ }
36
+ throw new SdkError("unavailable", "Folder trust changed while Nyte was importing it.");
37
+ }
38
+ async function legacyFolders(home) {
39
+ const [workspaces, nyte, uji] = await Promise.all([
40
+ readJson(join(home, ".nyte", "workspaces.json")),
41
+ readJson(join(home, ".nyte", "trust.json")),
42
+ readJson(join(home, ".uji", "trust.json"))
43
+ ]);
44
+ const granted = [
45
+ ...Value.Check(WorkspacesFile, workspaces) ? Object.entries(workspaces).flatMap(([path, row]) => row.trusted ? [path] : []) : [],
46
+ ...[nyte, uji].flatMap((file) => Value.Check(TrustFile, file) ? Object.keys(file) : [])
47
+ ];
48
+ const ownHome = await realpath(home).catch(() => home);
49
+ const found = await Promise.all(granted.map(canonicalFolder));
50
+ return [
51
+ ...new Set(found.flatMap((path) => path === null || path === ownHome || ownHome.startsWith(`${path}/`) || path === "/" ? [] : [path]))
52
+ ];
53
+ }
54
+ async function canonicalFolder(path) {
55
+ if (!isAbsolute(path))
56
+ return null;
57
+ const real = await realpath(path).catch(() => null);
58
+ if (real === null || (await stat(real).catch(() => null))?.isDirectory() !== true)
59
+ return null;
60
+ return real.replace(/\/+$/u, "");
61
+ }
62
+ async function readJson(path) {
63
+ const text = await readFile(path, "utf8").catch(() => null);
64
+ if (text === null)
65
+ return null;
66
+ try {
67
+ return JSON.parse(text);
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+
73
+ export { importLegacyTrust2 };
@@ -0,0 +1,72 @@
1
+ import {
2
+ parseNumber2,
3
+ parseText2
4
+ } from "./canvas-preview-69fkk9yn.js";
5
+
6
+ // src/store-owner.ts
7
+ import { resolve } from "node:path";
8
+ import process from "node:process";
9
+ import { DatabaseSync } from "node:sqlite";
10
+ import { SdkError } from "@nyte-ai/schema";
11
+ import { STORE_VERSION } from "@nyte-ai/core/store";
12
+ var CONTEND_MS = 1000;
13
+ var SQLITE_BUSY = 5;
14
+ var claims = new Map;
15
+
16
+ class StoreOwned2 extends SdkError {
17
+ constructor(message) {
18
+ super("unavailable", message);
19
+ }
20
+ }
21
+ function claimStore2(path) {
22
+ const key = resolve(path);
23
+ const claim = claims.get(key) ?? { lock: lockStore(key), holders: 0 };
24
+ claims.set(key, claim);
25
+ claim.holders += 1;
26
+ let released = false;
27
+ return () => {
28
+ if (released)
29
+ return;
30
+ released = true;
31
+ claim.holders -= 1;
32
+ if (claim.holders > 0)
33
+ return;
34
+ claims.delete(key);
35
+ claim.lock.close();
36
+ };
37
+ }
38
+ function lockStore(path) {
39
+ const lock = new DatabaseSync(`${path}.owner`, { timeout: CONTEND_MS });
40
+ try {
41
+ reserve(lock, path);
42
+ lock.exec("CREATE TABLE IF NOT EXISTS owner (id INTEGER PRIMARY KEY CHECK (id = 1), pid INTEGER NOT NULL, program TEXT NOT NULL, store INTEGER NOT NULL)");
43
+ lock.prepare("INSERT OR REPLACE INTO owner (id, pid, program, store) VALUES (1, ?, ?, ?)").run(process.pid, process.execPath, STORE_VERSION);
44
+ lock.exec("COMMIT");
45
+ reserve(lock, path);
46
+ } catch (cause) {
47
+ lock.close();
48
+ throw cause;
49
+ }
50
+ return lock;
51
+ }
52
+ function reserve(lock, path) {
53
+ try {
54
+ lock.exec("BEGIN IMMEDIATE");
55
+ } catch (cause) {
56
+ if (!(cause instanceof Error && ("errcode" in cause) && cause.errcode === SQLITE_BUSY))
57
+ throw cause;
58
+ throw new StoreOwned2(`${describeOwner(lock)} has ${path} open. Nyte opens a store in one process at a time; quit that one and try again.`);
59
+ }
60
+ }
61
+ function describeOwner(lock) {
62
+ try {
63
+ const row = lock.prepare("SELECT pid, program, store FROM owner WHERE id = 1").get();
64
+ if (row === undefined)
65
+ return "Another Nyte process";
66
+ return `Another Nyte process (pid ${String(parseNumber2(row.pid))}, ${parseText2(row.program)}, store version ${String(parseNumber2(row.store))})`;
67
+ } catch {
68
+ return "Another Nyte process";
69
+ }
70
+ }
71
+
72
+ export { StoreOwned2, claimStore2 };
@@ -0,0 +1,68 @@
1
+ // src/local/command.ts
2
+ import { spawn } from "node:child_process";
3
+ import { constants } from "node:fs";
4
+ import { access, stat } from "node:fs/promises";
5
+ import { delimiter, isAbsolute, join } from "node:path";
6
+ import { SdkError } from "@nyte-ai/schema";
7
+ import { processEnvironment } from "@nyte-ai/core";
8
+ async function run2(file, args, options) {
9
+ await processEnvironment();
10
+ return new Promise((resolve, reject) => {
11
+ const child = spawn(file, args, {
12
+ cwd: options.cwd,
13
+ env: { ...process.env, ...options.env },
14
+ stdio: ["pipe", "pipe", "pipe"],
15
+ windowsHide: true,
16
+ timeout: options.timeoutMs
17
+ });
18
+ const stdout = [];
19
+ const stderr = [];
20
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
21
+ let size = 0;
22
+ let truncated = false;
23
+ child.on("error", (error) => reject(new SdkError("unavailable", `Cannot run ${file}: ${error.message}`)));
24
+ child.stdout.on("data", (chunk) => {
25
+ if (truncated)
26
+ return;
27
+ size += chunk.byteLength;
28
+ if (size > limit) {
29
+ truncated = true;
30
+ stdout.push(chunk.subarray(0, chunk.byteLength - (size - limit)));
31
+ child.kill("SIGKILL");
32
+ return;
33
+ }
34
+ stdout.push(chunk);
35
+ });
36
+ child.stderr.on("data", (chunk) => stderr.push(chunk));
37
+ child.stdin.on("error", () => {
38
+ return;
39
+ });
40
+ child.on("close", (code) => resolve({
41
+ code,
42
+ stdout: Buffer.concat(stdout),
43
+ stderr: Buffer.concat(stderr).toString("utf8"),
44
+ truncated
45
+ }));
46
+ child.stdin.end(options.input);
47
+ });
48
+ }
49
+ async function findExecutable2(name, directories = []) {
50
+ if (isAbsolute(name))
51
+ return await executable(name) ? name : null;
52
+ await processEnvironment();
53
+ const path = (process.env.PATH ?? "").split(delimiter).filter((entry) => entry !== "");
54
+ const extensions = process.platform === "win32" ? ["", ...(process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")] : [""];
55
+ for (const directory of [...directories, ...path])
56
+ for (const extension of extensions) {
57
+ const candidate = join(directory, `${name}${extension}`);
58
+ if (await executable(candidate))
59
+ return candidate;
60
+ }
61
+ return null;
62
+ }
63
+ async function executable(path) {
64
+ const found = await stat(path).catch(() => null);
65
+ return found !== null && found.isFile() && await access(path, constants.X_OK).then(() => true, () => false);
66
+ }
67
+
68
+ export { run2, findExecutable2 };
@@ -0,0 +1,240 @@
1
+ import {
2
+ bindConnection2
3
+ } from "./canvas-preview-m02v4yy6.js";
4
+ import {
5
+ createStreamChannels2
6
+ } from "./canvas-preview-rp4x6y1h.js";
7
+
8
+ // src/serve/handler.ts
9
+ import { Type } from "typebox";
10
+ import { compile, isJsonObject, OPERATIONS, SdkError } from "@nyte-ai/schema";
11
+ import {
12
+ CANCEL_PATH,
13
+ CHANNEL_HEADER,
14
+ CHANNEL_PATH,
15
+ HOST_HEADER,
16
+ INPUT_HEADER,
17
+ STREAM_HEADER,
18
+ abortable,
19
+ answersBytes,
20
+ answersOnce,
21
+ asSdkError,
22
+ decodeInput,
23
+ encodeError,
24
+ encodeOutput,
25
+ errorStatus,
26
+ mapped,
27
+ namesOperation,
28
+ octetStream,
29
+ outputFrames,
30
+ parseJson,
31
+ readInputHeader,
32
+ sseFrames
33
+ } from "@nyte-ai/protocol";
34
+ var MAX_BODY_BYTES = 8 * 1024 * 1024;
35
+ var UPLOADS = new Set([
36
+ "files.write",
37
+ "job.write",
38
+ "files.upload"
39
+ ]);
40
+ var ALLOWED_HEADERS = `Authorization, Content-Type, ${INPUT_HEADER}, ${CHANNEL_HEADER}, ${STREAM_HEADER}`;
41
+ var EXPOSED_HEADERS = `X-Nyte-Version, X-Nyte-Mime, X-Nyte-Credential, ${HOST_HEADER}, ${CHANNEL_HEADER}`;
42
+ var tooLarge = new WeakSet;
43
+ var cancellations = compile(Type.Object({ channel: Type.String(), stream: Type.String() }));
44
+ function createHandler2(options) {
45
+ const limit = options.maxBodyBytes ?? MAX_BODY_BYTES;
46
+ const bindings = new WeakMap;
47
+ const channels = createStreamChannels2();
48
+ const bind = (connection) => {
49
+ const known = bindings.get(connection);
50
+ if (known !== undefined)
51
+ return known;
52
+ const created = bindConnection2(connection, options);
53
+ bindings.set(connection, created);
54
+ return created;
55
+ };
56
+ return async (request) => {
57
+ const cors = corsHeaders(request, options.origins);
58
+ if (cors === null)
59
+ return errorResponse(new SdkError("denied", "This origin may not call the host."), {});
60
+ if (request.method === "OPTIONS")
61
+ return new Response(null, {
62
+ status: 204,
63
+ headers: {
64
+ ...cors,
65
+ "Access-Control-Allow-Methods": "POST",
66
+ "Access-Control-Allow-Headers": ALLOWED_HEADERS,
67
+ "Access-Control-Max-Age": "600"
68
+ }
69
+ });
70
+ try {
71
+ const path = new URL(request.url).pathname.slice(1);
72
+ const name = request.method === "POST" && (path === CHANNEL_PATH || path === CANCEL_PATH) ? path : readOperation(request);
73
+ const authenticated = await options.connection(request);
74
+ if (name === CHANNEL_PATH) {
75
+ const value = await readBody(request, limit);
76
+ const deflate = isJsonObject(value) && value.deflate === true;
77
+ return withHeaders(channels.open(authenticated.connection, request.signal, deflate), {
78
+ ...cors,
79
+ ...authenticated.headers
80
+ });
81
+ }
82
+ if (name === CANCEL_PATH) {
83
+ const value = await readBody(request, limit);
84
+ if (!cancellations.Check(value))
85
+ throw new SdkError("invalid", "A stream cancellation needs its channel and stream.");
86
+ channels.cancel(authenticated.connection, value.channel, value.stream);
87
+ return withHeaders(new Response(null, { status: 204 }), {
88
+ ...cors,
89
+ ...authenticated.headers
90
+ });
91
+ }
92
+ const needed = OPERATIONS[name].authority;
93
+ if (!authenticated.authority.has(needed))
94
+ throw new SdkError("denied", `${name} needs ${needed} authority.`);
95
+ const binding = bind(authenticated.connection);
96
+ let response;
97
+ const channel = request.headers.get(CHANNEL_HEADER);
98
+ const stream = request.headers.get(STREAM_HEADER);
99
+ if (channel !== null || stream !== null) {
100
+ if (channel === null || stream === null)
101
+ throw new SdkError("invalid", "A shared stream needs its channel and identifier.");
102
+ const value = await readBody(request, limit);
103
+ response = await channels.start(authenticated.connection, channel, stream, request.signal, (signal) => answer(binding, name, value, request, signal));
104
+ } else
105
+ response = await serve(binding, name, request, limit);
106
+ return withHeaders(response, { ...cors, ...authenticated.headers });
107
+ } catch (error) {
108
+ return errorResponse(asSdkError(error), cors);
109
+ }
110
+ };
111
+ }
112
+ async function serve(binding, name, request, limit) {
113
+ if (UPLOADS.has(name) && answersOnce(name)) {
114
+ const body = limited(request, limit);
115
+ return json(await call(binding, name, readInputHeader(request) ?? {}, { body, signal: request.signal }));
116
+ }
117
+ return answer(binding, name, await readBody(request, limit), request, request.signal);
118
+ }
119
+ async function answer(binding, name, value, request, signal) {
120
+ const context = { body: null, signal };
121
+ if (answersOnce(name))
122
+ return json(await call(binding, name, value, context));
123
+ if (name === "job.output")
124
+ return new Response(outputFrames(abortable(await binding["job.output"](decodeInput(name, value), context), signal)), { status: 200, headers: { "Content-Type": "application/octet-stream" } });
125
+ if (answersBytes(name))
126
+ return octetStream(await bytes(binding, name, value, context), request.signal);
127
+ return new Response(sseFrames(ending(await frames(binding, name, value, context), signal)), {
128
+ status: 200,
129
+ headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache" }
130
+ });
131
+ }
132
+ async function call(binding, name, value, request) {
133
+ return encodeOutput(name, await binding[name](decodeInput(name, value), request));
134
+ }
135
+ async function bytes(binding, name, value, request) {
136
+ return binding[name](decodeInput(name, value), request);
137
+ }
138
+ async function frames(binding, name, value, request) {
139
+ return mapped(await binding[name](decodeInput(name, value), request), (frame) => encodeOutput(name, frame));
140
+ }
141
+ function ending(source, signal) {
142
+ return {
143
+ [Symbol.asyncIterator]() {
144
+ const iterator = abortable(source, signal)[Symbol.asyncIterator]();
145
+ return {
146
+ async next() {
147
+ const next = await iterator.next();
148
+ if (next.done === true && signal.reason instanceof SdkError)
149
+ throw signal.reason;
150
+ return next;
151
+ },
152
+ async return() {
153
+ await iterator.return?.();
154
+ return { done: true, value: undefined };
155
+ }
156
+ };
157
+ }
158
+ };
159
+ }
160
+ async function readBody(request, limit) {
161
+ const stream = limited(request, limit);
162
+ if (stream === null)
163
+ return {};
164
+ const chunks = [];
165
+ const reader = stream.getReader();
166
+ for (;; ) {
167
+ const read = await reader.read();
168
+ if (read.done)
169
+ break;
170
+ chunks.push(read.value);
171
+ }
172
+ const decoder = new TextDecoder;
173
+ const text = chunks.map((chunk) => decoder.decode(chunk, { stream: true })).join("") + decoder.decode();
174
+ return text.trim() === "" ? {} : parseJson(text);
175
+ }
176
+ function limited(request, limit) {
177
+ const declared = Number(request.headers.get("Content-Length") ?? "0");
178
+ if (declared > limit)
179
+ throw largerThan(limit);
180
+ if (request.body === null)
181
+ return null;
182
+ let total = 0;
183
+ return request.body.pipeThrough(new TransformStream({
184
+ transform(chunk, controller) {
185
+ total += chunk.byteLength;
186
+ if (total > limit)
187
+ controller.error(largerThan(limit));
188
+ else
189
+ controller.enqueue(chunk);
190
+ }
191
+ }), { signal: request.signal });
192
+ }
193
+ function largerThan(limit) {
194
+ const error = new SdkError("invalid", `The body is larger than ${limit} bytes.`);
195
+ tooLarge.add(error);
196
+ return error;
197
+ }
198
+ function corsHeaders(request, origins) {
199
+ const origin = request.headers.get("Origin");
200
+ if (origin === null || origin === new URL(request.url).origin)
201
+ return {};
202
+ if (!(origins ?? []).includes(origin))
203
+ return null;
204
+ return {
205
+ "Access-Control-Allow-Origin": origin,
206
+ "Access-Control-Expose-Headers": EXPOSED_HEADERS,
207
+ Vary: "Origin"
208
+ };
209
+ }
210
+ function readOperation(request) {
211
+ const path = new URL(request.url).pathname;
212
+ const name = path.slice(1);
213
+ if (request.method !== "POST" || !namesOperation(name))
214
+ throw new SdkError("unknown", `No operation answers ${request.method} ${path}.`);
215
+ return name;
216
+ }
217
+ function json(value) {
218
+ return new Response(JSON.stringify(value), {
219
+ status: 200,
220
+ headers: { "Content-Type": "application/json" }
221
+ });
222
+ }
223
+ function errorResponse(failure, headers) {
224
+ return new Response(JSON.stringify(encodeError(failure)), {
225
+ status: tooLarge.has(failure) ? 413 : errorStatus[failure.code],
226
+ headers: { ...headers, "Content-Type": "application/json" }
227
+ });
228
+ }
229
+ function withHeaders(response, headers) {
230
+ const merged = new Headers(response.headers);
231
+ for (const [key, value] of Object.entries(headers))
232
+ merged.set(key, value);
233
+ return new Response(response.body, {
234
+ status: response.status,
235
+ statusText: response.statusText,
236
+ headers: merged
237
+ });
238
+ }
239
+
240
+ export { createHandler2 };