@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,458 @@
1
+ import {
2
+ run2,
3
+ spawnCommand2,
4
+ killTree2,
5
+ findExecutable2
6
+ } from "./canvas-preview-bxnqt8cd.js";
7
+
8
+ // src/local/github.ts
9
+ import { homedir } from "node:os";
10
+ import { Type } from "typebox";
11
+ import { Compile } from "typebox/compile";
12
+ import { dev } from "@nyte-ai/core";
13
+ var ENV = {
14
+ GH_PROMPT_DISABLED: "1",
15
+ GH_NO_UPDATE_NOTIFIER: "1",
16
+ GIT_TERMINAL_PROMPT: "0",
17
+ NO_COLOR: "1",
18
+ LC_ALL: "C"
19
+ };
20
+ var OUTPUT_LIMIT = 1e6;
21
+ var QUERY_TIMEOUT_MS = 1e4;
22
+ var CREATE_TIMEOUT_MS = 60000;
23
+ var SIGN_IN_CODE_TIMEOUT_MS = 30000;
24
+ var SIGN_IN_LIFETIME_MS = 15 * 60000;
25
+ var NO_PULL_REQUEST = { kind: "none" };
26
+ var PULL_REQUEST_FIELDS = "number,title,url,state,isDraft,headRefName,baseRefName,statusCheckRollup";
27
+ var REMOTE_PRIORITY = ["upstream", "github", "origin"];
28
+ var RECOVERY = {
29
+ update: "Update the GitHub CLI (gh), then try again.",
30
+ signIn: "GitHub rejected the CLI's login. Run gh auth login in a terminal, then try again.",
31
+ signOut: "Couldn't sign out of GitHub. Run gh auth logout in a terminal, then try again.",
32
+ account: "Couldn't reach GitHub. Try again.",
33
+ pullRequest: "Couldn't read this branch's pull request. Try again.",
34
+ createPullRequest: "Couldn't open a pull request. Run gh pr create in a terminal to see why."
35
+ };
36
+ var authSchema = Compile(Type.Array(Type.Object({ active: Type.Boolean(), state: Type.String(), login: Type.String() })));
37
+ var accountSchema = Compile(Type.Object({
38
+ login: Type.String({ minLength: 1 }),
39
+ name: Type.Union([Type.String(), Type.Null()]),
40
+ avatar_url: Type.Union([Type.String(), Type.Null()])
41
+ }));
42
+ var optionalText = Type.Optional(Type.Union([Type.String(), Type.Null()]));
43
+ var PullRequestJson = Type.Object({
44
+ number: Type.Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }),
45
+ title: Type.String(),
46
+ url: Type.String(),
47
+ state: Type.Enum(["OPEN", "CLOSED", "MERGED"]),
48
+ isDraft: Type.Boolean(),
49
+ headRefName: Type.String({ minLength: 1 }),
50
+ baseRefName: Type.String({ minLength: 1 }),
51
+ statusCheckRollup: Type.Union([
52
+ Type.Null(),
53
+ Type.Array(Type.Object({
54
+ __typename: Type.String(),
55
+ name: optionalText,
56
+ context: optionalText,
57
+ status: optionalText,
58
+ conclusion: optionalText,
59
+ state: optionalText,
60
+ detailsUrl: optionalText,
61
+ targetUrl: optionalText
62
+ }))
63
+ ])
64
+ });
65
+ var pullRequestSchema = Compile(PullRequestJson);
66
+ function parseJson(validator, text) {
67
+ try {
68
+ return validator.Parse(JSON.parse(text));
69
+ } catch {
70
+ return;
71
+ }
72
+ }
73
+ function safeUrl(value, hostnames) {
74
+ const url = URL.parse(value ?? "");
75
+ if (url === null || url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.port !== "" || hostnames !== undefined && !hostnames.includes(url.hostname))
76
+ return;
77
+ return url.href;
78
+ }
79
+ var REPOSITORY_PART = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/u;
80
+ function parseRemote(remoteName, remote) {
81
+ const scp = /^(?:[^@\s]+@)?github\.com:([^/\s]+)\/([^/\s]+?)\/?$/iu.exec(remote);
82
+ const url = scp === null ? URL.parse(remote) : null;
83
+ const parts = scp === null ? url !== null && url.hostname.toLowerCase() === "github.com" ? url.pathname.split("/").filter((segment) => segment !== "") : [] : [scp[1] ?? "", scp[2] ?? ""];
84
+ if (parts.length !== 2)
85
+ return;
86
+ const owner = parts[0] ?? "";
87
+ const name = (parts[1] ?? "").replace(/\.git$/iu, "");
88
+ if (!REPOSITORY_PART.test(owner) || !REPOSITORY_PART.test(name))
89
+ return;
90
+ return { owner, name, remoteName, url: `https://github.com/${owner}/${name}` };
91
+ }
92
+ function checkState(entry) {
93
+ if (entry.__typename === "StatusContext") {
94
+ if (entry.state === "SUCCESS")
95
+ return "passed";
96
+ return entry.state === "ERROR" || entry.state === "FAILURE" ? "failed" : "pending";
97
+ }
98
+ if (entry.status !== "COMPLETED")
99
+ return "pending";
100
+ switch (entry.conclusion) {
101
+ case "SUCCESS":
102
+ case "NEUTRAL":
103
+ return "passed";
104
+ case "SKIPPED":
105
+ case "STALE":
106
+ return "skipped";
107
+ default:
108
+ return "failed";
109
+ }
110
+ }
111
+ function readCheck(entry) {
112
+ const url = safeUrl(entry.detailsUrl ?? entry.targetUrl);
113
+ const check = { name: entry.name ?? entry.context ?? "Check", state: checkState(entry) };
114
+ return url === undefined ? check : { ...check, url };
115
+ }
116
+ function readPullRequestJson(text) {
117
+ const pull = parseJson(pullRequestSchema, text);
118
+ const url = safeUrl(pull?.url, ["github.com"]);
119
+ if (pull === undefined || url === undefined)
120
+ return;
121
+ return {
122
+ number: pull.number,
123
+ title: pull.title,
124
+ url,
125
+ state: pull.state,
126
+ draft: pull.isDraft,
127
+ headRefName: pull.headRefName,
128
+ baseRefName: pull.baseRefName,
129
+ checks: (pull.statusCheckRollup ?? []).map(readCheck)
130
+ };
131
+ }
132
+ function readAccountJson(text) {
133
+ const account = parseJson(accountSchema, text);
134
+ if (account === undefined)
135
+ return;
136
+ const avatarUrl = safeUrl(account.avatar_url, ["avatars.githubusercontent.com"]);
137
+ return {
138
+ login: account.login,
139
+ ...account.name === null || account.name === "" ? {} : { name: account.name },
140
+ ...avatarUrl === undefined ? {} : { avatarUrl }
141
+ };
142
+ }
143
+ var USER_CODE = /one-time code\W*([A-Z0-9]{4}-[A-Z0-9]{4})\b/iu;
144
+ var PRINTED_URL = /https:\/\/\S+/u;
145
+ var SIGN_IN_LINE_LIMIT = 4096;
146
+ function startSignIn(file, cwd, ended) {
147
+ const started = Promise.withResolvers();
148
+ const expiresAt = Date.now() + SIGN_IN_LIFETIME_MS;
149
+ let userCode;
150
+ let verificationUri;
151
+ let done = false;
152
+ const child = spawnCommand2(file, [
153
+ "auth",
154
+ "login",
155
+ "--hostname",
156
+ "github.com",
157
+ "--web",
158
+ "--git-protocol",
159
+ "https",
160
+ "--skip-ssh-key"
161
+ ], { cwd, env: { ...process.env, ...ENV }, stdio: ["ignore", "pipe", "pipe"] });
162
+ const end = (start) => {
163
+ if (done)
164
+ return;
165
+ done = true;
166
+ clearTimeout(codeTimer);
167
+ clearTimeout(lifetime);
168
+ child.stdout?.destroy();
169
+ child.stderr?.destroy();
170
+ if (child.exitCode === null && child.signalCode === null)
171
+ killTree2(child, "SIGKILL");
172
+ started.resolve(start);
173
+ ended();
174
+ };
175
+ const readLine = (line) => {
176
+ userCode ??= USER_CODE.exec(line)?.[1]?.toUpperCase();
177
+ const printed = PRINTED_URL.exec(line)?.[0];
178
+ if (verificationUri === undefined && printed !== undefined) {
179
+ verificationUri = safeUrl(printed, ["github.com"]);
180
+ if (verificationUri === undefined)
181
+ end({ kind: "failed" });
182
+ }
183
+ if (userCode === undefined || verificationUri === undefined)
184
+ return;
185
+ clearTimeout(codeTimer);
186
+ started.resolve({ kind: "code", deviceCode: { userCode, verificationUri } });
187
+ };
188
+ for (const stream of [child.stdout, child.stderr]) {
189
+ let pending = "";
190
+ stream?.setEncoding("utf8");
191
+ stream?.on("data", (chunk) => {
192
+ const lines = (pending + chunk).split(/\r?\n/u);
193
+ pending = (lines.pop() ?? "").slice(-SIGN_IN_LINE_LIMIT);
194
+ for (const line of lines)
195
+ if (!done)
196
+ readLine(line);
197
+ });
198
+ }
199
+ child.on("error", () => end({ kind: "failed" }));
200
+ child.on("close", (code) => end(code === 0 ? { kind: "ended" } : { kind: "failed" }));
201
+ const codeTimer = setTimeout(() => end({ kind: "failed" }), SIGN_IN_CODE_TIMEOUT_MS);
202
+ const lifetime = setTimeout(() => end({ kind: "failed" }), SIGN_IN_LIFETIME_MS);
203
+ return { started: started.promise, expiresAt, cancel: () => end({ kind: "ended" }) };
204
+ }
205
+ function ghCommand(binary) {
206
+ return async (cwd, args, extra) => {
207
+ const file = await findExecutable2(binary);
208
+ if (file === null)
209
+ return { kind: "missing" };
210
+ const started = Date.now();
211
+ const ran = await run2(file, args, {
212
+ cwd,
213
+ env: ENV,
214
+ input: extra?.input,
215
+ limit: OUTPUT_LIMIT,
216
+ timeoutMs: extra?.timeoutMs ?? QUERY_TIMEOUT_MS
217
+ }).catch(() => null);
218
+ dev("github", "run", {
219
+ command: args.slice(0, 2).join(" "),
220
+ code: ran?.code ?? null,
221
+ ms: Date.now() - started
222
+ });
223
+ if (ran === null || ran.code === null || ran.truncated)
224
+ return { kind: "failed" };
225
+ return {
226
+ kind: "completed",
227
+ code: ran.code,
228
+ stdout: ran.stdout.toString("utf8"),
229
+ stderr: ran.stderr
230
+ };
231
+ };
232
+ }
233
+ async function readAuth(gh, cwd) {
234
+ const result = await gh(cwd, [
235
+ "auth",
236
+ "status",
237
+ "--hostname",
238
+ "github.com",
239
+ "--json",
240
+ "hosts",
241
+ "--jq",
242
+ '[(.hosts["github.com"] // [])[] | {active, state, login}]'
243
+ ]);
244
+ if (result.kind === "missing")
245
+ return result;
246
+ if (result.kind === "failed")
247
+ return { kind: "error", message: RECOVERY.account };
248
+ if (result.code !== 0)
249
+ return {
250
+ kind: "error",
251
+ message: /unknown flag: --(?:json|jq)\b/u.test(result.stderr) ? RECOVERY.update : RECOVERY.account
252
+ };
253
+ const entries = parseJson(authSchema, result.stdout);
254
+ if (entries === undefined)
255
+ return { kind: "error", message: RECOVERY.update };
256
+ const active = entries.find((entry) => entry.active);
257
+ if (active === undefined)
258
+ return { kind: "signed_out" };
259
+ if (active.state !== "success")
260
+ return {
261
+ kind: "error",
262
+ message: active.state === "error" ? RECOVERY.signIn : RECOVERY.account
263
+ };
264
+ return { kind: "ready", login: active.login };
265
+ }
266
+ async function readAccountState(gh, cwd) {
267
+ const auth = await readAuth(gh, cwd);
268
+ if (auth.kind === "missing")
269
+ return { kind: "cli_missing" };
270
+ if (auth.kind !== "ready")
271
+ return auth;
272
+ const result = await gh(cwd, ["api", "--hostname", "github.com", "user"]);
273
+ const account = result.kind === "completed" && result.code === 0 ? readAccountJson(result.stdout) : undefined;
274
+ return account === undefined ? { kind: "error", message: RECOVERY.account } : { kind: "ready", account };
275
+ }
276
+ function localGitHubAccount2(options) {
277
+ const binary = options?.gh ?? "gh";
278
+ const gh = ghCommand(binary);
279
+ const home = options?.home ?? homedir();
280
+ let signing;
281
+ const signingState = async (attempt) => {
282
+ const start = await attempt.started;
283
+ if (start.kind !== "code") {
284
+ const state = await readAccountState(gh, home);
285
+ return start.kind === "failed" && state.kind === "signed_out" ? { kind: "error", message: RECOVERY.signIn } : state;
286
+ }
287
+ return {
288
+ kind: "signing_in",
289
+ deviceCode: {
290
+ ...start.deviceCode,
291
+ expiresInSeconds: Math.max(0, Math.ceil((attempt.expiresAt - Date.now()) / 1000))
292
+ }
293
+ };
294
+ };
295
+ return {
296
+ account: () => signing === undefined ? readAccountState(gh, home) : signingState(signing),
297
+ async signIn() {
298
+ if (signing !== undefined)
299
+ return signingState(signing);
300
+ const state = await readAccountState(gh, home);
301
+ if (state.kind !== "signed_out" && state.kind !== "error")
302
+ return state;
303
+ if (signing !== undefined)
304
+ return signingState(signing);
305
+ const file = await findExecutable2(binary);
306
+ if (file === null)
307
+ return { kind: "cli_missing" };
308
+ const attempt = startSignIn(file, home, () => {
309
+ if (signing === attempt)
310
+ signing = undefined;
311
+ });
312
+ signing = attempt;
313
+ return signingState(attempt);
314
+ },
315
+ async signOut() {
316
+ if (signing !== undefined) {
317
+ signing.cancel();
318
+ signing = undefined;
319
+ return readAccountState(gh, home);
320
+ }
321
+ const auth = await readAuth(gh, home);
322
+ if (auth.kind !== "ready")
323
+ return readAccountState(gh, home);
324
+ const result = await gh(home, [
325
+ "auth",
326
+ "logout",
327
+ "--hostname",
328
+ "github.com",
329
+ "--user",
330
+ auth.login
331
+ ]);
332
+ const state = await readAccountState(gh, home);
333
+ if (result.kind === "completed" && result.code === 0 || state.kind !== "ready")
334
+ return state;
335
+ return { kind: "error", message: RECOVERY.signOut };
336
+ }
337
+ };
338
+ }
339
+ function localGitHub2(options) {
340
+ const gh = ghCommand(options?.gh ?? "gh");
341
+ const gitBinary = options?.git ?? "git";
342
+ const git = async (cwd, args) => {
343
+ const ran = await run2(gitBinary, args, {
344
+ cwd,
345
+ env: ENV,
346
+ timeoutMs: QUERY_TIMEOUT_MS
347
+ }).catch(() => null);
348
+ return ran?.code === 0 ? ran.stdout.toString("utf8").trim() : null;
349
+ };
350
+ const remotes = async (cwd) => {
351
+ const listed = await git(cwd, ["remote", "-v"]) ?? "";
352
+ const found = new Map;
353
+ for (const line of listed.split(`
354
+ `)) {
355
+ const [name = "", url = ""] = line.split(/\s+/u);
356
+ const repository = found.has(name) ? undefined : parseRemote(name, url);
357
+ if (repository !== undefined)
358
+ found.set(name, repository);
359
+ }
360
+ const rank = (name) => {
361
+ const position = REMOTE_PRIORITY.findIndex((candidate) => candidate === name);
362
+ return position < 0 ? REMOTE_PRIORITY.length : position;
363
+ };
364
+ return [...found.values()].sort((left, right) => rank(left.remoteName) - rank(right.remoteName));
365
+ };
366
+ const readHead = async (cwd, repository, found) => {
367
+ const branch = await git(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
368
+ if (branch === null || branch === "")
369
+ return;
370
+ const tracked = await git(cwd, ["config", "--get", `branch.${branch}.remote`]);
371
+ const owner = found.find((candidate) => candidate.remoteName === tracked)?.owner;
372
+ return owner === undefined || owner === repository.owner ? branch : `${owner}:${branch}`;
373
+ };
374
+ const readPullRequest = async (cwd, repository, head) => {
375
+ if (head === undefined)
376
+ return { kind: "none" };
377
+ const result = await gh(cwd, [
378
+ "pr",
379
+ "view",
380
+ head,
381
+ "--repo",
382
+ `${repository.owner}/${repository.name}`,
383
+ "--json",
384
+ PULL_REQUEST_FIELDS
385
+ ]);
386
+ if (result.kind === "completed" && result.code === 0) {
387
+ const pullRequest = readPullRequestJson(result.stdout);
388
+ return pullRequest === undefined ? { kind: "error", message: RECOVERY.pullRequest } : { kind: "ready", pullRequest };
389
+ }
390
+ if (result.kind === "completed" && /no (?:open )?pull requests? found/iu.test(result.stderr))
391
+ return { kind: "none" };
392
+ return { kind: "error", message: RECOVERY.pullRequest };
393
+ };
394
+ const readState = async (cwd) => {
395
+ const [found, auth] = await Promise.all([remotes(cwd), readAuth(gh, cwd)]);
396
+ const repository = found[0];
397
+ const located = repository === undefined ? {} : { repository };
398
+ if (auth.kind !== "ready")
399
+ return { state: { ...located, pullRequest: { kind: "unavailable" } }, auth, head: undefined };
400
+ if (repository === undefined)
401
+ return { state: { pullRequest: NO_PULL_REQUEST }, auth, head: undefined };
402
+ const head = await readHead(cwd, repository, found);
403
+ return {
404
+ state: { repository, pullRequest: await readPullRequest(cwd, repository, head) },
405
+ auth,
406
+ head
407
+ };
408
+ };
409
+ const createPullRequest = async (cwd, input) => {
410
+ const { state, auth, head } = await readState(cwd);
411
+ if (auth.kind === "missing")
412
+ return { kind: "cli_missing" };
413
+ if (auth.kind === "signed_out")
414
+ return { kind: "signed_out" };
415
+ if (auth.kind === "error")
416
+ return { kind: "failed", message: auth.message };
417
+ const { repository, pullRequest } = state;
418
+ if (repository === undefined)
419
+ return { kind: "no_remote" };
420
+ if (head === undefined)
421
+ return { kind: "detached" };
422
+ if (pullRequest.kind === "ready" && pullRequest.pullRequest.state === "OPEN")
423
+ return { kind: "exists", pullRequest: pullRequest.pullRequest };
424
+ const title = input.title?.trim() ?? "";
425
+ const body = input.body ?? "";
426
+ const result = await gh(cwd, [
427
+ "pr",
428
+ "create",
429
+ "--repo",
430
+ `${repository.owner}/${repository.name}`,
431
+ "--head",
432
+ head,
433
+ ...title === "" ? [] : ["--title", title],
434
+ ...body === "" ? [] : ["--body-file", "-"],
435
+ ...title === "" || body === "" ? ["--fill"] : [],
436
+ ...input.draft === true ? ["--draft"] : []
437
+ ], { input: body, timeoutMs: CREATE_TIMEOUT_MS });
438
+ if (result.kind === "missing")
439
+ return { kind: "cli_missing" };
440
+ if (result.kind === "completed" && result.code === 0) {
441
+ const url = result.stdout.split(/\r?\n/u).map((line) => safeUrl(line.trim(), ["github.com"])).find((candidate) => candidate !== undefined);
442
+ if (url !== undefined)
443
+ return { kind: "created", url };
444
+ }
445
+ if (result.kind === "completed" && /already exists/iu.test(result.stderr)) {
446
+ const current = await readPullRequest(cwd, repository, head);
447
+ if (current.kind === "ready")
448
+ return { kind: "exists", pullRequest: current.pullRequest };
449
+ }
450
+ return { kind: "failed", message: RECOVERY.createPullRequest };
451
+ };
452
+ return (env) => ({
453
+ state: async () => (await readState(env.cwd)).state,
454
+ createPullRequest: (input) => createPullRequest(env.cwd, input)
455
+ });
456
+ }
457
+
458
+ export { localGitHubAccount2, localGitHub2 };
@@ -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,141 @@
1
+ import {
2
+ createIgnores2,
3
+ watchTree2
4
+ } from "./canvas-preview-mgcx2b2p.js";
5
+
6
+ // src/local/git-watch.ts
7
+ import { lstat } from "node:fs/promises";
8
+ import { isAbsolute, join, relative, sep } from "node:path";
9
+ var WATCH_DELAY_MS = 250;
10
+ var POLL_MS = 2000;
11
+ var GIT_STATE = new Set([
12
+ "HEAD",
13
+ "index",
14
+ "packed-refs",
15
+ "config",
16
+ "MERGE_HEAD",
17
+ "CHERRY_PICK_HEAD",
18
+ "REVERT_HEAD",
19
+ "rebase-merge",
20
+ "rebase-apply"
21
+ ]);
22
+ function createWatcher2(cwd, read, repository, forget) {
23
+ const listeners = new Set;
24
+ let stop = null;
25
+ let checking = false;
26
+ let again = false;
27
+ const check = async () => {
28
+ if (checking) {
29
+ again = true;
30
+ return;
31
+ }
32
+ checking = true;
33
+ do {
34
+ again = false;
35
+ const current = await read().catch(() => null);
36
+ if (current !== null)
37
+ for (const listener of listeners)
38
+ listener(current);
39
+ } while (again && listeners.size > 0);
40
+ checking = false;
41
+ };
42
+ const restart = () => {
43
+ forget();
44
+ stop?.();
45
+ stop = start();
46
+ check();
47
+ };
48
+ const start = () => {
49
+ const disposers = [];
50
+ let polling = null;
51
+ let stopped = false;
52
+ const unwatched = () => {
53
+ polling ??= setInterval(() => void check(), POLL_MS);
54
+ };
55
+ const watchGitDir = (dir) => {
56
+ disposers.push(watchTree2(dir, { delay: WATCH_DELAY_MS, poll: null, unwatched }, (paths) => {
57
+ if ([...paths].some(movesStatus))
58
+ check();
59
+ }));
60
+ };
61
+ const gitEntry = async () => await lstat(join(cwd, ".git")).catch(() => null) !== null;
62
+ Promise.all([repository(), gitEntry()]).then(([repo, hadGit]) => {
63
+ if (stopped)
64
+ return;
65
+ const insideGitDir = repo === null ? null : pathInside(cwd, repo.gitDir);
66
+ const ignores = repo === null ? null : createIgnores2(repo.root);
67
+ const moved = async (paths) => {
68
+ let found = "none";
69
+ for (const path of paths) {
70
+ if (path === ".git") {
71
+ if (await gitEntry() !== hadGit)
72
+ return "repository";
73
+ continue;
74
+ }
75
+ if (repo === null || ignores === null)
76
+ continue;
77
+ if (insideGitDir !== null && (path === insideGitDir || path.startsWith(`${insideGitDir}/`))) {
78
+ if (movesStatus(path.slice(insideGitDir.length + 1)))
79
+ found = "status";
80
+ continue;
81
+ }
82
+ if (path.endsWith(".gitignore"))
83
+ ignores.forget(`${repo.prefix}${path}`.split("/").slice(0, -1).join("/"));
84
+ if (found !== "none")
85
+ continue;
86
+ const directory = (await lstat(join(cwd, path)).catch(() => null))?.isDirectory();
87
+ if (!await ignores.ignored(`${repo.prefix}${path}`, directory === true))
88
+ found = "status";
89
+ }
90
+ return found;
91
+ };
92
+ disposers.push(watchTree2(cwd, { delay: WATCH_DELAY_MS, poll: null, unwatched }, (paths) => {
93
+ moved(paths).then((outcome) => {
94
+ if (stopped)
95
+ return;
96
+ if (outcome === "repository")
97
+ restart();
98
+ else if (outcome === "status")
99
+ check();
100
+ });
101
+ }));
102
+ if (repo === null)
103
+ return;
104
+ if (insideGitDir === null)
105
+ watchGitDir(repo.gitDir);
106
+ if (repo.commonDir !== repo.gitDir && pathInside(cwd, repo.commonDir) === null)
107
+ watchGitDir(repo.commonDir);
108
+ });
109
+ return () => {
110
+ stopped = true;
111
+ if (polling !== null)
112
+ clearInterval(polling);
113
+ for (const dispose of disposers)
114
+ dispose();
115
+ };
116
+ };
117
+ return {
118
+ subscribe(listener, fail) {
119
+ listeners.add(listener);
120
+ stop ??= start();
121
+ read().then(listener, fail);
122
+ return () => {
123
+ listeners.delete(listener);
124
+ if (listeners.size === 0) {
125
+ stop?.();
126
+ stop = null;
127
+ }
128
+ };
129
+ }
130
+ };
131
+ }
132
+ function movesStatus(path) {
133
+ const [top = ""] = path.split("/");
134
+ return path === "" || GIT_STATE.has(top) || path.startsWith("refs/heads/") || path.startsWith("refs/remotes/");
135
+ }
136
+ function pathInside(cwd, dir) {
137
+ const inside = relative(cwd, dir);
138
+ return inside.startsWith("..") || isAbsolute(inside) ? null : inside.split(sep).join("/");
139
+ }
140
+
141
+ export { createWatcher2 };