loom-agent 1.2.4 → 1.2.6

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/bin/loom-tui.js CHANGED
@@ -32,6 +32,7 @@ const entry = path.join(__dirname, '..', 'src', 'tui-bootstrap.js');
32
32
  // is restored by the bootstrap shim before app code runs.
33
33
  const pkgRoot = path.join(__dirname, '..');
34
34
  process.env.LOOM_START_CWD = process.cwd();
35
+ process.env.LOOM_BIN_NAME = "loom";
35
36
  const bun = findBun();
36
37
 
37
38
  if (bun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loom-agent",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/toshalkumbhar8979-design/loomcode.git"
package/src/core/cli.js CHANGED
@@ -565,6 +565,7 @@ if (args.includes('--help') || args.includes('-h')) {
565
565
  // LOOM_START_CWD restores the user's project dir in tui-bootstrap.js.
566
566
  const pkgRoot = path.join(__dirname, '..', '..');
567
567
  process.env.LOOM_START_CWD = process.cwd();
568
+ process.env.LOOM_BIN_NAME = "loom";
568
569
  const tuiArgs = [tuiEntry];
569
570
  if (sessionId) tuiArgs.push('-s', sessionId);
570
571
  if (autoMode) tuiArgs.push('--auto');
package/src/tui/App.tsx CHANGED
@@ -87,7 +87,8 @@ export function App(props: { initialPrompt?: string; resumeSession?: string; aut
87
87
  setTimeout(function() {
88
88
  console.log("");
89
89
  console.log(LOOM_LOGO.join("\n"));
90
- console.log(" resume: loomcode -s " + sessionId);
90
+ const binName = process.env.LOOM_BIN_NAME || "loom";
91
+ console.log(" resume: " + binName + " -s " + sessionId);
91
92
  console.log("");
92
93
  process.exit(code);
93
94
  }, 150);
@@ -1505,6 +1506,7 @@ export function App(props: { initialPrompt?: string; resumeSession?: string; aut
1505
1506
  _skillDoneOff = on("turn:end", function(d: any) {
1506
1507
  if (d?.skills?.length) showToast("skill handled: " + d.skills.join(", "), "ok");
1507
1508
  });
1509
+ (globalThis as any).__loomTrace?.("onMount-done");
1508
1510
  });
1509
1511
  onCleanup(function() { persistUi(); if (_skillToastOff) _skillToastOff(); if (_skillDoneOff) _skillDoneOff(); });
1510
1512
 
@@ -7,9 +7,6 @@ export function SplashScreen() {
7
7
  const ui = palette("loom");
8
8
 
9
9
  return (
10
- // Centered like opencode: the whole block (logo + status + chatbox)
11
- // floats mid-screen and grows symmetrically around its center as the
12
- // chatbox lines up.
13
10
  <box flexDirection="column" flexGrow={1} alignItems="center" justifyContent="center" backgroundColor={ui.bg}>
14
11
  <box flexGrow={1} />
15
12
 
@@ -6,7 +6,51 @@
6
6
  // those files ship) and hand the real project directory through
7
7
  // LOOM_START_CWD. This file must stay import-free so the chdir happens
8
8
  // before any Loom module (which may read cwd at import time) executes.
9
+ const fs = require("fs");
10
+ const os = require("os");
11
+ const path = require("path");
12
+
9
13
  if (process.env.LOOM_START_CWD) {
10
14
  try { process.chdir(process.env.LOOM_START_CWD); } catch {}
11
15
  }
16
+
17
+ // Windows consoles default to a legacy codepage where the box-drawing /
18
+ // block glyphs used across the TUI render as "?" garbage, and VT input
19
+ // sequences (arrows, ctrl combos, bracketed paste) may never arrive. Switch
20
+ // both console CPs to UTF-8 before anything renders or reads stdin.
21
+ if (process.platform === "win32") {
22
+ try {
23
+ const { dlopen } = require("bun:ffi");
24
+ const k32 = dlopen("kernel32.dll", {
25
+ SetConsoleOutputCP: { args: ["uint"], returns: "int" },
26
+ SetConsoleCP: { args: ["uint"], returns: "int" },
27
+ });
28
+ k32.symbols.SetConsoleOutputCP(65001);
29
+ k32.symbols.SetConsoleCP(65001);
30
+ } catch {}
31
+ }
32
+
33
+ // Crash black-box: OpenTUI swallows post-render errors, leaving users stuck
34
+ // on the splash with no clue why. Persist every uncaught failure to disk so
35
+ // a frozen TUI can be diagnosed after the fact.
36
+ const crashPath = () => path.join(os.homedir(), ".loom", "tui-crash.log");
37
+ function record(kind, err) {
38
+ try {
39
+ fs.mkdirSync(path.dirname(crashPath()), { recursive: true });
40
+ fs.appendFileSync(
41
+ crashPath(),
42
+ `[${new Date().toISOString()}] ${kind}: ${(err && (err.stack || err.message)) || String(err)}\n`
43
+ );
44
+ } catch {}
45
+ }
46
+ process.on("uncaughtException", (e) => { record("uncaughtException", e); });
47
+ process.on("unhandledRejection", (r) => { record("unhandledRejection", r); });
48
+
49
+ record("boot", new Error(
50
+ `argv=${JSON.stringify(process.argv.slice(1))} cwd=${process.cwd()} ` +
51
+ `startCwd=${process.env.LOOM_START_CWD || "-"} bun=${process.version} ` +
52
+ `node=${process.versions.node || "-"} platform=${process.platform}`
53
+ ));
54
+ if (process.env.LOOM_TUI_TRACE) globalThis.__loomTrace = record;
55
+
12
56
  await import("./tui-open.tsx");
package/src/tui-open.tsx CHANGED
@@ -7,6 +7,21 @@ import { defaultMcpInstall } from "./core/plugin-cmd.js";
7
7
 
8
8
  const args = process.argv.slice(2);
9
9
 
10
+ // Windows: switch both console codepages to UTF-8 so the box-drawing logo
11
+ // and VT input sequences work even when launched without the bootstrap
12
+ // shim (bun run src/tui-open.tsx). No-op elsewhere / if FFI is unavailable.
13
+ if (process.platform === "win32") {
14
+ try {
15
+ const { dlopen } = require("bun:ffi");
16
+ const k32 = dlopen("kernel32.dll", {
17
+ SetConsoleOutputCP: { args: ["uint"], returns: "int" },
18
+ SetConsoleCP: { args: ["uint"], returns: "int" },
19
+ });
20
+ k32.symbols.SetConsoleOutputCP(65001);
21
+ k32.symbols.SetConsoleCP(65001);
22
+ } catch {}
23
+ }
24
+
10
25
  if (args.includes("--version") || args.includes("-v")) {
11
26
  console.log(`loom-code v${import.meta.require("../package.json").version}`);
12
27
  process.exit(0);
@@ -30,7 +45,11 @@ const sessionId = sIdx !== -1 ? args[sIdx + 1] : null;
30
45
  const autoMode = args.includes("--auto") || args.includes("-a");
31
46
  const initialPrompt = args.filter((a, i) => !a.startsWith("-") && (sIdx === -1 || i !== sIdx + 1)).join(" ");
32
47
 
33
- defaultMcpInstall();
48
+ try {
49
+ defaultMcpInstall();
50
+ } catch (e) {
51
+ globalThis.__loomTrace?.("mcp-install-failed", e);
52
+ }
34
53
 
35
54
  if (printMode) {
36
55
  const { Session } = require("./core/session.js");
@@ -43,9 +62,11 @@ if (printMode) {
43
62
  process.exit(resp.type === "error" ? 1 : 0);
44
63
  }
45
64
 
65
+ globalThis.__loomTrace?.("render-start");
46
66
  render(() => <App initialPrompt={initialPrompt} resumeSession={sessionId} autoMode={autoMode} />, {
47
67
  targetFps: 60,
48
68
  useMouse: true,
49
69
  autoFocus: true,
50
70
  exitOnCtrlC: false,
51
71
  });
72
+ globalThis.__loomTrace?.("render-returned");