@devframes/hub-ui-onboard 1.2.5 → 1.3.0

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/dist/index.d.mts CHANGED
@@ -67,8 +67,9 @@ interface CreateOnboardingOptions {
67
67
  * Ask the developer to allow an install that the panel requested; the
68
68
  * dev server can be reachable from other devices. Return `true` to run
69
69
  * it. Only one call is open at a time: clicks meanwhile share its answer.
70
- * Default: a `y/N` question in the terminal, or a refusal when stdin is
71
- * not a TTY.
70
+ * Default: a `y/N` question in the terminal. It refuses at once when stdin
71
+ * is not a TTY or another reader holds it in raw mode, and after 5 minutes
72
+ * without an answer.
72
73
  */
73
74
  onConfirm?: (confirmation: OnboardingConfirmation) => boolean | Promise<boolean>;
74
75
  }
package/dist/index.mjs CHANGED
@@ -40,12 +40,20 @@ const diagnostics = defineDiagnostics({
40
40
  fix: "Make sure that `stateDir` is writable, or point it at another directory."
41
41
  },
42
42
  DF9005: {
43
- why: (p) => `A browser asked to run \`${p.command}\`. Type y and press Enter to allow it.`,
43
+ why: (p) => `A browser asked to run \`${p.command}\`. Type y and press Enter within ${p.minutes} minutes to allow it.`,
44
44
  fix: "If you did not click Install, press Enter to refuse. Another device can reach this dev server, so bind it to localhost."
45
45
  },
46
46
  DF9006: {
47
47
  why: (p) => `A browser asked to run \`${p.command}\`, but no interactive terminal can confirm it. The install was refused.`,
48
48
  fix: "Run the command yourself, or pass an `onConfirm` function to `createOnboarding()`."
49
+ },
50
+ DF9007: {
51
+ why: (p) => `A browser asked to run \`${p.command}\`, but another program reads this terminal key by key, so it cannot show the question. The install was refused.`,
52
+ fix: "Run the command yourself. If a CLI owns the terminal, pass an `onConfirm` function to `createOnboarding()` that asks through that CLI."
53
+ },
54
+ DF9008: {
55
+ why: (p) => `Nobody allowed \`${p.command}\` within ${p.minutes} minutes. The install was refused.`,
56
+ fix: "Click Install again and answer in the terminal that runs the dev server. If the answer does not arrive, another program reads that terminal: pass an `onConfirm` function to `createOnboarding()`."
49
57
  }
50
58
  }
51
59
  });
@@ -103,22 +111,42 @@ function packageName(spec) {
103
111
  }
104
112
  //#endregion
105
113
  //#region src/terminal-confirm.ts
114
+ const ANSWER_MINUTES = 5;
106
115
  /**
107
116
  * The default `onConfirm`: a `y/N` question in the terminal that runs the dev
108
- * server. Without an interactive terminal nobody can answer, so it refuses.
117
+ * server. When nobody can answer it, it refuses.
109
118
  */
110
119
  function confirmInTerminal(command, input = process.stdin) {
120
+ const line = command.join(" ");
111
121
  if (!input.isTTY) {
112
- diagnostics.DF9006({ command: command.join(" ") });
122
+ diagnostics.DF9006({ command: line });
123
+ return Promise.resolve(false);
124
+ }
125
+ if (input.isRaw) {
126
+ diagnostics.DF9007({ command: line });
113
127
  return Promise.resolve(false);
114
128
  }
115
- diagnostics.DF9005({ command: command.join(" ") });
129
+ diagnostics.DF9005({
130
+ command: line,
131
+ minutes: ANSWER_MINUTES
132
+ });
116
133
  const flowing = input.readableFlowing;
117
134
  return new Promise((resolve) => {
118
- input.once("data", (chunk) => {
135
+ const timer = setTimeout(() => {
136
+ diagnostics.DF9008({
137
+ command: line,
138
+ minutes: ANSWER_MINUTES
139
+ });
140
+ settle(false);
141
+ }, ANSWER_MINUTES * 6e4);
142
+ const onData = (chunk) => settle(/^y(?:es)?$/i.test(String(chunk).trim()));
143
+ function settle(allowed) {
144
+ clearTimeout(timer);
145
+ input.off("data", onData);
119
146
  if (!flowing) input.pause();
120
- resolve(/^y(?:es)?$/i.test(String(chunk).trim()));
121
- });
147
+ resolve(allowed);
148
+ }
149
+ input.on("data", onData);
122
150
  });
123
151
  }
124
152
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/hub-ui-onboard",
3
3
  "type": "module",
4
- "version": "1.2.5",
4
+ "version": "1.3.0",
5
5
  "description": "A tiny stand-in for the devframe hub UI: a floating button that installs it on demand.",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -33,12 +33,12 @@
33
33
  "tinyexec": "^1.3.1"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/node": "^26.6.4",
37
- "tsdown": "^0.23.0",
36
+ "@types/node": "^26.6.5",
37
+ "tsdown": "0.23.0",
38
38
  "tsx": "^4.23.15",
39
- "unocss": "^66.10.5",
40
- "vite": "^8.3.3",
41
- "vitest": "^5.0.3"
39
+ "unocss": "^66.11.0",
40
+ "vite": "^8.3.4",
41
+ "vitest": "^5.0.5"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "pnpm run build:css && tsdown && vite build --config vite.client.config.ts",