loom-agent 1.2.37 → 1.3.2

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/CHANGELOG.md CHANGED
@@ -6,7 +6,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased] — completion harness, specialist agents, headless browser, TUI refresh
8
8
 
9
+ ### Security
10
+ - **All dependency advisories cleared — `npm audit` reports 0
11
+ vulnerabilities** (was 7: 4 critical, 1 high, 2 low):
12
+ - `@opentui/solid` / `@opentui/core` (+ all platform binaries)
13
+ 0.5.3 → **0.5.17** — fixes the `@babel/core` arbitrary-file-read
14
+ advisory and the `solid-js`/`seroval` critical chain.
15
+ - `seroval` + `seroval-plugins` forced to **1.6.9** via npm `overrides`
16
+ (solid-js is peer-pinned to 1.9.12 by @opentui/solid; 1.6.9 is exactly
17
+ the seroval line solid 1.9.17 itself moved to — fixes the critical
18
+ `fromJSON()` thenable-assimilation + memory-exhaustion advisories).
19
+ - `shell-quote` **removed** — it was an unused direct dependency carrying
20
+ a critical `quote()` command-injection advisory.
21
+ - `diff` ^7 → **^9.0.0** (we only use `diffLines`, unchanged; 9.x ships
22
+ CJS exports) — fixes the parsePatch/applyPatch DoS advisory.
23
+ - `brace-expansion` re-resolved to **5.0.12** (transitive, via
24
+ `npm audit fix`) — fixes the DoS/recursion advisories.
25
+
9
26
  ### Added
27
+ - **Docker sandbox with a guided `/sandbox` wizard (`src/core/sandbox.js`,
28
+ `SandboxModal`).** `/sandbox` (or `/sandbox setup`) opens a three-step
29
+ modal: (1) Docker check — if missing, shows the platform install link with
30
+ an "open download page" action and remembers the pending install; (2) OS
31
+ pick — Alpine (~250 MB, apk), Debian Slim (~600 MB, apt) or Ubuntu
32
+ (~900 MB, apt); (3) live build with streamed logs. Setup pulls the chosen
33
+ `node:20-*` image, creates the single shared `loom-sandbox` container with
34
+ the project mounted at `/workspace`, installs essentials (git, bash, curl,
35
+ ripgrep, coreutils) plus a headless Chromium where offered (best-effort).
36
+ The container is global — every session and every agent routes commands
37
+ through it — and `ensureProjectMount()` re-creates it cheaply when the
38
+ active project changes. Isolation: project dir only, no host network, no
39
+ `--privileged`. The bash tool routes through `docker exec` when enabled;
40
+ `LOOM_SANDBOX=0` is a hard kill-switch. Saying "docker is ready" after
41
+ installing reopens the wizard at the OS step.
10
42
  - **Drive-to-completion harness (`src/core/session.js`).** When the model ends
11
43
  a turn with todos still pending/in_progress (the "stops between tasks"
12
44
  failure), the loop injects a continuation listing the unfinished items — up
@@ -31,7 +63,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
63
  Chrome/Edge. The page singleton persists across calls. Permissions: passive
32
64
  reads allow, interactive click/fill/press ask.
33
65
 
66
+ ### Fixed
67
+ - **Agent loop no longer stops in the middle of work** (`src/core/session.js`
68
+ continuation guards — opencode/Claude-Code parity):
69
+ - **Truncation auto-continue.** `finish_reason=length` (output budget
70
+ exhausted — the #1 cause of mid-task stops with reasoning models, where
71
+ thinking eats max_tokens and the answer never streams) now continues
72
+ the turn with a "continue exactly from where it stopped" nudge instead
73
+ of dead-ending with a placeholder — up to 5 continuations per turn.
74
+ Empty truncated replies also drop the empty assistant row from history
75
+ (Anthropic 400s on empty assistant messages, which silently killed
76
+ subsequent calls).
77
+ - **Empty-reply nudges raised 1 → 3 per turn** (provider hiccups repeat).
78
+ - **Premature-wrap-up detection broadened.** The drive guard now also
79
+ fires when tools ran, todos exist, and the reply LOOKS unfinished
80
+ (short, or ends on a promise like "Now I will…") — catching models that
81
+ never call todowrite. Drive nudges raised 5 → 8 per turn. Leftover
82
+ todos are surfaced to the UI whenever the guard engaged.
83
+
34
84
  ### Changed
85
+ - **Slash popup decluttered.** The autocomplete popup and command palette
86
+ now show a short one-line description per command — argument syntax is no
87
+ longer appended (it lives in `/help` and the README table). Duplicate
88
+ entries were removed from the picker while their handlers stay callable:
89
+ `/model` → `/models`, `/thinking` + `/details` → `/settings`, `/rewind`
90
+ → `/restore` (40 → 36 entries). Every desc was shortened to ~2–35 chars
91
+ so rows fit on one clean line. README table regenerated from the real
92
+ list (it previously advertised commands that no longer exist).
35
93
  - **TUI design overhaul.** The splash leads with the full LOOM CODE wordmark
36
94
  in solid terracotta over a separator rule and a pill-style status
37
95
  row; the default "Loom Dark" (and Light) palettes got deeper surface
@@ -56,6 +114,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
56
114
  with the actual items; the interrupt line reports kept chars + the
57
115
  in-progress todo; the plan-complete line includes the planned step count;
58
116
  "(no response)"/"(interrupted)" placeholders describe what happened.
117
+ - **Sessions now live in per-session folders inside the project**
118
+ (claude-code/opencode style): `<project>/.loom/sessions/<id>/session.json`
119
+ (metadata) + `messages.jsonl` (one message per line, append/rewrite-safe).
120
+ Old flat `~/.loom/sessions/<id>.json` files stay readable and are migrated
121
+ into the project folder on the next save; the /sessions picker merges both.
122
+
123
+ ### Fixed
124
+ - **Resuming a session 400'd the next turn** (`NVIDIA error 400: missing
125
+ field tool_call_id`). The resume path rebuilt the in-memory message list
126
+ from `{role, content, toolCalls}` only — dropping `toolCallId` — so the
127
+ provider payload carried a tool row with no id. Resume now preserves
128
+ `toolCallId` (and aliases legacy snake_case `tool_calls`/`tool_call_id`
129
+ on load); both providers also skip orphaned tool rows defensively instead
130
+ of failing the turn.
131
+ - **"The model ended the turn without any text" now says why when it knows.**
132
+ `finish_reason` is captured from the stream; a truncated reply (reasoning
133
+ ate the output budget) reports that instead of a mystery placeholder.
59
134
 
60
135
  ## [1.2.36] — fix `loom web` / `loom acp` / `loom attach`
61
136
 
package/README.md CHANGED
@@ -128,44 +128,51 @@ Zed (add to `~/.config/zed/settings.json`, then Command Palette → `agent: new
128
128
  Full transport spec, JetBrains/Neovim configs, the protocol walkthrough, and a
129
129
  self-test client (`node scripts/acp-smoke.js`) live in **[docs/acp.md](docs/acp.md)**.
130
130
 
131
- ## Slash Commands (35 total)
131
+ ## Slash Commands (36 total)
132
132
 
133
133
  | Command | Args | Description |
134
134
  |---------|------|-------------|
135
- | `/help` | — | Show all commands |
136
- | `/build` | — | Build mode — all tools |
137
- | `/plan` | — | Plan mode — read-only analysis |
135
+ | `/help` | — | Show help |
136
+ | `/agents` | — | List agents |
137
+ | `/build` | — | Build mode — full tools |
138
+ | `/plan` | — | Plan mode — read only |
138
139
  | `/chat` | — | Chat mode — no tools |
139
- | `/agents` | — | List primary agents and subagents |
140
- | `/connect` | `[provider]` | Add/connect a provider |
141
- | `/key` | — | Edit API key for current provider |
140
+ | `/connect` | `[provider]` | Connect a provider |
141
+ | `/key` | — | Edit API key |
142
142
  | `/baseurl` | `[provider] [url]` | Set provider base URL |
143
- | `/model` | `[model-id]` | Pick active model |
144
- | `/models` | — | List available models |
145
- | `/providers` | — | List supported providers |
146
- | `/status` | — | Show connection status |
147
- | `/usage` | — | Show token usage and billing |
148
- | `/new` | — | Start a new session |
143
+ | `/models` | — | Model picker |
144
+ | `/providers` | — | List providers |
145
+ | `/status` | — | Connection status |
146
+ | `/usage` | — | Token usage & billing |
147
+ | `/budget` | `free\|cheap\|best\|auto` | Budget level |
148
+ | `/new` | — | New session |
149
149
  | `/clear` | — | Clear the chat |
150
- | `/compact` | — | Compact conversation |
151
- | `/undo` | — | Undo last exchange |
152
- | `/redo` | — | Redo last undone exchange |
153
- | `/reset` | — | Reset the session |
154
- | `/settings` | — | Toggle details/sidebar/etc. |
150
+ | `/restore` | — | Restore earlier state |
151
+ | `/settings` | — | Settings — details, thinking, sidebar |
155
152
  | `/sessions` | — | Browse saved sessions |
156
- | `/share` | — | Export current session to JSON |
157
- | `/export` | — | Export to markdown |
158
- | `/thinking` | — | Toggle thinking visibility |
159
- | `/details` | — | Toggle tool detail visibility |
160
- | `/init` | — | Create LOOM.md |
161
- | `/memory` | — | Show memory files |
162
- | `/doctor` | — | Run diagnostics |
153
+ | `/theme` | — | Switch UI theme |
154
+ | `/graph` | — | Memory graph |
163
155
  | `/skills` | `install\|remove` | Manage skills |
164
156
  | `/mcp` | `add\|remove\|toggle` | Manage MCP servers |
165
- | `/debug` | — | Show debug info |
166
- | `/fork` | — | Fork conversation |
157
+ | `/connectors` | `add\|remove\|toggle` | Manage connectors |
158
+ | `/permissions` | `reset\|auto` | Permission rules |
159
+ | `/subagents` | — | Subagent runs |
160
+ | `/context` | — | Context window usage |
161
+ | `/think` | `off\|low\|medium\|high` | Thinking budget |
162
+ | `/approve` | — | Approve plan → Build |
163
+ | `/tasks` | — | Background tasks |
164
+ | `/share` | — | Export chat as HTML |
165
+ | `/worktree` | `<name>` | New git worktree |
166
+ | `/sandbox` | `setup\|status\|on\|off\|rm` | Docker sandbox |
167
+ | `/style` | `[preset\|text]` | Output style preset |
168
+ | `/vim` | — | Toggle vim editing |
169
+ | `/remember` | `<fact>` | Save a fact to LOOM.md |
167
170
  | `/exit` | — | Quit Loom Code |
168
171
 
172
+ Aliases still work when typed but are hidden from the picker to keep it
173
+ clean: `/model` → `/models`, `/thinking` + `/details` → `/settings`,
174
+ `/rewind` → `/restore`.
175
+
169
176
  ## Keybindings
170
177
 
