rackmind-cli 0.1.5 → 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/LICENSE +21 -0
- package/README.md +67 -181
- package/bin/rackmind.js +5 -1
- package/dist/ai/models.d.ts +40 -0
- package/dist/ai/models.d.ts.map +1 -0
- package/dist/ai/models.js +90 -0
- package/dist/ai/models.js.map +1 -0
- package/dist/ai/providers/anthropic-provider.d.ts +22 -0
- package/dist/ai/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/ai/{client.js → providers/anthropic-provider.js} +41 -59
- package/dist/ai/providers/anthropic-provider.js.map +1 -0
- package/dist/ai/providers/base.d.ts +82 -0
- package/dist/ai/providers/base.d.ts.map +1 -0
- package/dist/ai/providers/base.js +9 -0
- package/dist/ai/providers/base.js.map +1 -0
- package/dist/ai/providers/claude-code-bridge.d.ts +51 -0
- package/dist/ai/providers/claude-code-bridge.d.ts.map +1 -0
- package/dist/ai/providers/claude-code-bridge.js +371 -0
- package/dist/ai/providers/claude-code-bridge.js.map +1 -0
- package/dist/ai/providers/claude-code-provider.d.ts +24 -0
- package/dist/ai/providers/claude-code-provider.d.ts.map +1 -0
- package/dist/ai/providers/claude-code-provider.js +246 -0
- package/dist/ai/providers/claude-code-provider.js.map +1 -0
- package/dist/ai/providers/claude-code-runner.d.ts +51 -0
- package/dist/ai/providers/claude-code-runner.d.ts.map +1 -0
- package/dist/ai/providers/claude-code-runner.js +325 -0
- package/dist/ai/providers/claude-code-runner.js.map +1 -0
- package/dist/ai/providers/index.d.ts +8 -0
- package/dist/ai/providers/index.d.ts.map +1 -0
- package/dist/ai/providers/index.js +28 -0
- package/dist/ai/providers/index.js.map +1 -0
- package/dist/ai/system-prompt.d.ts.map +1 -1
- package/dist/ai/system-prompt.js +1 -26
- package/dist/ai/system-prompt.js.map +1 -1
- package/dist/ai/tool-executor.d.ts +29 -1
- package/dist/ai/tool-executor.d.ts.map +1 -1
- package/dist/ai/tool-executor.js +85 -1
- package/dist/ai/tool-executor.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +21 -15
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/containers.d.ts.map +1 -1
- package/dist/commands/containers.js +10 -3
- package/dist/commands/containers.js.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +19 -7
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/lifecycle.d.ts.map +1 -1
- package/dist/commands/lifecycle.js +133 -105
- package/dist/commands/lifecycle.js.map +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +10 -4
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +20 -12
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/servers.d.ts.map +1 -1
- package/dist/commands/servers.js +29 -2
- package/dist/commands/servers.js.map +1 -1
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +66 -50
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/vms.d.ts.map +1 -1
- package/dist/commands/vms.js +9 -3
- package/dist/commands/vms.js.map +1 -1
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +21 -0
- package/dist/config/index.js.map +1 -1
- package/dist/globals.d.ts +21 -3
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +30 -4
- package/dist/globals.js.map +1 -1
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/dist/interactive/App.d.ts.map +1 -1
- package/dist/interactive/App.js +11 -5
- package/dist/interactive/App.js.map +1 -1
- package/dist/interactive/components/ConfirmDialog.d.ts +9 -0
- package/dist/interactive/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/interactive/components/ConfirmDialog.js +26 -0
- package/dist/interactive/components/ConfirmDialog.js.map +1 -0
- package/dist/interactive/components/InputBar.d.ts.map +1 -1
- package/dist/interactive/components/InputBar.js +10 -1
- package/dist/interactive/components/InputBar.js.map +1 -1
- package/dist/interactive/components/ToolOutput.d.ts +1 -1
- package/dist/interactive/components/ToolOutput.d.ts.map +1 -1
- package/dist/interactive/launch.d.ts +5 -0
- package/dist/interactive/launch.d.ts.map +1 -1
- package/dist/interactive/launch.js +16 -0
- package/dist/interactive/launch.js.map +1 -1
- package/dist/interactive/slashCommands.d.ts +1 -0
- package/dist/interactive/slashCommands.d.ts.map +1 -1
- package/dist/interactive/slashCommands.js +13 -0
- package/dist/interactive/slashCommands.js.map +1 -1
- package/dist/interactive/useRackMind.d.ts +9 -1
- package/dist/interactive/useRackMind.d.ts.map +1 -1
- package/dist/interactive/useRackMind.js +81 -8
- package/dist/interactive/useRackMind.js.map +1 -1
- package/dist/oneshot/run.d.ts.map +1 -1
- package/dist/oneshot/run.js +65 -14
- package/dist/oneshot/run.js.map +1 -1
- package/dist/server/client.d.ts +4 -2
- package/dist/server/client.d.ts.map +1 -1
- package/dist/server/client.js +6 -4
- package/dist/server/client.js.map +1 -1
- package/dist/server/ssh.d.ts.map +1 -1
- package/dist/server/ssh.js +1 -1
- package/dist/server/ssh.js.map +1 -1
- package/dist/utils/prompt.d.ts.map +1 -1
- package/dist/utils/prompt.js +52 -49
- package/dist/utils/prompt.js.map +1 -1
- package/dist/utils/table.d.ts +3 -0
- package/dist/utils/table.d.ts.map +1 -1
- package/dist/utils/table.js +4 -1
- package/dist/utils/table.js.map +1 -1
- package/package.json +44 -12
- package/dist/ai/client.d.ts +0 -71
- package/dist/ai/client.d.ts.map +0 -1
- package/dist/ai/client.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RackMind
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,238 +1,124 @@
|
|
|
1
1
|
# rackmind-cli
|
|
2
2
|
|
|
3
|
-
**[rackmind.ai](https://rackmind.ai)** — AI-powered infrastructure management
|
|
3
|
+
**[rackmind.ai](https://rackmind.ai)** — AI-powered infrastructure management from your terminal.
|
|
4
4
|
|
|
5
|
-
A Claude Code-style
|
|
5
|
+
A Claude Code-style REPL for managing Proxmox hosts, LXC containers, and QEMU VMs through natural language. Built for **MSPs, power users, and homelab operators** who live in the terminal and want their infra to answer back.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
> New contributor? Skip to [ONBOARDING.md](./ONBOARDING.md). It is the only doc you need to start hacking on this package.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install -g rackmind-cli
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Requires Node.js 20+ (CI runs on 22).
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
git clone https://github.com/rackmind-ai/rackmind-cli.git
|
|
17
|
-
cd rackmind-cli
|
|
18
|
-
npm install
|
|
19
|
-
npm run build
|
|
20
|
-
npm link
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Quick Start
|
|
17
|
+
## 30-second quick start
|
|
24
18
|
|
|
25
19
|
```bash
|
|
26
|
-
#
|
|
27
|
-
rackmind connect
|
|
20
|
+
# 1. Connect to your Proxmox host (prompts for URL + API token, stored encrypted)
|
|
21
|
+
rackmind connect homelab
|
|
28
22
|
|
|
29
|
-
#
|
|
23
|
+
# 2. Add your Anthropic API key (or run `rackmind login` for managed AI)
|
|
30
24
|
rackmind config set-api-key
|
|
31
25
|
|
|
32
|
-
#
|
|
26
|
+
# 3. Drop into the REPL
|
|
33
27
|
rackmind
|
|
34
28
|
|
|
35
|
-
# Or
|
|
36
|
-
rackmind "
|
|
29
|
+
# 4. Or one-shot it — pipeable, scriptable
|
|
30
|
+
rackmind "which LXC containers are using >80% disk?"
|
|
37
31
|
```
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
### Interactive Mode (REPL)
|
|
42
|
-
|
|
43
|
-
Launch with no arguments to enter the full interactive terminal:
|
|
33
|
+
That is the whole loop. Everything else below is reference.
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
rackmind
|
|
47
|
-
```
|
|
35
|
+
## Modes
|
|
48
36
|
|
|
49
|
-
|
|
37
|
+
### Interactive REPL — `rackmind`
|
|
50
38
|
|
|
51
|
-
-
|
|
52
|
-
- AI-powered command execution with tool use
|
|
53
|
-
- Streaming responses with markdown rendering
|
|
54
|
-
- Slash commands: `/help`, `/clear`, `/status`, `/servers`, `/model`, `/exit`, `/quit`, `/q`
|
|
55
|
-
- Keyboard shortcuts: Up/Down for history, Ctrl+C to exit
|
|
39
|
+
Natural-language conversation about your infra. Streaming responses, tool execution with confirmation prompts on destructive actions, command history, slash commands (`/help`, `/clear`, `/refresh`, `/status`, `/servers`, `/model`, `/exit`).
|
|
56
40
|
|
|
57
|
-
|
|
41
|
+
Anytime the model asks to start/stop/restart a container or VM, the REPL pauses and shows a yellow `[y/N]` dialog with the action, tool name, and arguments. Press `y` to proceed, `n`/`Esc`/Enter to cancel. Enter defaults to **no** — destructive actions require an explicit yes. Pass `-y` / `--yes` at launch to auto-approve every destructive action for the session (use only in trusted scripts).
|
|
58
42
|
|
|
59
|
-
|
|
43
|
+
### One-shot — `rackmind "<question>"`
|
|
60
44
|
|
|
61
|
-
|
|
62
|
-
rackmind "check disk usage on all containers"
|
|
63
|
-
rackmind ask "restart container 106"
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Fully pipeable:
|
|
45
|
+
Single question, streamed to stdout, exits cleanly. Designed for pipelines:
|
|
67
46
|
|
|
68
47
|
```bash
|
|
69
48
|
rackmind "list running containers" --json | jq '.response'
|
|
70
|
-
rackmind "what is the uptime?" --quiet
|
|
49
|
+
rackmind "what is the host uptime?" --quiet
|
|
71
50
|
```
|
|
72
51
|
|
|
73
52
|
### Subcommands
|
|
74
53
|
|
|
75
|
-
#### Server Management
|
|
76
|
-
|
|
77
54
|
```bash
|
|
78
|
-
rackmind connect <alias>
|
|
79
|
-
rackmind servers list
|
|
80
|
-
rackmind
|
|
81
|
-
rackmind
|
|
82
|
-
rackmind
|
|
55
|
+
rackmind connect <alias> # Add or switch to a server profile
|
|
56
|
+
rackmind servers list|add|remove|switch
|
|
57
|
+
rackmind status # Config + connection summary
|
|
58
|
+
rackmind containers | rackmind vms # List guests
|
|
59
|
+
rackmind start|stop|restart <vmid> # Lifecycle (confirmation by default; --force to skip)
|
|
60
|
+
rackmind exec "<cmd>" [--target=<vmid>]
|
|
61
|
+
rackmind logs <vmid> [-n N] [-f]
|
|
62
|
+
rackmind report # Full health report
|
|
63
|
+
rackmind config [set|reset|set-api-key|path]
|
|
64
|
+
rackmind login | logout | account # RackMind account auth + billing
|
|
83
65
|
```
|
|
84
66
|
|
|
85
|
-
|
|
67
|
+
Run `rackmind --help` or `rackmind <cmd> --help` for the full surface.
|
|
86
68
|
|
|
87
|
-
|
|
88
|
-
rackmind status # Show config, connection status, server list
|
|
89
|
-
rackmind containers # List all LXC containers
|
|
90
|
-
rackmind vms # List all QEMU virtual machines
|
|
91
|
-
rackmind report # Generate a full health report
|
|
92
|
-
```
|
|
69
|
+
### Global flags
|
|
93
70
|
|
|
94
|
-
|
|
71
|
+
| Flag | Description |
|
|
72
|
+
| ------------------- | ------------------------------------------------------------------------------------------ |
|
|
73
|
+
| `--json` | JSON output to stdout (implies `--quiet`) |
|
|
74
|
+
| `--quiet` | Suppress spinners, banners, decoration |
|
|
75
|
+
| `--no-color` | Disable color (also respects `NO_COLOR`) |
|
|
76
|
+
| `--server <alias>` | Use a specific server profile for this invocation (overrides the active one) |
|
|
77
|
+
| `-y, --yes` | Auto-confirm every destructive prompt (AI tool calls, dangerous shell, `stop` / `restart`) |
|
|
78
|
+
| `-i, --interactive` | Force the REPL (default when no prompt is given on a TTY) |
|
|
95
79
|
|
|
96
|
-
|
|
97
|
-
rackmind start <vmid> # Start a container or VM
|
|
98
|
-
rackmind stop <vmid> # Stop a container or VM (with confirmation)
|
|
99
|
-
rackmind restart <vmid> # Restart a container or VM (with confirmation)
|
|
100
|
-
rackmind stop <vmid> --force # Skip confirmation prompt
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### Command Execution
|
|
80
|
+
### Output streams
|
|
104
81
|
|
|
105
|
-
|
|
106
|
-
rackmind exec "uptime" # Run on the Proxmox host
|
|
107
|
-
rackmind exec "apt update" --target=106 # Run inside LXC container 106
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
#### Logs
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
rackmind logs <vmid> # Tail logs for a container or VM
|
|
114
|
-
rackmind logs <vmid> -n 100 # Show last 100 lines
|
|
115
|
-
rackmind logs <vmid> -f # Follow log output
|
|
116
|
-
```
|
|
82
|
+
`rackmind` follows the POSIX convention:
|
|
117
83
|
|
|
118
|
-
|
|
84
|
+
- **stdout** — user-facing data: tables, reports, JSON, AI responses
|
|
85
|
+
- **stderr** — diagnostics: spinners, progress, banners, prompts, errors
|
|
119
86
|
|
|
120
|
-
|
|
121
|
-
rackmind config # Show current configuration
|
|
122
|
-
rackmind config set <key> <value> # Set a preference
|
|
123
|
-
rackmind config reset # Reset preferences to defaults
|
|
124
|
-
rackmind config set-api-key # Set or update the Anthropic API key
|
|
125
|
-
rackmind config path # Print the config file path
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Available preference keys:
|
|
129
|
-
|
|
130
|
-
- `model` -- AI model (default: `claude-sonnet-4-5`)
|
|
131
|
-
- `theme` -- Color theme: `dark` or `light`
|
|
132
|
-
- `confirmDestructive` -- Require confirmation for destructive actions (`true`/`false`)
|
|
133
|
-
- `timestampMessages` -- Show timestamps on messages (`true`/`false`)
|
|
134
|
-
|
|
135
|
-
#### Account & Billing
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
rackmind login # Authenticate with your RackMind account
|
|
139
|
-
rackmind logout # Clear stored auth token
|
|
140
|
-
rackmind account # Show current plan, usage, and account info
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Global Flags
|
|
144
|
-
|
|
145
|
-
These flags work with any command:
|
|
146
|
-
|
|
147
|
-
| Flag | Description |
|
|
148
|
-
| ------------------- | --------------------------------------------------------- |
|
|
149
|
-
| `--json` | Output in JSON format (implies `--quiet`) |
|
|
150
|
-
| `--quiet` | Suppress spinners, banners, and non-essential output |
|
|
151
|
-
| `--no-color` | Disable colored output (also respects `NO_COLOR` env var) |
|
|
152
|
-
| `--server <url>` | Override the RackMind server URL |
|
|
153
|
-
| `-i, --interactive` | Force interactive REPL mode |
|
|
87
|
+
So `rackmind status > status.txt` writes a complete report to the file, and `rackmind containers --json | jq` works as expected.
|
|
154
88
|
|
|
155
89
|
## Configuration
|
|
156
90
|
|
|
157
|
-
Config
|
|
158
|
-
|
|
159
|
-
Credentials (API keys, passwords, token secrets) are encrypted using Node.js `crypto` with a machine-derived key. They are never stored in plaintext.
|
|
160
|
-
|
|
161
|
-
Config writes are atomic (write to temp file, then rename) to prevent corruption.
|
|
162
|
-
|
|
163
|
-
## Subscription & Billing
|
|
164
|
-
|
|
165
|
-
RackMind CLI uses your RackMind account for billing and subscription management. All billing is handled through the website at [rackmind.ai](https://rackmind.ai).
|
|
166
|
-
|
|
167
|
-
### Authentication
|
|
168
|
-
|
|
169
|
-
Authenticate the CLI with your RackMind account:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
rackmind login
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
This opens your browser to sign in. Once authenticated, the CLI stores a local auth token (encrypted) so you stay logged in across sessions.
|
|
176
|
-
|
|
177
|
-
To log out:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
rackmind logout
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Free vs Pro
|
|
184
|
-
|
|
185
|
-
| Feature | Free | Pro ($15/mo) |
|
|
186
|
-
| -------------------------- | --------------- | ---------------- |
|
|
187
|
-
| Server connections | 1 | Unlimited |
|
|
188
|
-
| Managed AI interactions/mo | 25 | 200 |
|
|
189
|
-
| Bring Your Own Key (BYOK) | -- | Unlimited |
|
|
190
|
-
| Solution memory | -- | Included |
|
|
191
|
-
| Historical metrics | 1 hour | Unlimited |
|
|
192
|
-
| Terminal AI | -- | Included |
|
|
193
|
-
|
|
194
|
-
**Free tier** -- great for trying RackMind on a single server with basic AI assistance.
|
|
91
|
+
Config lives at `~/.config/rackmind/config.json` (XDG-compliant). Credentials are encrypted with AES-256-GCM using a machine-derived key — they are never written in plaintext. Writes are atomic (temp file + rename) to prevent corruption.
|
|
195
92
|
|
|
196
|
-
|
|
93
|
+
A handful of env vars tune the CLI for development and CI — see [`.env.example`](https://github.com/rackmind-ai/rackmind-cli/blob/main/.env.example) on GitHub for the full list. The file isn't shipped to the npm tarball.
|
|
197
94
|
|
|
198
|
-
|
|
95
|
+
## Plans
|
|
199
96
|
|
|
200
|
-
|
|
97
|
+
| Feature | Free | Pro ($15/mo) |
|
|
98
|
+
| -------------------------- | ------ | ------------ |
|
|
99
|
+
| Server connections | 1 | Unlimited |
|
|
100
|
+
| Managed AI interactions/mo | 25 | 200 |
|
|
101
|
+
| Bring Your Own Key (BYOK) | — | Unlimited |
|
|
102
|
+
| Solution memory | — | Included |
|
|
103
|
+
| Historical metrics | 1 hour | Unlimited |
|
|
104
|
+
| Terminal AI | — | Included |
|
|
201
105
|
|
|
202
|
-
|
|
203
|
-
https://rackmind.ai/account
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
Or view your current plan from the CLI:
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
rackmind account
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Requirements
|
|
213
|
-
|
|
214
|
-
- Node.js 20+
|
|
215
|
-
- A Proxmox VE server with API token access
|
|
216
|
-
- An Anthropic API key (for AI features) or a RackMind Pro subscription for managed AI
|
|
106
|
+
Subscription management lives at <https://rackmind.ai/account>.
|
|
217
107
|
|
|
218
108
|
## Development
|
|
219
109
|
|
|
220
110
|
```bash
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
npm
|
|
224
|
-
npm run
|
|
225
|
-
npm run
|
|
111
|
+
git clone https://github.com/rackmind-ai/rackmind-cli.git
|
|
112
|
+
cd rackmind-cli
|
|
113
|
+
npm install
|
|
114
|
+
npm run dev # tsx src/index.ts
|
|
115
|
+
npm run build # tsc to dist/
|
|
116
|
+
npm link # expose `rackmind` globally for local testing
|
|
117
|
+
npm run check # lint + format-check + type-check + tests (must pass)
|
|
226
118
|
```
|
|
227
119
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
tsc --noEmit
|
|
232
|
-
npx eslint .
|
|
233
|
-
npx prettier --check .
|
|
234
|
-
```
|
|
120
|
+
Detailed contributor setup, architecture overview, and the commit gate are in [ONBOARDING.md](./ONBOARDING.md). Architecture and CLI-specific guardrails are in [CLAUDE.md](./CLAUDE.md). Org-wide engineering standards are at <https://github.com/rackmind-ai/.github/blob/main/STANDARDS.md>.
|
|
235
121
|
|
|
236
122
|
## License
|
|
237
123
|
|
|
238
|
-
|
|
124
|
+
[MIT](./LICENSE)
|
package/bin/rackmind.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import('../dist/index.js').catch((err) => {
|
|
4
|
-
|
|
4
|
+
if (err.code === 'ERR_MODULE_NOT_FOUND') {
|
|
5
|
+
console.error('rackmind: dist/index.js not found — run `npm run build` first.');
|
|
6
|
+
} else {
|
|
7
|
+
console.error('Failed to start rackmind:', err.message);
|
|
8
|
+
}
|
|
5
9
|
process.exit(1);
|
|
6
10
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type AIProviderKind = 'anthropic' | 'claude-code';
|
|
2
|
+
export interface ModelOption {
|
|
3
|
+
/** Model id used in config and passed to getAIProvider(). */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Human-readable display name. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Provider family. */
|
|
8
|
+
provider: AIProviderKind;
|
|
9
|
+
/** Whether this is the default model for new conversations. */
|
|
10
|
+
isDefault?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_ANTHROPIC_MODEL_ID = "claude-sonnet-4-5";
|
|
13
|
+
/**
|
|
14
|
+
* Feature flag for the private `claude-code` provider. Invisible to every
|
|
15
|
+
* user-facing surface unless this returns true. Do NOT document this env
|
|
16
|
+
* var or mention it in error messages.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isClaudeCodeEnabled(): boolean;
|
|
19
|
+
/** Look up a model by id. Returns undefined if unknown. */
|
|
20
|
+
export declare function getModelById(modelId: string): ModelOption | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Models that should be shown in user-facing surfaces right now. Filters
|
|
23
|
+
* out gated providers whose feature flag is off.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getVisibleModels(): ModelOption[];
|
|
26
|
+
/**
|
|
27
|
+
* Get the provider kind for a model id, or undefined if the model is
|
|
28
|
+
* unknown OR gated off in the current environment. Use this instead of
|
|
29
|
+
* reaching into ALL_MODELS directly when you need to decide whether to
|
|
30
|
+
* route a request — it enforces the gate.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getVisibleProviderForModel(modelId: string): AIProviderKind | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a preferred model id to one that is actually usable right now.
|
|
35
|
+
* If the preferred id is unknown or points at a gated-off provider, falls
|
|
36
|
+
* back to the default Anthropic model so the user isn't left stranded by
|
|
37
|
+
* a stale config value.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveUsableModelId(preferredModelId: string | undefined): string;
|
|
40
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/ai/models.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,aAAa,CAAC;AAEzD,MAAM,WAAW,WAAW;IACxB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,QAAQ,EAAE,cAAc,CAAC;IACzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAiC9D;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAErE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAMhD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAKtF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKjF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Model registry & visibility gating
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Central catalogue of AI models the CLI knows how to route. Every surface
|
|
5
|
+
// that enumerates models for the user (slash commands, config, help text)
|
|
6
|
+
// MUST filter through getVisibleModels() so gated providers stay invisible
|
|
7
|
+
// to normal users.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
export const DEFAULT_ANTHROPIC_MODEL_ID = 'claude-sonnet-4-5';
|
|
10
|
+
/**
|
|
11
|
+
* The full list of models the CLI knows about. Keep tight — every entry
|
|
12
|
+
* here shows up in the user-facing model picker once its provider is
|
|
13
|
+
* visible.
|
|
14
|
+
*/
|
|
15
|
+
const ALL_MODELS = [
|
|
16
|
+
{
|
|
17
|
+
id: 'claude-sonnet-4-5',
|
|
18
|
+
name: 'Claude Sonnet 4.5',
|
|
19
|
+
provider: 'anthropic',
|
|
20
|
+
isDefault: true,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'claude-haiku-4-5-20251001',
|
|
24
|
+
name: 'Claude Haiku 4.5',
|
|
25
|
+
provider: 'anthropic',
|
|
26
|
+
},
|
|
27
|
+
// Intentionally undocumented entries below. Gated — never surface
|
|
28
|
+
// unless isClaudeCodeEnabled() returns true.
|
|
29
|
+
{
|
|
30
|
+
id: 'claude-code:sonnet',
|
|
31
|
+
name: 'Claude Code (Sonnet)',
|
|
32
|
+
provider: 'claude-code',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'claude-code:opus',
|
|
36
|
+
name: 'Claude Code (Opus)',
|
|
37
|
+
provider: 'claude-code',
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* Feature flag for the private `claude-code` provider. Invisible to every
|
|
42
|
+
* user-facing surface unless this returns true. Do NOT document this env
|
|
43
|
+
* var or mention it in error messages.
|
|
44
|
+
*/
|
|
45
|
+
export function isClaudeCodeEnabled() {
|
|
46
|
+
return process.env.RACKMIND_CLAUDE_CODE === '1';
|
|
47
|
+
}
|
|
48
|
+
/** Look up a model by id. Returns undefined if unknown. */
|
|
49
|
+
export function getModelById(modelId) {
|
|
50
|
+
return ALL_MODELS.find((m) => m.id === modelId);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Models that should be shown in user-facing surfaces right now. Filters
|
|
54
|
+
* out gated providers whose feature flag is off.
|
|
55
|
+
*/
|
|
56
|
+
export function getVisibleModels() {
|
|
57
|
+
const claudeCodeEnabled = isClaudeCodeEnabled();
|
|
58
|
+
return ALL_MODELS.filter((m) => {
|
|
59
|
+
if (m.provider === 'claude-code')
|
|
60
|
+
return claudeCodeEnabled;
|
|
61
|
+
return true;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the provider kind for a model id, or undefined if the model is
|
|
66
|
+
* unknown OR gated off in the current environment. Use this instead of
|
|
67
|
+
* reaching into ALL_MODELS directly when you need to decide whether to
|
|
68
|
+
* route a request — it enforces the gate.
|
|
69
|
+
*/
|
|
70
|
+
export function getVisibleProviderForModel(modelId) {
|
|
71
|
+
const model = getModelById(modelId);
|
|
72
|
+
if (!model)
|
|
73
|
+
return undefined;
|
|
74
|
+
if (model.provider === 'claude-code' && !isClaudeCodeEnabled())
|
|
75
|
+
return undefined;
|
|
76
|
+
return model.provider;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve a preferred model id to one that is actually usable right now.
|
|
80
|
+
* If the preferred id is unknown or points at a gated-off provider, falls
|
|
81
|
+
* back to the default Anthropic model so the user isn't left stranded by
|
|
82
|
+
* a stale config value.
|
|
83
|
+
*/
|
|
84
|
+
export function resolveUsableModelId(preferredModelId) {
|
|
85
|
+
if (preferredModelId && getVisibleProviderForModel(preferredModelId)) {
|
|
86
|
+
return preferredModelId;
|
|
87
|
+
}
|
|
88
|
+
return DEFAULT_ANTHROPIC_MODEL_ID;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/ai/models.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qCAAqC;AACrC,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,mBAAmB;AACnB,8EAA8E;AAe9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,mBAAmB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,GAAkB;IAC9B;QACI,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,IAAI;KAClB;IACD;QACI,EAAE,EAAE,2BAA2B;QAC/B,IAAI,EAAE,kBAAkB;QACxB,QAAQ,EAAE,WAAW;KACxB;IACD,kEAAkE;IAClE,6CAA6C;IAC7C;QACI,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,sBAAsB;QAC5B,QAAQ,EAAE,aAAa;KAC1B;IACD;QACI,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,oBAAoB;QAC1B,QAAQ,EAAE,aAAa;KAC1B;CACJ,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AACpD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,OAAe;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC5B,MAAM,iBAAiB,GAAG,mBAAmB,EAAE,CAAC;IAChD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,QAAQ,KAAK,aAAa;YAAE,OAAO,iBAAiB,CAAC;QAC3D,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAe;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,KAAK,aAAa,IAAI,CAAC,mBAAmB,EAAE;QAAE,OAAO,SAAS,CAAC;IACjF,OAAO,KAAK,CAAC,QAAQ,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,gBAAoC;IACrE,IAAI,gBAAgB,IAAI,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACnE,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IACD,OAAO,0BAA0B,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ServerClient } from '../../server/client.js';
|
|
2
|
+
import type { AIProvider, ChatHistory, MultiTurnCallbacks, ProviderOptions, StreamCallbacks } from './base.js';
|
|
3
|
+
export declare class AnthropicProvider implements AIProvider {
|
|
4
|
+
private readonly anthropic;
|
|
5
|
+
private readonly model;
|
|
6
|
+
private readonly maxTokens;
|
|
7
|
+
/** Cached server context — fetched once per session, cleared by /refresh */
|
|
8
|
+
private cachedContext;
|
|
9
|
+
constructor(options: ProviderOptions);
|
|
10
|
+
getModel(): string;
|
|
11
|
+
/** Clear cached server context so next turn re-fetches from Proxmox API. */
|
|
12
|
+
invalidateContextCache(): void;
|
|
13
|
+
chat(query: string, serverClient: ServerClient, serverAlias: string, callbacks: StreamCallbacks): Promise<void>;
|
|
14
|
+
chatMultiTurn(query: string, history: ChatHistory, serverClient: ServerClient, serverAlias: string, callbacks: MultiTurnCallbacks): Promise<ChatHistory>;
|
|
15
|
+
dispose(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Create a message with retry logic for transient errors.
|
|
18
|
+
* Rate limits and overload errors trigger exponential backoff.
|
|
19
|
+
*/
|
|
20
|
+
private createWithRetry;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=anthropic-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/anthropic-provider.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,OAAO,KAAK,EACR,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EAClB,MAAM,WAAW,CAAC;AAKnB,qBAAa,iBAAkB,YAAW,UAAU;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,4EAA4E;IAC5E,OAAO,CAAC,aAAa,CAA8B;gBAEvC,OAAO,EAAE,eAAe;IAYpC,QAAQ,IAAI,MAAM;IAIlB,4EAA4E;IAC5E,sBAAsB,IAAI,IAAI;IAKxB,IAAI,CACN,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,GAC3B,OAAO,CAAC,IAAI,CAAC;IA6DV,aAAa,CACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,kBAAkB,GAC9B,OAAO,CAAC,WAAW,CAAC;IA4EjB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;OAGG;IACH,OAAO,CAAC,eAAe;CAgC1B"}
|