hanoman 0.1.41 → 0.1.42

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.41",
3
- "sha": "5ef26fe",
4
- "builtAt": "2026-08-15T14:26:22.718Z"
2
+ "version": "0.1.42",
3
+ "sha": "ad6403a",
4
+ "builtAt": "2026-08-17T00:53:19.226Z"
5
5
  }
package/dist/server.js CHANGED
@@ -10173,12 +10173,24 @@ function broadcast(a, f) {
10173
10173
  const msg = frame(f);
10174
10174
  for (const c of a.clients) c.send(msg);
10175
10175
  }
10176
+ function flushOutput(a) {
10177
+ if (a.flushTimer) {
10178
+ clearTimeout(a.flushTimer);
10179
+ a.flushTimer = void 0;
10180
+ }
10181
+ if (!a.pending) return;
10182
+ const d = a.pending;
10183
+ a.pending = "";
10184
+ a.scrollback = trimScrollback(a.scrollback + d);
10185
+ broadcast(a, { t: "data", d });
10186
+ }
10176
10187
  function open(id) {
10177
10188
  const pty = spawnPty("attach-session", "-d", "-t", name(id));
10178
- const a = { pty, scrollback: "", clients: /* @__PURE__ */ new Set(), lastPhases: "" };
10189
+ const a = { pty, scrollback: "", clients: /* @__PURE__ */ new Set(), lastPhases: "", pending: "" };
10179
10190
  pty.onData((d) => {
10180
- a.scrollback = (a.scrollback + d).slice(-MAX_SCROLLBACK);
10181
- broadcast(a, { t: "data", d });
10191
+ a.pending += d;
10192
+ if (a.pending.length >= COALESCE_MAX_BYTES) flushOutput(a);
10193
+ else if (!a.flushTimer) a.flushTimer = setTimeout(() => flushOutput(a), COALESCE_MS);
10182
10194
  });
10183
10195
  pty.onExit(() => {
10184
10196
  if (attached.get(id) === a) drop(id);
@@ -10190,6 +10202,7 @@ function open(id) {
10190
10202
  function drop(id) {
10191
10203
  const a = attached.get(id);
10192
10204
  if (!a) return;
10205
+ flushOutput(a);
10193
10206
  attached.delete(id);
10194
10207
  a.pty.kill();
10195
10208
  for (const c of a.clients) c.close();
@@ -10198,6 +10211,7 @@ function drop(id) {
10198
10211
  function end(id, code) {
10199
10212
  const a = attached.get(id);
10200
10213
  if (!a) return;
10214
+ flushOutput(a);
10201
10215
  broadcast(a, { t: "exit", code });
10202
10216
  drop(id);
10203
10217
  }
@@ -10291,7 +10305,7 @@ function spawnPty(...args) {
10291
10305
  );
10292
10306
  }
10293
10307
  }
10294
- var socket, PREFIX, MAX_SCROLLBACK, POLL_MS, markerFilled, attached, claudeBin, shellBin, codexBin, agentBin, rootBypassEnv, frame, name, promptFilePath, goalGatePath, goalStatePath, agentsFilePath, NO_SERVER, TmuxError, sq, idFor, FMT, listSessions, liveDecisions, getSession, hooks, emitBirth, emitDeath, customAgentSource, customAgentsFor, sleep, paneText, dialogIO, DIALOG_CAPTURE_LINES, GOAL_ARMED_MARKERS, goalArmed, phaseKey, paneComplete, sessionFinished, poll, detach;
10308
+ var socket, PREFIX, MAX_SCROLLBACK, SCROLLBACK_SLACK, POLL_MS, markerFilled, attached, claudeBin, shellBin, codexBin, agentBin, rootBypassEnv, frame, name, promptFilePath, goalGatePath, goalStatePath, agentsFilePath, NO_SERVER, TmuxError, sq, idFor, FMT, listSessions, liveDecisions, getSession, hooks, emitBirth, emitDeath, customAgentSource, customAgentsFor, sleep, paneText, dialogIO, DIALOG_CAPTURE_LINES, GOAL_ARMED_MARKERS, goalArmed, COALESCE_MS, COALESCE_MAX_BYTES, trimScrollback, phaseKey, paneComplete, sessionFinished, poll, detach;
10295
10309
  var init_pty = __esm({
10296
10310
  "src/services/pty.ts"() {
10297
10311
  "use strict";
@@ -10305,6 +10319,7 @@ var init_pty = __esm({
10305
10319
  socket = () => effectiveStr("HANOMAN_TMUX_SOCKET") ?? "hanoman";
10306
10320
  PREFIX = "hanoman-";
10307
10321
  MAX_SCROLLBACK = 256 * 1024;
10322
+ SCROLLBACK_SLACK = 64 * 1024;
10308
10323
  POLL_MS = 500;
10309
10324
  markerFilled = (f) => {
10310
10325
  try {
@@ -10418,6 +10433,9 @@ var init_pty = __esm({
10418
10433
  const text = paneText(id);
10419
10434
  return GOAL_ARMED_MARKERS[agent].some((m) => text.includes(m));
10420
10435
  };
10436
+ COALESCE_MS = 16;
10437
+ COALESCE_MAX_BYTES = 64 * 1024;
10438
+ trimScrollback = (s2) => s2.length > MAX_SCROLLBACK + SCROLLBACK_SLACK ? s2.slice(-MAX_SCROLLBACK) : s2;
10421
10439
  phaseKey = (phases, complete) => JSON.stringify({ phases, complete });
10422
10440
  paneComplete = (p) => !!p.flow && !!p.phaseFile && sessionComplete(readPhases(p.phaseFile, p.flow), p.cwd, p.specId);
10423
10441
  sessionFinished = (id) => {
@@ -45299,7 +45317,12 @@ function buildApp({ requireAuth = true, agentDocFile, env = process.env } = {})
45299
45317
  done(err, void 0);
45300
45318
  }
45301
45319
  });
45302
- app2.register(websocket, { options: { maxPayload: MAX_WS_MESSAGE_BYTES } });
45320
+ app2.register(websocket, {
45321
+ options: {
45322
+ maxPayload: MAX_WS_MESSAGE_BYTES,
45323
+ perMessageDeflate: { zlibDeflateOptions: { level: 6, memLevel: 7 }, concurrencyLimit: 10 }
45324
+ }
45325
+ });
45303
45326
  app2.addHook("onClose", async () => {
45304
45327
  await stopTelegramRuntime();
45305
45328
  detachAll();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.41",
3
+ "version": "0.1.42",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {