@honeydeck/honeydeck 0.1.1 → 0.1.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honeydeck/honeydeck",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MDX and React-based presentation framework for AI-friendly slide decks.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
package/src/cli/SPEC.md CHANGED
@@ -43,6 +43,7 @@ Behavior:
43
43
  - Generates starter files, including `deck.mdx`, `styles.css`, `.gitignore`, `package.json`, `public/`, and `components/SparkleButton.tsx`
44
44
  - Renders `deck.mdx` and `styles.css` from real template files that can also run as a development demo
45
45
  - Installs dependencies with npm unless `--skip-install` is used
46
+ - Shows a live process indicator for non-interactive work such as starter file generation and dependency installation; long-running installs keep updating so users know work is still active
46
47
  - Asks whether to open the Honeydeck agent skills installer unless `--skip-skill` or `--install-skill` is used, and makes clear that accepting runs `npx skills add`
47
48
  - Cancelling any `honeydeck init` prompt or interrupting the spawned skills installer aborts the init flow instead of continuing
48
49
  - If cancellation or interruption happens after `honeydeck init` created a new project directory, Honeydeck cleans up that generated project directory before exiting; it never deletes a directory that existed before init started
package/src/cli/dev.ts CHANGED
@@ -24,7 +24,7 @@
24
24
  import { readFileSync } from "node:fs";
25
25
  import { dirname, resolve } from "node:path";
26
26
  import { fileURLToPath } from "node:url";
27
- import { createServer, type Plugin } from "vite";
27
+ import { createServer, type Plugin, searchForWorkspaceRoot } from "vite";
28
28
  import { honeydeckPlugin } from "#vite-plugin/index.ts";
29
29
  import { hasHelpFlag } from "./args.ts";
30
30
  import { formatCommandBanner } from "./banner.ts";
@@ -58,6 +58,20 @@ const INDEX_HTML_PATH = resolve(APP_SHELL_DIR, "index.html");
58
58
  */
59
59
  const PACKAGE_ROOT = resolve(__dirname, "../..");
60
60
 
61
+ /**
62
+ * Bare dependencies imported by the Honeydeck app shell/runtime before any
63
+ * user-authored HTML entry exists. Vite cannot discover these reliably from
64
+ * its normal HTML scan because `honeydeck dev` serves a custom app shell from
65
+ * /@fs/, so keep the CommonJS/large ESM deps pre-bundled explicitly.
66
+ */
67
+ const DEV_OPTIMIZE_DEPS = [
68
+ "react",
69
+ "react/jsx-runtime",
70
+ "react/jsx-dev-runtime",
71
+ "react-dom/client",
72
+ "lucide-react",
73
+ ] as const;
74
+
61
75
  // ---------------------------------------------------------------------------
62
76
  // Arg parsing
63
77
  // ---------------------------------------------------------------------------
