create-snipara 1.3.0 → 1.3.2
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 +51 -21
- package/dist/index.js +155 -58
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
# create-snipara
|
|
2
2
|
|
|
3
|
-
One-command
|
|
3
|
+
One-command scaffolding and maintenance CLI for **Hosted MCP config + optional snipara-companion + optional RLM-Runtime**.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npx create-snipara
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
`create-snipara` is
|
|
9
|
+
`create-snipara` is onboarding and scaffolding. It is not a product connection surface. The product surfaces remain:
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- Hosted MCP for LLM agents
|
|
12
|
+
- HTTP API / SDK for apps, integrators, backends, and pipelines
|
|
13
|
+
|
|
14
|
+
The CLI can wire local helpers around those surfaces:
|
|
15
|
+
|
|
16
|
+
- `snipara-companion` for local `rlm-hook` workflows when you want them
|
|
13
17
|
- `rlm-runtime` for optional local code execution
|
|
14
18
|
- local config, env files, hook scripts, and a project companion pack
|
|
19
|
+
- `snipara-mcp` only for local stdio compatibility, development, or testing
|
|
15
20
|
|
|
16
21
|
## Install Profiles
|
|
17
22
|
|
|
18
23
|
The CLI now works around explicit install profiles:
|
|
19
24
|
|
|
20
|
-
| Profile | What it installs | Best for
|
|
21
|
-
| ------------------ | ----------------------------------------- |
|
|
22
|
-
| `hosted-only` | MCP config only
|
|
23
|
-
| `hosted-companion` | MCP + `snipara-companion` |
|
|
24
|
-
| `full-stack` | MCP + `snipara-companion` + `rlm-runtime` | Hosted context plus local execution
|
|
25
|
-
| `runtime-only` | `rlm-runtime` only | Local execution without hosted API
|
|
25
|
+
| Profile | What it installs | Best for |
|
|
26
|
+
| ------------------ | ----------------------------------------- | --------------------------------------------------- |
|
|
27
|
+
| `hosted-only` | Hosted MCP config only | Default: agents without local helper workflows |
|
|
28
|
+
| `hosted-companion` | MCP + `snipara-companion` | Hook-heavy clients that want local helper workflows |
|
|
29
|
+
| `full-stack` | MCP + `snipara-companion` + `rlm-runtime` | Hosted context plus local execution |
|
|
30
|
+
| `runtime-only` | `rlm-runtime` only | Local execution without hosted API |
|
|
26
31
|
|
|
27
|
-
Default profile: `hosted-
|
|
32
|
+
Default profile: `hosted-only`
|
|
28
33
|
|
|
29
34
|
## What It Does
|
|
30
35
|
|
|
31
36
|
- detects local environment and project state
|
|
32
|
-
-
|
|
33
|
-
- installs `snipara-
|
|
37
|
+
- writes Hosted MCP configuration
|
|
38
|
+
- installs `snipara-companion` when the selected profile needs local helper workflows
|
|
39
|
+
- installs optional `rlm-runtime`
|
|
34
40
|
- configures `.mcp.json`
|
|
35
41
|
- updates `.env`, `.env.local`, and `.env.example`
|
|
36
42
|
- generates `.snipara/companion/README.md`
|
|
@@ -110,6 +116,7 @@ npx create-snipara print-config --json
|
|
|
110
116
|
|
|
111
117
|
```bash
|
|
112
118
|
# Use an explicit install profile
|
|
119
|
+
npx create-snipara --profile hosted-only
|
|
113
120
|
npx create-snipara --profile hosted-companion
|
|
114
121
|
npx create-snipara --profile full-stack
|
|
115
122
|
|
|
@@ -121,7 +128,7 @@ npx create-snipara -y --api-key rlm_xxx --slug my-project
|
|
|
121
128
|
|
|
122
129
|
# Skip selected layers
|
|
123
130
|
npx create-snipara --skip-companion
|
|
124
|
-
npx create-snipara --skip-mcp
|
|
131
|
+
npx create-snipara --skip-mcp # Skip local snipara-mcp package if explicitly requested
|
|
125
132
|
npx create-snipara --skip-runtime
|
|
126
133
|
npx create-snipara --skip-hooks
|
|
127
134
|
|
|
@@ -135,10 +142,22 @@ npx create-snipara upgrade --with-runtime
|
|
|
135
142
|
The intended split is:
|
|
136
143
|
|
|
137
144
|
- `create-snipara`: install, inspect, repair, and upgrade the local project setup
|
|
138
|
-
- `snipara-companion`: ongoing local runtime workflows through `rlm-hook`
|
|
139
|
-
- `snipara-mcp`:
|
|
145
|
+
- `snipara-companion`: optional ongoing local runtime workflows through `rlm-hook`
|
|
146
|
+
- `snipara-mcp`: local stdio bridge, client-package development, compatibility, and testing
|
|
140
147
|
- `rlm-runtime`: optional local execution engine
|
|
141
148
|
|
|
149
|
+
## Codex Setup
|
|
150
|
+
|
|
151
|
+
For Codex, keep the setup minimal:
|
|
152
|
+
|
|
153
|
+
- use Hosted MCP as the core Snipara surface
|
|
154
|
+
- use `AGENTS.md` for project instructions
|
|
155
|
+
- choose `hosted-only` if you do not need local helper workflows
|
|
156
|
+
- add `snipara-companion` only if you explicitly want the local helper CLI
|
|
157
|
+
- use local `snipara-mcp` only for stdio compatibility, development, or tests
|
|
158
|
+
|
|
159
|
+
Codex does not require hook presets to use Snipara successfully.
|
|
160
|
+
|
|
142
161
|
This keeps setup and runtime separated while still giving the user one obvious command to start from.
|
|
143
162
|
|
|
144
163
|
## Generated Local Pack
|
|
@@ -149,7 +168,18 @@ After setup, the project gets a local pack at `.snipara/companion/`:
|
|
|
149
168
|
- `commands.json`: starter commands for the current project
|
|
150
169
|
- `doctor.json`: most recent validation report
|
|
151
170
|
|
|
152
|
-
This pack is meant to be the local source of truth for machine-level setup.
|
|
171
|
+
This pack is meant to be the local source of truth for machine-level setup. When
|
|
172
|
+
`snipara-companion` is installed, it includes business-folder onboarding commands
|
|
173
|
+
such as:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
rlm-hook onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json
|
|
177
|
+
rlm-hook onboard-folder ./client-export --source-provider local_folder --apply
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Use this for dashboardless business-context imports after an LLM client has
|
|
181
|
+
materialized Drive, Notion, Gmail, or local files into a folder. For source-code
|
|
182
|
+
repositories, use the GitHub OAuth/code onboarding path instead.
|
|
153
183
|
|
|
154
184
|
## API Key Requirements
|
|
155
185
|
|
|
@@ -157,16 +187,16 @@ This pack is meant to be the local source of truth for machine-level setup.
|
|
|
157
187
|
| ------------------------------------ | -------------------- | ----------- |
|
|
158
188
|
| Hosted MCP queries | Required | Not needed |
|
|
159
189
|
| Memory / planning tools | Required | Not needed |
|
|
160
|
-
| `snipara-companion` hosted workflows |
|
|
190
|
+
| `snipara-companion` hosted workflows | Optional | Not needed |
|
|
161
191
|
| `rlm-runtime` `execute_python` MCP | Not needed | Not needed |
|
|
162
192
|
| `rlm run` / `rlm agent` CLI | Optional for context | Required |
|
|
163
193
|
|
|
164
194
|
## Example Flows
|
|
165
195
|
|
|
166
|
-
### Default
|
|
196
|
+
### Default hosted setup
|
|
167
197
|
|
|
168
198
|
```bash
|
|
169
|
-
npx create-snipara --profile hosted-
|
|
199
|
+
npx create-snipara --profile hosted-only
|
|
170
200
|
```
|
|
171
201
|
|
|
172
202
|
### Full local stack
|
|
@@ -193,7 +223,7 @@ npx create-snipara print-config --json
|
|
|
193
223
|
When testing a locally packed tarball, use `npm exec --package` instead of `npx`, for example:
|
|
194
224
|
|
|
195
225
|
```bash
|
|
196
|
-
npm exec --package ./create-snipara-1.3.
|
|
226
|
+
npm exec --package ./create-snipara-1.3.1.tgz create-snipara -- --help
|
|
197
227
|
```
|
|
198
228
|
|
|
199
229
|
This avoids `npx` resolution issues with unpublished tarballs.
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import fs from "fs";
|
|
|
9
9
|
import path from "path";
|
|
10
10
|
import { execSync, spawn } from "child_process";
|
|
11
11
|
import { homedir } from "os";
|
|
12
|
-
var VERSION = "1.3.
|
|
12
|
+
var VERSION = "1.3.1";
|
|
13
13
|
var BASE_URL = "https://www.snipara.com";
|
|
14
14
|
var API_URL = "https://api.snipara.com";
|
|
15
15
|
var COMPANION_PACKAGE_NAME = "snipara-companion";
|
|
@@ -23,11 +23,11 @@ function getCompanionInitClientFlag(aiClient) {
|
|
|
23
23
|
}
|
|
24
24
|
function buildProgram() {
|
|
25
25
|
const program = new Command();
|
|
26
|
-
program.name("create-snipara").description("
|
|
26
|
+
program.name("create-snipara").description("Scaffold hosted Snipara MCP config plus optional local helper workflows").version(VERSION);
|
|
27
27
|
program.command("init").description("Install and configure Snipara for this project").option("--api-key <key>", "Snipara project API key").option("--team-key <key>", "Snipara team API key").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID").option(
|
|
28
28
|
"--profile <profile>",
|
|
29
29
|
"Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
|
|
30
|
-
).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip snipara-mcp installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--runtime-only", "Install only RLM-Runtime").option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
|
|
30
|
+
).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--runtime-only", "Install only RLM-Runtime").option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
|
|
31
31
|
printBanner();
|
|
32
32
|
await runInit(options);
|
|
33
33
|
});
|
|
@@ -58,7 +58,7 @@ function addSharedRootOptions(program) {
|
|
|
58
58
|
program.option("--api-key <key>", "Snipara project API key").option("--team-key <key>", "Snipara team API key").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID").option(
|
|
59
59
|
"--profile <profile>",
|
|
60
60
|
"Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
|
|
61
|
-
).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip snipara-mcp installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--runtime-only", "Install only RLM-Runtime").option("-y, --yes", "Accept defaults without prompting");
|
|
61
|
+
).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip rlm-runtime installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--runtime-only", "Install only RLM-Runtime").option("-y, --yes", "Accept defaults without prompting");
|
|
62
62
|
}
|
|
63
63
|
async function main() {
|
|
64
64
|
const program = buildProgram();
|
|
@@ -72,7 +72,7 @@ async function runInit(options) {
|
|
|
72
72
|
if (answers.installCompanion) {
|
|
73
73
|
await installNodeCompanion(false);
|
|
74
74
|
}
|
|
75
|
-
if (answers.
|
|
75
|
+
if (answers.profile !== "runtime-only" || answers.installRuntime) {
|
|
76
76
|
await createMcpConfig(answers);
|
|
77
77
|
}
|
|
78
78
|
if (answers.installHooks && answers.aiClient === "claude-code") {
|
|
@@ -154,7 +154,10 @@ async function runPrintConfig(options) {
|
|
|
154
154
|
console.log(` Profile: ${answers.profile}`);
|
|
155
155
|
console.log(` AI client: ${answers.aiClient}`);
|
|
156
156
|
console.log(` Companion: ${answers.installCompanion ? "enabled" : "disabled"}`);
|
|
157
|
-
console.log(
|
|
157
|
+
console.log(
|
|
158
|
+
` Hosted MCP config: ${answers.profile !== "runtime-only" ? "enabled" : "disabled"}`
|
|
159
|
+
);
|
|
160
|
+
console.log(` Local snipara-mcp package: ${answers.installMcp ? "enabled" : "disabled"}`);
|
|
158
161
|
console.log(` Runtime: ${answers.installRuntime ? "enabled" : "disabled"}`);
|
|
159
162
|
console.log(` Hooks: ${answers.installHooks ? "enabled" : "disabled"}`);
|
|
160
163
|
console.log(` Existing .mcp.json: ${detection.files.mcpConfig ? "yes" : "no"}`);
|
|
@@ -166,12 +169,12 @@ function printBanner() {
|
|
|
166
169
|
chalk.cyan(`
|
|
167
170
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
168
171
|
\u2551 \u2551
|
|
169
|
-
\u2551 ${chalk.bold("Snipara")} -
|
|
172
|
+
\u2551 ${chalk.bold("Snipara")} - Hosted MCP + API / SDK setup \u2551
|
|
170
173
|
\u2551 \u2551
|
|
171
|
-
\u2551 \u2022 Hosted MCP
|
|
172
|
-
\u2551 \u2022
|
|
173
|
-
\u2551 \u2022
|
|
174
|
-
\u2551 \u2022 One CLI for
|
|
174
|
+
\u2551 \u2022 Hosted MCP for LLM agents \u2551
|
|
175
|
+
\u2551 \u2022 API / SDK for product integrations \u2551
|
|
176
|
+
\u2551 \u2022 Optional local companion and runtime helpers \u2551
|
|
177
|
+
\u2551 \u2022 One CLI for scaffolding, doctor, repair, and upgrade \u2551
|
|
175
178
|
\u2551 \u2551
|
|
176
179
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
177
180
|
`)
|
|
@@ -370,7 +373,7 @@ function resolveRequestedProfile(options) {
|
|
|
370
373
|
if (options.profile && isInstallProfile(options.profile)) {
|
|
371
374
|
return options.profile;
|
|
372
375
|
}
|
|
373
|
-
return "hosted-
|
|
376
|
+
return "hosted-only";
|
|
374
377
|
}
|
|
375
378
|
function isInstallProfile(value) {
|
|
376
379
|
return ["hosted-only", "hosted-companion", "full-stack", "runtime-only"].includes(value);
|
|
@@ -380,12 +383,12 @@ function installProfileChoices() {
|
|
|
380
383
|
{
|
|
381
384
|
title: "Hosted only",
|
|
382
385
|
value: "hosted-only",
|
|
383
|
-
description: "
|
|
386
|
+
description: "Default: hosted MCP config, no local companion or runtime"
|
|
384
387
|
},
|
|
385
388
|
{
|
|
386
389
|
title: "Hosted + Companion",
|
|
387
390
|
value: "hosted-companion",
|
|
388
|
-
description: "
|
|
391
|
+
description: "Hosted MCP config plus optional local companion workflows"
|
|
389
392
|
},
|
|
390
393
|
{
|
|
391
394
|
title: "Hosted + Companion + Runtime",
|
|
@@ -403,19 +406,19 @@ function buildAnswersFromProfile(input) {
|
|
|
403
406
|
const defaults = {
|
|
404
407
|
"hosted-only": {
|
|
405
408
|
installCompanion: false,
|
|
406
|
-
installMcp:
|
|
409
|
+
installMcp: false,
|
|
407
410
|
installRuntime: false,
|
|
408
411
|
installHooks: false
|
|
409
412
|
},
|
|
410
413
|
"hosted-companion": {
|
|
411
414
|
installCompanion: true,
|
|
412
|
-
installMcp:
|
|
415
|
+
installMcp: false,
|
|
413
416
|
installRuntime: false,
|
|
414
417
|
installHooks: input.aiClient === "claude-code"
|
|
415
418
|
},
|
|
416
419
|
"full-stack": {
|
|
417
420
|
installCompanion: true,
|
|
418
|
-
installMcp:
|
|
421
|
+
installMcp: false,
|
|
419
422
|
installRuntime: true,
|
|
420
423
|
installHooks: input.aiClient === "claude-code"
|
|
421
424
|
},
|
|
@@ -507,17 +510,28 @@ async function installPythonPackages(answers, upgrade) {
|
|
|
507
510
|
function stripExtras(name) {
|
|
508
511
|
return name.replace(/\[.*\]$/, "");
|
|
509
512
|
}
|
|
510
|
-
function
|
|
511
|
-
|
|
512
|
-
if (commandExists("
|
|
513
|
-
|
|
513
|
+
function detectNodePackageManagers() {
|
|
514
|
+
const managers = [];
|
|
515
|
+
if (commandExists("pnpm")) {
|
|
516
|
+
managers.push("pnpm");
|
|
517
|
+
}
|
|
518
|
+
if (commandExists("npm")) {
|
|
519
|
+
managers.push("npm");
|
|
520
|
+
}
|
|
521
|
+
return managers;
|
|
522
|
+
}
|
|
523
|
+
function getCompanionInstallCommand(packageManager, upgrade) {
|
|
524
|
+
if (packageManager === "pnpm") {
|
|
525
|
+
return `pnpm add -g ${upgrade ? "--latest " : ""}${COMPANION_PACKAGE_NAME}`;
|
|
526
|
+
}
|
|
527
|
+
return `npm install -g ${upgrade ? COMPANION_PACKAGE_NAME + "@latest" : COMPANION_PACKAGE_NAME}`;
|
|
514
528
|
}
|
|
515
529
|
async function installNodeCompanion(upgrade) {
|
|
516
530
|
console.log(chalk.bold(`
|
|
517
531
|
\u{1F9F0} ${upgrade ? "Upgrading" : "Installing"} Local Companion CLI
|
|
518
532
|
`));
|
|
519
|
-
const
|
|
520
|
-
if (
|
|
533
|
+
const packageManagers = detectNodePackageManagers();
|
|
534
|
+
if (packageManagers.length === 0) {
|
|
521
535
|
console.log(chalk.yellow(" \u26A0\uFE0F npm/pnpm not found. Please install manually:\n"));
|
|
522
536
|
console.log(chalk.gray(` npm install -g ${COMPANION_PACKAGE_NAME}
|
|
523
537
|
`));
|
|
@@ -526,23 +540,40 @@ async function installNodeCompanion(upgrade) {
|
|
|
526
540
|
const spinner = ora(
|
|
527
541
|
`${upgrade ? "Upgrading" : "Installing"} ${COMPANION_PACKAGE_NAME}...`
|
|
528
542
|
).start();
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
543
|
+
const failures = [];
|
|
544
|
+
for (const packageManager of packageManagers) {
|
|
545
|
+
const installCmd = getCompanionInstallCommand(packageManager, upgrade);
|
|
546
|
+
try {
|
|
547
|
+
execSync(installCmd, {
|
|
548
|
+
stdio: "pipe",
|
|
549
|
+
encoding: "utf-8"
|
|
550
|
+
});
|
|
551
|
+
if (commandExists("rlm-hook")) {
|
|
552
|
+
spinner.succeed(
|
|
553
|
+
`${upgrade ? "Upgraded" : "Installed"} ${COMPANION_PACKAGE_NAME} via ${packageManager}`
|
|
554
|
+
);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
failures.push(
|
|
558
|
+
`${packageManager}: command completed but rlm-hook is still not available on PATH`
|
|
559
|
+
);
|
|
560
|
+
} catch (error) {
|
|
561
|
+
const detail = error instanceof Error && "message" in error ? error.message.split("\n")[0] : "unknown error";
|
|
562
|
+
failures.push(`${packageManager}: ${detail}`);
|
|
563
|
+
}
|
|
545
564
|
}
|
|
565
|
+
spinner.fail(`Failed to ${upgrade ? "upgrade" : "install"} ${COMPANION_PACKAGE_NAME}`);
|
|
566
|
+
console.log(chalk.yellow("\n Attempt summary:"));
|
|
567
|
+
for (const failure of failures) {
|
|
568
|
+
console.log(chalk.gray(` - ${failure}`));
|
|
569
|
+
}
|
|
570
|
+
console.log(chalk.yellow("\n Install manually with:"));
|
|
571
|
+
console.log(
|
|
572
|
+
chalk.gray(
|
|
573
|
+
` npm install -g ${upgrade ? COMPANION_PACKAGE_NAME + "@latest" : COMPANION_PACKAGE_NAME}
|
|
574
|
+
`
|
|
575
|
+
)
|
|
576
|
+
);
|
|
546
577
|
}
|
|
547
578
|
async function createMcpConfig(answers) {
|
|
548
579
|
console.log(chalk.bold("\n\u2699\uFE0F Creating Configuration\n"));
|
|
@@ -556,7 +587,7 @@ async function createMcpConfig(answers) {
|
|
|
556
587
|
console.log(chalk.yellow(" Could not parse existing .mcp.json, creating new..."));
|
|
557
588
|
}
|
|
558
589
|
}
|
|
559
|
-
if (answers.
|
|
590
|
+
if (answers.profile !== "runtime-only") {
|
|
560
591
|
mcpConfig.mcpServers.snipara = {
|
|
561
592
|
type: "http",
|
|
562
593
|
url: `${API_URL}/mcp/${answers.projectSlug}`,
|
|
@@ -810,24 +841,42 @@ function getClientGuidance(client) {
|
|
|
810
841
|
if (client === "cursor") {
|
|
811
842
|
return [
|
|
812
843
|
"Cursor reads the generated .mcp.json directly, so the hosted Snipara MCP surface is available after restart.",
|
|
813
|
-
"Use the companion CLI for explicit upload, planning, chunk lookup, doctor, and task commit workflows outside the editor UI."
|
|
844
|
+
"Use the companion CLI only for explicit upload, planning, chunk lookup, doctor, and task commit workflows outside the editor UI."
|
|
814
845
|
];
|
|
815
846
|
}
|
|
816
847
|
if (client === "claude-desktop") {
|
|
817
848
|
return [
|
|
818
849
|
"Claude Desktop uses the generated desktop MCP config plus the same hosted Snipara tool contract.",
|
|
819
|
-
"
|
|
850
|
+
"Use companion only for bootstrap, upload, and task summaries that are easier to run from a terminal."
|
|
820
851
|
];
|
|
821
852
|
}
|
|
822
853
|
return [
|
|
823
|
-
"The generated pack assumes
|
|
824
|
-
"Use the companion CLI
|
|
854
|
+
"The generated pack assumes Hosted MCP for agents and API / SDK for product integrations.",
|
|
855
|
+
"Use the companion CLI only when local planning, upload, doctor, or task commit flows help."
|
|
825
856
|
];
|
|
826
857
|
}
|
|
827
858
|
function getCompanionCommands(answers) {
|
|
828
859
|
const projectIdFlag = answers.projectId ? ` --project-id ${answers.projectId}` : "";
|
|
829
860
|
const apiKeyFlag = answers.apiKeyType === "none" || answers.apiKey.includes("YOUR_") ? " --api-key <rlm_key>" : ` --api-key ${answers.apiKey}`;
|
|
830
861
|
const clientFlag = getCompanionInitClientFlag(answers.aiClient);
|
|
862
|
+
const businessOnboardingCommands = answers.installCompanion ? [
|
|
863
|
+
{
|
|
864
|
+
title: "Preview a business folder import",
|
|
865
|
+
command: "rlm-hook onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json",
|
|
866
|
+
purpose: "Classify a local or LLM-materialized business folder and review the Snipara sync manifest before upload."
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
title: "Apply a business folder import",
|
|
870
|
+
command: "rlm-hook onboard-folder ./client-export --source-provider local_folder --apply",
|
|
871
|
+
purpose: "Upload approved business-context documents to hosted Snipara and trigger document reindexing."
|
|
872
|
+
}
|
|
873
|
+
] : [
|
|
874
|
+
{
|
|
875
|
+
title: "Enable business folder onboarding",
|
|
876
|
+
command: "npx create-snipara repair --with-companion",
|
|
877
|
+
purpose: "Install snipara-companion so this project can run rlm-hook onboard-folder without using the dashboard."
|
|
878
|
+
}
|
|
879
|
+
];
|
|
831
880
|
return [
|
|
832
881
|
{
|
|
833
882
|
title: "Bootstrap local companion",
|
|
@@ -846,8 +895,13 @@ function getCompanionCommands(answers) {
|
|
|
846
895
|
},
|
|
847
896
|
{
|
|
848
897
|
title: "Run a focused hosted query",
|
|
849
|
-
command: 'rlm-hook query --query "
|
|
850
|
-
purpose: "Pull ranked context before editing or
|
|
898
|
+
command: 'rlm-hook query --query "how does auth middleware work?" --max-tokens 4000',
|
|
899
|
+
purpose: "Pull ranked source context before editing, reviewing, or drafting."
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
title: "Load linked standards only when needed",
|
|
903
|
+
command: "rlm-hook shared-context --categories MANDATORY BEST_PRACTICES",
|
|
904
|
+
purpose: "Fetch project-linked team or workspace guidance without treating it as memory."
|
|
851
905
|
},
|
|
852
906
|
{
|
|
853
907
|
title: "Generate a hosted plan",
|
|
@@ -859,6 +913,7 @@ function getCompanionCommands(answers) {
|
|
|
859
913
|
command: "rlm-hook upload --path docs/local-playbook.md --file ./docs/local-playbook.md",
|
|
860
914
|
purpose: "Push local notes or docs into hosted Snipara context."
|
|
861
915
|
},
|
|
916
|
+
...businessOnboardingCommands,
|
|
862
917
|
{
|
|
863
918
|
title: "Inspect a specific chunk",
|
|
864
919
|
command: "rlm-hook chunk get --chunk-id <chunk_id>",
|
|
@@ -867,12 +922,17 @@ function getCompanionCommands(answers) {
|
|
|
867
922
|
{
|
|
868
923
|
title: "Bootstrap the session memory view",
|
|
869
924
|
command: "rlm-hook session-bootstrap",
|
|
870
|
-
purpose: "Load
|
|
925
|
+
purpose: "Load durable decisions, learnings, and optional short-lived carryover at session start."
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
title: "Ask memory about past decisions",
|
|
929
|
+
command: 'rlm-hook recall --query "What did we decide about auth retries?" --type decision',
|
|
930
|
+
purpose: "Query durable memory for past decisions, preferences, or validated learnings."
|
|
871
931
|
},
|
|
872
932
|
{
|
|
873
933
|
title: "Commit durable task memory",
|
|
874
934
|
command: 'rlm-hook task-commit --summary "Hardened webhook retries and updated tests" --category engineering --outcome completed --files src/api/webhooks.ts tests/webhooks.test.ts',
|
|
875
|
-
purpose: "Persist reusable
|
|
935
|
+
purpose: "Persist reusable outcomes back into hosted memory after the work is done."
|
|
876
936
|
}
|
|
877
937
|
];
|
|
878
938
|
}
|
|
@@ -894,7 +954,8 @@ This project uses Snipara as a hosted-first context and memory layer with an opt
|
|
|
894
954
|
- Project id: \`${answers.projectId || "not-set"}\`
|
|
895
955
|
- AI client: \`${answers.aiClient}\`
|
|
896
956
|
- Installed local companion: \`${answers.installCompanion ? "yes" : "no"}\`
|
|
897
|
-
-
|
|
957
|
+
- Generated hosted MCP config: \`${answers.profile !== "runtime-only" ? "yes" : "no"}\`
|
|
958
|
+
- Installed local snipara-mcp package: \`${answers.installMcp ? "yes" : "no"}\`
|
|
898
959
|
- Installed runtime: \`${answers.installRuntime ? "yes" : "no"}\`
|
|
899
960
|
- Generated hooks: \`${answers.installHooks ? "yes" : "no"}\`
|
|
900
961
|
|
|
@@ -910,6 +971,22 @@ This project uses Snipara as a hosted-first context and memory layer with an opt
|
|
|
910
971
|
|
|
911
972
|
${guidance.map((line) => `- ${line}`).join("\n")}
|
|
912
973
|
|
|
974
|
+
## Business Folder Onboarding
|
|
975
|
+
|
|
976
|
+
Use this when Claude, ChatGPT, Codex, or another LLM client has already materialized Drive, Notion, Gmail, or local business files into a folder.
|
|
977
|
+
|
|
978
|
+
${answers.installCompanion ? `Preview first:
|
|
979
|
+
|
|
980
|
+
\`rlm-hook onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json\`
|
|
981
|
+
|
|
982
|
+
Apply only after reviewing the manifest:
|
|
983
|
+
|
|
984
|
+
\`rlm-hook onboard-folder ./client-export --source-provider local_folder --apply\`` : `This setup did not install snipara-companion. Enable it before business folder imports:
|
|
985
|
+
|
|
986
|
+
\`npx create-snipara repair --with-companion\``}
|
|
987
|
+
|
|
988
|
+
For source-code repositories, use the GitHub OAuth/code onboarding path instead of \`onboard-folder\`.
|
|
989
|
+
|
|
913
990
|
## Suggested Commands
|
|
914
991
|
|
|
915
992
|
${commands.map(
|
|
@@ -922,8 +999,10 @@ ${item.purpose}`
|
|
|
922
999
|
|
|
923
1000
|
## Design Rule
|
|
924
1001
|
|
|
1002
|
+
- Context first: use hosted queries, shared-context, and document loads for source truth.
|
|
1003
|
+
- Memory second: use session bootstrap and task commit for durable decisions, learnings, and preferences.
|
|
925
1004
|
- Durable memory, policy, and orchestration stay hosted in Snipara.
|
|
926
|
-
- The local companion is for capture, bootstrap, upload, exploration, doctor, repair, and explicit task summaries.
|
|
1005
|
+
- The local companion is optional tooling for capture, bootstrap, upload, exploration, doctor, repair, and explicit task summaries.
|
|
927
1006
|
`;
|
|
928
1007
|
const pack = {
|
|
929
1008
|
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1104,7 +1183,9 @@ function printSuccess(answers, report) {
|
|
|
1104
1183
|
console.log(` ${chalk.green("\u2713")} ${answers.profile}`);
|
|
1105
1184
|
console.log(chalk.bold("\nWhat was installed:\n"));
|
|
1106
1185
|
if (answers.installMcp) {
|
|
1107
|
-
console.log(
|
|
1186
|
+
console.log(
|
|
1187
|
+
chalk.green(" \u2713 snipara-mcp") + chalk.dim(" - Local stdio compatibility package")
|
|
1188
|
+
);
|
|
1108
1189
|
}
|
|
1109
1190
|
if (answers.installRuntime) {
|
|
1110
1191
|
console.log(chalk.green(" \u2713 rlm-runtime") + chalk.dim(" - Safe code execution"));
|
|
@@ -1117,20 +1198,36 @@ function printSuccess(answers, report) {
|
|
|
1117
1198
|
if (answers.installHooks) {
|
|
1118
1199
|
console.log(chalk.green(" \u2713 hooks") + chalk.dim(" - Local session lifecycle scripts"));
|
|
1119
1200
|
}
|
|
1201
|
+
if (answers.profile !== "runtime-only") {
|
|
1202
|
+
console.log(chalk.green(" \u2713 .mcp.json") + chalk.dim(" - Hosted MCP config"));
|
|
1203
|
+
}
|
|
1120
1204
|
console.log(chalk.green(" \u2713 .snipara/companion") + chalk.dim(" - Local pack + doctor report"));
|
|
1121
1205
|
const failedChecks = report.checks.filter((check) => check.status === "fail");
|
|
1122
1206
|
const warnedChecks = report.checks.filter((check) => check.status === "warn");
|
|
1123
1207
|
console.log(chalk.bold("\nNext steps:\n"));
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1208
|
+
let nextStep = 1;
|
|
1209
|
+
const printNextStep = (message) => {
|
|
1210
|
+
console.log(` ${nextStep}. ${message}`);
|
|
1211
|
+
nextStep += 1;
|
|
1212
|
+
};
|
|
1213
|
+
printNextStep("Restart your AI client if you created or changed hosted MCP config.");
|
|
1214
|
+
printNextStep("Open .snipara/companion/README.md for local commands and repair flow.");
|
|
1215
|
+
printNextStep("Run create-snipara doctor anytime you want a fresh local validation report.");
|
|
1127
1216
|
if (answers.installCompanion) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1217
|
+
printNextStep("Use rlm-hook query / plan / upload / task-commit for explicit local workflows.");
|
|
1218
|
+
printNextStep(
|
|
1219
|
+
"For business folders, preview with: rlm-hook onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json"
|
|
1220
|
+
);
|
|
1221
|
+
printNextStep(
|
|
1222
|
+
"Apply after review with: rlm-hook onboard-folder ./client-export --source-provider local_folder --apply"
|
|
1223
|
+
);
|
|
1224
|
+
} else if (answers.profile !== "runtime-only") {
|
|
1225
|
+
printNextStep(
|
|
1226
|
+
"For dashboardless business folder imports, enable companion with: npx create-snipara repair --with-companion"
|
|
1130
1227
|
);
|
|
1131
1228
|
}
|
|
1132
1229
|
if (answers.installRuntime && !answers.runRlmInit) {
|
|
1133
|
-
|
|
1230
|
+
printNextStep("Run rlm init when you want to choose sandbox/docker/local execution.");
|
|
1134
1231
|
}
|
|
1135
1232
|
if (failedChecks.length > 0 || warnedChecks.length > 0) {
|
|
1136
1233
|
console.log(chalk.bold("\nValidation summary:\n"));
|
|
@@ -1229,7 +1326,7 @@ function resolveMaintenanceProfile(detection, explicitProfile) {
|
|
|
1229
1326
|
if (detection.existingConfig.hasSniparaServer) {
|
|
1230
1327
|
return "hosted-only";
|
|
1231
1328
|
}
|
|
1232
|
-
return detection.tooling.runtimeCli ? "runtime-only" : "hosted-
|
|
1329
|
+
return detection.tooling.runtimeCli ? "runtime-only" : "hosted-only";
|
|
1233
1330
|
}
|
|
1234
1331
|
function readApiKeyFromEnvFiles() {
|
|
1235
1332
|
const candidates = [".env.local", ".env"];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-snipara",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.2",
|
|
4
|
+
"description": "Scaffold hosted Snipara MCP config plus optional local helper and runtime workflows",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|