@hitch42/applet 0.1.1-beta.20 → 0.1.1-beta.21

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 (94) hide show
  1. package/dist/_internal/client.d.ts +0 -2
  2. package/dist/_internal/client.js +3 -5
  3. package/dist/_internal/log-context.d.ts +0 -2
  4. package/dist/_internal/log-context.js +1 -2
  5. package/dist/_internal/server.d.ts +2 -10
  6. package/dist/_internal/server.js +9 -14
  7. package/dist/applet.js +64 -23
  8. package/dist/auth-DuMRqSGe.js +49 -0
  9. package/dist/{batch-_ZjAg-Kk.js → batch-CiLZ177G.js} +3 -4
  10. package/dist/build-C7hi2yg4.js +1 -0
  11. package/dist/{build-D47vK5aa.js → build-FAQSHJgm.js} +4 -3
  12. package/dist/{ci-BTFTCBgy.js → ci-oWlUJKm9.js} +5 -6
  13. package/dist/client/hitch/client.d.ts +1 -1
  14. package/dist/client/hitch/client.js +1 -2
  15. package/dist/client/hitch/phone.d.ts +1 -1
  16. package/dist/client/hitch/phone.js +1 -2
  17. package/dist/client/hitch.d.ts +2 -2
  18. package/dist/client/hitch.js +2 -2
  19. package/dist/client/react/markdown-editor.d.ts +1 -1
  20. package/dist/client/react/markdown-editor.js +1 -2
  21. package/dist/client/react/markdown.d.ts +1 -1
  22. package/dist/client/react/markdown.js +1 -2
  23. package/dist/client/react.d.ts +2 -2
  24. package/dist/client/react.js +2 -2
  25. package/dist/client.d.ts +2 -4
  26. package/dist/client.js +3 -5
  27. package/dist/{contract-CJv-n1l3.d.ts → contract-CUc0B2rl.d.ts} +1 -3
  28. package/dist/{contract-BeKz1Qcs.js → contract-D9LCNGjD.js} +1 -2
  29. package/dist/{create-C2UrZYSK.d.ts → create-BJqLT8Uq.d.ts} +0 -4
  30. package/dist/{deploy-BbqyK5Ik.js → deploy-BM55ZoSp.js} +160 -152
  31. package/dist/{device-BgIfytaR.js → device-CZWWckCq.js} +54 -34
  32. package/dist/{email-protocol-B9u_dh2p.d.ts → email-protocol-CEqzASSx.d.ts} +0 -6
  33. package/dist/{generate-BLD0DoCk.js → generate-48pqFh5M.js} +31 -37
  34. package/dist/generate-BYK4aNud.js +1 -0
  35. package/dist/generated-agents-BUnJ0FQA.js +215 -0
  36. package/dist/git-credential-CU7-Erzs.js +24 -0
  37. package/dist/git-deploy-C12nMNB6.js +290 -0
  38. package/dist/git-deploy-CNz6mxiF.js +1 -0
  39. package/dist/git-migration-CIq-sN61.js +629 -0
  40. package/dist/git-safety-Ck3X7jvA.js +13 -0
  41. package/dist/{headers-CeRX-Xji.js → headers-BcEMIVCo.js} +1 -2
  42. package/dist/{hitch-client-DtyTZzP5.d.ts → hitch-client-D33JOEOi.d.ts} +5 -7
  43. package/dist/{hitch-client-Cw-WZ_8v.js → hitch-client-Dph_kzDd.js} +5 -7
  44. package/dist/{hitch-file-url-BPKj9zVG.js → hitch-file-url--AMjDOzP.js} +1 -2
  45. package/dist/index.d.ts +8 -15
  46. package/dist/index.js +32 -37
  47. package/dist/{init-BKUBf6i9.js → init-Bb6WT8UB.js} +70 -18
  48. package/dist/{lazy-client-CwIzYAoE.js → lazy-client--QCL0wiu.js} +1 -2
  49. package/dist/{load-config-DGALUExv.js → load-config-Cffvj-aM.js} +24 -26
  50. package/dist/{log-context-DWznGjfz.js → log-context-BepwdjrR.js} +1 -2
  51. package/dist/login-BWZKo7Ui.js +21 -0
  52. package/dist/{logs-Cv5z1e2w.js → logs-glCVHI-8.js} +6 -6
  53. package/dist/{manifest-BBHD_EY9.d.ts → manifest-CpghlaJc.d.ts} +6 -7
  54. package/dist/manifest-patterns-BfxqImlp.js +4 -0
  55. package/dist/{markdown-CwlqzBtP.js → markdown-BA_XzFxq.js} +2 -3
  56. package/dist/{markdown-DSHOQIOb.d.ts → markdown-BXt65dDo.d.ts} +1 -3
  57. package/dist/{markdown-editor-BmEaBzd7.d.ts → markdown-editor-CB_nWLzj.d.ts} +1 -5
  58. package/dist/{markdown-editor-C5mLHGqu.js → markdown-editor-CaUuphfc.js} +3 -5
  59. package/dist/parent-D52Kxp8U.js +1 -0
  60. package/dist/parent-Zx8Eg1Ki.js +75 -0
  61. package/dist/{project-CrxdZR0B.js → project-DZGk765E.js} +63 -54
  62. package/dist/{prompt-ChS-grYO.js → prompt-CW98R-Un.js} +1 -2
  63. package/dist/{query-cache-CXmAyLv3.js → query-cache-DQJy45RT.js} +1 -2
  64. package/dist/{query-utils-zz9pVjgp.d.ts → query-utils-okxIoKM3.d.ts} +0 -2
  65. package/dist/{schedules-Dajgni_z.js → schedules-CSUb84e2.js} +5 -5
  66. package/dist/server.d.ts +5 -13
  67. package/dist/server.js +17 -20
  68. package/dist/source-hash-BbvtRaus.js +107 -0
  69. package/dist/store-E5NhITHl.js +448 -0
  70. package/dist/{upload-D_kkmne_.d.ts → upload-DXZyjZSS.d.ts} +6 -10
  71. package/dist/{upload-DRbVhuDm.js → upload-DtMavo8Q.js} +4 -6
  72. package/dist/{use-phone-ug4B5gQp.js → use-phone-CB_idmrz.js} +9 -13
  73. package/dist/{use-phone-M7c_HsB7.d.ts → use-phone-DBAkasPq.d.ts} +0 -4
  74. package/dist/{variables-B-CLu8cY.js → variables-CgZstC7I.js} +7 -8
  75. package/dist/vite.d.ts +1 -3
  76. package/dist/vite.js +41 -50
  77. package/dist/{workflow-DurM6Fwx.d.ts → workflow-BnBrJIzu.d.ts} +0 -2
  78. package/dist/{workflow-engine-BOTzURKM.js → workflow-engine-CyyaVENo.js} +2 -4
  79. package/dist/{workflow-CTo2kZF1.js → workflow-l2SlVePB.js} +2 -4
  80. package/dist/workspace-CtIKSgMD.js +76 -0
  81. package/package.json +6 -5
  82. package/scaffold/.agents/skills/hitch-applets/SKILL.md +27 -9
  83. package/scaffold/.agents/skills/hitch-applets/references/files.md +2 -2
  84. package/scaffold/.agents/skills/hitch-applets/references/manifest.md +8 -6
  85. package/scaffold/.agents/skills/hitch-applets/references/performance.md +2 -2
  86. package/scaffold/.agents/skills/hitch-applets/references/records.md +8 -8
  87. package/scaffold/.agents/skills/hitch-cli/SKILL.md +52 -43
  88. package/scaffold/AGENTS.md +6 -0
  89. package/dist/auth-D3CrCtZq.js +0 -21
  90. package/dist/build-JtbY8q2p.js +0 -2
  91. package/dist/generate-COCRy1Bs.js +0 -2
  92. package/dist/login-CceGvlMi.js +0 -14
  93. package/dist/store-B8N_8JIN.js +0 -196
  94. package/dist/workspace-8yqXsvce.js +0 -31
