@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,613 @@
1
+ import {
2
+ sha2562
3
+ } from "./canvas-preview-0nq75h9k.js";
4
+ import {
5
+ run2
6
+ } from "./canvas-preview-bxnqt8cd.js";
7
+ import {
8
+ feed2
9
+ } from "./canvas-preview-yjz0f7n4.js";
10
+ import {
11
+ PATCH_LIMIT2,
12
+ textEntry2,
13
+ readPatches2,
14
+ lineStat2,
15
+ parseNumstat2,
16
+ parseNameStatus2
17
+ } from "./canvas-preview-tjhabynd.js";
18
+ import {
19
+ createWatcher2
20
+ } from "./canvas-preview-af86jz8t.js";
21
+ import {
22
+ decodeText2
23
+ } from "./canvas-preview-kn7kvbfj.js";
24
+
25
+ // src/local/git.ts
26
+ import { lstat, readFile, stat } from "node:fs/promises";
27
+ import { join, resolve } from "node:path";
28
+ import { asId, SdkError } from "@nyte-ai/schema";
29
+ import { dev } from "@nyte-ai/core";
30
+ var PATCH_BATCH = 32;
31
+ var LOG_DEFAULT = 50;
32
+ var ENV = {
33
+ GIT_OPTIONAL_LOCKS: "0",
34
+ GIT_TERMINAL_PROMPT: "0",
35
+ GIT_LITERAL_PATHSPECS: "1",
36
+ LC_ALL: "C"
37
+ };
38
+ var CONFIG = ["-c", "core.quotepath=off", "-c", "color.ui=false", "-c", "diff.noprefix=false"];
39
+ var DIFF = [
40
+ "--no-color",
41
+ "--no-ext-diff",
42
+ "--no-textconv",
43
+ "--src-prefix=a/",
44
+ "--dst-prefix=b/",
45
+ "-M"
46
+ ];
47
+ function localGit2(env, options) {
48
+ const binary = options?.git ?? "git";
49
+ let emptyTree = null;
50
+ const git = (cwd, args, extra) => {
51
+ const started = Date.now();
52
+ return run2(binary, [...CONFIG, ...args], { cwd, env: ENV, ...extra }).then((ran) => {
53
+ dev("git", "run", {
54
+ command: args[0],
55
+ args: args.length,
56
+ code: ran.code,
57
+ ms: Date.now() - started
58
+ });
59
+ return ran;
60
+ });
61
+ };
62
+ let located = null;
63
+ const lookUp = async () => {
64
+ const ran = await git(env.cwd, [
65
+ "rev-parse",
66
+ "--show-toplevel",
67
+ "--absolute-git-dir",
68
+ "--show-prefix",
69
+ "--path-format=absolute",
70
+ "--git-common-dir"
71
+ ]);
72
+ if (ran.code !== 0)
73
+ return null;
74
+ const [root, gitDir, prefix = "", commonDir] = ran.stdout.toString("utf8").split(`
75
+ `);
76
+ return root === undefined || gitDir === undefined ? null : {
77
+ root: resolve(root),
78
+ gitDir: resolve(gitDir),
79
+ commonDir: resolve(commonDir || gitDir),
80
+ prefix
81
+ };
82
+ };
83
+ const repository = async () => {
84
+ const pending = located;
85
+ const known = pending === null ? null : await pending;
86
+ if (known !== null && located === pending && await exists(join(known.gitDir, "HEAD")))
87
+ return known;
88
+ if (located === pending || located === null)
89
+ located = lookUp();
90
+ return located;
91
+ };
92
+ const forget = () => {
93
+ located = null;
94
+ };
95
+ const required = async () => {
96
+ const found = await repository();
97
+ if (found === null)
98
+ throw new SdkError("unavailable", `${env.cwd} is not in a git repository.`);
99
+ return found;
100
+ };
101
+ const readRepository = async (repo) => {
102
+ const [porcelain, staged, unstaged] = await Promise.all([
103
+ git(repo.root, [
104
+ "status",
105
+ "--porcelain=v2",
106
+ "--branch",
107
+ "-z",
108
+ "--untracked-files=all",
109
+ ...within(repo)
110
+ ]),
111
+ git(repo.root, ["diff", "--cached", "--numstat", "-z", "-M", ...within(repo)]),
112
+ git(repo.root, ["diff", "--numstat", "-z", ...within(repo)])
113
+ ]);
114
+ if (porcelain.code !== 0)
115
+ throw new SdkError("unavailable", porcelain.stderr.trim());
116
+ return readStatus(repo, porcelain.stdout.toString("utf8"), {
117
+ staged: staged.stdout.toString("utf8"),
118
+ unstaged: unstaged.stdout.toString("utf8")
119
+ });
120
+ };
121
+ const status = async () => {
122
+ const repo = await repository();
123
+ return repo === null ? { kind: "none" } : readRepository(repo);
124
+ };
125
+ const empty = (root) => {
126
+ emptyTree ??= git(root, ["hash-object", "-t", "tree", "--stdin"], { input: "" }).then((ran) => ran.stdout.toString("utf8").trim());
127
+ return emptyTree;
128
+ };
129
+ const resolves = async (root, rev) => {
130
+ const ran = await git(root, ["rev-parse", "--verify", "-q", `${rev}^{commit}`]);
131
+ return ran.code === 0 ? ran.stdout.toString("utf8").trim() : null;
132
+ };
133
+ const resolveRange = async (root, scope) => {
134
+ const head = async () => await resolves(root, "HEAD") ?? await empty(root);
135
+ switch (scope.kind) {
136
+ case "worktree":
137
+ return { args: [await head()], untracked: true };
138
+ case "staged":
139
+ return { args: ["--cached", await head()], untracked: false };
140
+ case "unstaged":
141
+ return { args: [], untracked: true };
142
+ case "commit": {
143
+ const commit = await resolves(root, scope.commit);
144
+ if (commit === null)
145
+ throw new SdkError("unknown", `No commit ${scope.commit}.`);
146
+ return {
147
+ args: [await resolves(root, `${commit}^`) ?? await empty(root), commit],
148
+ untracked: false
149
+ };
150
+ }
151
+ case "branch": {
152
+ const base = await git(root, ["merge-base", scope.base, "HEAD"]);
153
+ if (base.code !== 0)
154
+ throw new SdkError("unknown", `No merge base between ${scope.base} and HEAD.`);
155
+ return { args: [base.stdout.toString("utf8").trim(), "HEAD"], untracked: false };
156
+ }
157
+ }
158
+ };
159
+ const whitespace = (ignore) => ignore === true ? ["--ignore-all-space"] : [];
160
+ const listChanged = async (repo, scope, current) => {
161
+ const range = await resolveRange(repo.root, scope);
162
+ const ran = await git(repo.root, [
163
+ "diff",
164
+ "--name-status",
165
+ "-z",
166
+ "-M",
167
+ ...range.args,
168
+ ...within(repo)
169
+ ]);
170
+ if (ran.code !== 0)
171
+ throw new SdkError("unavailable", ran.stderr.trim());
172
+ const tracked = parseNameStatus2(ran.stdout.toString("utf8")).map((file) => withPaths(file, (path) => relativeToPrefix(repo, path)));
173
+ return range.untracked ? [...tracked, ...current.untracked.map((path) => ({ path, status: "untracked" }))] : tracked;
174
+ };
175
+ const changesAt = async (repo, scope, current, ignoreWhitespace) => {
176
+ const range = await resolveRange(repo.root, scope);
177
+ const [changed, numstat] = await Promise.all([
178
+ listChanged(repo, scope, current),
179
+ git(repo.root, [
180
+ "diff",
181
+ "--numstat",
182
+ "-z",
183
+ "-M",
184
+ ...whitespace(ignoreWhitespace),
185
+ ...range.args,
186
+ ...within(repo)
187
+ ])
188
+ ]);
189
+ const stats = parseNumstat2(numstat.stdout.toString("utf8"));
190
+ const files = await Promise.all(changed.map(async (file) => ({
191
+ ...file,
192
+ stat: file.status === "untracked" ? await untrackedStat(join(repo.root, into(repo, file.path))) : stats.get(into(repo, file.path)) ?? { kind: "unknown" }
193
+ })));
194
+ return { revision: current.revision, files };
195
+ };
196
+ const patchesAt = async (repo, scope, paths, current, ignoreWhitespace) => {
197
+ const { root } = repo;
198
+ const changed = new Map((await listChanged(repo, scope, current)).map((file) => [file.path, file]));
199
+ const wanted = [...new Set(paths)].flatMap((path) => {
200
+ const file = changed.get(path);
201
+ return file === undefined ? [] : [file];
202
+ });
203
+ const range = await resolveRange(root, scope);
204
+ const entries = new Map;
205
+ const read = async (files, limit) => git(root, [
206
+ "diff",
207
+ ...DIFF,
208
+ "-U3",
209
+ ...whitespace(ignoreWhitespace),
210
+ ...range.args,
211
+ "--",
212
+ ...files.flatMap((file) => file.from === undefined ? [file.path] : [file.from, file.path])
213
+ ], { limit });
214
+ for (let start = 0;start < wanted.length; start += PATCH_BATCH) {
215
+ const batch = wanted.slice(start, start + PATCH_BATCH);
216
+ const tracked = batch.flatMap((file) => file.status === "untracked" ? [] : [withPaths(file, (path) => into(repo, path))]);
217
+ for (const file of batch)
218
+ if (file.status === "untracked")
219
+ entries.set(file.path, {
220
+ ...await untrackedEntry(join(root, into(repo, file.path)), file.path),
221
+ fresh: true
222
+ });
223
+ if (tracked.length === 0)
224
+ continue;
225
+ for (const entry of await readPatches2(tracked, read, (file) => sha2562(`${file.path}\x00`))) {
226
+ const path = relativeToPrefix(repo, entry.path);
227
+ entries.set(path, { ...entry, path, fresh: true });
228
+ }
229
+ }
230
+ return { revision: current.revision, entries };
231
+ };
232
+ const blob = async (root, spec) => {
233
+ const ran = await git(root, ["cat-file", "blob", spec], { limit: PATCH_LIMIT2 });
234
+ if (ran.code !== 0 && !ran.truncated)
235
+ return { kind: "absent" };
236
+ return decodeSide(ran.stdout, ran.truncated);
237
+ };
238
+ const worktree = async (root, path) => {
239
+ const target = join(root, path);
240
+ const stats = await stat(target).catch(() => null);
241
+ if (stats === null || !stats.isFile())
242
+ return { kind: "absent" };
243
+ const bytes = await readFile(target).catch(() => null);
244
+ if (bytes === null)
245
+ return { kind: "absent" };
246
+ return decodeSide(bytes.subarray(0, PATCH_LIMIT2), bytes.byteLength > PATCH_LIMIT2);
247
+ };
248
+ const write = async (takesIndex, expect, operation, moves = "revision") => {
249
+ const repo = await required();
250
+ if (takesIndex && await exists(join(repo.gitDir, "index.lock")))
251
+ return { kind: "busy", runs: [] };
252
+ const before = await readRepository(repo);
253
+ if (expect !== undefined && expect !== before.revision)
254
+ return { kind: "stale", revision: before.revision };
255
+ const ran = await operation(repo, before);
256
+ if (ran === "unchanged")
257
+ return { kind: "unchanged" };
258
+ if ("rejected" in ran)
259
+ return { kind: "rejected", reason: ran.rejected };
260
+ if (ran.code !== 0) {
261
+ const output = `${ran.stdout.toString("utf8")}
262
+ ${ran.stderr}`;
263
+ if (/nothing to commit|no changes added to commit|nothing added to commit/.test(output))
264
+ return { kind: "unchanged" };
265
+ return {
266
+ kind: "rejected",
267
+ reason: ran.stderr.trim() || ran.stdout.toString("utf8").trim() || `git exited with ${ran.code}`
268
+ };
269
+ }
270
+ const after = await readRepository(repo);
271
+ return moves === "revision" && after.revision === before.revision ? { kind: "unchanged" } : { kind: "applied", revision: after.revision };
272
+ };
273
+ const watcher = createWatcher2(env.cwd, status, repository, forget);
274
+ const follow = (read) => feed2((sink) => {
275
+ let seen = null;
276
+ let pending = null;
277
+ let reading = false;
278
+ let closed = false;
279
+ const drain = async () => {
280
+ if (reading)
281
+ return;
282
+ reading = true;
283
+ while (pending !== null && !closed) {
284
+ const next = pending;
285
+ pending = null;
286
+ try {
287
+ sink.push(await read(next));
288
+ } catch (error) {
289
+ closed = true;
290
+ sink.fail(error);
291
+ }
292
+ }
293
+ reading = false;
294
+ };
295
+ const unsubscribe = watcher.subscribe((current) => {
296
+ const key = current.kind === "none" ? "none" : current.revision;
297
+ if (key === seen)
298
+ return;
299
+ seen = key;
300
+ pending = current;
301
+ drain();
302
+ }, (error) => sink.fail(error));
303
+ return () => {
304
+ closed = true;
305
+ unsubscribe();
306
+ };
307
+ });
308
+ const inRepo = (read) => async (current) => {
309
+ if (current.kind === "none")
310
+ throw new SdkError("unavailable", `${env.cwd} is not in a git repository.`);
311
+ return read(await required(), current);
312
+ };
313
+ return {
314
+ status,
315
+ watch: () => follow(async (current) => current),
316
+ async changes(scope, diff) {
317
+ const repo = await required();
318
+ return changesAt(repo, scope, await readRepository(repo), diff?.ignoreWhitespace);
319
+ },
320
+ watchChanges: (scope, diff) => follow(inRepo((repo, current) => changesAt(repo, scope, current, diff?.ignoreWhitespace))),
321
+ patches: (scope, paths, diff) => follow(inRepo((repo, current) => patchesAt(repo, scope, paths, current, diff?.ignoreWhitespace))),
322
+ async contents(path, scope) {
323
+ const repo = await required();
324
+ const current = await readRepository(repo);
325
+ const root = repo.root;
326
+ const from = into(repo, (await listChanged(repo, scope, current)).find((file) => file.path === path)?.from ?? path);
327
+ const at = into(repo, path);
328
+ const head = current.head === null ? null : "HEAD";
329
+ switch (scope.kind) {
330
+ case "worktree":
331
+ return {
332
+ path,
333
+ old: head === null ? { kind: "absent" } : await blob(root, `${head}:${from}`),
334
+ new: await worktree(root, at)
335
+ };
336
+ case "staged":
337
+ return {
338
+ path,
339
+ old: head === null ? { kind: "absent" } : await blob(root, `${head}:${from}`),
340
+ new: await blob(root, `:${at}`)
341
+ };
342
+ case "unstaged":
343
+ return { path, old: await blob(root, `:${from}`), new: await worktree(root, at) };
344
+ case "commit": {
345
+ const parent = await resolves(root, `${scope.commit}^`);
346
+ return {
347
+ path,
348
+ old: parent === null ? { kind: "absent" } : await blob(root, `${parent}:${from}`),
349
+ new: await blob(root, `${scope.commit}:${at}`)
350
+ };
351
+ }
352
+ case "branch": {
353
+ const base = (await git(root, ["merge-base", scope.base, "HEAD"])).stdout.toString("utf8").trim();
354
+ return {
355
+ path,
356
+ old: base === "" ? { kind: "absent" } : await blob(root, `${base}:${from}`),
357
+ new: await blob(root, `HEAD:${at}`)
358
+ };
359
+ }
360
+ }
361
+ },
362
+ async log(input) {
363
+ const repo = await required();
364
+ const skip = input?.cursor === undefined ? 0 : Number(input.cursor) || 0;
365
+ const limit = Math.max(1, input?.limit ?? LOG_DEFAULT);
366
+ const ran = await git(repo.root, [
367
+ "log",
368
+ "-z",
369
+ `--skip=${skip}`,
370
+ `-n${limit + 1}`,
371
+ "--format=%H%x1f%P%x1f%an%x1f%ct%x1f%s"
372
+ ]);
373
+ if (ran.code !== 0)
374
+ return { items: [], next: null };
375
+ const records = ran.stdout.toString("utf8").split("\x00").filter((record) => record !== "");
376
+ const items = records.slice(0, limit).map((record) => {
377
+ const [id = "", parents = "", author = "", time = "0", subject = ""] = record.split("\x1F");
378
+ return {
379
+ id: asId(id),
380
+ subject,
381
+ author,
382
+ committedAt: Number(time) * 1000,
383
+ parents: parents === "" ? [] : parents.split(" ").map((parent) => asId(parent))
384
+ };
385
+ });
386
+ const next = records.length > limit ? asId(String(skip + limit)) : null;
387
+ return { items, next };
388
+ },
389
+ async refs() {
390
+ const repo = await required();
391
+ const [current, branches, remotes] = await Promise.all([
392
+ git(repo.root, ["symbolic-ref", "--short", "-q", "HEAD"]),
393
+ git(repo.root, [
394
+ "for-each-ref",
395
+ "--format=%(refname:short)%00%(objectname)%00%(upstream:short)",
396
+ "refs/heads"
397
+ ]),
398
+ git(repo.root, ["remote"])
399
+ ]);
400
+ return {
401
+ current: current.code === 0 ? current.stdout.toString("utf8").trim() : null,
402
+ branches: lines(branches.stdout).map((line) => {
403
+ const [name = "", commit = "", upstream = ""] = line.split("\x00");
404
+ return {
405
+ name,
406
+ commit: asId(commit),
407
+ upstream: upstream === "" ? null : upstream
408
+ };
409
+ }),
410
+ remotes: lines(remotes.stdout)
411
+ };
412
+ },
413
+ async blame(path) {
414
+ const repo = await required();
415
+ const ran = await git(repo.root, ["blame", "--porcelain", "--", into(repo, path)]);
416
+ if (ran.code !== 0)
417
+ throw new SdkError("unknown", ran.stderr.trim() || `Cannot blame ${path}.`);
418
+ return parseBlame(path, ran.stdout.toString("utf8"));
419
+ },
420
+ stage: (paths, guard) => write(true, guard?.expect, (repo) => git(repo.root, ["add", "-A", "--", ...paths.map((path) => into(repo, path))])),
421
+ unstage: (paths, guard) => write(true, guard?.expect, (repo, before) => {
422
+ const inside = paths.map((path) => into(repo, path));
423
+ return git(repo.root, before.head === null ? ["rm", "--cached", "-r", "-q", "--", ...inside] : ["restore", "--staged", "--", ...inside]);
424
+ }),
425
+ discard: (paths, guard) => write(true, guard?.expect, async (repo, before) => {
426
+ const untracked = new Set(before.untracked);
427
+ const tracked = paths.filter((path) => !untracked.has(path)).map((path) => into(repo, path));
428
+ const loose = paths.filter((path) => untracked.has(path)).map((path) => into(repo, path));
429
+ const restored = tracked.length === 0 ? null : await git(repo.root, ["restore", "--worktree", "--", ...tracked]);
430
+ if (restored !== null && restored.code !== 0)
431
+ return restored;
432
+ return loose.length === 0 ? restored ?? "unchanged" : git(repo.root, ["clean", "-f", "-q", "--", ...loose]);
433
+ }),
434
+ commit: (input, guard) => write(true, guard?.expect, async (repo) => {
435
+ if (input.files === "staged")
436
+ return git(repo.root, ["commit", "-q", "-m", input.message]);
437
+ if (input.files === "all")
438
+ return git(repo.root, ["commit", "-q", "-a", "-m", input.message]);
439
+ const files = input.files.map((path) => into(repo, path));
440
+ const added = await git(repo.root, ["add", "-A", "--", ...files]);
441
+ if (added.code !== 0)
442
+ return added;
443
+ return git(repo.root, ["commit", "-q", "-m", input.message, "--", ...files]);
444
+ }),
445
+ branch: (input, guard) => write(input.checkout, guard?.expect, (repo) => git(repo.root, input.checkout ? ["switch", "-q", "-c", input.name] : ["branch", input.name]), "always"),
446
+ push: (input, guard) => write(false, guard?.expect, async (repo, before) => {
447
+ if (input?.setUpstream === true && before.branch === null)
448
+ return { rejected: "HEAD is detached; there is no branch to push." };
449
+ const ran = await git(repo.root, input?.setUpstream === true && before.branch !== null ? ["push", "--porcelain", "--set-upstream", "origin", before.branch] : ["push", "--porcelain"]);
450
+ const flags = lines(ran.stdout).flatMap((line) => /^[ +\-*!=]\t/.test(line) ? [line[0]] : []);
451
+ return ran.code === 0 && flags.length > 0 && flags.every((flag) => flag === "=") ? "unchanged" : ran;
452
+ }, "always")
453
+ };
454
+ }
455
+ async function readStatus(repo, porcelain, numstat) {
456
+ const tokens = porcelain.split("\x00");
457
+ const stagedStats = parseNumstat2(numstat.staged);
458
+ const unstagedStats = parseNumstat2(numstat.unstaged);
459
+ const staged = [];
460
+ const unstaged = [];
461
+ const untracked = [];
462
+ const conflicts = [];
463
+ let head = null;
464
+ let branch = null;
465
+ let upstream = null;
466
+ let ahead = 0;
467
+ let behind = 0;
468
+ const change = (path, code, stats, from) => {
469
+ const stat = stats.get(path);
470
+ const counts = stat?.kind === "text" ? { added: stat.added, removed: stat.removed } : { added: 0, removed: 0 };
471
+ const status = code === "A" ? "added" : code === "D" ? "deleted" : code === "R" || code === "C" ? "renamed" : "modified";
472
+ return from === undefined || status !== "renamed" ? { path, status, ...counts } : { path, status, ...counts, from };
473
+ };
474
+ for (let index = 0;index < tokens.length; index += 1) {
475
+ const token = tokens[index] ?? "";
476
+ if (token.startsWith("# branch.oid ")) {
477
+ const oid = token.slice("# branch.oid ".length);
478
+ head = oid === "(initial)" ? null : oid;
479
+ } else if (token.startsWith("# branch.head ")) {
480
+ const name = token.slice("# branch.head ".length);
481
+ branch = name === "(detached)" ? null : name;
482
+ } else if (token.startsWith("# branch.upstream "))
483
+ upstream = token.slice("# branch.upstream ".length);
484
+ else if (token.startsWith("# branch.ab ")) {
485
+ const [plus = "+0", minus = "-0"] = token.slice("# branch.ab ".length).split(" ");
486
+ ahead = Number(plus.slice(1)) || 0;
487
+ behind = Number(minus.slice(1)) || 0;
488
+ } else if (token.startsWith("1 ") || token.startsWith("2 ")) {
489
+ const renamed = token.startsWith("2 ");
490
+ const fields = splitFields(token, renamed ? 9 : 8);
491
+ const codes = fields.fields[1] ?? "..";
492
+ const from = renamed ? tokens[index + 1] : undefined;
493
+ if (renamed)
494
+ index += 1;
495
+ const x = codes[0] ?? ".";
496
+ const y = codes[1] ?? ".";
497
+ if (x !== ".")
498
+ staged.push(change(fields.rest, x, stagedStats, from));
499
+ if (y !== ".")
500
+ unstaged.push(change(fields.rest, y, unstagedStats, undefined));
501
+ } else if (token.startsWith("u "))
502
+ conflicts.push(splitFields(token, 10).rest);
503
+ else if (token.startsWith("? "))
504
+ untracked.push(token.slice(2));
505
+ }
506
+ const stamps = await Promise.all([...unstaged.map((file) => file.path), ...untracked].map(async (path) => {
507
+ const found = await lstat(join(repo.root, path)).catch(() => null);
508
+ return `${path}:${found === null ? "-" : `${found.size}:${found.mtimeMs}`}`;
509
+ }));
510
+ return {
511
+ kind: "repository",
512
+ root: repo.root,
513
+ head: head === null ? null : asId(head),
514
+ branch,
515
+ upstream: upstream === null ? null : { name: upstream, ahead, behind },
516
+ revision: asId(sha2562([porcelain, head ?? "", numstat.staged, numstat.unstaged, ...stamps].join("\x00"))),
517
+ staged: staged.map((file) => withPaths(file, (path) => relativeToPrefix(repo, path))),
518
+ unstaged: unstaged.map((file) => withPaths(file, (path) => relativeToPrefix(repo, path))),
519
+ untracked: untracked.map((path) => relativeToPrefix(repo, path)),
520
+ conflicts: conflicts.map((path) => relativeToPrefix(repo, path))
521
+ };
522
+ }
523
+ function into(repo, path) {
524
+ return `${repo.prefix}${path}`;
525
+ }
526
+ function relativeToPrefix(repo, path) {
527
+ return path.startsWith(repo.prefix) ? path.slice(repo.prefix.length) : `${"../".repeat(repo.prefix.split("/").length - 1)}${path}`;
528
+ }
529
+ function within(repo) {
530
+ return repo.prefix === "" ? [] : ["--", repo.prefix];
531
+ }
532
+ function withPaths(file, map) {
533
+ return file.from === undefined ? { ...file, path: map(file.path) } : { ...file, path: map(file.path), from: map(file.from) };
534
+ }
535
+ function splitFields(token, count) {
536
+ const parts = token.split(" ");
537
+ const fields = parts.slice(0, Math.min(count, parts.length - 1));
538
+ return { fields, rest: parts.slice(fields.length).join(" ") };
539
+ }
540
+ function parseBlame(path, output) {
541
+ const authors = new Map;
542
+ const rows = [];
543
+ let commit = "";
544
+ let line = 0;
545
+ for (const text of output.split(`
546
+ `)) {
547
+ const header = /^([0-9a-f]{40,64}) \d+ (\d+)(?: \d+)?$/.exec(text);
548
+ if (header !== null) {
549
+ commit = header[1] ?? "";
550
+ line = Number(header[2]);
551
+ if (!authors.has(commit))
552
+ authors.set(commit, { author: "", at: 0 });
553
+ continue;
554
+ }
555
+ const known = authors.get(commit);
556
+ if (text.startsWith("author ") && known !== undefined)
557
+ known.author = text.slice(7);
558
+ else if (text.startsWith("author-time ") && known !== undefined)
559
+ known.at = Number(text.slice(12)) * 1000;
560
+ else if (text.startsWith("\t"))
561
+ rows.push({
562
+ line,
563
+ commit: asId(commit),
564
+ author: known?.author ?? "",
565
+ at: known?.at ?? 0
566
+ });
567
+ }
568
+ return { path, lines: rows };
569
+ }
570
+ async function untrackedStat(path) {
571
+ const stats = await stat(path).catch(() => null);
572
+ if (stats === null || !stats.isFile() || stats.size > PATCH_LIMIT2)
573
+ return { kind: "unknown" };
574
+ const bytes = await readFile(path).catch(() => null);
575
+ const text = bytes === null ? null : decodeText2(bytes);
576
+ return text === null ? { kind: "binary" } : lineStat2("", text);
577
+ }
578
+ async function untrackedEntry(target, path) {
579
+ const stats = await stat(target).catch(() => null);
580
+ if (stats === null || !stats.isFile())
581
+ return {
582
+ path,
583
+ status: "untracked",
584
+ digest: "",
585
+ kind: "failed",
586
+ reason: `${path} is not a file.`
587
+ };
588
+ const bytes = await readFile(target).catch((error) => error instanceof Error ? error.message : String(error));
589
+ if (typeof bytes === "string")
590
+ return { path, status: "untracked", digest: "", kind: "failed", reason: bytes };
591
+ const digest = sha2562(bytes);
592
+ if (bytes.byteLength > PATCH_LIMIT2)
593
+ return { path, status: "untracked", digest, kind: "too-large", limit: PATCH_LIMIT2 };
594
+ const text = decodeText2(bytes);
595
+ return text === null ? { path, status: "untracked", digest, kind: "binary" } : textEntry2(path, "untracked", null, text);
596
+ }
597
+ function decodeSide(bytes, truncated) {
598
+ if (bytes.includes(0))
599
+ return { kind: "binary" };
600
+ if (truncated)
601
+ return { kind: "truncated", head: new TextDecoder().decode(bytes) };
602
+ const text = decodeText2(bytes);
603
+ return text === null ? { kind: "binary" } : { kind: "text", text };
604
+ }
605
+ function lines(output) {
606
+ return output.toString("utf8").split(`
607
+ `).filter((line) => line !== "");
608
+ }
609
+ async function exists(path) {
610
+ return lstat(path).then(() => true, () => false);
611
+ }
612
+
613
+ export { localGit2 };
@@ -0,0 +1,14 @@
1
+ import {
2
+ seedSigner2
3
+ } from "./canvas-preview-31w7xm8z.js";
4
+ import {
5
+ readKeyFile2
6
+ } from "./canvas-preview-wg80rbc2.js";
7
+
8
+ // src/identity-key.ts
9
+ import { join } from "node:path";
10
+ async function identitySigner2(id, home) {
11
+ return seedSigner2(id, await readKeyFile2(join(home, ".nyte", "identity.key"), "identity key"));
12
+ }
13
+
14
+ export { identitySigner2 };