hotsheet 0.17.0-beta.21 → 0.17.0-beta.22

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/channel.js CHANGED
@@ -34731,6 +34731,48 @@ function clearAllPermissions() {
34731
34731
  queue.length = 0;
34732
34732
  }
34733
34733
 
34734
+ // src/channelStdioWatcher.ts
34735
+ function installStdioDisconnectHandler(opts) {
34736
+ const { stdin, stdout, onDisconnect, log } = opts;
34737
+ let fired = false;
34738
+ const fire = (reason) => {
34739
+ if (fired) return;
34740
+ fired = true;
34741
+ if (log !== void 0) {
34742
+ log(`stdio disconnected (${reason}) \u2014 triggering channel-server cleanup`);
34743
+ }
34744
+ try {
34745
+ onDisconnect(reason);
34746
+ } catch (err) {
34747
+ if (log !== void 0) {
34748
+ log(`onDisconnect threw: ${err instanceof Error ? err.message : String(err)}`);
34749
+ }
34750
+ }
34751
+ };
34752
+ const onStdinEnd = () => {
34753
+ fire("stdin-end");
34754
+ };
34755
+ const onStdinClose = () => {
34756
+ fire("stdin-close");
34757
+ };
34758
+ const onStdoutError = (err) => {
34759
+ if (err.code === "EPIPE" || err.code === "ECONNRESET" || err.code === "ECANCELED") {
34760
+ fire("stdout-error");
34761
+ }
34762
+ };
34763
+ stdin.on("end", onStdinEnd);
34764
+ stdin.on("close", onStdinClose);
34765
+ stdout.on("error", onStdoutError);
34766
+ let disposed = false;
34767
+ return () => {
34768
+ if (disposed) return;
34769
+ disposed = true;
34770
+ stdin.off("end", onStdinEnd);
34771
+ stdin.off("close", onStdinClose);
34772
+ stdout.off("error", onStdoutError);
34773
+ };
34774
+ }
34775
+
34734
34776
  // src/channel.ts
34735
34777
  var CHANNEL_VERSION = 7;
34736
34778
  var dataDir = ".hotsheet";
@@ -34778,6 +34820,15 @@ mcp.setRequestHandler(CallToolRequestSchema, async (request) => {
34778
34820
  return result;
34779
34821
  });
34780
34822
  await mcp.connect(new StdioServerTransport());
34823
+ installStdioDisconnectHandler({
34824
+ stdin: process.stdin,
34825
+ stdout: process.stdout,
34826
+ log: (msg) => process.stderr.write(`${serverName}: ${msg}
34827
+ `),
34828
+ onDisconnect: () => {
34829
+ void cleanup();
34830
+ }
34831
+ });
34781
34832
  var PermissionRequestSchema = external_exports3.object({
34782
34833
  method: external_exports3.literal("notifications/claude/channel/permission_request"),
34783
34834
  params: external_exports3.object({
@@ -35001,6 +35052,7 @@ async function cleanup() {
35001
35052
  }
35002
35053
  process.on("SIGTERM", () => void cleanup());
35003
35054
  process.on("SIGINT", () => void cleanup());
35055
+ process.on("SIGHUP", () => void cleanup());
35004
35056
  process.on("exit", () => {
35005
35057
  try {
35006
35058
  unlinkSync(portFile);
package/dist/cli.js CHANGED
@@ -21039,7 +21039,15 @@ var init_global_config = __esm({
21039
21039
  // HS-8290 — terminal-dashboard settings (formerly stored per-project but
21040
21040
  // are inherently cross-project since the dashboard shows tiles for every
21041
21041
  // registered project in one view). See docs/39-visibility-groupings.md.
21042
- dashboard: DashboardConfigSchema2.optional()
21042
+ dashboard: DashboardConfigSchema2.optional(),
21043
+ // HS-8446 — global diagnostics opt-in. When true, the slow-server
21044
+ // banner (HS-8175 / HS-8226) is allowed to surface AND the HS-8054
21045
+ // UI-hang toast fires. Default false so the noisier diagnostic
21046
+ // surfaces stay opt-in across every project on this machine. The
21047
+ // freeze-log entries (`<dataDir>/freeze.log`) and the server-side
21048
+ // event-loop heartbeat continue to fire regardless — the gate only
21049
+ // suppresses the in-window UI surfaces.
21050
+ diagnosticsEnabled: external_exports.boolean().optional()
21043
21051
  }).strict();
21044
21052
  }
21045
21053
  });
@@ -27276,14 +27284,17 @@ pageRoutes.get("/", (c) => {
27276
27284
  ] })
27277
27285
  ] }) }),
27278
27286
  /* @__PURE__ */ jsx("div", { className: "settings-section", style: "margin-top:16px", children: [
27279
- /* @__PURE__ */ jsx("div", { className: "settings-section-header", children: /* @__PURE__ */ jsx("h3", { children: "Diagnostics" }) }),
27287
+ /* @__PURE__ */ jsx("div", { className: "settings-section-header", children: /* @__PURE__ */ jsx("h3", { children: [
27288
+ "Diagnostics ",
27289
+ /* @__PURE__ */ jsx("span", { className: "settings-scope-badge", title: "This setting applies to every project on this machine.", children: "Global" })
27290
+ ] }) }),
27280
27291
  /* @__PURE__ */ jsx("div", { className: "settings-field settings-field-checkbox", children: [
27281
27292
  /* @__PURE__ */ jsx("label", { children: [
27282
- /* @__PURE__ */ jsx("input", { type: "checkbox", id: "settings-diagnostics-freeze-toast" }),
27283
- " Show UI-hang toast when freezes are detected"
27293
+ /* @__PURE__ */ jsx("input", { type: "checkbox", id: "settings-diagnostics-enabled" }),
27294
+ " Enable diagnostic UI surfaces (slow-server banner + UI-hang toast)"
27284
27295
  ] }),
27285
27296
  /* @__PURE__ */ jsx("span", { className: "settings-hint", children: [
27286
- "When on, a small toast pops in for each \u2265 500 ms UI hang the HS-8054 longtask observer catches (rate-limited to once every 10 s). Off by default. Freezes are always logged to ",
27297
+ "When on, the slow-server banner (HS-8175 / HS-8226) surfaces when an HTTP request stays in flight past 3 s, and the HS-8054 longtask observer emits a small toast for each \u2265 500 ms UI hang (rate-limited to once every 10 s). Off by default \u2014 both surfaces are primarily useful when actively investigating event-loop blocks. Freezes are always logged to ",
27287
27298
  /* @__PURE__ */ jsx("code", { children: "<dataDir>/freeze.log" }),
27288
27299
  " for diagnostics regardless of this setting."
27289
27300
  ] })