@@ -0,0 +1,290 @@
1
+ import { m as resolveInstanceUrl } from "./store-E5NhITHl.js";
2
+ import { a as findWorkspaceRoot, o as isRootLayout, r as findParentRoot, t as SDK_VERSION_PATTERN } from "./workspace-CtIKSgMD.js";
3
+ import { i as withOrgAuth } from "./auth-DuMRqSGe.js";
4
+ import { n as ORG_CODE_PATTERN, t as APPLET_CODE_PATTERN } from "./manifest-patterns-BfxqImlp.js";
5
+ import { n as gitEnvironment } from "./source-hash-BbvtRaus.js";
6
+ import { n as stagedSecretPaths, t as StagedSecretsError } from "./git-safety-Ck3X7jvA.js";
7
+ import { existsSync } from "node:fs";
8
+ import { readFile } from "node:fs/promises";
9
+ import { resolve } from "node:path";
10
+ import { execFile } from "node:child_process";
11
+ import { promisify } from "node:util";
12
+ // src/git-deploy.ts
13
+ const execFileAsync = promisify(execFile);
14
+ function hitchRemoteUrl(organizationUrl, code) {
15
+ return `${organizationUrl}/api/git/${code}.git`;
16
+ }
17
+ async function runClone(name, directory, _message) {
18
+ const parts = name.split("/");
19
+ const [org, code] = parts;
20
+ if (parts.length !== 2 || !org || !code || !ORG_CODE_PATTERN.test(org) || !APPLET_CODE_PATTERN.test(code)) throw new Error("Use applet clone <org>/<code> [dir].");
21
+ const cwd = process.cwd();
22
+ const parent = findParentRoot(cwd);
23
+ if (findWorkspaceRoot(cwd) !== void 0 && parent !== cwd) throw new Error("Run applet clone outside an applet repo, or in a .hitchroot parent.");
24
+ const base = parent ?? cwd;
25
+ const target = directory === void 0 ? resolve(base, code) : resolve(directory);
26
+ await withOrgAuth(org, async (organizationUrl, token) => {
27
+ try {
28
+ await gitWithAuth(base, org, organizationUrl, token, [
29
+ "clone",
30
+ "--origin",
31
+ "hitch",
32
+ hitchRemoteUrl(organizationUrl, code),
33
+ target
34
+ ]);
35
+ return { unauthorized: false };
36
+ } catch (error) {
37
+ const message = gitError(error);
38
+ if (/401|Authentication failed|HTTP Basic: Access denied/i.test(message)) return { unauthorized: true };
39
+ throw new Error(message, { cause: error });
40
+ }
41
+ });
42
+ const clonedRoot = resolve(target);
43
+ await configureGitCredentialHelper(clonedRoot, org);
44
+ if (!await git(clonedRoot, [
45
+ "rev-parse",
46
+ "--verify",
47
+ "HEAD"
48
+ ]).then(() => true).catch(() => false)) console.log("The applet has no code in Hitch yet.");
49
+ console.log(`Cloned ${code} into ${target}. Run applet deploy -m "..." to deploy changes.`);
50
+ const rootLayout = isRootLayout(clonedRoot);
51
+ const sdk = await readFile(resolve(clonedRoot, rootLayout ? "applet.manifest.ts" : "hitch.config.ts"), "utf8").then((text) => /\bsdk:\s*["']([^"'\s]+)["']/.exec(text)?.[1]).catch((error) => {
52
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
53
+ throw error;
54
+ });
55
+ if (rootLayout && (sdk === void 0 || !SDK_VERSION_PATTERN.test(sdk))) throw new Error("The cloned manifest must contain an exact \"sdk\" version.");
56
+ if (sdk) console.log(`Run pnpm dlx ${rootLayout ? `@hitch42/applet@${sdk}` : sdk} bootstrap to set up this checkout.`);
57
+ }
58
+ function syncAction(input) {
59
+ if (!input.remoteMain || input.isAncestor) return "continue";
60
+ return input.hasMergeBase ? "rebase" : "unrelated";
61
+ }
62
+ function deployErrorMessage(code) {
63
+ if (code === "main_moved") return "Someone deployed while you were deploying. Run applet deploy again to rebase onto their change.";
64
+ }
65
+ function gitError(error) {
66
+ if (error instanceof Error && "stderr" in error && typeof error.stderr === "string") return error.stderr.trim() || error.message;
67
+ return error instanceof Error ? error.message : String(error);
68
+ }
69
+ async function git(root, args) {
70
+ const { stdout } = await execFileAsync("git", args, {
71
+ cwd: root,
72
+ env: gitEnvironment()
73
+ });
74
+ return stdout.trim();
75
+ }
76
+ async function configureGitCredentialHelper(root, org) {
77
+ await withOrgAuth(org, async (organizationUrl) => {
78
+ const instanceUrl = await resolveInstanceUrl();
79
+ for (const args of gitCredentialConfigCommands(organizationUrl, instanceUrl)) await git(root, args);
80
+ return { unauthorized: false };
81
+ });
82
+ }
83
+ function gitCredentialConfigCommands(organizationUrl, instanceUrl) {
84
+ const key = `credential.${organizationUrl}.helper`;
85
+ const quotedInstance = `'${instanceUrl.replaceAll("'", "'\\''")}'`;
86
+ return [[
87
+ "config",
88
+ "--local",
89
+ "--replace-all",
90
+ key,
91
+ ""
92
+ ], [
93
+ "config",
94
+ "--local",
95
+ "--add",
96
+ key,
97
+ `!pnpm exec applet git-credential --instance ${quotedInstance}`
98
+ ]];
99
+ }
100
+ async function hasRef(root, ref) {
101
+ try {
102
+ await git(root, [
103
+ "show-ref",
104
+ "--verify",
105
+ "--quiet",
106
+ ref
107
+ ]);
108
+ return true;
109
+ } catch {
110
+ return false;
111
+ }
112
+ }
113
+ async function gitNetwork(root, org, args) {
114
+ return (await withOrgAuth(org, async (organizationUrl, token) => {
115
+ try {
116
+ return {
117
+ unauthorized: false,
118
+ output: await gitWithAuth(root, org, organizationUrl, token, args)
119
+ };
120
+ } catch (error) {
121
+ const message = gitError(error);
122
+ if (/401|Authentication failed|HTTP Basic: Access denied/i.test(message)) return {
123
+ unauthorized: true,
124
+ output: ""
125
+ };
126
+ throw new Error(message, { cause: error });
127
+ }
128
+ })).output;
129
+ }
130
+ async function gitProxyErrorMessage(message, org, repositoryUrl, token) {
131
+ if (!/\b403\b/.test(message)) return message;
132
+ const response = await fetch(`${repositoryUrl}/info/refs?service=git-upload-pack`, {
133
+ headers: { Authorization: `Bearer ${token}` },
134
+ redirect: "error"
135
+ });
136
+ if (response.status === 403 && response.headers.get("Content-Type")?.includes("application/json")) {
137
+ if ((await response.json()).code === "git_not_enabled") return `Hitch git is not switched on for ${org}. Deploy with the current stable CLI instead.`;
138
+ }
139
+ return message;
140
+ }
141
+ async function gitWithAuth(root, org, organizationUrl, token, args) {
142
+ try {
143
+ const { stdout } = await execFileAsync("git", args, {
144
+ cwd: root,
145
+ env: {
146
+ ...gitEnvironment(),
147
+ GIT_TERMINAL_PROMPT: "0",
148
+ GIT_CONFIG_COUNT: "1",
149
+ GIT_CONFIG_KEY_0: `http.${organizationUrl}/.extraHeader`,
150
+ GIT_CONFIG_VALUE_0: `Authorization: Bearer ${token}`
151
+ }
152
+ });
153
+ return stdout.trim();
154
+ } catch (error) {
155
+ const message = gitError(error);
156
+ if (!/\b403\b/.test(message)) throw error;
157
+ const repositoryUrl = args[0] === "clone" ? args[3] : await git(root, [
158
+ "remote",
159
+ "get-url",
160
+ "hitch"
161
+ ]);
162
+ if (!repositoryUrl.startsWith(`${organizationUrl}/api/git/`)) throw error;
163
+ throw new Error(await gitProxyErrorMessage(message, org, repositoryUrl, token), { cause: error });
164
+ }
165
+ }
166
+ async function refreshHitchMain(workspaceRoot, org, code) {
167
+ await withOrgAuth(org, async (organizationUrl) => {
168
+ const url = hitchRemoteUrl(organizationUrl, code);
169
+ let current;
170
+ try {
171
+ current = await git(workspaceRoot, [
172
+ "remote",
173
+ "get-url",
174
+ "hitch"
175
+ ]);
176
+ } catch {
177
+ current = void 0;
178
+ }
179
+ if (current === void 0) await git(workspaceRoot, [
180
+ "remote",
181
+ "add",
182
+ "hitch",
183
+ url
184
+ ]);
185
+ else if (current !== url) await git(workspaceRoot, [
186
+ "remote",
187
+ "set-url",
188
+ "hitch",
189
+ url
190
+ ]);
191
+ return { unauthorized: false };
192
+ });
193
+ await configureGitCredentialHelper(workspaceRoot, org);
194
+ try {
195
+ await gitNetwork(workspaceRoot, org, [
196
+ "fetch",
197
+ "hitch",
198
+ "main"
199
+ ]);
200
+ } catch (error) {
201
+ if (!/couldn't find remote ref main|requested URL returned error: 404|repository '[^']*' not found/i.test(gitError(error))) throw error;
202
+ }
203
+ }
204
+ async function prepareGitDeploy(workspaceRoot, code, org, message, prebuilt = false) {
205
+ let topLevel;
206
+ try {
207
+ topLevel = await git(workspaceRoot, ["rev-parse", "--show-toplevel"]);
208
+ } catch (error) {
209
+ if (!/not a git repository/i.test(gitError(error))) throw error;
210
+ await git(workspaceRoot, [
211
+ "init",
212
+ "-b",
213
+ "main"
214
+ ]);
215
+ topLevel = workspaceRoot;
216
+ }
217
+ if (resolve(topLevel) !== resolve(workspaceRoot)) throw new Error(`The git repository must start at the workspace root ${workspaceRoot}.`);
218
+ if ((await Promise.all([
219
+ "rebase-merge",
220
+ "rebase-apply",
221
+ "MERGE_HEAD"
222
+ ].map((name) => git(workspaceRoot, [
223
+ "rev-parse",
224
+ "--git-path",
225
+ name
226
+ ])))).some((path) => existsSync(resolve(workspaceRoot, path)))) throw new Error("A rebase or merge is in progress. Finish or abort it, then run applet deploy again.");
227
+ if (await git(workspaceRoot, ["status", "--porcelain"])) {
228
+ if (!message) throw new Error("You have uncommitted changes. Pass -m \"<message>\" to commit them with the deploy.");
229
+ await git(workspaceRoot, ["add", "-A"]);
230
+ const secrets = stagedSecretPaths((await git(workspaceRoot, [
231
+ "diff",
232
+ "--cached",
233
+ "--name-only",
234
+ "-z",
235
+ "--diff-filter=ACMR"
236
+ ])).split("\0").filter(Boolean));
237
+ if (secrets.length > 0) throw new StagedSecretsError(secrets);
238
+ await git(workspaceRoot, [
239
+ "commit",
240
+ "-m",
241
+ message
242
+ ]);
243
+ } else if (message) console.log("There is nothing to commit.");
244
+ try {
245
+ await git(workspaceRoot, [
246
+ "rev-parse",
247
+ "--verify",
248
+ "HEAD"
249
+ ]);
250
+ } catch {
251
+ throw new Error("Nothing to deploy: the repository has no commits.");
252
+ }
253
+ await refreshHitchMain(workspaceRoot, org, code);
254
+ const remoteMain = await hasRef(workspaceRoot, "refs/remotes/hitch/main");
255
+ const isAncestor = remoteMain ? await git(workspaceRoot, [
256
+ "merge-base",
257
+ "--is-ancestor",
258
+ "hitch/main",
259
+ "HEAD"
260
+ ]).then(() => true).catch(() => false) : false;
261
+ const action = syncAction({
262
+ remoteMain,
263
+ isAncestor,
264
+ hasMergeBase: remoteMain && !isAncestor ? await git(workspaceRoot, [
265
+ "merge-base",
266
+ "hitch/main",
267
+ "HEAD"
268
+ ]).then(() => true).catch(() => false) : false
269
+ });
270
+ if (action === "unrelated") throw new Error("This folder's history is not the applet's history in Hitch. Clone the applet repository and move your changes into it.");
271
+ if (action === "rebase" && prebuilt) throw new Error("main moved since your last deploy, so the build in --dist is out of date. Run applet deploy without --dist.");
272
+ if (action === "rebase") {
273
+ console.log("main moved since your last deploy. Rebasing onto it.");
274
+ try {
275
+ await git(workspaceRoot, ["rebase", "hitch/main"]);
276
+ } catch {
277
+ await git(workspaceRoot, ["rebase", "--abort"]).catch(() => void 0);
278
+ throw new Error("Your changes conflict with main. Run git pull --rebase hitch main, fix the conflicts, then run applet deploy again.");
279
+ }
280
+ }
281
+ return git(workspaceRoot, ["rev-parse", "HEAD"]);
282
+ }
283
+ async function pushStagedCommit(workspaceRoot, org, sha) {
284
+ await gitNetwork(workspaceRoot, org, [
285
+ "push",
286
+ "hitch",
287
+ `HEAD:refs/hitch/staged/${sha}`
288
+ ]);
289
+ }
290
+ export { prepareGitDeploy as a, runClone as c, hitchRemoteUrl as i, syncAction as l, gitCredentialConfigCommands as n, pushStagedCommit as o, gitProxyErrorMessage as r, refreshHitchMain as s, deployErrorMessage as t };
@@ -0,0 +1 @@
1
+ export { c as runClone } from "./git-deploy-C12nMNB6.js";