@engenty/wizards-runtime 0.7.9 → 0.7.11

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 (63) hide show
  1. package/LICENSE-FIGURES +37 -0
  2. package/README.md +5 -2
  3. package/TRADEMARKS.md +47 -0
  4. package/apps/runtime/dist/app.js +2 -2
  5. package/apps/runtime/dist/cli/autostart.js +90 -7
  6. package/apps/runtime/dist/cli/autoupdate.js +18 -5
  7. package/apps/runtime/dist/cli/clients.js +25 -6
  8. package/apps/runtime/dist/cli/connect.js +7 -2
  9. package/apps/runtime/dist/cli/environment.js +33 -2
  10. package/apps/runtime/dist/cli/exec.js +38 -1
  11. package/apps/runtime/dist/cli/home.js +15 -0
  12. package/apps/runtime/dist/cli/machine.js +18 -8
  13. package/apps/runtime/dist/cli/processes.js +23 -3
  14. package/apps/runtime/dist/cli/setup.js +11 -1
  15. package/apps/runtime/dist/cli/start.js +33 -7
  16. package/apps/runtime/dist/cli/uninstall.js +100 -6
  17. package/apps/runtime/dist/cli/update.js +28 -12
  18. package/apps/runtime/dist/cli/versions.js +16 -4
  19. package/apps/runtime/dist/docs/user/install.md +18 -8
  20. package/apps/runtime/dist/harness/env.js +41 -8
  21. package/apps/runtime/dist/harness/index.js +10 -1
  22. package/apps/runtime/dist/harness/model.js +1 -1
  23. package/apps/runtime/dist/render/browser-path.js +43 -11
  24. package/apps/runtime/dist/services/engenty-shapes.js +3 -2
  25. package/apps/runtime/dist/update.js +4 -0
  26. package/apps/web/dist/assets/{AboutDialog-CShc0mRo.js → AboutDialog-CPRAlD2H.js} +1 -1
  27. package/apps/web/dist/assets/{ChangelogDialog-C4dVSwtN.js → ChangelogDialog-CZrd-MgC.js} +1 -1
  28. package/apps/web/dist/assets/{ChatView-KkOboyOo.js → ChatView-DVeERQdi.js} +1 -1
  29. package/apps/web/dist/assets/{EditorPage-lQ3YgsFT.js → EditorPage-DhUoKcss.js} +1 -1
  30. package/apps/web/dist/assets/{Harness-D6mgLWTb.js → Harness-DiB8CBdY.js} +1 -1
  31. package/apps/web/dist/assets/{NewWizardChannels-CPlh_37J.js → NewWizardChannels-Ba3XGpro.js} +1 -1
  32. package/apps/web/dist/assets/{NewWizardPage-D0FVJtXK.js → NewWizardPage-C2Oh2sMM.js} +1 -1
  33. package/apps/web/dist/assets/{OnboardingPage-BXPOMrQR.js → OnboardingPage-D_4ShWrL.js} +1 -1
  34. package/apps/web/dist/assets/{ProjectPage-DroTprqs.js → ProjectPage-C58rq50b.js} +1 -1
  35. package/apps/web/dist/assets/{PublicRunner-j3qoKjQQ.js → PublicRunner-CE0ohzyd.js} +1 -1
  36. package/apps/web/dist/assets/{ReadOnly-CKgSQ2z1.js → ReadOnly-CD5YWvrW.js} +1 -1
  37. package/apps/web/dist/assets/{RunDrawer-CJZ_ISAd.js → RunDrawer-Cd8-qHV7.js} +1 -1
  38. package/apps/web/dist/assets/{SettingsPage-BHZ0Z-og.js → SettingsPage-ChYLv-MG.js} +1 -1
  39. package/apps/web/dist/assets/{SetupPage-CDkYkjJX.js → SetupPage-hX7deF0g.js} +1 -1
  40. package/apps/web/dist/assets/{SharePage-BlVjVjHG.js → SharePage-B6u9kS12.js} +1 -1
  41. package/apps/web/dist/assets/changelog-Dn9LT4MS.js +1 -0
  42. package/apps/web/dist/assets/engenty-Cko4qGFV.js +1 -0
  43. package/apps/web/dist/assets/fluffy-engenty-Db7agOjV.js +520 -0
  44. package/apps/web/dist/assets/index-4jH2mkp7.js +14 -0
  45. package/apps/web/dist/assets/index-BwW652E-.css +1 -0
  46. package/apps/web/dist/assets/{oss-credits-qGhcbqiM.js → oss-credits-Bc05Qv5H.js} +1 -1
  47. package/apps/web/dist/favicon.svg +2 -1
  48. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  49. package/apps/web/dist/icons/icon-192.png +0 -0
  50. package/apps/web/dist/icons/icon-512.png +0 -0
  51. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  52. package/apps/web/dist/index.html +3 -3
  53. package/apps/web/dist/install.ps1 +307 -0
  54. package/apps/web/dist/mcp/flow.html +33 -88
  55. package/bin/wizards.mjs +59 -35
  56. package/package.json +6 -7
  57. package/plugin/.claude-plugin/plugin.json +1 -1
  58. package/plugin/hooks/engenty.ts +3 -2
  59. package/apps/web/dist/assets/changelog-Be0i5Jjw.js +0 -1
  60. package/apps/web/dist/assets/engenty-WpMi3xwq.js +0 -1
  61. package/apps/web/dist/assets/fluffy-engenty-DPNHytrz.js +0 -575
  62. package/apps/web/dist/assets/index-C4aHMcg9.css +0 -1
  63. package/apps/web/dist/assets/index-C61HAltK.js +0 -14
package/bin/wizards.mjs CHANGED
@@ -4,8 +4,8 @@
4
4
  //
5
5
  // The same file is two things. In the npm package `wizards` (`npx wizards`, `npm install -g
6
6
  // wizards`) it is the launcher, with nothing beside it but the installer (install.sh) and no
7
- // dependencies: on macOS and Linux it installs engenty wizards into ~/.engenty/wizards with that
8
- // installer (its own Node, the runtime @engenty/wizards-runtime, the `wizards` command), brings an
7
+ // dependencies: it installs engenty wizards into ~/.engenty/wizards with that installer (on Windows
8
+ // install.ps1: its own Node, the runtime @engenty/wizards-runtime, the `wizards` command), brings an
9
9
  // older install there up to its own version, and hands the command to it. In the runtime, which
10
10
  // the installer puts there, it is the command itself.
11
11
  //
@@ -27,17 +27,24 @@ const home = join(
27
27
  "wizards",
28
28
  );
29
29
  const runtime = join(home, "runtime");
30
- const wrapper = join(home, "bin", "wizards");
30
+ const windows = process.platform === "win32";
31
+ const wrapper = join(home, "bin", windows ? "wizards.cmd" : "wizards");
31
32
  /** The runtime's npm package. Up to 0.7.4 it was `wizards` itself; that name is the launcher now. */
32
33
  const RUNTIME = "@engenty/wizards-runtime";
33
34
  /** Whether this copy is the runtime, or the launcher without it. */
34
35
  const hasRuntime = existsSync(join(root, "apps", "runtime", "dist", "cli", "main.js"));
35
36
  /** The installer: beside the launcher, or in the runtime's built SPA. */
36
- const installer = [join(root, "install.sh"), join(root, "apps", "web", "dist", "install.sh")].find(
37
- (file) => existsSync(file),
38
- );
37
+ const installerName = windows ? "install.ps1" : "install.sh";
38
+ const installer = [
39
+ join(root, installerName),
40
+ join(root, "apps", "web", "dist", installerName),
41
+ ].find((file) => existsSync(file));
39
42
  // uninstall: never installs or hands over first; the install it takes away may no longer run.
40
43
  const RUN_HERE = ["help", "validate", "mcp", "uninstall"];
44
+ /** The installer's line, as a person types it here. */
45
+ const installLine = windows
46
+ ? " irm https://engenty.ai/install.ps1 | iex\n"
47
+ : " curl -fsSL https://engenty.ai/install.sh | bash\n";
41
48
  const tilde = (path) =>