@@ -156,7 +170,7 @@ export function parseDevArgs(args: string[]): DevOptions {
156
170
  * /@fs/ script src, and lets Vite's `transformIndexHtml` pipeline apply
157
171
  * any further HTML transforms (e.g. inject the HMR client).
158
172
  */
159
- function appShellPlugin(): Plugin {
173
+ function appShellPlugin(projectRoot: string): Plugin {
160
174
  return {
161
175
  name: "honeydeck:app-shell",
162
176
 
@@ -164,9 +178,11 @@ function appShellPlugin(): Plugin {
164
178
  return {
165
179
  server: {
166
180
  fs: {
167
- // Allow Vite's /@fs/ handler to serve any file under the honeydeck
168
- // package root (so src/runtime/app-shell/main.tsx is accessible).
169
- allow: [PACKAGE_ROOT],
181
+ // Setting server.fs.allow replaces Vite's default allow list.
182
+ // Keep the user's workspace root allowed for normal node_modules
183
+ // serving, then add the Honeydeck package root so /@fs/ can reach
184
+ // src/runtime/app-shell/main.tsx when it lives outside that root.
185
+ allow: [searchForWorkspaceRoot(projectRoot), PACKAGE_ROOT],
170
186
  },
171
187
  },
172
188
  };
@@ -232,9 +248,13 @@ export async function runDev(args: string[]): Promise<void> {
232
248
 
233
249
  server: createDevServerConfig(port, open),
234
250
 
251
+ optimizeDeps: {
252
+ include: [...DEV_OPTIMIZE_DEPS],
253
+ },
254
+
235
255
  plugins: [
236
256
  // 1. App shell: serve our index.html + configure fs.allow
237
- appShellPlugin(),
257
+ appShellPlugin(root),
238
258
  // 2. Virtual modules + MDX compilation + Tailwind
239
259
  ...honeydeckPlugin({ root, entry }),
240
260
  ],
package/src/cli/init.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * 8. outro() — success message with next steps.
14
14
  */
15
15
 
16
- import { execSync } from "node:child_process";
16
+ import { spawn } from "node:child_process";
17
17
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
18
18
  import { dirname, join, resolve } from "node:path";
19
19
  import * as p from "@clack/prompts";
@@ -101,6 +101,29 @@ export function parseInitArgs(args: string[]): InitOptions {
101
101
 
102
102
  const INSTALL_COMMAND = "npm install";
103
103
 
104
+ function runCommand(command: string, cwd: string): Promise<void> {
105
+ return new Promise((resolveCommand, rejectCommand) => {
106
+ const child = spawn(command, {
107
+ cwd,
108
+ shell: true,
109
+ stdio: "ignore",
110
+ });
111
+
112
+ child.once("error", rejectCommand);
113
+ child.once("exit", (code, signal) => {
114
+ if (code === 0) {
115
+ resolveCommand();
116
+ return;
117
+ }
118
+
119
+ const reason = signal
120
+ ? `signal ${signal}`
121
+ : `exit code ${code ?? "unknown"}`;
122
+ rejectCommand(new Error(`${command} failed with ${reason}`));
123
+ });
124
+ });
125
+ }
126
+
104
127
  // ---------------------------------------------------------------------------
105
128
  // Validation
106
129
  // ---------------------------------------------------------------------------
@@ -285,10 +308,7 @@ export async function runInit(args: string[]): Promise<void> {
285
308
  installSpinner.start("Installing dependencies with npm…");
286
309
 
287
310
  try {
288
- execSync(INSTALL_COMMAND, {
289
- cwd: projectDir,
290
- stdio: "pipe",
291
- });
311
+ await runCommand(INSTALL_COMMAND, projectDir);
292
312
  installSpinner.stop("Dependencies installed ✅");
293
313
  } catch (_err) {
294
314
  installSpinner.stop("Dependency installation failed ⚠️");
@@ -352,7 +372,7 @@ export async function runInit(args: string[]): Promise<void> {
352
372
  ` cd ${projectName}`,
353
373
  " npm run dev",
354
374
  "",
355
- " Happy presenting! 🎞",
375
+ " Happy presenting! 🐝",
356
376
  "",
357
377
  ].join("\n"),
358
378
  );
@@ -199,6 +199,7 @@ Observable build/dev behavior:
199
199
  - `honeydeck build` produces a static single-page application.
200
200
  - Project `public/` assets are served/copied at the web root.
201
201
  - Project-local CSS, React components, layout maps, and static image imports work from the selected deck root.
202
+ - In dev, Honeydeck's package app shell may be served from outside the selected deck root, but Vite still allows the user's workspace root for normal dependency serving and pre-bundles Honeydeck runtime browser dependencies such as React, React DOM, and runtime icons.
202
203
  - Built decks use hash-based routes and can be deployed to static hosts without server-side routing.
203
204
  - The app shell applies the initial effective `data-honeydeck-color-mode` to `<html>` before mounting React so first-render browser defaults and generated assets match the deck mode.
204
205