terminal-commands 0.1.3 → 0.2.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/README.md +101 -4
- package/dist/agent.js +626 -124
- package/dist/cli.js +875 -140
- package/dist/index.js +1064 -357
- package/dist/native/GO-LICENSE +27 -0
- package/dist/native/darwin-arm64/fs-helper +0 -0
- package/dist/native/darwin-x64/fs-helper +0 -0
- package/dist/native/linux-arm64/fs-helper +0 -0
- package/dist/native/linux-x64/fs-helper +0 -0
- package/dist/native/win32-arm64/fs-helper.exe +0 -0
- package/dist/native/win32-x64/fs-helper.exe +0 -0
- package/dist/stdio.js +784 -179
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -16,15 +16,42 @@ approval prompts are enabled.
|
|
|
16
16
|
- Passes only a small environment allowlist to child processes, excluding API keys and other secrets.
|
|
17
17
|
- Restricts dedicated filesystem tools to the approved roots.
|
|
18
18
|
|
|
19
|
+
File reads, bounded directory listings and writes use a bundled native helper
|
|
20
|
+
with Go's handle-based `os.Root` API. Approved roots are pinned and checked
|
|
21
|
+
against their original file identities; a concurrent parent-directory or root
|
|
22
|
+
symlink swap cannot redirect an operation into another directory. File writes
|
|
23
|
+
truncate only an already safely opened regular file. The helper is required:
|
|
24
|
+
missing, crashed or unsupported helpers refuse file IO, with no path-string
|
|
25
|
+
fallback. Relative paths and the originally configured root aliases remain
|
|
26
|
+
supported. Roots should be ordinary directories on a trusted local filesystem;
|
|
27
|
+
this boundary does not prevent privileged mount changes or hard-link aliases.
|
|
28
|
+
|
|
29
|
+
Process working directories use the same checked root identities and native
|
|
30
|
+
directory handles during startup. Unix wrappers use `fchdir` followed by `exec`,
|
|
31
|
+
preserving the supervised PID/process group. Windows holds canonical ancestors
|
|
32
|
+
against rename through process creation; existing `taskkill /T` supervision
|
|
33
|
+
includes the wrapper's child. An approved executable still has the user's
|
|
34
|
+
ordinary OS permissions; the directory boundary is not a process sandbox.
|
|
35
|
+
|
|
36
|
+
See [Go's traversal-resistant APIs](https://go.dev/blog/osroot) for the native
|
|
37
|
+
filesystem boundary and its mount/hard-link limitations.
|
|
38
|
+
|
|
19
39
|
Command-line programs still execute with your operating-system user permissions. A program can access more than the dedicated filesystem tools, so review every command approval carefully.
|
|
20
40
|
|
|
21
|
-
The MCP
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
The local MCP server exposes the low-level process supervisor (`start_process`,
|
|
42
|
+
`read_process_output`, `list_processes`, and `terminate_process`) **only to the local
|
|
43
|
+
companion**. The public gateway exposes `submit_process` and `get_process_task`, which
|
|
44
|
+
return immediately with a task ID and then retrieve task status and bounded output.
|
|
45
|
+
There is no legacy public direct-execution API.
|
|
25
46
|
|
|
26
47
|
## Run
|
|
27
48
|
|
|
49
|
+
Building from source requires Node.js 20+ and Go 1.27.2+. `npm test` builds the
|
|
50
|
+
host's helper, while `npm pack` builds all six supported release targets. The
|
|
51
|
+
published package includes them, so installed users need only Node.js. Helpers
|
|
52
|
+
are built from the reviewed `native/fs-helper` source without CGO or downloaded
|
|
53
|
+
runtime executables. Unsupported OS/architecture combinations fail closed.
|
|
54
|
+
|
|
28
55
|
```bash
|
|
29
56
|
npm install
|
|
30
57
|
npm run build
|
|
@@ -133,3 +160,73 @@ Point the client's remote MCP server configuration at the same `http://127.0.0.1
|
|
|
133
160
|
it registers remote MCP servers; the connection and tool-discovery steps are otherwise identical.
|
|
134
161
|
|
|
135
162
|
For a published or independently hosted server, deploy a stable public HTTPS `/mcp` endpoint and implement OAuth 2.1. Do not expose this local server directly to the internet.
|
|
163
|
+
|
|
164
|
+
## Protocol-v2 production companion
|
|
165
|
+
|
|
166
|
+
The protocol-v2 companion is released as `terminal-commands@0.2.0`. Upgrade
|
|
167
|
+
and reconnect paired machines before deploying gateway v0.2.0; the gateway
|
|
168
|
+
intentionally rejects older protocol handshakes.
|
|
169
|
+
|
|
170
|
+
A local process is always approval-gated, and a repeated task ID returns its
|
|
171
|
+
existing session instead of spawning a duplicate. The supervisor enforces a
|
|
172
|
+
bounded process limit (32 running and 512 retained by default) and removes old
|
|
173
|
+
completed sessions after one hour. Task-ID tombstones remain in the live
|
|
174
|
+
companion to prevent replay after session history expires.
|
|
175
|
+
|
|
176
|
+
The local supervisor is currently memory-backed. If the local server itself
|
|
177
|
+
restarts, an already-running OS process may become unsupervised; a gateway task
|
|
178
|
+
will remain `unknown` until it can be reconciled, never automatically rerun.
|
|
179
|
+
|
|
180
|
+
## Local approval boundary and replay safety
|
|
181
|
+
|
|
182
|
+
The CLI generates a fresh 256-bit `MACHINE_TERMINAL_LOCAL_AGENT_TOKEN` for its local
|
|
183
|
+
MCP child and gateway companion. Only the approved companion can use destructive
|
|
184
|
+
tools over HTTP. Direct HTTP clients (including tunnels) are **denied by default**, even for
|
|
185
|
+
reads; stdio clients are **read-only by default**. Never expose the
|
|
186
|
+
local agent token in logs or shell arguments. Trusted local stdio administrators
|
|
187
|
+
can explicitly set `MACHINE_TERMINAL_TRUST_STDIO=1`; this grants local execution
|
|
188
|
+
without per-call companion confirmation and must not be enabled for untrusted clients.
|
|
189
|
+
|
|
190
|
+
The CLI also creates a private, persistent `device-secret` paired with the device ID.
|
|
191
|
+
The gateway stores only its hash, requires the matching secret on reconnect, and closes
|
|
192
|
+
device WebSockets when their OAuth access token expires. Losing the secret requires an
|
|
193
|
+
explicit re-pair: remove the server-side device registration with authorized
|
|
194
|
+
administrative access, then connect with a new secret. Signing out alone does not
|
|
195
|
+
rotate the device identity.
|
|
196
|
+
|
|
197
|
+
Process startup writes replay-resistant task receipts **before** executing commands.
|
|
198
|
+
The CLI saves them in `task-receipts.json` under its private config directory.
|
|
199
|
+
Receipts survive local-service restarts, expire after 30 days, and are bounded to
|
|
200
|
+
20,000 recent task IDs. The gateway retains idempotency metadata beyond output
|
|
201
|
+
retention, so old cloud requests still cannot be silently dispatched again.
|
|
202
|
+
|
|
203
|
+
On Unix the process supervisor runs commands in their own process groups; termination
|
|
204
|
+
sends SIGTERM and escalates to SIGKILL after a short grace period. On Windows it
|
|
205
|
+
uses process termination plus taskkill /T /F for forced descendant cleanup.
|
|
206
|
+
Programs that create independent/detached processes may still escape group cleanup;
|
|
207
|
+
Terminal Commands is not a full OS sandbox.
|
|
208
|
+
|
|
209
|
+
## Revoke a lost or compromised device
|
|
210
|
+
|
|
211
|
+
From a trusted terminal running the v0.2.0 CLI, use:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
terminal-commands revoke-device --device-id <paired-device-id>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The command requires an interactive confirmation and a **fresh Auth0 device login**
|
|
218
|
+
with the separate `terminal:devices:revoke` permission. It never saves the
|
|
219
|
+
elevated management token. The Auth0 API and device-code client must first be
|
|
220
|
+
configured to grant this permission to authorized account owners.
|
|
221
|
+
|
|
222
|
+
Revocation persists on the gateway, closes the current WebSocket and rejects
|
|
223
|
+
future connections using the revoked **device ID** even with its original
|
|
224
|
+
secret. Revocation cannot terminate processes already running on the machine,
|
|
225
|
+
revoke stolen Auth0 tokens, or block registration under another ID. Immediately
|
|
226
|
+
also revoke compromised Auth0 credentials and investigate the host. Restoring
|
|
227
|
+
the same ID requires a reviewed administrative reset, not a fresh login.
|
|
228
|
+
|
|
229
|
+
Use `terminal-commands paired-devices` to list paired device IDs even when
|
|
230
|
+
machines are offline, including revoked status. The CLI fetches paginated,
|
|
231
|
+
owner-scoped metadata with the same fresh elevated OAuth permission; secrets
|
|
232
|
+
and pairing credential hashes are never returned.
|