loom-agent 1.2.6 → 1.2.7

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": "loom-agent",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/toshalkumbhar8979-design/loomcode.git"
package/src/tui/App.tsx CHANGED
@@ -1506,7 +1506,7 @@ export function App(props: { initialPrompt?: string; resumeSession?: string; aut
1506
1506
  _skillDoneOff = on("turn:end", function(d: any) {
1507
1507
  if (d?.skills?.length) showToast("skill handled: " + d.skills.join(", "), "ok");
1508
1508
  });
1509
- (globalThis as any).__loomTrace?.("onMount-done");
1509
+ (globalThis as any).__loomTrace("onMount-done", new Error("mount complete"));
1510
1510
  });
1511
1511
  onCleanup(function() { persistUi(); if (_skillToastOff) _skillToastOff(); if (_skillDoneOff) _skillDoneOff(); });
1512
1512
 
@@ -45,6 +45,22 @@ function record(kind, err) {
45
45
  }
46
46
  process.on("uncaughtException", (e) => { record("uncaughtException", e); });
47
47
  process.on("unhandledRejection", (r) => { record("unhandledRejection", r); });
48
+ globalThis.__loomTrace = record;
49
+
50
+ // Watchdog: append a heartbeat every 3s carrying measured event-loop lag.
51
+ // A synchronous hang shows up as a timestamp gap exactly covering the
52
+ // blocking phase; markers around it name the guilty step.
53
+ const __hbStart = Date.now();
54
+ let __hbTick = 0;
55
+ let __hbScheduled = __hbStart;
56
+ const __hbTimer = setInterval(() => {
57
+ const now = Date.now();
58
+ const lag = now - __hbScheduled;
59
+ record("heartbeat", new Error(`tick=${++__hbTick} lag=${lag}ms uptime=${now - __hbStart}ms`));
60
+ __hbScheduled = now + 3000;
61
+ }, 3000);
62
+ try { __hbTimer.unref?.(); } catch {}
63
+ process.on("exit", () => { try { record("exit", new Error(`uptime=${Date.now() - __hbStart}ms ticks=${__hbTick}`)); } catch {} });
48
64
 
49
65
  record("boot", new Error(
50
66
  `argv=${JSON.stringify(process.argv.slice(1))} cwd=${process.cwd()} ` +
package/src/tui-open.tsx CHANGED
@@ -5,6 +5,7 @@ import { render } from "@opentui/solid";
5
5
  import { App } from "./tui/App.tsx";
6
6
  import { defaultMcpInstall } from "./core/plugin-cmd.js";
7
7
 
8
+ globalThis.__loomTrace?.("entry", new Error("module imports evaluated"));
8
9
  const args = process.argv.slice(2);
9
10
 
10
11
  // Windows: switch both console codepages to UTF-8 so the box-drawing logo
@@ -45,10 +46,11 @@ const sessionId = sIdx !== -1 ? args[sIdx + 1] : null;
45
46
  const autoMode = args.includes("--auto") || args.includes("-a");
46
47
  const initialPrompt = args.filter((a, i) => !a.startsWith("-") && (sIdx === -1 || i !== sIdx + 1)).join(" ");
47
48
 
49
+ globalThis.__loomTrace("mcp-start", new Error("defaultMcpInstall beginning"));
48
50
  try {
49
51
  defaultMcpInstall();
50
52
  } catch (e) {
51
- globalThis.__loomTrace?.("mcp-install-failed", e);
53
+ globalThis.__loomTrace("mcp-install-failed", e);
52
54
  }
53
55
 
54
56
  if (printMode) {
@@ -62,11 +64,11 @@ if (printMode) {
62
64
  process.exit(resp.type === "error" ? 1 : 0);
63
65
  }
64
66
 
65
- globalThis.__loomTrace?.("render-start");
67
+ globalThis.__loomTrace("render-start", new Error("pre-render"));
66
68
  render(() => <App initialPrompt={initialPrompt} resumeSession={sessionId} autoMode={autoMode} />, {
67
69
  targetFps: 60,
68
70
  useMouse: true,
69
71
  autoFocus: true,
70
72
  exitOnCtrlC: false,
71
73
  });
72
- globalThis.__loomTrace?.("render-returned");
74
+ globalThis.__loomTrace("render-returned", new Error("post-render"));