scalix 1.5.1 → 1.6.0
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/.env.example +5 -3
- package/CHANGELOG.md +40 -0
- package/LICENSE +0 -1
- package/README.md +91 -3
- package/dist/agent-presets.js +33 -0
- package/dist/agent.js +372 -43
- package/dist/api-client.js +64 -5
- package/dist/board-context.js +81 -0
- package/dist/browser-access.js +0 -0
- package/dist/cli.js +397 -45
- package/dist/cloud.js +1 -1
- package/dist/command-sandbox.js +146 -0
- package/dist/commands.js +18 -6
- package/dist/config.js +44 -5
- package/dist/constants.js +90 -11
- package/dist/context-builder.js +9 -1
- package/dist/cost-tracker.js +1 -1
- package/dist/feedback.js +51 -0
- package/dist/headless.js +43 -9
- package/dist/ipc-server.js +371 -110
- package/dist/keychain.js +34 -9
- package/dist/marketplace.js +400 -0
- package/dist/mcp.js +498 -29
- package/dist/openrouter-oauth.js +149 -0
- package/dist/project-index.js +46 -23
- package/dist/providers/index.js +21 -4
- package/dist/sandbox.js +115 -27
- package/dist/secure-fetch.js +117 -0
- package/dist/sessions.js +12 -0
- package/dist/settings.js +193 -44
- package/dist/slash-commands.js +8 -0
- package/dist/sub-agent.js +6 -2
- package/dist/tools-browser.js +95 -18
- package/dist/tools-extra.js +101 -7
- package/dist/tools-memory.js +74 -0
- package/dist/tools-web.js +92 -28
- package/dist/tools.js +99 -23
- package/dist/workspace-trust.js +11 -1
- package/dist/worktree.js +24 -5
- package/package.json +5 -3
package/.env.example
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Required — your Scalix API key
|
|
2
|
-
SCALIX_API_KEY=
|
|
2
|
+
SCALIX_API_KEY=scalix_sk_...
|
|
3
3
|
|
|
4
|
-
# Optional —
|
|
5
|
-
#
|
|
4
|
+
# Optional — API base URL. This is the host root, NOT the /v1 endpoint: the
|
|
5
|
+
# client appends /v1/ai/... itself. Point it at a self-hosted gateway if you
|
|
6
|
+
# have one; the default is Scalix cloud.
|
|
7
|
+
# SCALIX_BASE_URL=https://api.scalix.world
|
|
6
8
|
|
|
7
9
|
# Optional — override the default model
|
|
8
10
|
# SCALIX_MODEL=
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Scalix Coder will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.6.0] - 2026-11-11
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **`/marketplace` — the Scalix curated plugin catalog.** Browse, inspect and install catalog listings from the TUI: MCP servers into `mcp-services.json`, skills into `.scalix/skills/`, rules into `.scalix/rules/`, subagents into `.scalix/agents/`. Every listing is re-validated client-side before anything touches disk (https-only public-host remote entries, bare stdio command names, relative file paths, env-var names only — never credential values), stdio installs require explicit confirmation, and install telemetry is best-effort and anonymous. New module `src/marketplace.ts`; 21 unit tests.
|
|
9
|
+
|
|
10
|
+
### Security
|
|
11
|
+
- **Repo-supplied slash commands are trust-gated and run with a sanitized environment.** `.scalix/commands/*.md` templates were loaded in every front end without the workspace-trust check that plugins and hooks get, and their `` !`cmd` `` inline-bash expansions executed with the full parent environment — API keys readable. Inline bash now runs with `sanitizeEnvForCommand()`, loading is gated on `isWorkspaceTrusted()` (with a skip notice), and a repo carrying `commands/` now triggers the trust prompt. (Audit F1)
|
|
12
|
+
- **`browser_session_save` / `restore` reject traversal names.** The `name` argument became a filename via `path.join` without validation, so `../../..` wrote and read JSON outside the sandbox. Names are now restricted to `[A-Za-z0-9._-]` at the schema and in `saveSessionState`. (F2)
|
|
13
|
+
- **`search_files` ripgrep fast path is sandbox-contained.** The rg branch took any absolute `path` and read it; the JS fallback already validated. The target now goes through `sandboxPath()` before any backend runs, with rg output relativized to preserve the old shape. (F3)
|
|
14
|
+
- **Project `settings.local.json` can no longer escalate permissions.** A trusted repo could set `permissionMode: "yolo"`, reclassify tools via `toolOverrides`, disable blocklist/injection patterns, or add scoped "allow" rules. Project files may now only tighten: `plan` mode, deny-only scoped rules, and a whitelist of tightening security fields; escalation attempts are ignored with a notice. Managed settings (`managed-settings.json`) are now validated with the same validators as user config. (F4)
|
|
15
|
+
- **`@file` prompt references are sandbox-contained.** `@/abs/path.ext` in a prompt read any file on disk in the TUI and was attacker-influenceable via `--pipe`; both `agent.ts` and `commands.ts` expansion now route through the sandbox check. (F5)
|
|
16
|
+
- **Alibaba Cloud metadata IP `100.100.100.200` is treated as private** by `web_fetch` and the browser tools — it sits outside every previously-listed range and exposed instance credentials on ECS. (F9)
|
|
17
|
+
- MCP `serverUrl` values are redacted (userinfo stripped) before logging; MCP fetch now downgrades 301/302/303 redirects of POST requests to GET and drops the body per the fetch spec. (F12 + redirect semantics)
|
|
18
|
+
- IPC `setPermissionMode` validates the mode against `PERMISSION_MODES` instead of applying any string. (F14)
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **A user abort no longer pollutes the model circuit breaker.** Aborting mid-request was recorded as a model failure — five Escapes within the reset window silently rotated the model. The abort path now returns `'[interrupted]'` consistently whether it lands between tool calls or mid-request. (Audit: agent abort contract)
|
|
22
|
+
- **Retry backoff, stream-fallback waits, and tool-confirmation prompts are abort-aware.** Cancelling during a Retry-After wait (up to 60s) or a pending confirmation (up to 300s) returns immediately instead of parking the loop.
|
|
23
|
+
- **Conflicted sub-agent worktree merges keep their branch.** Teardown ran `git branch -D` unconditionally, destroying the sub-agent's unmerged commits right after reporting the conflict; removal now uses a safe delete and keeps unmerged `scalix-agent/*` branches for recovery. A failed merge probe is reported as a failure (with `error`) instead of `{merged: true, commitCount: 0}`.
|
|
24
|
+
- **`/delegate` works on BYOK sessions.** The headless sub-agent config omitted `provider` (and cloud credentials), so the sub-agent called the Scalix URL shape against a third-party base URL and 404'd on every request.
|
|
25
|
+
- **Per-request timeout defaults to 300s.** The comment promised it but unset `SCALIX_REQUEST_TIMEOUT_MS` meant *no* timeout; a wedged connection hung the turn forever.
|
|
26
|
+
- The capability probe (`streamsToolCalls`) can no longer fail a turn — errors default to the conservative non-streaming answer.
|
|
27
|
+
- `clearHistory()` / `loadMessages()` reset the output-format instruction index, so a `/load` followed by a JSON-format request can no longer overwrite an unrelated system message.
|
|
28
|
+
- Streaming TTFT and per-turn metrics reset each loop iteration, so `turn:summary` reports the turn that produced the final response.
|
|
29
|
+
- `scalix run` no longer double-prints errors (REPORTED_ERROR dedup applied to headless).
|
|
30
|
+
|
|
31
|
+
### VS Code extension
|
|
32
|
+
- **Fixed the send dead-latch.** The chat panel set the tab's `isRunning` flag before reading it, so the direct-send branch was dead code: every message queued as "Queued: …" and was only released when an unrelated engine status event arrived.
|
|
33
|
+
- **Chat tabs stay in sync with the engine.** Switching tabs now posts `switchSession` (the host previously kept sending to the previous tab's session, and background-tab streams were dropped); `send`/`abort` honor the message's own `sessionId` with the host value as fallback. Queued messages now carry their images through the queue.
|
|
34
|
+
- **Feedback is actually stored.** The submit-feedback flow thanked the user and discarded everything; it now records through `FeedbackService` (local history, capped at 100 — nothing leaves the machine).
|
|
35
|
+
- **Tool-approval handler cleanup on dispose.** With a sidebar and an editor-tab chat open, closing the editor tab left its dead confirm handler registered, so in-panel approvals silently stopped for the surviving surface.
|
|
36
|
+
- `scalix.cliPath`, `scalix.baseUrl`, `scalix.openaiBaseUrl`, `scalix.provider`, and `scalix.permissionMode` are now machine-scoped — a repo's `.vscode/settings.json` can no longer point the engine spawn at arbitrary code or redirect the API key's destination endpoint.
|
|
37
|
+
|
|
38
|
+
### Known issues (from the 2026-10-14 audit, not yet addressed)
|
|
39
|
+
- The webview's per-tab `innerHTML` cache destroys event listeners on restored tabs (dead confirm-card buttons after a tab round-trip) — needs the data-driven re-render refactor.
|
|
40
|
+
- Background-tab stream events are still dropped rather than buffered per session.
|
|
41
|
+
- The OS command sandbox (seatbelt/bwrap) remains opt-in and default-off; the regex command blocklist is explicitly not a security boundary.
|
|
42
|
+
- DNS-rebinding TOCTOU remains in `web_fetch`/MCP fetch (validation and fetch resolve DNS independently).
|
|
43
|
+
- `vscode-extension/tests` are still not wired into either publish workflow.
|
|
44
|
+
|
|
5
45
|
## [1.5.1] - 2026-08-08
|
|
6
46
|
|
|
7
47
|
### Added
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
AI-powered coding agent for the terminal and [VS Code](https://marketplace.visualstudio.com/items?itemName=scalix.scalix) — built by [Scalix World](https://scalix.world).
|
|
4
4
|
|
|
5
|
-
](https://www.npmjs.com/package/scalix)
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
@@ -61,12 +61,28 @@ Notes:
|
|
|
61
61
|
|
|
62
62
|
### Install
|
|
63
63
|
|
|
64
|
+
```bash
|
|
65
|
+
npm install -g scalix
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Requires Node 18 or newer. If `npm install -g` needs `sudo` on your machine, that
|
|
69
|
+
is a sign npm's global prefix points somewhere root-owned — point it at your home
|
|
70
|
+
directory (`npm config set prefix ~/.npm-global`) rather than installing as root.
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary>From source (contributors)</summary>
|
|
74
|
+
|
|
75
|
+
The repository is private; you need access before this will clone.
|
|
76
|
+
|
|
64
77
|
```bash
|
|
65
78
|
git clone https://github.com/scalixworld/scalix-coder.git && cd scalix-coder
|
|
66
79
|
npm install
|
|
67
|
-
|
|
80
|
+
npm run build
|
|
81
|
+
npm link
|
|
68
82
|
```
|
|
69
83
|
|
|
84
|
+
</details>
|
|
85
|
+
|
|
70
86
|
### Run
|
|
71
87
|
|
|
72
88
|
```bash
|
|
@@ -83,6 +99,7 @@ First launch opens a setup wizard to configure your Scalix API key, endpoint, an
|
|
|
83
99
|
| `SCALIX_MODEL` | Comma-separated model IDs |
|
|
84
100
|
| `SCALIX_BASE_URL` | API base URL |
|
|
85
101
|
| `SCALIX_PROJECT` | Project ID for org-wide keys (sent as `x-scalix-project` on platform tool calls) |
|
|
102
|
+
| `SCALIX_COMMAND_SANDBOX` | OS-level command sandbox: `off` \| `filesystem` \| `strict` (overrides config) |
|
|
86
103
|
| `BRAVE_API_KEY` | Brave Search API key |
|
|
87
104
|
| `TAVILY_API_KEY` | Tavily Search API key |
|
|
88
105
|
|
|
@@ -106,6 +123,7 @@ scalix run "generate a migration" --output migration.sql --format patch
|
|
|
106
123
|
| `/models` | List active models |
|
|
107
124
|
| `/model` | Switch model |
|
|
108
125
|
| `/mode` | Set permission mode |
|
|
126
|
+
| `/sandbox` | Set the OS command sandbox (off \| filesystem \| strict) |
|
|
109
127
|
| `/compact` | Compress context |
|
|
110
128
|
| `/cost` | Token usage & cost |
|
|
111
129
|
| `/budget` | Budget status |
|
|
@@ -208,7 +226,9 @@ scalix run "generate a migration" --output migration.sql --format patch
|
|
|
208
226
|
| `notebook_edit` | Jupyter notebook operations |
|
|
209
227
|
| `monitor` | Background process output |
|
|
210
228
|
| `agent` | Spawn sub-agents |
|
|
211
|
-
| `
|
|
229
|
+
| `write_artifact` | Write a reviewable plan / walkthrough / tasklist / summary to `.scalix/artifacts/` |
|
|
230
|
+
| `list_artifacts` | List previously written artifacts (newest first) |
|
|
231
|
+
| `add_mcp_server` | Register MCP servers |
|
|
212
232
|
|
|
213
233
|
## Configuration
|
|
214
234
|
|
|
@@ -239,6 +259,74 @@ Config is stored in `~/.scalix-coder/config.json`.
|
|
|
239
259
|
| `.scalix/rules/*.md` | Scoped rules |
|
|
240
260
|
| `mcp-services.json` | MCP server config |
|
|
241
261
|
|
|
262
|
+
### Command sandbox (opt-in)
|
|
263
|
+
|
|
264
|
+
`run_command` can execute inside a kernel-enforced sandbox — the OS-level wall
|
|
265
|
+
behind the logical checks (blocklist, injection detection, path containment).
|
|
266
|
+
Set `commandSandbox` in `~/.scalix-coder/config.json` (or `SCALIX_COMMAND_SANDBOX`):
|
|
267
|
+
|
|
268
|
+
| Mode | What it does |
|
|
269
|
+
| ------------ | ------------ |
|
|
270
|
+
| `off` | Default. No sandbox — behaviour unchanged. |
|
|
271
|
+
| `filesystem` | macOS seatbelt / Linux bubblewrap: writes confined to the workspace + system temp, reads unrestricted, network allowed. |
|
|
272
|
+
| `strict` | `filesystem` plus no network (unshared netns / seatbelt `deny network*`). For untrusted builds. |
|
|
273
|
+
|
|
274
|
+
Notes: Windows is not supported — with a mode set there, commands fail closed
|
|
275
|
+
with the reason instead of running unsandboxed. Package managers that cache in
|
|
276
|
+
`$HOME` (pip, cargo) will fail cache writes in `filesystem` mode; that is the
|
|
277
|
+
wall working. The backend binary must exist (`sandbox-exec` on macOS ships with
|
|
278
|
+
the OS; `bwrap` must be installed on Linux) — a missing backend is reported,
|
|
279
|
+
never skipped.
|
|
280
|
+
|
|
281
|
+
### MCP servers
|
|
282
|
+
|
|
283
|
+
Servers listed in `mcp-services.json` (project root, or `.scalix/` as a
|
|
284
|
+
fallback) are connected at startup and their tools are offered to the model as
|
|
285
|
+
`mcp__<server>__<tool>`. Both transports are supported:
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"mcpServers": [
|
|
290
|
+
{ "serverLabel": "github", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
|
|
291
|
+
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_…" } },
|
|
292
|
+
{ "serverLabel": "docs", "serverUrl": "https://docs.example.com/mcp", "authorizationEnv": "DOCS_TOKEN" }
|
|
293
|
+
]
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
The Claude Desktop / VS Code object-map dialect (`"mcpServers": {"github": {…}}`)
|
|
298
|
+
is accepted too, so an existing config can be dropped in unchanged.
|
|
299
|
+
|
|
300
|
+
- `disabled: true` skips an entry without deleting it; `allowedTools.toolNames`
|
|
301
|
+
registers only the named tools from that server.
|
|
302
|
+
- A server that fails to start is logged and skipped — it never takes the run
|
|
303
|
+
down with it. `/mcp` lists the status of each.
|
|
304
|
+
- **Command (stdio) servers only start in a trusted workspace**, because
|
|
305
|
+
spawning one runs arbitrary local code. They get a clean environment, not the
|
|
306
|
+
agent's, so they cannot read its API keys.
|
|
307
|
+
- MCP tools are external, so they require confirmation under the default
|
|
308
|
+
permission mode.
|
|
309
|
+
|
|
310
|
+
### Scalix Marketplace (`/marketplace`)
|
|
311
|
+
|
|
312
|
+
Browse the curated plugin catalog and install it in one command:
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
/marketplace featured listings
|
|
316
|
+
/marketplace <query> search the catalog
|
|
317
|
+
/marketplace info <id> detail + what an install would write
|
|
318
|
+
/marketplace install <id> install (stdio MCP needs `--confirm`)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Four artifact kinds are installed into this workspace: **MCP servers**
|
|
322
|
+
(`mcp-services.json`), **skills** (`.scalix/skills/<name>/`), **rules**
|
|
323
|
+
(`.scalix/rules/`) and **subagents** (`.scalix/agents/`). Every listing carries
|
|
324
|
+
a trust tier — ★ official, ✔ verified, · community — and an env-var reference
|
|
325
|
+
is stored by NAME only (you set the value in your environment). The catalog is
|
|
326
|
+
fetched from `https://api.scalix.world/v1/marketplace` (override with
|
|
327
|
+
`SCALIX_MARKETPLACE_URL`); payloads are re-validated before anything is
|
|
328
|
+
written to disk. Full contract: `scalix-cloud/docs/MARKETPLACE.md`.
|
|
329
|
+
|
|
242
330
|
## VS Code Extension
|
|
243
331
|
|
|
244
332
|
Install from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=scalix.scalix) — or from [Open VSX](https://open-vsx.org/extension/scalix/scalix) if you use Cursor, Windsurf, or VSCodium:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const AGENT_PRESETS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'cloud-architect',
|
|
4
|
+
name: 'Cloud Architect',
|
|
5
|
+
description: 'Full Scalix Cloud tools access with architecture-first planning',
|
|
6
|
+
systemPromptAdditions: 'You are an expert Scalix Cloud Architect. Prioritize robust, scalable infrastructure. Plan changes carefully.',
|
|
7
|
+
permissionMode: 'default'
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: 'dba',
|
|
11
|
+
name: 'Database Administrator',
|
|
12
|
+
description: 'Focused on database migrations and SQL optimization',
|
|
13
|
+
systemPromptAdditions: 'You are a Senior DBA. Prioritize data integrity and query performance. Always verify schemas before altering.',
|
|
14
|
+
permissionMode: 'default'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 'devops',
|
|
18
|
+
name: 'DevOps Engineer',
|
|
19
|
+
description: 'CI/CD, deployments, and infrastructure management',
|
|
20
|
+
systemPromptAdditions: 'You are a DevOps engineer focused on CI/CD pipelines, containerization, and safe deployments.',
|
|
21
|
+
permissionMode: 'default'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'full-access',
|
|
25
|
+
name: 'Full Access (Auto)',
|
|
26
|
+
description: 'All tools enabled, autonomous execution mode',
|
|
27
|
+
systemPromptAdditions: 'You are fully autonomous. Execute the required steps directly.',
|
|
28
|
+
permissionMode: 'auto'
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
export function getPreset(id) {
|
|
32
|
+
return AGENT_PRESETS.find(p => p.id === id);
|
|
33
|
+
}
|