{"_id":"@data443/convaa-runner","_rev":"2-60c63a14e12ea61a9f1248f6f87b4e01","name":"@data443/convaa-runner","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@data443/convaa-runner","version":"0.1.0","_id":"@data443/convaa-runner@0.1.0","maintainers":[{"name":"kirillvk","email":"k.kashigin@gmail.com"}],"bin":{"convaa-runner":"dist/index.js"},"dist":{"shasum":"80c05f9487cf8f2a8bb32c657e24d701e4811122","tarball":"https://registry.npmjs.org/@data443/convaa-runner/-/convaa-runner-0.1.0.tgz","fileCount":5,"integrity":"sha512-2exinrosx2U88d3tH+yj7/SetYIusWqZhiEuUQgWG+qhX8OZm8XzBeneA1So7/qeVBh6tccqLyRkXQsgDF9eCg==","signatures":[{"sig":"MEUCIQDFai5oc89O40g8POncdtfd9AM4mFdHSmSOBNLTo+ojOAIgIeDq/eqH91/bQaujUFtNIO6Yy7FwWY9ob82Oy18P6F4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20302},"type":"commonjs","gitHead":"ba3369789cf94d509d312884000bcb1977fc9c10","scripts":{"dev":"tsx watch src/index.ts","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"kirillvk","email":"k.kashigin@gmail.com"},"_npmVersion":"10.8.1","description":"On-prem command runner for Convaa — dials out to the proxy and executes read-only allowlisted diagnostics (locally or via SSH).","directories":{},"_nodeVersion":"20.16.0","dependencies":{"ws":"^8.18.0","ssh2":"^1.15.0","dotenv":"^16.4.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.0","@types/ws":"^8.5.10","typescript":"^5.5.0","@types/node":"^20.14.0","@types/ssh2":"^1.15.0"},"_npmOperationalInternal":{"tmp":"tmp/convaa-runner_0.1.0_1784671392652_0.23472501603440588","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@data443/convaa-runner","version":"0.1.1","description":"On-prem command runner for Convaa — dials out to the proxy and runs read-only diagnostics plus, inside an owner-granted read-write zone, gated file reads/writes/edits and dev commands (locally or via SSH).","type":"commonjs","bin":{"convaa-runner":"dist/index.js"},"scripts":{"build":"tsc","start":"node dist/index.js","dev":"tsx watch src/index.ts","typecheck":"tsc --noEmit","test":"vitest run","prepublishOnly":"npm run build"},"dependencies":{"dotenv":"^16.4.5","ssh2":"^1.15.0","ws":"^8.18.0"},"devDependencies":{"@types/node":"^20.14.0","@types/ssh2":"^1.15.0","@types/ws":"^8.5.10","tsx":"^4.16.0","typescript":"^5.5.0","vitest":"^2.1.9"},"publishConfig":{"access":"public"},"_id":"@data443/convaa-runner@0.1.1","gitHead":"fb02e613d467c8a1e2496c7e51cd76b60a706088","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-XjKiwdXYVsYquyp6NdvZ5RU/VAvOxs8tw/MBUO1nRFqaYokX1E2RI+2RCntE8e8uoz85j5aLLHxw11VvO55GvA==","shasum":"f42a10e2aad12edd862c944179d5c131856dcb7b","tarball":"https://registry.npmjs.org/@data443/convaa-runner/-/convaa-runner-0.1.1.tgz","fileCount":9,"unpackedSize":55274,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEcTsxZFErdMS3RHz9C5Aq6heuvYwl7ZWd0C7NJTqTBDAiEA2Zcs3RRSpmsEFq+DrEgYP/W5+k7IpLcasddt/RctdRs="}]},"_npmUser":{"name":"kirillvk","email":"k.kashigin@gmail.com"},"directories":{},"maintainers":[{"name":"kirillvk","email":"k.kashigin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/convaa-runner_0.1.1_1786229352418_0.3684737536049545"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T22:03:12.434Z","modified":"2026-08-08T22:49:12.715Z","0.1.0":"2026-07-21T22:03:12.796Z","0.1.1":"2026-08-08T22:49:12.560Z"},"description":"On-prem command runner for Convaa — dials out to the proxy and runs read-only diagnostics plus, inside an owner-granted read-write zone, gated file reads/writes/edits and dev commands (locally or via SSH).","maintainers":[{"name":"kirillvk","email":"k.kashigin@gmail.com"}],"readme":"# Convaa runner — connect your machine\n\nLets the Convaa assistant run commands on a machine **you** control — your laptop, a server, or a\nbox inside your network — and stream the output back into the shared thread. The runner **dials out**\nto Convaa over `wss://…/runner`, so there are no inbound firewall holes to open.\n\nEach runner is tied to **your** account by a personal token you mint in the app; you can connect as\nmany machines as you like and bind any of them to a session. When another member of a session triggers\na command on your machine, **you** (the device owner) have to approve it first.\n\n## Quick start (from the app)\n\n1. In a session, open your profile panel → **Connect a machine** → name the machine. Convaa mints a\n   **one-time token** (you only see it once) and shows you a ready-to-paste command.\n2. Run one of the commands it gives you on the machine you want to connect:\n\n   **Recommended — sandboxed container** (nothing to install but Docker; the current directory is\n   mounted at `/workspace`):\n\n   ```bash\n   docker run --rm -it -v \"$PWD:/workspace\" \\\n     ghcr.io/data443/convaa-runner --token <TOKEN> --url wss://<your-convaa-host>/runner\n   ```\n\n   **On your machine directly** (via npx; `--unsafe-host` opts out of the container sandbox):\n\n   ```bash\n   npx @data443/convaa-runner --token <TOKEN> --unsafe-host --url wss://<your-convaa-host>/runner\n   ```\n\n3. It prints `[runner] connected …`. Back in the session, use the composer **Runner** picker to bind\n   this machine to the session. The agent's commands now run on it.\n\n`<your-convaa-host>` is your Convaa host (the app fills it in for you — e.g. `convaa.ai`). Disconnect a\nmachine any time from the same **Connect a machine** panel; its token is revoked immediately.\n\n## Flags and environment\n\nThe client takes flags (which override the matching env vars) or plain env vars:\n\n| Flag | Env var | Meaning |\n| --- | --- | --- |\n| `--token <t>` | `RUNNER_TOKEN` | Your machine token (from **Connect a machine**), or the shared bastion secret. |\n| `--url <wss>` | `PROXY_WS_URL` | The Convaa runner endpoint, `wss://<host>/runner`. Defaults to `wss://convaa.ai/runner`. |\n| `--name <n>` | `RUNNER_NAME` | Display name for the machine. |\n| `--unsafe-host` | — | Run directly on the host instead of the sandboxed container (required for the npx path). |\n\n**Sandbox gate:** run outside the container image without `--unsafe-host` and the client refuses to\nstart and points you at the Docker command — so a bare `npx` on your laptop is always a deliberate\nchoice. The container image sets `CONVAA_RUNNER_SANDBOXED=1`, so it never needs the flag.\n\n## SSH targets (optional)\n\nTo run commands on other devices instead of just the runner host, set `HOSTS` to a JSON map of\n**read-only** SSH targets:\n\n```\nHOSTS={\"core1\":{\"host\":\"10.0.0.1\",\"user\":\"netadmin\",\"keyPath\":\"/keys/id_ed25519\"}}\n```\n\nMount the key read-only (`-v /path/to/keys:/keys:ro` for Docker). The agent passes `host: \"core1\"` to\nrun there. Use least-privilege accounts, and run the runner on a box that can actually reach the gear —\na cloud-hosted container only sees its own network unless it joins yours over a mesh VPN (Tailscale /\nWireGuard).\n\n## Run from source (development)\n\n```bash\ncd runner\ncp .env.example .env      # set PROXY_WS_URL + RUNNER_TOKEN (+ optional HOSTS)\nnpm install\nnpm run build && npm start    # or: npm run dev\n```\n\n## Shared / self-hosted runner (advanced)\n\nThe same client also backs the org's shared on-cluster bastion: point `RUNNER_TOKEN` at the shared\nsecret the proxy expects (`SHARED_RUNNER_ORG_ID` gates which org may bind it) instead of a per-user\ntoken, and run it wherever it can reach both Convaa and your infrastructure.\n\n## Safety model\n\n- **Read-only by default.** With the policy gate off, only a read-only allowlist runs (network/DNS\n  diagnostics, `cat`/`grep`-style reads); shell chaining, redirection, and mutating commands are\n  rejected — enforced on **both** the proxy and the runner.\n- **Policy gate + approvals.** When the Vaikora gate is enabled, mutating commands are allowed only\n  after it approves (which can require a teammate's approval in the thread).\n- **Owner approval for cross-user commands.** When someone other than the device owner triggers a\n  command on a personal runner, it waits for the owner's explicit approval and fails closed otherwise.\n- **No inbound access.** The runner only dials out; it never opens a port.\n\n## Publishing (maintainers)\n\n`@data443/convaa-runner` publishes to npm and `ghcr.io/data443/convaa-runner` to GHCR. To cut a runner\nrelease: bump `version` in `package.json`, commit, and push a `convaa-runner-v<version>` tag — the\n`convaa-runner-npm` workflow publishes to npm (needs the `NPM_TOKEN` repo secret, an npm **automation**\ntoken), and `convaa-runner-image` rebuilds the image on any `runner/**` change to `main`.\n","readmeFilename":"README.md"}