42
49
  path.startsWith(homedir() + sep) ? `~${path.slice(homedir().length)}` : path;
43
50
 
@@ -112,7 +119,12 @@ function isInstall() {
112
119
  function terminalEnv() {
113
120
  const env = {};
114
121
  for (const [key, value] of Object.entries(process.env)) {
115
- if (!key.startsWith("npm_") && !["INIT_CWD", "NODE", "COLOR"].includes(key)) {
122
+ // PATH comes after, once: Windows calls it Path, and two of them would leave one to chance.
123
+ if (
124
+ !key.startsWith("npm_") &&
125
+ !["INIT_CWD", "NODE", "COLOR"].includes(key) &&
126
+ key.toUpperCase() !== "PATH"
127
+ ) {
116
128
  env[key] = value;
117
129
  }
118
130
  }
@@ -128,7 +140,10 @@ function install(version, quiet) {
128
140
  if (!installer) {
129
141
  return false;
130
142
  }
131
- const result = spawnSync("bash", [installer, "--no-setup"], {
143
+ const [shell, ...shellArgs] = windows
144
+ ? ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", installer, "-NoSetup"]
145
+ : ["bash", installer, "--no-setup"];
146
+ const result = spawnSync(shell, shellArgs, {
132
147
  // A command whose output is read (validate --json, mcp) keeps its stdout to itself.
133
148
  stdio: ["ignore", quiet ? 2 : "inherit", "inherit"],
134
149
  env: {
@@ -161,10 +176,29 @@ function runs() {
161
176
  }
162
177
  }
163
178
 
179
+ /**
180
+ * The installed command with these arguments. On Windows its Node and script, which is what
181
+ * wizards.cmd runs: a .cmd file starts only through cmd.exe, which would read the arguments again.
182
+ */
183
+ function installedCommand(argv) {
184
+ if (!windows) {
185
+ return [wrapper, argv];
186
+ }
187
+ const script = join(runtime, "current", "node_modules", RUNTIME, "bin", "wizards.mjs");
188
+ return [join(home, "tools", "node", "node.exe"), [script, ...argv]];
189
+ }
190
+
191
+ /** Runs the installed command with these arguments, waiting for it. */
192
+ function installedRun(argv, quiet) {
193
+ const [file, all] = installedCommand(argv);
194
+ spawnSync(file, all, { stdio: ["ignore", quiet ? 2 : "inherit", "inherit"], env: terminalEnv() });
195
+ }
196
+
164
197
  /** Runs the installed command with these arguments; its exit code. */
165
198
  function handOver() {
166
199
  return new Promise((done) => {
167
- const child = spawn(wrapper, args, { stdio: "inherit", env: terminalEnv() });
200
+ const [file, argv] = installedCommand(args);
201
+ const child = spawn(file, argv, { stdio: "inherit", env: terminalEnv() });
168
202
  // Ctrl-C reaches the installed command as well (same terminal); this one waits for it.
169
203
  process.on("SIGINT", () => undefined);
170
204
  process.on("SIGTERM", () => child.kill("SIGTERM"));
@@ -184,19 +218,6 @@ if (command === "version") {
184
218
  const own = versionOf(root) || "0.0.0";
185
219
  const quiet = RUN_HERE.includes(command);
186
220
  const checkout = existsSync(join(root, "pnpm-workspace.yaml"));
187
- // Windows has no installer yet, and the setup, the service and the AI clients are written for
188
- // macOS and Linux: it says so instead of half working. What needs no install still runs.
189
- if (process.platform === "win32" && !checkout && !(hasRuntime && RUN_HERE.includes(command))) {
190
- console.error(
191
- "engenty wizards for Windows is coming soon.\n\n" +
192
- "Until then it runs in WSL (Windows Subsystem for Linux). In PowerShell:\n\n" +
193
- " wsl --install\n\n" +
194
- "then, in the Ubuntu terminal that opens:\n\n" +
195
- " curl -fsSL https://engenty.ai/install.sh | bash\n\n" +
196
- "https://engenty.ai/docs/user/install\n",
197
- );
198
- process.exit(1);
199
- }
200
221
  if (isInstall() && !hasRuntime) {
201
222
  // The launcher in the install's place: an update of 0.7.4 or older fetched `wizards`, the
202
223
  // runtime's name then, and its next start switched to it. The installer it carries brings the
@@ -217,7 +238,7 @@ if (isInstall() && !hasRuntime) {
217
238
  }
218
239
  process.exit(await handOver());
219
240
  }
220
- const fromNpm = process.platform !== "win32" && !checkout && !isInstall();
241
+ const fromNpm = !checkout && !isInstall();
221
242
  if (fromNpm && command === "uninstall" && !hasRuntime) {
222
243
  // The install's own uninstall takes it away; it never updates first. An install the update
223
244
  // left without its runtime gets it back (above, in the installed command) and then uninstalls.
@@ -235,15 +256,18 @@ if (
235
256
  const installed = installedVersion();
236
257
  if (!installed || older(installed, own)) {
237
258
  const running = installed && runs();
238
- if (install(own, quiet)) {
239
- // What runs is still the old version: it starts again as the new one.
240
- if (running) {
241
- spawnSync(wrapper, ["restart"], {
242
- stdio: ["ignore", quiet ? 2 : "inherit", "inherit"],
243
- env: terminalEnv(),
244
- });
245
- }
246
- } else if (hasRuntime && currentNode && !installed) {
259
+ // Windows keeps the files of a running program locked: the runtime stops for the update.
260
+ if (running && windows) {
261
+ installedRun(["stop"], quiet);
262
+ }
263
+ const done = install(own, quiet);
264
+ // What ran is still the old version: it starts again as the new one.
265
+ if (running && windows) {
266
+ installedRun(["start", "--background", "--no-open"], quiet);
267
+ } else if (running && done) {
268
+ installedRun(["restart"], quiet);
269
+ }
270
+ if (!done && hasRuntime && currentNode && !installed) {
247
271
  console.error(
248
272
  `The install into ${tilde(home)} failed; this time engenty wizards runs from npm.\n`,
249
273
  );
@@ -259,14 +283,14 @@ if (
259
283
  if (!hasRuntime) {
260
284
  console.error(
261
285
  `engenty wizards couldn’t be installed into ${tilde(home)}. The installer on its own:\n\n` +
262
- " curl -fsSL https://engenty.ai/install.sh | bash\n",
286
+ installLine,
263
287
  );
264
288
  process.exit(1);
265
289
  }
266
290
  }
267
291
  if (!currentNode && command === "uninstall") {
268
292
  // The install's own Node, if it is still there, runs this copy's uninstall.
269
- const node = join(home, "tools", "node", "bin", "node");
293
+ const node = join(home, "tools", "node", windows ? "node.exe" : "bin/node");
270
294
  const result = existsSync(node)
271
295
  ? spawnSync(node, [fileURLToPath(import.meta.url), ...args], { stdio: "inherit" })
272
296
  : null;
@@ -276,7 +300,7 @@ if (!currentNode) {
276
300
  console.error(
277
301
  `engenty wizards needs Node.js 24.11 or newer. This is ${process.version}.\n` +
278
302
  "The installer brings its own and leaves yours alone:\n\n" +
279
- " curl -fsSL https://engenty.ai/install.sh | bash\n",
303
+ installLine,
280
304
  );
281
305
  process.exit(1);
282
306
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@engenty/wizards-runtime",
3
- "version": "0.7.9",
3
+ "version": "0.7.11",
4
4
  "description": "Make a wish. Get your wizard. It guides you step by step. Let AI do the work. Runs on your machine, on the AI subscription you already have. The runtime, which `npx wizards` installs.",
5
- "license": "FSL-1.1-MIT",
5
+ "license": "FSL-1.1-MIT AND CC-BY-4.0",
6
6
  "homepage": "https://engenty.ai",
7
7
  "repository": {
8
8
  "type": "git",
@@ -15,15 +15,13 @@
15
15
  "engines": {
16
16
  "node": ">=24.11"
17
17
  },
18
- "os": [
19
- "darwin",
20
- "linux"
21
- ],
22
18
  "files": [
23
19
  "apps",
24
20
  "bin",
25
21
  "modules",
26
- "plugin"
22
+ "plugin",
23
+ "LICENSE-FIGURES",
24
+ "TRADEMARKS.md"
27
25
  ],
28
26
  "dependencies": {
29
27
  "@ai-sdk/anthropic": "4.0.54",
@@ -50,6 +48,7 @@
50
48
  "@turbodocx/html-to-docx": "1.23.1",
51
49
  "ai": "7.0.102",
52
50
  "aws4fetch": "1.0.20",
51
+ "cross-spawn": "7.0.6",
53
52
  "drizzle-orm": "0.45.3",
54
53
  "effect": "4.0.0-beta.59",
55
54
  "exceljs": "4.4.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wizards",
3
3
  "displayName": "engenty wizards",
4
- "version": "0.7.9",
4
+ "version": "0.7.11",
5
5
  "description": "Build page-by-page AI wizards that people open on a shared link — designed, tested and published from Claude Code — run your published ones in the chat, and keep them in a pane beside it.",
6
6
  "author": {
7
7
  "name": "engenty"
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: CC-BY-4.0
1
2
  /**
2
3
  * The flat engenties of the studio (apps/web/src/engenty/engenty.tsx) at rest, as one SVG
3
4
  * string per kind: the same bodies, the one eye, no animation. The fills are the studio's
@@ -38,7 +39,7 @@ const stroke = (d: string, color: string, width: number, opacity: number) =>
38
39
  const KINDS: Record<string, Kind> = {
39
40
  round: {
40
41
  fill: FILL.cobalt,
41
- body: "M60 22 Q96 26 96 62 Q96 96 60 100 Q24 96 24 62 Q24 26 60 22 Z",
42
+ body: "M60 22 C65.2 22 71.2 24 75.8 26 C80.2 28 84 30.7 87 34 C90 37.3 92.2 41.3 93.8 46 C95.2 50.7 96 56.8 96 62 C96 67.2 95.2 72.7 93.8 77.1 C92.2 81.5 90 85.3 87 88.5 C84 91.7 80.2 94.2 75.8 96.1 C71.2 98 65.2 100 60 100 C54.8 100 48.8 98 44.2 96.1 C39.8 94.2 36 91.7 33 88.5 C30 85.3 27.8 81.5 26.2 77.1 C24.8 72.7 24 67.2 24 62 C24 56.8 24.8 50.7 26.2 46 C27.8 41.3 30 37.3 33 34 C36 30.7 39.8 28 44.2 26 C48.8 24 54.8 22 60 22 Z",
42
43
  over: `<circle cx="97" cy="34" r="6" fill="${FILL.cobalt}" opacity="0.5"/><circle cx="106" cy="24" r="3.5" fill="${FILL.cobalt}" opacity="0.35"/>`,
43
44
  eye: { ex: 68, ey: 58, r: 8, ink: "oklch(18% 0.08 260)" },
44
45
  shadow: { cy: 108, rx: 26 },
@@ -47,7 +48,7 @@ const KINDS: Record<string, Kind> = {
47
48
  fill: FILL.amber,
48
49
  body: "M60 16 Q90 34 90 66 Q90 96 60 98 Q30 96 30 66 Q30 34 60 16 Z",
49
50
  eye: { ex: 60, ey: 56, r: 8, ink: "oklch(30% 0.10 60)" },
50
- after: stroke("M48 76 Q54 72 60 76 Q66 80 72 76", "oklch(30% 0.10 55)", 2.6, 1),
51
+ after: stroke("M49 75 C54 78 64 78.5 71 71.4", "oklch(30% 0.10 55)", 2.6, 1),
51
52
  shadow: { cy: 106, rx: 24 },
52
53
  },
53
54
  dome: {