@b9g/shovel 0.2.8 → 0.2.9

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/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to Shovel will be documented in this file.
4
4
 
5
+ ## [0.2.8] - 2026-02-10
6
+
7
+ ### Bug Fixes
8
+
9
+ - **Config file watching during develop** - `shovel.json` and `package.json` changes are now correctly detected during `shovel develop`. The previous `fs.watch()` approach broke on atomic saves (most editors write to a temp file then rename). Now uses esbuild's native `watchFiles` mechanism which handles this correctly. ([#59](https://github.com/bikeshaving/shovel/issues/59))
10
+
11
+ ### Features
12
+
13
+ - **Dev server keyboard shortcuts** - `Ctrl+R` (reload), `Ctrl+L` (clear), `Ctrl+C` (quit), `?` (help) shortcuts in the dev server terminal. Only active when stdin is a TTY. ([#60](https://github.com/bikeshaving/shovel/issues/60))
14
+
5
15
  ## [0.2.7] - 2026-02-06
6
16
 
7
17
  ### Features
package/bin/cli.js CHANGED
@@ -75,7 +75,7 @@ program.command("develop <entrypoint>").description("Start development server wi
75
75
  DEFAULTS.WORKERS
76
76
  ).option("--platform <name>", "Runtime platform (node, cloudflare, bun)").action(async (entrypoint, options) => {
77
77
  checkPlatformReexec(options);
78
- const { developCommand } = await import("../src/_chunks/develop-SVLFKAF5.js");
78
+ const { developCommand } = await import("../src/_chunks/develop-N265AMEN.js");
79
79
  await developCommand(entrypoint, options, config);
80
80
  });
81
81
  program.command("create [name]").description("Create a new Shovel project").action(async (name) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/shovel",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "ServiceWorker-first universal deployment platform. Write ServiceWorker apps once, deploy anywhere (Node/Bun/Cloudflare). Registry-based multi-app orchestration.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "@b9g/async-context": "^0.2.1",
18
18
  "@b9g/cache": "^0.2.2",
19
- "@b9g/filesystem": "^0.1.11",
19
+ "@b9g/filesystem": "^0.2.0",
20
20
  "@b9g/http-errors": "^0.2.1",
21
21
  "@b9g/node-webworker": "^0.2.1",
22
22
  "@b9g/platform": "^0.1.17",
@@ -26,7 +26,7 @@
26
26
  "@clack/prompts": "^0.7.0",
27
27
  "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
28
28
  "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
29
- "@logtape/logtape": "^1.2.0",
29
+ "@logtape/logtape": "^2.0.0",
30
30
  "commander": "^13.1.0",
31
31
  "esbuild": "^0.27.2",
32
32
  "mime": "^4.0.4",
@@ -37,7 +37,7 @@
37
37
  "@b9g/crank": "^0.7.2",
38
38
  "@b9g/libuild": "^0.1.22",
39
39
  "@b9g/router": "^0.2.2",
40
- "@logtape/file": "^1.0.0",
40
+ "@logtape/file": "^2.0.0",
41
41
  "@types/bun": "^1.3.4",
42
42
  "@typescript-eslint/eslint-plugin": "^8.0.0",
43
43
  "@typescript-eslint/parser": "^8.0.0",
@@ -10,6 +10,7 @@ import {
10
10
  import { getLogger } from "@logtape/logtape";
11
11
  import { resolvePlatform } from "@b9g/platform";
12
12
  import { networkInterfaces } from "os";
13
+ import { exec } from "child_process";
13
14
  var logger = getLogger(["shovel", "develop"]);
14
15
  function getDisplayUrls(host, port) {
15
16
  const urls = {
@@ -56,7 +57,8 @@ async function developCommand(entrypoint, options, config) {
56
57
  const platformModule = await loadPlatformModule(platformName);
57
58
  const platformESBuildConfig = platformModule.getESBuildConfig();
58
59
  let devServer = null;
59
- const SHORTCUTS_HELP = "Shortcuts: Ctrl+R (reload) \xB7 Ctrl+L (clear) \xB7 Ctrl+C (quit) \xB7 ? (help)";
60
+ const localUrl = `http://localhost:${port}`;
61
+ const SHORTCUTS_HELP = "Ctrl+R (reload) Ctrl+O (open) Ctrl+C (quit) ? (help)";
60
62
  const startOrReloadServer = async (workerPath) => {
61
63
  if (!devServer) {
62
64
  devServer = await platformModule.createDevServer({
@@ -117,6 +119,10 @@ async function developCommand(entrypoint, options, config) {
117
119
  process.stdin.setRawMode(true);
118
120
  process.stdin.resume();
119
121
  process.stdin.setEncoding("utf8");
122
+ process.on("SIGCONT", () => {
123
+ process.stdin.setRawMode(true);
124
+ process.stdin.resume();
125
+ });
120
126
  process.stdin.on("data", async (key) => {
121
127
  switch (key) {
122
128
  case "":
@@ -129,9 +135,33 @@ async function developCommand(entrypoint, options, config) {
129
135
  case "":
130
136
  await shutdown("SIGINT");
131
137
  break;
138
+ case "":
139
+ process.stdin.setRawMode(false);
140
+ process.kill(process.pid, "SIGTSTP");
141
+ break;
142
+ case "":
143
+ await shutdown("SIGQUIT");
144
+ break;
145
+ case "":
146
+ await shutdown("SIGINT");
147
+ break;
148
+ case "": {
149
+ const cmd = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
150
+ exec(`${cmd} ${localUrl}`);
151
+ break;
152
+ }
153
+ case "\r":
154
+ process.stdout.write("\n");
155
+ break;
156
+ case "\x7F":
157
+ process.stdout.write("\b \b");
158
+ break;
132
159
  case "?":
133
160
  logger.info(SHORTCUTS_HELP);
134
161
  break;
162
+ default:
163
+ process.stdout.write(key);
164
+ break;
135
165
  }
136
166
  });
137
167
  }