171
178
  Every key is configurable from `~/.loom/tui.json` (`keybinds`, `leader`,
package/package.json CHANGED
@@ -1,125 +1,126 @@
1
- {
2
- "name": "loom-agent",
3
- "version": "1.2.37",
4
- "repository": {
5
- "type": "git",
6
- "url": "git+https://github.com/toshalkumbhar8979-design/loomcode.git"
7
- },
8
- "homepage": "https://github.com/toshalkumbhar8979-design/loomcode#readme",
9
- "bugs": {
10
- "url": "https://github.com/toshalkumbhar8979-design/loomcode/issues"
11
- },
12
- "description": "Loom Code — AI-powered coding agent for the terminal. Multi-provider support including NVIDIA. OpenTUI interface.",
13
- "main": "src/index.js",
14
- "publishConfig": {
15
- "access": "public",
16
- "tag": "latest"
17
- },
18
- "bin": {
19
- "loom": "bin/loom-bun.js",
20
- "loom-tui": "bin/loom-tui.js"
21
- },
22
- "scripts": {
23
- "start": "node src/index.js",
24
- "dev": "node --watch src/index.js",
25
- "setup": "node src/setup.js",
26
- "test": "bun run src/tui/test-interactive.tsx && bun run test:unit && bun run lint:core",
27
- "test:unit": "bun test src/core/agents.test.js src/core/hooks.test.js src/core/custom-commands.test.js src/core/background-tasks.test.js src/core/memory.test.js src/core/subagent-log.test.js src/core/session.test.js src/tools/index.test.js src/tools/security.test.js src/providers/providers.test.js src/providers/caching.test.js src/providers/caching-thinking.test.js src/providers/registry.test.js src/mcp/mcp-client.test.js src/mcp/mcp-manager.test.js src/core/session-store.test.js src/skills/skills-manager.test.js src/core/usage.test.js src/core/permissions.test.js src/core/format.test.js src/acp/acp-server.test.js src/tui/keybinds.test.ts",
28
- "lint:core": "node node_modules/typescript/bin/tsc -p tsconfig.core.json",
29
- "smoke:acp": "node scripts/acp-smoke.js",
30
- "tui": "bun bin/loom-tui.js",
31
- "tui:win": "\"%USERPROFILE%\\..\\bun\\bin\\bun.exe\" run src/tui-open.tsx",
32
- "prepublishOnly": "npm test",
33
- "postinstall": "node scripts/postinstall.js",
34
- "lint": "tsc --noEmit"
35
- },
36
- "dependencies": {
37
- "@anthropic-ai/sdk": "^0.120.0",
38
- "@opentui/core": "0.5.3",
39
- "@opentui/solid": "0.5.3",
40
- "@shikijs/themes": "4.4.3",
41
- "@supabase/supabase-js": "^2.45.0",
42
- "boxen": "^8.0.0",
43
- "chalk": "^5.3.0",
44
- "cli-spinners": "^3.2.0",
45
- "commander": "^12.1.0",
46
- "convex": "^1.14.0",
47
- "dayjs": "^1.11.0",
48
- "diff": "^7.0.0",
49
- "dotenv": "^16.4.0",
50
- "glob": "^13.0.6",
51
- "inquirer": "^12.1.0",
52
- "openai": "^5.23.2",
53
- "ora": "^8.0.0",
54
- "playwright-core": "^1.64.1",
55
- "shell-quote": "^1.8.1",
56
- "solid-js": "1.9.12",
57
- "strip-ansi": "^7.1.0",
58
- "tiktoken": "^1.0.22",
59
- "uuid": "^11.0.0",
60
- "wrap-ansi": "^9.0.0"
61
- },
62
- "optionalDependencies": {
63
- "@opentui/core-darwin-arm64": "0.5.3",
64
- "@opentui/core-darwin-x64": "0.5.3",
65
- "@opentui/core-linux-arm64": "0.5.3",
66
- "@opentui/core-linux-x64": "0.5.3",
67
- "@opentui/core-win32-x64": "0.5.3",
68
- "@oven/bun-darwin-aarch64": "1.3.14",
69
- "@oven/bun-darwin-x64": "1.3.14",
70
- "@oven/bun-linux-aarch64": "1.3.14",
71
- "@oven/bun-linux-x64": "1.3.14",
72
- "@oven/bun-windows-aarch64": "1.3.14",
73
- "@oven/bun-windows-x64": "1.3.14"
74
- },
75
- "overrides": {
76
- "glob": "^13.0.6"
77
- },
78
- "devDependencies": {
79
- "@types/bun": "^1.2.0",
80
- "typescript": "^5.7.3"
81
- },
82
- "files": [
83
- "bunfig.toml",
84
- "tsconfig.json",
85
- "bin/loom-bun.js",
86
- "bin/loom.js",
87
- "bin/loom-tui.js",
88
- "src/**/*.js",
89
- "src/**/*.tsx",
90
- "src/**/*.ts",
91
- "!src/**/test-*",
92
- "!src/**/*.test.*",
93
- "!src/test-loop.js",
94
- "!src/test-tools.js",
95
- "README.md",
96
- "CHANGELOG.md",
97
- "LICENSE",
98
- ".env.example",
99
- "LOOM.md",
100
- "docs/acp.md",
101
- "scripts/acp-smoke.js",
102
- "scripts/postinstall.js"
103
- ],
104
- "keywords": [
105
- "ai",
106
- "cli",
107
- "coding-agent",
108
- "loom-code",
109
- "anthropic",
110
- "openai",
111
- "nvidia",
112
- "terminal",
113
- "opentui"
114
- ],
115
- "engines": {
116
- "node": ">=18.0.0",
117
- "bun": ">=1.0.0"
118
- },
119
- "directories": {
120
- "doc": "docs"
121
- },
122
- "author": "",
123
- "license": "MIT",
124
- "type": "commonjs"
125
- }
1
+ {
2
+ "name": "loom-agent",
3
+ "version": "1.3.2",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/toshalkumbhar8979-design/loomcode.git"
7
+ },
8
+ "homepage": "https://github.com/toshalkumbhar8979-design/loomcode#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/toshalkumbhar8979-design/loomcode/issues"
11
+ },
12
+ "description": "Loom Code — AI-powered coding agent for the terminal. Multi-provider support including NVIDIA. OpenTUI interface.",
13
+ "main": "src/index.js",
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "tag": "latest"
17
+ },
18
+ "bin": {
19
+ "loom": "bin/loom-bun.js",
20
+ "loom-tui": "bin/loom-tui.js"
21
+ },
22
+ "scripts": {
23
+ "start": "node src/index.js",
24
+ "dev": "node --watch src/index.js",
25
+ "setup": "node src/setup.js",
26
+ "test": "bun run src/tui/test-interactive.tsx && bun run test:unit && bun run lint:core",
27
+ "test:unit": "bun test src/core/agents.test.js src/core/hooks.test.js src/core/custom-commands.test.js src/core/background-tasks.test.js src/core/memory.test.js src/core/subagent-log.test.js src/core/session.test.js src/core/sandbox.test.js src/tools/index.test.js src/tools/security.test.js src/providers/providers.test.js src/providers/caching.test.js src/providers/caching-thinking.test.js src/providers/registry.test.js src/mcp/mcp-client.test.js src/mcp/mcp-manager.test.js src/core/session-store.test.js src/skills/skills-manager.test.js src/core/usage.test.js src/core/permissions.test.js src/core/format.test.js src/acp/acp-server.test.js src/tui/keybinds.test.ts",
28
+ "lint:core": "node node_modules/typescript/bin/tsc -p tsconfig.core.json",
29
+ "smoke:acp": "node scripts/acp-smoke.js",
30
+ "tui": "bun bin/loom-tui.js",
31
+ "tui:win": "\"%USERPROFILE%\\..\\bun\\bin\\bun.exe\" run src/tui-open.tsx",
32
+ "prepublishOnly": "npm test",
33
+ "postinstall": "node scripts/postinstall.js",
34
+ "lint": "tsc --noEmit"
35
+ },
36
+ "dependencies": {
37
+ "@anthropic-ai/sdk": "^0.120.0",
38
+ "@opentui/core": "0.5.17",
39
+ "@opentui/solid": "0.5.17",
40
+ "@shikijs/themes": "4.4.3",
41
+ "@supabase/supabase-js": "^2.45.0",
42
+ "boxen": "^8.0.0",
43
+ "chalk": "^5.3.0",
44
+ "cli-spinners": "^3.2.0",
45
+ "commander": "^12.1.0",
46
+ "convex": "^1.14.0",
47
+ "dayjs": "^1.11.0",
48
+ "diff": "^9.0.0",
49
+ "dotenv": "^16.4.0",
50
+ "glob": "^13.0.6",
51
+ "inquirer": "^12.1.0",
52
+ "openai": "^5.23.2",
53
+ "ora": "^8.0.0",
54
+ "playwright-core": "^1.64.1",
55
+ "solid-js": "1.9.12",
56
+ "strip-ansi": "^7.1.0",
57
+ "tiktoken": "^1.0.22",
58
+ "uuid": "^11.0.0",
59
+ "wrap-ansi": "^9.0.0"
60
+ },
61
+ "optionalDependencies": {
62
+ "@opentui/core-darwin-arm64": "0.5.17",
63
+ "@opentui/core-darwin-x64": "0.5.17",
64
+ "@opentui/core-linux-arm64": "0.5.17",
65
+ "@opentui/core-linux-x64": "0.5.17",
66
+ "@opentui/core-win32-x64": "0.5.17",
67
+ "@oven/bun-darwin-aarch64": "1.3.14",
68
+ "@oven/bun-darwin-x64": "1.3.14",
69
+ "@oven/bun-linux-aarch64": "1.3.14",
70
+ "@oven/bun-linux-x64": "1.3.14",
71
+ "@oven/bun-windows-aarch64": "1.3.14",
72
+ "@oven/bun-windows-x64": "1.3.14"
73
+ },
74
+ "overrides": {
75
+ "glob": "^13.0.6",
76
+ "seroval": "1.6.9",
77
+ "seroval-plugins": "1.6.9"
78
+ },
79
+ "devDependencies": {
80
+ "@types/bun": "^1.2.0",
81
+ "typescript": "^5.7.3"
82
+ },
83
+ "files": [
84
+ "bunfig.toml",
85
+ "tsconfig.json",
86
+ "bin/loom-bun.js",
87
+ "bin/loom.js",
88
+ "bin/loom-tui.js",
89
+ "src/**/*.js",
90
+ "src/**/*.tsx",
91
+ "src/**/*.ts",
92
+ "!src/**/test-*",
93
+ "!src/**/*.test.*",
94
+ "!src/test-loop.js",
95
+ "!src/test-tools.js",
96
+ "README.md",
97
+ "CHANGELOG.md",
98
+ "LICENSE",
99
+ ".env.example",
100
+ "LOOM.md",
101
+ "docs/acp.md",
102
+ "scripts/acp-smoke.js",
103
+ "scripts/postinstall.js"
104
+ ],
105
+ "keywords": [
106
+ "ai",
107
+ "cli",
108
+ "coding-agent",
109
+ "loom-code",
110
+ "anthropic",
111
+ "openai",
112
+ "nvidia",
113
+ "terminal",
114
+ "opentui"
115
+ ],
116
+ "engines": {
117
+ "node": ">=18.0.0",
118
+ "bun": ">=1.0.0"
119
+ },
120
+ "directories": {
121
+ "doc": "docs"
122
+ },
123
+ "author": "",
124
+ "license": "MIT",
125
+ "type": "commonjs"
126
+ }