local-commander-agent 0.3.44 → 0.3.46
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 +13 -0
- package/README.md +14 -14
- package/bin/localcommander.mjs +3 -1
- package/bin/posix.mjs +66 -0
- package/package.json +57 -47
- package/runtime/JobHost.exe +0 -0
- package/runtime/LocalCommanderAgent.exe +0 -0
- package/runtime/OwnerBridge.exe +0 -0
- package/runtime/agent.mjs +584 -237
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Change history
|
|
2
2
|
|
|
3
|
+
## 0.3.46 - 2026-10-22
|
|
4
|
+
|
|
5
|
+
- Simpler setup on macOS and Linux: the approval page opens in your browser by itself, and on a Mac access is one click in a window (Full Access, or Choose Folder). Linux asks one question in the terminal: press Enter for Full Access or type a folder.
|
|
6
|
+
- Fixed: on macOS, updates keep access to the agent's key in the Keychain.
|
|
7
|
+
- Includes everything in 0.3.45.
|
|
8
|
+
|
|
9
|
+
## 0.3.45 - 2026-10-22
|
|
10
|
+
|
|
11
|
+
- New: macOS 14 or later on Apple Silicon, and Linux x64 or arm64 with a systemd user session. Run the same `npx local-commander-agent@latest` in Terminal; npm downloads only the runtime for your computer. Setup pairs the computer, asks what may be used in the terminal, and runs the agent as a background service that starts when you sign in.
|
|
12
|
+
- Fixed: a computer that lost its connection without noticing (after sleep, a network change or a server restart) now reconnects within about three minutes instead of staying offline.
|
|
13
|
+
- Fixed: a request that never reached a sleeping computer no longer keeps one of its execution slots busy; the computer frees it when it reconnects.
|
|
14
|
+
- Includes everything in 0.3.44.
|
|
15
|
+
|
|
3
16
|
## 0.3.44 - 2026-10-22
|
|
4
17
|
|
|
5
18
|
- New: when you set up a computer, the window that asks what may be used now shows the Local Commander account the computer joined. Someone helping you can approve your computer from their own phone with the code you read to them. Continue only if you know that account; Cancel shares nothing.
|
package/README.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# Local Commander Agent
|
|
2
2
|
|
|
3
|
-
**Connect your AI assistant to your
|
|
3
|
+
**Connect your AI assistant to your computer through [Local Commander](https://localcmd.app).** The agent lets an authorized MCP client work with local files, run explicitly approved commands, and access approved localhost services on your paired computer.
|
|
4
4
|
|
|
5
|
-
> **Requires the Local Commander service at https://localcmd.app.** This npm package is its
|
|
5
|
+
> **Requires the Local Commander service at https://localcmd.app.** This npm package is its computer companion, not a standalone MCP server, an offline AI assistant, or a JavaScript SDK. Installing the package alone is not enough: you need a Local Commander account, an approved device pairing, a running agent, an internet connection, and an authorized MCP connection from your AI client. Local management commands such as status and stop do not require the service to be online.
|
|
6
6
|
|
|
7
7
|
[Website and sign-in](https://localcmd.app) ┬╖ [Support](https://localcmd.app/support) ┬╖ [Privacy](https://localcmd.app/privacy)
|
|
8
8
|
|
|
9
9
|
## Before you start
|
|
10
10
|
|
|
11
|
-
Use **Windows 11 x64** and a currently supported Node.js LTS version meeting the package's Node.js 20+ minimum. Node.js/npm are needed to launch `npx`; the installed background agent includes its own Node runtime. You do not need Docker, WSL, a repository checkout, a database, or administrator rights for normal setup. Your AI client must support authenticated remote MCP connections; availability depends on the client and workspace policy.
|
|
11
|
+
Use **Windows 11 x64**, **macOS 14 or later on Apple Silicon**, or **Linux with a systemd user session** (Ubuntu 24.04 x64 or arm64), and a currently supported Node.js LTS version meeting the package's Node.js 20+ minimum. Node.js/npm are needed to launch `npx`; the installed background agent includes its own Node runtime. You do not need Docker, WSL, a repository checkout, a database, or administrator rights for normal setup. Your AI client must support authenticated remote MCP connections; availability depends on the client and workspace policy.
|
|
12
12
|
|
|
13
13
|
## Install and connect
|
|
14
14
|
|
|
15
|
-
1. Open PowerShell or Windows Terminal
|
|
15
|
+
1. Open a terminal as your normal user (PowerShell or Windows Terminal on Windows, Terminal on macOS or Linux) and run:
|
|
16
16
|
|
|
17
17
|
```powershell
|
|
18
18
|
npx local-commander-agent@latest
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
2. The installer opens a browser. Sign in to [Local Commander](https://localcmd.app), check the displayed pairing code, and approve this computer. Approve only a pairing you just started yourself.
|
|
22
|
-
3. Choose access in the local Windows
|
|
22
|
+
3. Choose access in the local window (on Windows and macOS; Linux asks one question in the terminal):
|
|
23
23
|
- **Full access - all connected drives (default):** approve the available drive letters, file reads/writes, installed commands and localhost services at once. There is no folder picker or separate approval for Node.
|
|
24
24
|
- **Selected folders:** choose one folder in the folder picker. It starts read/write; more folders and write permission can be added later.
|
|
25
25
|
|
|
@@ -32,15 +32,15 @@ Use **Windows 11 x64** and a currently supported Node.js LTS version meeting the
|
|
|
32
32
|
|
|
33
33
|
Complete the browser authorization with the same Local Commander account. Device pairing and AI-client authorization are separate steps. For an AI client that runs on this same computer, you can instead use direct local MCP (see "Direct local MCP" below). Do not configure `npx local-commander-agent` itself as a stdio server.
|
|
34
34
|
|
|
35
|
-
You can close the installation terminal. The agent runs in the background and starts when
|
|
35
|
+
You can close the installation terminal. The agent runs in the background and starts when you sign in to this computer. The computer must be awake and online for remote AI tasks. As a first test, ask the connected assistant to list the files in a folder you approved.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
On Windows, installation and update also add `localcommander` to your **user PATH**. Open a new CMD/terminal window, then run `localcommander status`, `localcommander monitor --watch`, or `localcommander logs --follow` from any folder. No global npm installation is needed. The launcher uses your required Node.js installation and an installed copy of the CLI, so clearing npm's cache does not remove the command. Fetch newer releases with `npx local-commander-agent@latest update`. Uninstall removes Local Commander's PATH entry and launcher while preserving your other entries.
|
|
38
38
|
|
|
39
39
|
## Direct local MCP (AI clients on this computer)
|
|
40
40
|
|
|
41
|
-
An AI client that runs on the same
|
|
41
|
+
An AI client that runs on the same computer, such as Claude Code, Codex or Cursor, can use your approved workspaces directly through the running agent. No cloud round trip happens per call. It keeps working while the internet or localcmd.app is unavailable, and calls take milliseconds instead of a cloud admission. Hosted assistants such as ChatGPT or claude.ai on the web still use `https://localcmd.app/mcp`.
|
|
42
42
|
|
|
43
|
-
1. Turn it on once. This is an owner choice for this
|
|
43
|
+
1. Turn it on once. This is an owner choice for this user account, and `off` revokes it immediately:
|
|
44
44
|
|
|
45
45
|
```powershell
|
|
46
46
|
localcommander mcp on
|
|
@@ -57,15 +57,15 @@ An AI client that runs on the same Windows computer, such as Claude Code, Codex
|
|
|
57
57
|
Other clients: { "command": "cmd", "args": ["/c", "localcommander", "mcp"] }
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
The tools are the same as the remote ones: `workspace_list`, file reads and writes, search, Git, `project_snapshot`, `command_run` and `localhost_request`. Each takes an optional `workspace` (a grant id, a root such as `D:\`, or a display name). The same workspace grants, Full Access or scoped mode and owner denials apply, and commands run hidden with your
|
|
60
|
+
The tools are the same as the remote ones: `workspace_list`, file reads and writes, search, Git, `project_snapshot`, `command_run` and `localhost_request`. Each takes an optional `workspace` (a grant id, a root such as `D:\`, or a display name). The same workspace grants, Full Access or scoped mode and owner denials apply, and commands run hidden with your user account's rights.
|
|
61
61
|
|
|
62
|
-
The agent listens only on `127.0.0.1`, and only while direct local MCP is on. Every connection must first prove a key that only this
|
|
62
|
+
The agent listens only on `127.0.0.1`, and only while direct local MCP is on. Every connection must first prove a key that only this user's protected Local Commander state can derive, so other users and other computers cannot connect. Check the state with `localcommander mcp status`; turn it off with `localcommander mcp off`. While an enterprise Guard policy is configured, direct local calls are refused so that Guard evidence cannot be bypassed.
|
|
63
63
|
|
|
64
64
|
## What тАЬall connected drivesтАЭ means
|
|
65
65
|
|
|
66
66
|
It expands the **filesystem scope** to the drive letters shown at the moment you consent. It includes available local fixed and removable drives. Mapped network drives and `subst` letters are not included. New drive letters, unavailable drives and unmounted volumes are not automatically added; run `configure-access` again after making the desired drive available. Grants are path/drive-letter based, not tied to a particular removable disk's hardware identity: reusing an approved letter gives access under that letter.
|
|
67
67
|
|
|
68
|
-
Full access allows installed commands resolved from absolute owner PATH entries or an absolute executable path, plus localhost services. Explicit command/port denials and write restrictions still apply. It does not elevate
|
|
68
|
+
Full access allows installed commands resolved from absolute owner PATH entries or an absolute executable path, plus localhost services. Explicit command/port denials and write restrictions still apply. It does not elevate privileges. Protected Local Commander state/runtime and secret-file filters apply to file tools; programs run with your user account's rights, so these controls are not an OS sandbox. ChatGPT/Claude or your workspace may still ask for their own action confirmations. Existing installations keep their current permissions until the owner runs `configure-access` and selects full access using a release that supports it.
|
|
69
69
|
|
|
70
70
|
## Manage the installation
|
|
71
71
|
|
|
@@ -143,7 +143,7 @@ Do not paste `(Get-Command git).Source` into CMD: CMD passes it literally instea
|
|
|
143
143
|
|
|
144
144
|
Under full access, `deny-command` and `deny-localhost` exclude the named command or port while other commands/ports remain available. Native `.exe`/`.com` commands receive argument arrays directly. `.cmd`/`.bat` launchers use a hidden PowerShell wrapper and reject cmd metacharacters in arguments; use an explicit interpreter for more complex scripts. Allowing a general interpreter is not containment against it launching a denied program.
|
|
145
145
|
|
|
146
|
-
Under **owner-approved Full Access**, installed Windows shells, script hosts and administration executables (including PowerShell and CMD) work without per-command registration. They execute under the
|
|
146
|
+
Under **owner-approved Full Access**, installed Windows shells, script hosts and administration executables (including PowerShell and CMD) work without per-command registration. They execute under the user account's own rights, not elevated privileges. Owner-defined `deny-command` exclusions and explicit write/localhost restrictions still apply. A general interpreter can access resources beyond file-tool path checks; Full Access is not an OS sandbox. Existing scoped grants stay scoped until the owner deliberately changes access with `configure-access`.
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
For a remote MCP client with an unknown device/workspace, use `workspace_list`, then `execution_session_open`, perform the requested work and read results. Reuse valid, already authorized session and target context where supported. `diagnostics` is for faults, not a mandatory startup roundtrip. Diagnostics reports quota separately from the device's execution slot limit. Its optional `repairSafe` mode releases only expired reservations from this OAuth connection that never acquired a dispatch lease. It never retries work, changes permissions or clears unknown executions.
|
|
@@ -153,7 +153,7 @@ For a remote MCP client with an unknown device/workspace, use `workspace_list`,
|
|
|
153
153
|
| Symptom | What to check |
|
|
154
154
|
| --- | --- |
|
|
155
155
|
| `npx` is not recognized | Install supported Node.js LTS, then open a new terminal. |
|
|
156
|
-
| Unsupported OS or architecture |
|
|
156
|
+
| Unsupported OS or architecture | Supported: Windows 11 x64, macOS 14 or later on Apple Silicon, Linux x64 or arm64 with systemd. Windows ARM64 and Intel Macs are not supported. |
|
|
157
157
|
| Pairing does not complete | Open https://localcmd.app, verify your account and internet access, then rerun the install command to resume. Do not share pairing codes. |
|
|
158
158
|
| `ACCESS_SETUP_CANCELLED` | No filesystem grant was saved by that dialog. Rerun setup and choose the intended scope. |
|
|
159
159
|
| `STATE_CHANGED` | Local account/policy/permissions changed while the dialog was open. Review current state and reopen the dialog. |
|
package/bin/localcommander.mjs
CHANGED
|
@@ -723,8 +723,10 @@ function help() {
|
|
|
723
723
|
].join("\n");
|
|
724
724
|
}
|
|
725
725
|
async function main() {
|
|
726
|
-
requireWindows();
|
|
727
726
|
if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u.test(VERSION)) fail("PACKAGE_VERSION_INVALID");
|
|
727
|
+
// macOS and Linux run the per-platform runtime package through its own lifecycle (#253).
|
|
728
|
+
if (process.platform !== "win32") return (await import("./posix.mjs")).runPosix(process.argv.slice(2), VERSION);
|
|
729
|
+
requireWindows();
|
|
728
730
|
const command = process.argv[2] || "bootstrap";
|
|
729
731
|
const args = process.argv.slice(3);
|
|
730
732
|
if (command === "-h" || command === "--help" || command === "help") {
|
package/bin/posix.mjs
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// macOS and Linux: the runtime ships in a per-platform package (an optional dependency, so npm installs only the
|
|
2
|
+
// matching one). Its lifecycle accepts only a private, owner-only artifact directory, so the files are copied from the
|
|
3
|
+
// npx cache into a fresh private directory and the lifecycle installs from there into its own versions directory.
|
|
4
|
+
import { constants } from "node:fs";
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { spawnSync } from "node:child_process";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
|
|
11
|
+
const PACKAGES = { "darwin-arm64": "local-commander-agent-darwin-arm64", "linux-x64": "local-commander-agent-linux-x64", "linux-arm64": "local-commander-agent-linux-arm64" };
|
|
12
|
+
// npm command -> lifecycle command. The default (`npx local-commander-agent@latest`) is setup, as on Windows.
|
|
13
|
+
const COMMANDS = { bootstrap: "setup", install: "setup", setup: "setup", update: "update", pair: "pair", access: "access", "configure-access": "access",
|
|
14
|
+
start: "start", stop: "stop", status: "status", rollback: "rollback", uninstall: "uninstall" };
|
|
15
|
+
const EXECUTABLES = new Set(["node", "posix-host", "owner-store"]);
|
|
16
|
+
|
|
17
|
+
function fail(code) { const error = new Error(code); error.code = code; throw error; }
|
|
18
|
+
|
|
19
|
+
export function posixHelp() {
|
|
20
|
+
return [
|
|
21
|
+
"Local Commander",
|
|
22
|
+
"",
|
|
23
|
+
" npx local-commander-agent@latest set up this computer, pair it and choose access",
|
|
24
|
+
" npx local-commander-agent@latest update install this version, keeping pairing and access",
|
|
25
|
+
" npx local-commander-agent@latest status|start|stop|pair|access|rollback",
|
|
26
|
+
" npx local-commander-agent@latest uninstall [--purge-state]",
|
|
27
|
+
""
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function runPosix(argv, version) {
|
|
32
|
+
const name = PACKAGES[process.platform + "-" + process.arch];
|
|
33
|
+
if (!name) fail(process.platform === "darwin" ? "MACOS_APPLE_SILICON_REQUIRED" : process.platform === "linux" ? "LINUX_X64_OR_ARM64_REQUIRED" : "PLATFORM_UNSUPPORTED");
|
|
34
|
+
const command = argv[0] || "bootstrap", args = argv.slice(1);
|
|
35
|
+
if (command === "-h" || command === "--help" || command === "help") { process.stdout.write(posixHelp()); return; }
|
|
36
|
+
const lifecycle = COMMANDS[command];
|
|
37
|
+
if (!lifecycle) fail("ARGUMENT_INVALID");
|
|
38
|
+
if (lifecycle === "uninstall" ? args.length > 1 || (args.length === 1 && args[0] !== "--purge-state") : args.length) fail("ARGUMENT_INVALID");
|
|
39
|
+
if (typeof process.getuid === "function" && process.getuid() === 0) fail("POSIX_OWNER_REQUIRED");
|
|
40
|
+
|
|
41
|
+
let packageJson;
|
|
42
|
+
try { packageJson = createRequire(import.meta.url).resolve(name + "/package.json"); } catch { fail("PLATFORM_PACKAGE_MISSING"); }
|
|
43
|
+
const meta = JSON.parse(await fs.readFile(packageJson, "utf8"));
|
|
44
|
+
if (meta.name !== name || meta.version !== version) fail("PLATFORM_PACKAGE_MISMATCH");
|
|
45
|
+
const source = path.join(path.dirname(packageJson), "runtime");
|
|
46
|
+
const manifest = JSON.parse(await fs.readFile(path.join(source, "manifest.json"), "utf8"));
|
|
47
|
+
const files = Object.keys(manifest?.files ?? {});
|
|
48
|
+
if (manifest?.platform !== process.platform || manifest?.arch !== process.arch || !files.length || files.some(file => !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(file))) fail("PLATFORM_PACKAGE_INVALID");
|
|
49
|
+
|
|
50
|
+
// Canonical parent: on macOS os.tmpdir() is under /var, a symlink to /private/var, and the lifecycle rejects aliases.
|
|
51
|
+
const stage = await fs.mkdtemp(path.join(await fs.realpath(os.tmpdir()), "local-commander-"));
|
|
52
|
+
try {
|
|
53
|
+
await fs.chmod(stage, 0o700);
|
|
54
|
+
for (const file of [...files, "manifest.json"]) {
|
|
55
|
+
const target = path.join(stage, file);
|
|
56
|
+
await fs.copyFile(path.join(source, file), target, constants.COPYFILE_EXCL);
|
|
57
|
+
await fs.chmod(target, EXECUTABLES.has(file) ? 0o700 : 0o600);
|
|
58
|
+
}
|
|
59
|
+
// The lifecycle verifies every file against the manifest, then copies them into its own versions directory.
|
|
60
|
+
const result = spawnSync(path.join(stage, "node"), [path.join(stage, "lifecycle.mjs"), lifecycle, ...args], { stdio: "inherit" });
|
|
61
|
+
if (result.error) throw result.error;
|
|
62
|
+
process.exitCode = result.status ?? 1;
|
|
63
|
+
} finally {
|
|
64
|
+
await fs.rm(stage, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,47 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "local-commander-agent",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"localcommander": "bin/localcommander.mjs"
|
|
8
|
-
},
|
|
9
|
-
"os": [
|
|
10
|
-
"win32"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"agent"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "local-commander-agent",
|
|
3
|
+
"version": "0.3.46",
|
|
4
|
+
"description": "Computer companion for Local Commander: connect AI clients to local files, approved commands and localhost. Requires https://localcmd.app.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"localcommander": "bin/localcommander.mjs"
|
|
8
|
+
},
|
|
9
|
+
"os": [
|
|
10
|
+
"win32",
|
|
11
|
+
"darwin",
|
|
12
|
+
"linux"
|
|
13
|
+
],
|
|
14
|
+
"cpu": [
|
|
15
|
+
"x64",
|
|
16
|
+
"arm64"
|
|
17
|
+
],
|
|
18
|
+
"optionalDependencies": {
|
|
19
|
+
"local-commander-agent-darwin-arm64": "0.3.46",
|
|
20
|
+
"local-commander-agent-linux-arm64": "0.3.46",
|
|
21
|
+
"local-commander-agent-linux-x64": "0.3.46"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20.0.0"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"bin/",
|
|
28
|
+
"runtime/",
|
|
29
|
+
"README.md",
|
|
30
|
+
"CHANGELOG.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"prepack": "node ../../scripts/build-npm-agent.mjs",
|
|
34
|
+
"prepublishOnly": "node ../../scripts/check-npm-publish-auth.mjs && node ../../scripts/verify-npm-agent.mjs"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"mcp",
|
|
41
|
+
"local",
|
|
42
|
+
"agent",
|
|
43
|
+
"chatgpt",
|
|
44
|
+
"claude",
|
|
45
|
+
"windows",
|
|
46
|
+
"macos",
|
|
47
|
+
"linux"
|
|
48
|
+
],
|
|
49
|
+
"localCommander": {
|
|
50
|
+
"controlPlaneOrigin": "https://localcmd.app"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://localcmd.app",
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://localcmd.app/support",
|
|
55
|
+
"email": "peter.mamrukov@localcmd.app"
|
|
56
|
+
}
|
|
57
|
+
}
|
package/runtime/JobHost.exe
CHANGED
|
Binary file
|
|
Binary file
|
package/runtime/OwnerBridge.exe
CHANGED
|
Binary file
|