create-snipara 1.0.0 → 1.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 +84 -11
- package/dist/index.js +209 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,29 +26,59 @@ You'll be prompted for:
|
|
|
26
26
|
|--------|-------------|
|
|
27
27
|
| **Project slug** | Auto-detected from git remote or directory name |
|
|
28
28
|
| **Project ID** | Optional, for advanced use cases |
|
|
29
|
-
| **API key** |
|
|
29
|
+
| **API key type** | Project key, Team key, Sign up, or Skip |
|
|
30
|
+
| **API key** | Your Snipara API key |
|
|
30
31
|
| **AI client** | Claude Code, Cursor, Claude Desktop, or other |
|
|
31
32
|
| **Packages** | Choose what to install |
|
|
33
|
+
| **LLM provider** | OpenAI, Anthropic, or None (for `rlm run`/`rlm agent` CLI) |
|
|
34
|
+
| **Run rlm init** | Optional - configure execution environment (sandbox/docker/local) |
|
|
35
|
+
|
|
36
|
+
## API Key Requirements
|
|
37
|
+
|
|
38
|
+
| Tool | Snipara API Key | LLM API Key (OpenAI/Anthropic) |
|
|
39
|
+
|------|-----------------|-------------------------------|
|
|
40
|
+
| `execute_python` MCP | Not needed | Not needed (your AI client is the LLM) |
|
|
41
|
+
| `rlm_context_query` MCP | **Required** | Not needed |
|
|
42
|
+
| `rlm_remember`/`rlm_recall` | **Required** | Not needed |
|
|
43
|
+
| `rlm run` / `rlm agent` CLI | Optional (for context) | **Required** |
|
|
44
|
+
|
|
45
|
+
### Key Types
|
|
46
|
+
|
|
47
|
+
| Type | Description |
|
|
48
|
+
|------|-------------|
|
|
49
|
+
| **Project API key** | Access to a single project |
|
|
50
|
+
| **Team API key** | Access to all projects in your team |
|
|
32
51
|
|
|
33
52
|
## Command Line Options
|
|
34
53
|
|
|
35
54
|
```bash
|
|
36
|
-
#
|
|
37
|
-
npx create-snipara
|
|
55
|
+
# Basic usage
|
|
56
|
+
npx create-snipara
|
|
57
|
+
|
|
58
|
+
# With project API key
|
|
59
|
+
npx create-snipara --api-key rlm_your_project_key
|
|
60
|
+
|
|
61
|
+
# With team API key (access all team projects)
|
|
62
|
+
npx create-snipara --team-key rlm_your_team_key
|
|
38
63
|
|
|
39
64
|
# Specify project slug
|
|
40
65
|
npx create-snipara --slug my-project
|
|
41
66
|
|
|
67
|
+
# Runtime only - no Snipara API key needed
|
|
68
|
+
# (for execute_python MCP tool only)
|
|
69
|
+
npx create-snipara --runtime-only
|
|
70
|
+
|
|
42
71
|
# Skip specific installations
|
|
43
72
|
npx create-snipara --skip-mcp # Skip snipara-mcp
|
|
44
73
|
npx create-snipara --skip-runtime # Skip rlm-runtime
|
|
45
74
|
npx create-snipara --skip-hooks # Skip Claude Code hooks
|
|
75
|
+
npx create-snipara --skip-test # Skip connection test
|
|
46
76
|
|
|
47
|
-
# Accept all defaults
|
|
48
|
-
npx create-snipara -y
|
|
77
|
+
# Accept all defaults (non-interactive)
|
|
78
|
+
npx create-snipara -y --api-key rlm_xxx --slug my-project
|
|
49
79
|
|
|
50
|
-
# Full example
|
|
51
|
-
npx create-snipara --
|
|
80
|
+
# Full example with team key
|
|
81
|
+
npx create-snipara --team-key rlm_team_xxx --slug my-project --skip-hooks
|
|
52
82
|
```
|
|
53
83
|
|
|
54
84
|
## What Gets Created
|
|
@@ -85,8 +115,14 @@ npx create-snipara --api-key rlm_xxx --slug my-project --skip-hooks
|
|
|
85
115
|
Updates `.env.example` and `.env.local` with:
|
|
86
116
|
|
|
87
117
|
```bash
|
|
118
|
+
# Snipara Configuration
|
|
88
119
|
SNIPARA_API_KEY=your_api_key
|
|
89
120
|
SNIPARA_PROJECT_SLUG=your-project
|
|
121
|
+
|
|
122
|
+
# RLM-Runtime LLM Provider (if configured)
|
|
123
|
+
OPENAI_API_KEY=sk-...
|
|
124
|
+
# or
|
|
125
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
90
126
|
```
|
|
91
127
|
|
|
92
128
|
## After Installation
|
|
@@ -101,12 +137,48 @@ SNIPARA_PROJECT_SLUG=your-project
|
|
|
101
137
|
1. Restart Claude Desktop
|
|
102
138
|
2. Config is at `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
103
139
|
|
|
104
|
-
### RLM-Runtime
|
|
140
|
+
### RLM-Runtime Usage
|
|
141
|
+
|
|
142
|
+
**MCP Tools (no LLM API key needed):**
|
|
143
|
+
|
|
144
|
+
Your AI client (Claude, GPT, etc.) provides the LLM - no additional API key required.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
• execute_python - Run Python in sandbox
|
|
148
|
+
• get_repl_context - Get session variables
|
|
149
|
+
• set_repl_context - Set session variables
|
|
150
|
+
• clear_repl_context - Clear session
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Execution Environments:**
|
|
154
|
+
|
|
155
|
+
| Environment | Description | Use Case |
|
|
156
|
+
|-------------|-------------|----------|
|
|
157
|
+
| **sandbox** | RestrictedPython, safe stdlib only | Default, most secure |
|
|
158
|
+
| **docker** | Full Python in isolated container | Recommended for full features |
|
|
159
|
+
| **local** | Full access, no isolation | Development only |
|
|
160
|
+
|
|
161
|
+
During setup, you can run `rlm init` to configure the default environment.
|
|
162
|
+
Or configure later:
|
|
105
163
|
|
|
106
164
|
```bash
|
|
165
|
+
rlm init # Interactive configuration
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**CLI Commands (requires LLM API key):**
|
|
169
|
+
|
|
170
|
+
For `rlm run` and `rlm agent`, you need an LLM provider API key:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Set your LLM provider
|
|
174
|
+
export OPENAI_API_KEY=sk-...
|
|
175
|
+
# or
|
|
176
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
177
|
+
|
|
178
|
+
# Run commands
|
|
107
179
|
rlm init # Initialize configuration
|
|
108
180
|
rlm run --env docker # Run with Docker isolation
|
|
109
|
-
rlm
|
|
181
|
+
rlm agent "task" # Autonomous agent mode
|
|
110
182
|
rlm visualize # Launch trajectory dashboard
|
|
111
183
|
```
|
|
112
184
|
|
|
@@ -119,7 +191,7 @@ After setup, you have access to 43+ MCP tools:
|
|
|
119
191
|
| **Context** | `rlm_context_query`, `rlm_ask`, `rlm_search`, `rlm_sections` |
|
|
120
192
|
| **Planning** | `rlm_plan`, `rlm_decompose`, `rlm_multi_query` |
|
|
121
193
|
| **Memory** | `rlm_remember`, `rlm_recall`, `rlm_memories`, `rlm_forget` |
|
|
122
|
-
| **Execution** | `execute_python`, `
|
|
194
|
+
| **Execution** | `execute_python`, `get_repl_context` (via RLM-Runtime) |
|
|
123
195
|
| **Swarms** | `rlm_swarm_create`, `rlm_claim`, `rlm_task_create` |
|
|
124
196
|
|
|
125
197
|
## Requirements
|
|
@@ -133,7 +205,8 @@ After setup, you have access to 43+ MCP tools:
|
|
|
133
205
|
- **Website**: https://snipara.com
|
|
134
206
|
- **Documentation**: https://snipara.com/docs
|
|
135
207
|
- **Dashboard**: https://snipara.com/dashboard
|
|
136
|
-
- **
|
|
208
|
+
- **npm**: https://www.npmjs.com/package/create-snipara
|
|
209
|
+
- **Support**: hello@starbox-group.com
|
|
137
210
|
|
|
138
211
|
## License
|
|
139
212
|
|
package/dist/index.js
CHANGED
|
@@ -7,13 +7,13 @@ import chalk from "chalk";
|
|
|
7
7
|
import ora from "ora";
|
|
8
8
|
import fs from "fs";
|
|
9
9
|
import path from "path";
|
|
10
|
-
import { execSync } from "child_process";
|
|
10
|
+
import { execSync, spawn } from "child_process";
|
|
11
11
|
import { homedir } from "os";
|
|
12
|
-
var VERSION = "1.
|
|
12
|
+
var VERSION = "1.2.0";
|
|
13
13
|
var BASE_URL = "https://www.snipara.com";
|
|
14
14
|
var API_URL = "https://api.snipara.com";
|
|
15
15
|
async function main() {
|
|
16
|
-
program.name("create-snipara").description("Initialize Snipara MCP + RLM-Runtime with a single command").version(VERSION).option("--api-key <key>", "Snipara API key (project or team)").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID (optional, for advanced use)").option("--skip-mcp", "Skip snipara-mcp installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hooks installation").option("--skip-test", "Skip connection test").option("-y, --yes", "Accept defaults without prompting").parse();
|
|
16
|
+
program.name("create-snipara").description("Initialize Snipara MCP + RLM-Runtime with a single command").version(VERSION).option("--api-key <key>", "Snipara API key (project or team)").option("--team-key <key>", "Team API key (access all team projects)").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID (optional, for advanced use)").option("--skip-mcp", "Skip snipara-mcp installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hooks installation").option("--skip-test", "Skip connection test").option("--runtime-only", "Install only RLM-Runtime (no API key needed for local execution)").option("-y, --yes", "Accept defaults without prompting").parse();
|
|
17
17
|
const options = program.opts();
|
|
18
18
|
printBanner();
|
|
19
19
|
const answers = await gatherConfiguration(options);
|
|
@@ -29,6 +29,9 @@ async function main() {
|
|
|
29
29
|
await testConnection(answers);
|
|
30
30
|
}
|
|
31
31
|
printSuccess(answers);
|
|
32
|
+
if (answers.runRlmInit && answers.installRuntime) {
|
|
33
|
+
await runRlmInit();
|
|
34
|
+
}
|
|
32
35
|
}
|
|
33
36
|
function printBanner() {
|
|
34
37
|
console.log(
|
|
@@ -57,11 +60,29 @@ async function gatherConfiguration(options) {
|
|
|
57
60
|
detectedSlug = existingConfig.slug || detectedSlug;
|
|
58
61
|
detectedProjectId = existingConfig.projectId || "";
|
|
59
62
|
}
|
|
63
|
+
if (options.runtimeOnly) {
|
|
64
|
+
console.log(chalk.cyan("\n \u2139\uFE0F Runtime-only mode: No API key needed for local code execution\n"));
|
|
65
|
+
console.log(chalk.dim(" execute_python works without any API key when used in Claude Code."));
|
|
66
|
+
console.log(chalk.dim(" For rlm run/agent CLI, you'll need OPENAI_API_KEY or ANTHROPIC_API_KEY.\n"));
|
|
67
|
+
return {
|
|
68
|
+
projectSlug: options.slug || detectedSlug || "my-project",
|
|
69
|
+
projectId: "",
|
|
70
|
+
apiKey: "",
|
|
71
|
+
apiKeyType: "none",
|
|
72
|
+
installMcp: false,
|
|
73
|
+
installRuntime: true,
|
|
74
|
+
installHooks: false,
|
|
75
|
+
aiClient: detectedClient
|
|
76
|
+
};
|
|
77
|
+
}
|
|
60
78
|
if (options.yes) {
|
|
79
|
+
const apiKey2 = options.teamKey || options.apiKey || "YOUR_API_KEY_HERE";
|
|
80
|
+
const apiKeyType2 = options.teamKey ? "team" : "project";
|
|
61
81
|
return {
|
|
62
82
|
projectSlug: options.slug || detectedSlug || "my-project",
|
|
63
83
|
projectId: options.projectId || detectedProjectId,
|
|
64
|
-
apiKey:
|
|
84
|
+
apiKey: apiKey2,
|
|
85
|
+
apiKeyType: apiKeyType2,
|
|
65
86
|
installMcp: !options.skipMcp,
|
|
66
87
|
installRuntime: !options.skipRuntime,
|
|
67
88
|
installHooks: !options.skipHooks && detectedClient === "claude-code",
|
|
@@ -83,19 +104,34 @@ async function gatherConfiguration(options) {
|
|
|
83
104
|
initial: options.projectId || detectedProjectId || ""
|
|
84
105
|
},
|
|
85
106
|
{
|
|
86
|
-
type: options.apiKey ? null : "select",
|
|
87
|
-
name: "
|
|
88
|
-
message: "
|
|
107
|
+
type: options.apiKey || options.teamKey ? null : "select",
|
|
108
|
+
name: "apiKeyType",
|
|
109
|
+
message: "What type of API key do you have?",
|
|
89
110
|
choices: [
|
|
90
|
-
{
|
|
91
|
-
|
|
92
|
-
|
|
111
|
+
{
|
|
112
|
+
title: "Project API key",
|
|
113
|
+
value: "project",
|
|
114
|
+
description: "Access to a single project"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
title: "Team API key",
|
|
118
|
+
value: "team",
|
|
119
|
+
description: "Access to all projects in your team"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
title: "Sign up for free (100 queries/mo)",
|
|
123
|
+
value: "signup"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
title: "I'll add the API key later",
|
|
127
|
+
value: "skip"
|
|
128
|
+
}
|
|
93
129
|
]
|
|
94
130
|
},
|
|
95
131
|
{
|
|
96
|
-
type: (prev, values) => values.
|
|
132
|
+
type: (prev, values) => values.apiKeyType === "project" || values.apiKeyType === "team" ? "text" : null,
|
|
97
133
|
name: "apiKey",
|
|
98
|
-
message: "Enter your API key:",
|
|
134
|
+
message: (prev, values) => values.apiKeyType === "team" ? "Enter your Team API key:" : "Enter your Project API key:",
|
|
99
135
|
validate: (v) => v.startsWith("rlm_") ? true : "API key should start with rlm_"
|
|
100
136
|
},
|
|
101
137
|
{
|
|
@@ -133,13 +169,13 @@ async function gatherConfiguration(options) {
|
|
|
133
169
|
title: "snipara-mcp",
|
|
134
170
|
value: "mcp",
|
|
135
171
|
selected: !options.skipMcp,
|
|
136
|
-
description: "MCP server for context queries"
|
|
172
|
+
description: "MCP server for context queries (requires API key)"
|
|
137
173
|
},
|
|
138
174
|
{
|
|
139
175
|
title: "rlm-runtime",
|
|
140
176
|
value: "runtime",
|
|
141
177
|
selected: !options.skipRuntime,
|
|
142
|
-
description: "Safe code execution
|
|
178
|
+
description: "Safe code execution (no API key for execute_python)"
|
|
143
179
|
},
|
|
144
180
|
{
|
|
145
181
|
title: "Claude Code hooks",
|
|
@@ -151,23 +187,95 @@ async function gatherConfiguration(options) {
|
|
|
151
187
|
hint: "Space to toggle, Enter to confirm"
|
|
152
188
|
}
|
|
153
189
|
]);
|
|
154
|
-
let apiKey = options.apiKey;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
190
|
+
let apiKey = options.teamKey || options.apiKey;
|
|
191
|
+
let apiKeyType = options.teamKey ? "team" : "project";
|
|
192
|
+
if (!apiKey) {
|
|
193
|
+
if (response.apiKeyType === "signup") {
|
|
194
|
+
apiKey = await handleSignup();
|
|
195
|
+
apiKeyType = "project";
|
|
196
|
+
} else if (response.apiKeyType === "project" || response.apiKeyType === "team") {
|
|
197
|
+
apiKey = response.apiKey;
|
|
198
|
+
apiKeyType = response.apiKeyType;
|
|
199
|
+
} else if (response.apiKeyType === "skip") {
|
|
200
|
+
apiKey = "YOUR_API_KEY_HERE";
|
|
201
|
+
apiKeyType = "none";
|
|
202
|
+
}
|
|
161
203
|
}
|
|
162
204
|
const packages = response.packages || [];
|
|
205
|
+
let llmProvider;
|
|
206
|
+
let llmApiKey;
|
|
207
|
+
if (packages.includes("runtime")) {
|
|
208
|
+
console.log(chalk.cyan("\n \u2139\uFE0F RLM-Runtime API Key Info:\n"));
|
|
209
|
+
console.log(chalk.dim(" \u2022 execute_python MCP tool: No LLM API key needed"));
|
|
210
|
+
console.log(chalk.dim(" (Your AI client - Claude, GPT, etc. - provides the LLM)"));
|
|
211
|
+
console.log(chalk.dim(" \u2022 rlm run / rlm agent CLI: Requires an LLM API key\n"));
|
|
212
|
+
const llmResponse = await prompts([
|
|
213
|
+
{
|
|
214
|
+
type: "select",
|
|
215
|
+
name: "llmProvider",
|
|
216
|
+
message: "Will you use rlm run/agent CLI? (requires LLM API key)",
|
|
217
|
+
choices: [
|
|
218
|
+
{
|
|
219
|
+
title: "No - I'll only use execute_python in my AI client",
|
|
220
|
+
value: "none",
|
|
221
|
+
description: "No additional API key needed"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
title: "Yes - OpenAI (GPT-4, etc.)",
|
|
225
|
+
value: "openai",
|
|
226
|
+
description: "Requires OPENAI_API_KEY"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
title: "Yes - Anthropic (Claude)",
|
|
230
|
+
value: "anthropic",
|
|
231
|
+
description: "Requires ANTHROPIC_API_KEY"
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
type: (prev) => prev !== "none" ? "text" : null,
|
|
237
|
+
name: "llmApiKey",
|
|
238
|
+
message: (prev) => prev === "openai" ? "Enter your OpenAI API key (sk-...):" : "Enter your Anthropic API key (sk-ant-...):",
|
|
239
|
+
validate: (v, values) => {
|
|
240
|
+
if (values.llmProvider === "openai" && !v.startsWith("sk-")) {
|
|
241
|
+
return "OpenAI key should start with sk-";
|
|
242
|
+
}
|
|
243
|
+
if (values.llmProvider === "anthropic" && !v.startsWith("sk-ant-")) {
|
|
244
|
+
return "Anthropic key should start with sk-ant-";
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
]);
|
|
250
|
+
llmProvider = llmResponse.llmProvider;
|
|
251
|
+
llmApiKey = llmResponse.llmApiKey;
|
|
252
|
+
}
|
|
253
|
+
let runRlmInit2 = false;
|
|
254
|
+
if (packages.includes("runtime")) {
|
|
255
|
+
console.log(chalk.cyan("\n \u2139\uFE0F RLM-Runtime Execution Environments:\n"));
|
|
256
|
+
console.log(chalk.dim(" \u2022 sandbox - RestrictedPython, safe stdlib only (default)"));
|
|
257
|
+
console.log(chalk.dim(" \u2022 docker - Full Python in isolated container (recommended)"));
|
|
258
|
+
console.log(chalk.dim(" \u2022 local - Full access, no isolation (development only)\n"));
|
|
259
|
+
const initResponse = await prompts({
|
|
260
|
+
type: "confirm",
|
|
261
|
+
name: "runRlmInit",
|
|
262
|
+
message: "Run 'rlm init' now to configure execution environment?",
|
|
263
|
+
initial: false
|
|
264
|
+
});
|
|
265
|
+
runRlmInit2 = initResponse.runRlmInit || false;
|
|
266
|
+
}
|
|
163
267
|
return {
|
|
164
268
|
projectSlug: response.projectSlug,
|
|
165
269
|
projectId: response.projectId || "",
|
|
166
270
|
apiKey: apiKey || "YOUR_API_KEY_HERE",
|
|
271
|
+
apiKeyType,
|
|
167
272
|
installMcp: packages.includes("mcp"),
|
|
168
273
|
installRuntime: packages.includes("runtime"),
|
|
169
274
|
installHooks: packages.includes("hooks"),
|
|
170
|
-
aiClient: response.aiClient || detectedClient
|
|
275
|
+
aiClient: response.aiClient || detectedClient,
|
|
276
|
+
llmProvider,
|
|
277
|
+
llmApiKey,
|
|
278
|
+
runRlmInit: runRlmInit2
|
|
171
279
|
};
|
|
172
280
|
}
|
|
173
281
|
async function handleSignup() {
|
|
@@ -474,12 +582,27 @@ async function updateEnvFiles(answers) {
|
|
|
474
582
|
const envExamplePath = path.join(process.cwd(), ".env.example");
|
|
475
583
|
const envLocalPath = path.join(process.cwd(), ".env.local");
|
|
476
584
|
const envPath = path.join(process.cwd(), ".env");
|
|
477
|
-
|
|
585
|
+
let envVars = "";
|
|
586
|
+
if (answers.apiKeyType !== "none") {
|
|
587
|
+
envVars += `
|
|
478
588
|
# Snipara Configuration
|
|
479
589
|
SNIPARA_API_KEY=${answers.apiKey.includes("YOUR_") ? "your_api_key_here" : answers.apiKey}
|
|
480
590
|
SNIPARA_PROJECT_SLUG=${answers.projectSlug}
|
|
481
591
|
${answers.projectId ? `SNIPARA_PROJECT_ID=${answers.projectId}` : ""}
|
|
482
592
|
`.trim();
|
|
593
|
+
}
|
|
594
|
+
if (answers.llmProvider && answers.llmProvider !== "none" && answers.llmApiKey) {
|
|
595
|
+
const llmVarName = answers.llmProvider === "openai" ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
|
|
596
|
+
envVars += `
|
|
597
|
+
|
|
598
|
+
# RLM-Runtime LLM Provider (for rlm run/agent CLI)
|
|
599
|
+
${llmVarName}=${answers.llmApiKey}`;
|
|
600
|
+
}
|
|
601
|
+
envVars = envVars.trim();
|
|
602
|
+
if (!envVars) {
|
|
603
|
+
console.log(chalk.dim(" No environment variables to save"));
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
483
606
|
if (fs.existsSync(envExamplePath)) {
|
|
484
607
|
const content = fs.readFileSync(envExamplePath, "utf-8");
|
|
485
608
|
if (!content.includes("SNIPARA_API_KEY")) {
|
|
@@ -505,6 +628,32 @@ ${envVars}
|
|
|
505
628
|
}
|
|
506
629
|
}
|
|
507
630
|
}
|
|
631
|
+
async function runRlmInit() {
|
|
632
|
+
console.log(chalk.bold("\n\u{1F527} Running RLM-Runtime Configuration\n"));
|
|
633
|
+
console.log(chalk.dim(" Starting 'rlm init' - follow the prompts to configure execution environment...\n"));
|
|
634
|
+
return new Promise((resolve) => {
|
|
635
|
+
const child = spawn("rlm", ["init"], {
|
|
636
|
+
stdio: "inherit",
|
|
637
|
+
shell: true
|
|
638
|
+
});
|
|
639
|
+
child.on("close", (code) => {
|
|
640
|
+
if (code === 0) {
|
|
641
|
+
console.log(chalk.green("\n \u2713 RLM-Runtime configured successfully"));
|
|
642
|
+
} else if (code !== null) {
|
|
643
|
+
console.log(chalk.yellow(`
|
|
644
|
+
\u26A0\uFE0F rlm init exited with code ${code}`));
|
|
645
|
+
console.log(chalk.dim(" You can run 'rlm init' manually later to configure execution environment."));
|
|
646
|
+
}
|
|
647
|
+
resolve();
|
|
648
|
+
});
|
|
649
|
+
child.on("error", (error) => {
|
|
650
|
+
console.log(chalk.yellow(`
|
|
651
|
+
\u26A0\uFE0F Could not run rlm init: ${error.message}`));
|
|
652
|
+
console.log(chalk.dim(" Run 'rlm init' manually after installation completes."));
|
|
653
|
+
resolve();
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
}
|
|
508
657
|
async function testConnection(answers) {
|
|
509
658
|
console.log(chalk.bold("\n\u{1F50C} Testing Connection\n"));
|
|
510
659
|
const spinner = ora("Connecting to Snipara API...").start();
|
|
@@ -561,9 +710,23 @@ function printSuccess(answers) {
|
|
|
561
710
|
if (answers.installHooks) {
|
|
562
711
|
console.log(chalk.green(" \u2713 Claude Code hooks") + chalk.dim(" - Session memory automation"));
|
|
563
712
|
}
|
|
564
|
-
|
|
713
|
+
if (answers.apiKeyType !== "none") {
|
|
714
|
+
console.log(chalk.green(" \u2713 .mcp.json") + chalk.dim(" - MCP server configuration"));
|
|
715
|
+
}
|
|
716
|
+
if (answers.apiKeyType === "team") {
|
|
717
|
+
console.log(chalk.cyan("\n \u{1F511} Using Team API key - access to all team projects"));
|
|
718
|
+
} else if (answers.apiKeyType === "project") {
|
|
719
|
+
console.log(chalk.dim(`
|
|
720
|
+
\u{1F511} Using Project API key for: ${answers.projectSlug}`));
|
|
721
|
+
}
|
|
565
722
|
console.log(chalk.bold("\nNext steps:\n"));
|
|
566
|
-
if (answers.
|
|
723
|
+
if (answers.apiKeyType === "none" && answers.installRuntime) {
|
|
724
|
+
console.log(" 1. Restart your AI client (Claude Code, Cursor, etc.)");
|
|
725
|
+
console.log(" 2. Use execute_python MCP tool - no API key needed!");
|
|
726
|
+
console.log(chalk.dim("\n For rlm run/agent CLI, set one of these env vars:"));
|
|
727
|
+
console.log(chalk.dim(" export OPENAI_API_KEY=sk-..."));
|
|
728
|
+
console.log(chalk.dim(" export ANTHROPIC_API_KEY=sk-ant-..."));
|
|
729
|
+
} else if (answers.apiKey.includes("YOUR_") || answers.apiKeyType === "none") {
|
|
567
730
|
console.log(` 1. Get your API key at ${chalk.cyan(`${BASE_URL}/signup`)}`);
|
|
568
731
|
console.log(" 2. Update SNIPARA_API_KEY in .mcp.json");
|
|
569
732
|
console.log(" 3. Restart your AI client");
|
|
@@ -573,15 +736,30 @@ function printSuccess(answers) {
|
|
|
573
736
|
console.log(" 3. Start using MCP tools like rlm_context_query");
|
|
574
737
|
}
|
|
575
738
|
if (answers.installRuntime) {
|
|
576
|
-
console.log(chalk.bold("\nRLM-Runtime
|
|
577
|
-
console.log(chalk.dim("
|
|
578
|
-
console.log(chalk.dim("
|
|
579
|
-
console.log(chalk.dim("
|
|
580
|
-
|
|
739
|
+
console.log(chalk.bold("\nRLM-Runtime:\n"));
|
|
740
|
+
console.log(chalk.dim(" MCP tools (no LLM API key needed - your AI client provides the LLM):"));
|
|
741
|
+
console.log(chalk.dim(" \u2022 execute_python - Run Python in sandbox"));
|
|
742
|
+
console.log(chalk.dim(" \u2022 get_repl_context - Get session variables"));
|
|
743
|
+
if (answers.llmProvider && answers.llmProvider !== "none") {
|
|
744
|
+
const providerName = answers.llmProvider === "openai" ? "OpenAI" : "Anthropic";
|
|
745
|
+
console.log(chalk.dim(`
|
|
746
|
+
CLI commands (using ${providerName}):`));
|
|
747
|
+
console.log(chalk.dim(" \u2022 rlm run - Run with LLM orchestration"));
|
|
748
|
+
console.log(chalk.dim(" \u2022 rlm agent - Autonomous agent mode"));
|
|
749
|
+
console.log(chalk.dim(" \u2022 rlm visualize - Trajectory dashboard"));
|
|
750
|
+
} else {
|
|
751
|
+
console.log(chalk.dim("\n CLI commands (not configured - set LLM API key later if needed):"));
|
|
752
|
+
console.log(chalk.dim(" \u2022 rlm run - Requires OPENAI_API_KEY or ANTHROPIC_API_KEY"));
|
|
753
|
+
console.log(chalk.dim(" \u2022 rlm agent - Requires OPENAI_API_KEY or ANTHROPIC_API_KEY"));
|
|
754
|
+
}
|
|
755
|
+
if (!answers.runRlmInit) {
|
|
756
|
+
console.log(chalk.dim("\n To configure execution environment (sandbox/docker/local):"));
|
|
757
|
+
console.log(chalk.cyan(" rlm init"));
|
|
758
|
+
}
|
|
581
759
|
}
|
|
582
760
|
console.log(chalk.dim(`
|
|
583
761
|
Docs: ${BASE_URL}/docs`));
|
|
584
|
-
console.log(chalk.dim(" Support: hello@
|
|
762
|
+
console.log(chalk.dim(" Support: hello@starbox-group.com\n"));
|
|
585
763
|
}
|
|
586
764
|
function detectProjectSlug() {
|
|
587
765
|
try {
|
package/package.json
CHANGED