create-snipara 1.3.16 → 1.3.18

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.
Files changed (3) hide show
  1. package/README.md +35 -14
  2. package/dist/index.js +327 -49
  3. package/package.json +5 -1
package/README.md CHANGED
@@ -16,7 +16,7 @@ so an LLM client can use Snipara context and reviewed memory.
16
16
 
17
17
  Use it for:
18
18
 
19
- - Hosted MCP onboarding for Codex, Claude Code, Cursor, ChatGPT Desktop, and similar clients
19
+ - Hosted MCP onboarding for Claude Code, Cursor, Windsurf, Codex, Gemini, VS Code/Copilot, Continue, ChatGPT Desktop, and similar clients
20
20
  - free account signup with reviewed Context + Memory
21
21
  - local project wiring, `doctor`, `repair`, and `upgrade`
22
22
  - GitHub repository sync and PR Answer Packs approval when the current folder is a GitHub repo
@@ -32,8 +32,8 @@ flowchart LR
32
32
  Project["Local project"] --> CLI["npx create-snipara"]
33
33
  CLI --> Auth["Snipara auth and project key"]
34
34
  CLI --> MCP["Hosted MCP config"]
35
- CLI --> Templates["AGENTS.md, CLAUDE.md, Cursor, Codex snippets"]
36
- MCP --> Agents["Codex, Claude Code, Cursor, ChatGPT Desktop"]
35
+ CLI --> Templates["AGENTS.md, CLAUDE.md, Cursor, Codex, MCP references"]
36
+ MCP --> Agents["Claude Code, Cursor, Codex, Gemini, VS Code, ChatGPT"]
37
37
  Templates --> Agents
38
38
  Agents --> Context["Snipara context and memory"]
39
39
  ```
@@ -52,6 +52,7 @@ The default CLI path wires the local companion around those surfaces:
52
52
 
53
53
  - `snipara-companion` for local workflow commands and managed phase commits; legacy `rlm-hook` commands remain compatible
54
54
  - `snipara-sandbox` for optional local code execution
55
+ - `snipara-orchestrator` only when explicitly requested with `--with-orchestrator`
55
56
  - local config, env files, hook scripts, and a project companion pack
56
57
  - `snipara-mcp` only for local stdio compatibility, development, or testing
57
58
 
@@ -59,12 +60,12 @@ The default CLI path wires the local companion around those surfaces:
59
60
 
60
61
  The CLI now works around explicit install profiles:
61
62
 
62
- | Profile | What it installs | Best for |
63
- | ------------------ | --------------------------------------------- | --------------------------------------------------- |
64
- | `hosted-companion` | MCP + `snipara-companion` | Default: hosted context plus managed local workflow |
65
- | `hosted-only` | Hosted MCP config only | Locked-down or minimal environments |
66
- | `full-stack` | MCP + `snipara-companion` + `snipara-sandbox` | Hosted context plus sandboxed local execution |
67
- | `runtime-only` | `snipara-sandbox` only | Local execution without hosted API |
63
+ | Profile | What it installs | Best for |
64
+ | ------------------ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
65
+ | `hosted-companion` | MCP + `snipara-companion` | Default: hosted context plus managed local workflow |
66
+ | `hosted-only` | Hosted MCP config only | Locked-down or minimal environments |
67
+ | `full-stack` | MCP + `snipara-companion` + `snipara-sandbox` | Hosted context plus sandboxed local execution. Does not include orchestrator unless `--with-orchestrator` is passed |
68
+ | `runtime-only` | `snipara-sandbox` only | Local execution without hosted API |
68
69
 
69
70
  Default profile: `hosted-companion`
70
71
 
@@ -74,7 +75,7 @@ Free onboarding is now **Context + Memory**, not Context-only:
74
75
 
75
76
  - Context Free: three projects and 1,000 context queries/month
76
77
  - Memory Free: reviewed hosted memories for continuity across sessions
77
- - Hosted MCP: direct connection for Claude Code, Codex, Cursor, ChatGPT Desktop, and other MCP clients
78
+ - Hosted MCP: direct connection for Claude Code, Cursor, Windsurf, Codex, Gemini, VS Code/Copilot, Continue, ChatGPT Desktop, and other MCP clients
78
79
 
79
80
  The CLI opens a browser device-flow login when the user does not already have a key, auto-provisions the free Context + Memory account when needed, then writes the returned API key into the local MCP config.
80
81
 
@@ -102,9 +103,11 @@ That distinction matters:
102
103
  - explains the GitHub PR Answer Packs path for AI-assisted pull request workflows
103
104
  - installs `snipara-companion` by default for local managed workflows
104
105
  - installs optional `snipara-sandbox`
106
+ - installs optional `snipara-orchestrator` for proof gates, drift checks, and htask workflows when requested
105
107
  - configures `.mcp.json`
106
108
  - generates merge-ready AI agent templates in `.snipara/templates/`, including Pro+ symbol-card, code-impact, and managed workflow guidance for paid Context plans
107
109
  - creates `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/snipara.mdc`, and `.codex/config.toml` when those files do not already exist
110
+ - writes client-specific companion packs such as `.snipara/companion/CODEX.md` or `.snipara/companion/GEMINI.md`
108
111
  - updates `.env`, `.env.local`, and `.env.example`
109
112
  - generates `.snipara/companion/README.md`
110
113
  - generates `.snipara/companion/commands.json`
@@ -139,6 +142,8 @@ By default, this uses the recommended `hosted-companion` setup: hosted MCP plus
139
142
  the local `snipara-companion` workflow helper. Legacy `rlm-hook` commands remain
140
143
  compatible. Add `--advanced` when you want profile selection, project id entry,
141
144
  hook prompts, GitHub automation prompts, or sandbox provider prompts.
145
+ Use `--with-orchestrator` only when you explicitly need the advanced production
146
+ validation and htask package; it is not part of `full-stack` by default.
142
147
 
143
148
  The advanced flow asks for:
144
149
 
@@ -155,6 +160,7 @@ The generated agent templates cover:
155
160
  - Cursor `.cursor/rules/snipara.mdc`
156
161
  - Codex `.codex/config.toml` snippet
157
162
  - ChatGPT/OpenAI HTTP MCP snippet
163
+ - Gemini, VS Code, Continue, and custom HTTP MCP reference snippets
158
164
 
159
165
  When `snipara-companion` is installed, the companion pack also includes the compaction-safe managed workflow:
160
166
 
@@ -297,18 +303,22 @@ The intended split is:
297
303
  - `snipara-mcp`: local stdio bridge, client-package development, compatibility, and testing
298
304
  - `snipara-sandbox`: optional local execution engine
299
305
 
300
- ## Codex Setup
306
+ ## Client Packs
301
307
 
302
- For Codex, keep Hosted MCP as the core path and let companion add workflow
303
- ergonomics:
308
+ For every selected AI client, keep Hosted MCP as the core path and let
309
+ companion add workflow ergonomics:
304
310
 
305
311
  - use Hosted MCP as the core Snipara surface
306
312
  - use `AGENTS.md` for project instructions
313
+ - use the selected pack under `.snipara/companion/`, for example `CODEX.md`, `CURSOR.md`, or `GEMINI.md`
307
314
  - use the default `hosted-companion` path when you want compaction-safe local phase commits
308
315
  - choose `hosted-only` or `--skip-companion` only in locked-down environments
309
316
  - use local `snipara-mcp` only for stdio compatibility, development, or tests
310
317
 
311
- Codex does not require hook presets to use Snipara successfully.
318
+ Claude Code, Cursor, and Windsurf can receive generated automation files when
319
+ that client has a useful local hook surface. Codex, Gemini, VS Code, Continue,
320
+ ChatGPT, and custom clients are treated as MCP-first: they get the hosted MCP
321
+ configuration/reference and agent instructions, not invented local hooks.
312
322
 
313
323
  This keeps setup and runtime separated while still giving the user one obvious command to start from.
314
324
 
@@ -317,6 +327,7 @@ This keeps setup and runtime separated while still giving the user one obvious c
317
327
  After setup, the project gets a local pack at `.snipara/companion/`:
318
328
 
319
329
  - `README.md`: local usage guidance
330
+ - `<CLIENT>.md`: selected client setup overlay, such as `CODEX.md` or `GEMINI.md`
320
331
  - `commands.json`: starter commands for the current project
321
332
  - `doctor.json`: most recent validation report
322
333
 
@@ -414,6 +425,16 @@ npx create-snipara --profile full-stack --advanced
414
425
 
415
426
  Best when the user also wants sandboxed `snipara-sandbox` execution.
416
427
 
428
+ ### Full local stack plus production orchestration
429
+
430
+ ```bash
431
+ npx create-snipara --profile full-stack --with-orchestrator
432
+ ```
433
+
434
+ Best when the user wants Hosted MCP, companion workflows, Sandbox execution, and
435
+ the explicit `snipara-orchestrator` package for production gates, drift checks,
436
+ or htask coordination.
437
+
417
438
  ### Connect the current repository
418
439
 
419
440
  ```bash
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.15";
12
+ var VERSION = "1.3.18";
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";
@@ -18,18 +18,77 @@ var LEGACY_COMPANION_COMMAND_NAME = "rlm-hook";
18
18
  var GITHUB_ANSWER_PACKS_LABEL = "GitHub PR Answer Packs";
19
19
  var MCP_PACKAGE_NAME = "snipara-mcp";
20
20
  var SANDBOX_PACKAGE_NAME = "snipara-sandbox[all]";
21
+ var ORCHESTRATOR_PACKAGE_NAME = "snipara-orchestrator";
21
22
  var SANDBOX_SERVER_NAME = "snipara-sandbox";
22
23
  var LEGACY_RUNTIME_SERVER_NAME = "rlm-runtime";
23
24
  var SANDBOX_COMMAND_NAME = "snipara-sandbox";
24
25
  var LEGACY_SANDBOX_COMMAND_NAME = "rlm";
26
+ var ORCHESTRATOR_COMMAND_NAME = "snipara-orchestrator";
25
27
  var DEVICE_CLIENT_ID = "create-snipara";
26
28
  var DeviceAuthorizationAborted = class extends Error {
27
29
  };
30
+ var AI_CLIENT_CHOICES = [
31
+ {
32
+ title: "Claude Code (CLI/VS Code extension)",
33
+ value: "claude-code",
34
+ description: "Best hooks support"
35
+ },
36
+ {
37
+ title: "Cursor",
38
+ value: "cursor",
39
+ description: "Hosted MCP plus Cursor rules and automation bundles"
40
+ },
41
+ {
42
+ title: "Windsurf",
43
+ value: "windsurf",
44
+ description: "Hosted MCP plus Windsurf automation bundles"
45
+ },
46
+ {
47
+ title: "OpenAI Codex",
48
+ value: "codex",
49
+ description: "Hosted MCP plus AGENTS.md and Codex config"
50
+ },
51
+ {
52
+ title: "Gemini CLI",
53
+ value: "gemini",
54
+ description: "Hosted MCP reference plus agent instructions"
55
+ },
56
+ {
57
+ title: "VS Code / Copilot",
58
+ value: "vscode",
59
+ description: "Hosted MCP reference for VS Code-compatible clients"
60
+ },
61
+ {
62
+ title: "Continue",
63
+ value: "continue",
64
+ description: "Hosted MCP reference for Continue"
65
+ },
66
+ {
67
+ title: "ChatGPT / OpenAI MCP",
68
+ value: "chatgpt",
69
+ description: "Hosted MCP for ChatGPT Desktop or OpenAI-compatible clients"
70
+ },
71
+ {
72
+ title: "Claude Desktop",
73
+ value: "claude-desktop",
74
+ description: "Desktop MCP config flow"
75
+ },
76
+ { title: "Other MCP client", value: "other" }
77
+ ];
28
78
  function getCompanionInitClientFlag(aiClient) {
29
- if (aiClient === "cursor") {
30
- return " --client cursor";
31
- }
32
- return aiClient === "claude-code" ? " --client claude-code" : "";
79
+ const supportedClientMap = {
80
+ "claude-code": "claude-code",
81
+ cursor: "cursor",
82
+ windsurf: "windsurf",
83
+ codex: "codex",
84
+ gemini: "gemini",
85
+ chatgpt: "chatgpt",
86
+ vscode: "vscode",
87
+ continue: "continue",
88
+ other: "custom"
89
+ };
90
+ const companionClient = supportedClientMap[aiClient];
91
+ return companionClient ? ` --client ${companionClient}` : "";
33
92
  }
34
93
  function buildProgram() {
35
94
  const program = new Command();
@@ -37,7 +96,7 @@ function buildProgram() {
37
96
  program.command("init").description("Install and configure Snipara for this project").option("--api-key <key>", "Snipara API key").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID").option("--advanced", "Show advanced profile, project id, hooks, GitHub, and sandbox prompts").option(
38
97
  "--profile <profile>",
39
98
  "Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
40
- ).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip snipara-sandbox installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--github", "Open GitHub repository automation setup when a git remote is detected").option("--skip-github", "Skip the GitHub automation prompt").option("--github-path <path>", "Optional GitHub path filter for the initial repository sync").option("--runtime-only", "Install only Snipara Sandbox").option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
99
+ ).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip snipara-sandbox installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--with-orchestrator", "Install optional snipara-orchestrator package").option("--github", "Open GitHub repository automation setup when a git remote is detected").option("--skip-github", "Skip the GitHub automation prompt").option("--github-path <path>", "Optional GitHub path filter for the initial repository sync").option("--runtime-only", "Install only Snipara Sandbox").option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
41
100
  printBanner();
42
101
  await runInit(options);
43
102
  });
@@ -45,11 +104,11 @@ function buildProgram() {
45
104
  printBanner();
46
105
  await runDoctor(options);
47
106
  });
48
- program.command("repair").description("Rebuild local Snipara config and re-run validation").option("--api-key <key>", "Snipara API key override").option("--slug <slug>", "Project slug override").option("--project-id <id>", "Project ID override").option("--profile <profile>", "Target install profile").option("--with-hooks", "Force hook generation").option("--with-runtime", "Force Snipara Sandbox server/config").option("--with-mcp", "Force MCP config").option("--with-companion", "Force companion pack generation").action(async (options) => {
107
+ program.command("repair").description("Rebuild local Snipara config and re-run validation").option("--api-key <key>", "Snipara API key override").option("--slug <slug>", "Project slug override").option("--project-id <id>", "Project ID override").option("--profile <profile>", "Target install profile").option("--with-hooks", "Force hook generation").option("--with-runtime", "Force Snipara Sandbox server/config").option("--with-mcp", "Force MCP config").option("--with-companion", "Force companion pack generation").option("--with-orchestrator", "Install optional snipara-orchestrator package").action(async (options) => {
49
108
  printBanner();
50
109
  await runRepair(options);
51
110
  });
52
- program.command("upgrade").description("Upgrade installed Snipara local components").option("--with-hooks", "Refresh hooks after upgrade").option("--with-runtime", "Upgrade Snipara Sandbox even if not detected").option("--with-mcp", "Upgrade snipara-mcp even if not detected").option("--with-companion", "Upgrade companion even if not detected").action(async (options) => {
111
+ program.command("upgrade").description("Upgrade installed Snipara local components").option("--with-hooks", "Refresh hooks after upgrade").option("--with-runtime", "Upgrade Snipara Sandbox even if not detected").option("--with-mcp", "Upgrade snipara-mcp even if not detected").option("--with-companion", "Upgrade companion even if not detected").option("--with-orchestrator", "Upgrade snipara-orchestrator even if not detected").action(async (options) => {
53
112
  printBanner();
54
113
  await runUpgrade(options);
55
114
  });
@@ -68,7 +127,7 @@ function addSharedRootOptions(program) {
68
127
  program.option("--api-key <key>", "Snipara API key").option("--slug <slug>", "Project slug").option("--project-id <id>", "Project ID").option("--advanced", "Show advanced profile, project id, hooks, GitHub, and sandbox prompts").option(
69
128
  "--profile <profile>",
70
129
  "Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
71
- ).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip snipara-sandbox installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--github", "Open GitHub repository automation setup when a git remote is detected").option("--skip-github", "Skip the GitHub automation prompt").option("--github-path <path>", "Optional GitHub path filter for the initial repository sync").option("--runtime-only", "Install only Snipara Sandbox").option("-y, --yes", "Accept defaults without prompting");
130
+ ).option("--skip-companion", "Skip local companion CLI installation").option("--skip-mcp", "Skip local snipara-mcp package installation").option("--skip-runtime", "Skip snipara-sandbox installation").option("--skip-hooks", "Skip hook generation").option("--skip-test", "Skip hosted connection test").option("--with-orchestrator", "Install optional snipara-orchestrator package").option("--github", "Open GitHub repository automation setup when a git remote is detected").option("--skip-github", "Skip the GitHub automation prompt").option("--github-path <path>", "Optional GitHub path filter for the initial repository sync").option("--runtime-only", "Install only Snipara Sandbox").option("-y, --yes", "Accept defaults without prompting");
72
131
  }
73
132
  async function main() {
74
133
  const program = buildProgram();
@@ -100,6 +159,7 @@ function parseInitOptionsFromArgv(args) {
100
159
  "--skip-runtime": "skipRuntime",
101
160
  "--skip-hooks": "skipHooks",
102
161
  "--skip-test": "skipTest",
162
+ "--with-orchestrator": "withOrchestrator",
103
163
  "--runtime-only": "runtimeOnly",
104
164
  "--github": "github",
105
165
  "--skip-github": "skipGithub",
@@ -130,7 +190,7 @@ function parseInitOptionsFromArgv(args) {
130
190
  }
131
191
  async function runInit(options) {
132
192
  const answers = await gatherConfiguration(normalizeInitOptions(options));
133
- if (answers.installMcp || answers.installRuntime) {
193
+ if (answers.installMcp || answers.installRuntime || answers.installOrchestrator) {
134
194
  await installPythonPackages(answers, false);
135
195
  }
136
196
  if (answers.installCompanion) {
@@ -168,7 +228,7 @@ async function runDoctor(options) {
168
228
  async function runRepair(options) {
169
229
  const answers = loadExistingAnswers(options);
170
230
  console.log(chalk.bold("\n\u{1F6E0}\uFE0F Repairing Local Setup\n"));
171
- if (answers.installMcp || answers.installRuntime) {
231
+ if (answers.installMcp || answers.installRuntime || answers.installOrchestrator) {
172
232
  await installPythonPackages(answers, true);
173
233
  }
174
234
  if (answers.installCompanion) {
@@ -191,10 +251,11 @@ async function runUpgrade(options) {
191
251
  const upgradedAnswers = {
192
252
  ...answers,
193
253
  installMcp: options.withMcp || answers.installMcp,
194
- installRuntime: options.withRuntime || answers.installRuntime
254
+ installRuntime: options.withRuntime || answers.installRuntime,
255
+ installOrchestrator: options.withOrchestrator || answers.installOrchestrator
195
256
  };
196
257
  console.log(chalk.bold("\n\u2B06\uFE0F Upgrading Local Components\n"));
197
- if (options.withMcp || options.withRuntime || detection.existingConfig.hasRuntimeServer) {
258
+ if (options.withMcp || options.withRuntime || options.withOrchestrator || detection.existingConfig.hasRuntimeServer || detection.tooling.orchestratorCli) {
198
259
  await installPythonPackages(upgradedAnswers, true);
199
260
  }
200
261
  if (options.withCompanion || detection.tooling.companionCli || answers.installCompanion) {
@@ -207,8 +268,8 @@ async function runUpgrade(options) {
207
268
  if (options.withHooks || answers.installHooks) {
208
269
  await installClaudeCodeHooks({ ...answers, installHooks: true });
209
270
  }
210
- await createCompanionPack(answers);
211
- const report = await runValidation(answers, true);
271
+ await createCompanionPack(upgradedAnswers);
272
+ const report = await runValidation(upgradedAnswers, true);
212
273
  writeDoctorReport(report);
213
274
  printDoctorReport(detectEnvironment(), report);
214
275
  }
@@ -245,6 +306,7 @@ async function runPrintConfig(options) {
245
306
  );
246
307
  console.log(` Local snipara-mcp package: ${answers.installMcp ? "enabled" : "disabled"}`);
247
308
  console.log(` Snipara Sandbox: ${answers.installRuntime ? "enabled" : "disabled"}`);
309
+ console.log(` Snipara Orchestrator: ${answers.installOrchestrator ? "enabled" : "disabled"}`);
248
310
  console.log(` Hooks: ${answers.installHooks ? "enabled" : "disabled"}`);
249
311
  console.log(` GitHub repo: ${githubRepo ? githubRepo.fullName : "not detected"}`);
250
312
  console.log(` ${GITHUB_ANSWER_PACKS_LABEL}: ${githubAnswerPacks}`);
@@ -305,6 +367,7 @@ async function gatherConfiguration(options) {
305
367
  skipCompanion: !!options.skipCompanion,
306
368
  skipMcp: !!options.skipMcp,
307
369
  skipRuntime: !!options.skipRuntime,
370
+ withOrchestrator: !!options.withOrchestrator,
308
371
  skipHooks: !!options.skipHooks,
309
372
  configureGitHub: Boolean(options.github && detectedGitRepo && !options.skipGithub),
310
373
  githubRepo: detectedGitRepo || void 0,
@@ -363,37 +426,17 @@ async function gatherConfiguration(options) {
363
426
  type: "select",
364
427
  name: "aiClient",
365
428
  message: "Which AI client are you using?",
366
- initial: ["claude-code", "cursor", "codex", "chatgpt", "claude-desktop", "other"].indexOf(
367
- detectedClient
429
+ initial: Math.max(
430
+ 0,
431
+ AI_CLIENT_CHOICES.findIndex((choice) => choice.value === detectedClient)
368
432
  ),
369
- choices: [
370
- {
371
- title: "Claude Code (CLI/VS Code extension)",
372
- value: "claude-code",
373
- description: "Best hooks support"
374
- },
375
- {
376
- title: "Cursor",
377
- value: "cursor",
378
- description: "MCP via .mcp.json plus companion terminal workflows"
379
- },
380
- {
381
- title: "OpenAI Codex",
382
- value: "codex",
383
- description: "Hosted MCP plus AGENTS.md"
384
- },
385
- {
386
- title: "ChatGPT / OpenAI MCP",
387
- value: "chatgpt",
388
- description: "Hosted MCP for ChatGPT Desktop or OpenAI-compatible clients"
389
- },
390
- {
391
- title: "Claude Desktop",
392
- value: "claude-desktop",
393
- description: "Desktop MCP config flow"
394
- },
395
- { title: "Other", value: "other" }
396
- ]
433
+ choices: AI_CLIENT_CHOICES
434
+ },
435
+ {
436
+ type: showAdvancedPrompts ? "confirm" : null,
437
+ name: "installOrchestrator",
438
+ message: "Install snipara-orchestrator for production gates, drift checks, or htask workflows?",
439
+ initial: Boolean(options.withOrchestrator)
397
440
  },
398
441
  {
399
442
  type: showAdvancedPrompts ? "confirm" : null,
@@ -440,6 +483,7 @@ async function gatherConfiguration(options) {
440
483
  skipCompanion: !!options.skipCompanion,
441
484
  skipMcp: !!options.skipMcp,
442
485
  skipRuntime: !!options.skipRuntime,
486
+ withOrchestrator: Boolean(options.withOrchestrator || response.installOrchestrator),
443
487
  skipHooks: !!options.skipHooks || !response.installHooks,
444
488
  configureGitHub: Boolean(
445
489
  (response.configureGitHub || options.github) && detectedGitRepo && !options.skipGithub
@@ -571,6 +615,7 @@ function buildAnswersFromProfile(input) {
571
615
  installCompanion: selected.installCompanion && !input.skipCompanion,
572
616
  installMcp: selected.installMcp && !input.skipMcp,
573
617
  installRuntime: selected.installRuntime && !input.skipRuntime,
618
+ installOrchestrator: input.withOrchestrator,
574
619
  installHooks: selected.installHooks && !input.skipHooks,
575
620
  aiClient: input.aiClient,
576
621
  configureGitHub: Boolean(input.configureGitHub && input.githubRepo),
@@ -725,6 +770,9 @@ function detectSandboxCommand() {
725
770
  }
726
771
  return null;
727
772
  }
773
+ function detectOrchestratorCommand() {
774
+ return commandExists(ORCHESTRATOR_COMMAND_NAME) ? ORCHESTRATOR_COMMAND_NAME : null;
775
+ }
728
776
  async function installPythonPackages(answers, upgrade) {
729
777
  console.log(chalk.bold(`
730
778
  \u{1F4E6} ${upgrade ? "Upgrading" : "Installing"} Python Packages
@@ -738,6 +786,11 @@ async function installPythonPackages(answers, upgrade) {
738
786
  if (answers.installRuntime) {
739
787
  console.log(chalk.gray(` pip install ${upgrade ? "-U " : ""}${SANDBOX_PACKAGE_NAME}`));
740
788
  }
789
+ if (answers.installOrchestrator) {
790
+ console.log(
791
+ chalk.gray(` pip install ${upgrade ? "-U " : ""}${ORCHESTRATOR_PACKAGE_NAME}`)
792
+ );
793
+ }
741
794
  console.log("");
742
795
  return;
743
796
  }
@@ -748,6 +801,9 @@ async function installPythonPackages(answers, upgrade) {
748
801
  if (answers.installRuntime) {
749
802
  packages.push(SANDBOX_PACKAGE_NAME);
750
803
  }
804
+ if (answers.installOrchestrator) {
805
+ packages.push(ORCHESTRATOR_PACKAGE_NAME);
806
+ }
751
807
  if (packages.length === 0) return;
752
808
  const spinner = ora(
753
809
  `${upgrade ? "Upgrading" : "Installing"} ${packages.map(stripExtras).join(", ")}...`
@@ -906,6 +962,22 @@ async function createAgentTemplates(answers) {
906
962
  {
907
963
  path: path.join(templatesDir, "chatgpt-openai-mcp.json"),
908
964
  content: buildChatGptMcpTemplate(answers)
965
+ },
966
+ {
967
+ path: path.join(templatesDir, "gemini-mcp-reference.json"),
968
+ content: buildGenericMcpReferenceTemplate(answers, "gemini")
969
+ },
970
+ {
971
+ path: path.join(templatesDir, "vscode-mcp-reference.json"),
972
+ content: buildGenericMcpReferenceTemplate(answers, "vscode")
973
+ },
974
+ {
975
+ path: path.join(templatesDir, "continue-mcp-reference.json"),
976
+ content: buildGenericMcpReferenceTemplate(answers, "continue")
977
+ },
978
+ {
979
+ path: path.join(templatesDir, "custom-mcp-reference.json"),
980
+ content: buildGenericMcpReferenceTemplate(answers, "custom")
909
981
  }
910
982
  ];
911
983
  for (const template of templates) {
@@ -1054,6 +1126,26 @@ function buildChatGptMcpTemplate(answers) {
1054
1126
  )}
1055
1127
  `;
1056
1128
  }
1129
+ function buildGenericMcpReferenceTemplate(answers, client) {
1130
+ return `${JSON.stringify(
1131
+ {
1132
+ client,
1133
+ note: "Reference format only; paste the server fields into this client's MCP settings.",
1134
+ mcpServers: {
1135
+ snipara: {
1136
+ type: "http",
1137
+ url: buildHostedMcpEndpoint(answers),
1138
+ headers: {
1139
+ "X-API-Key": "${SNIPARA_API_KEY}"
1140
+ }
1141
+ }
1142
+ }
1143
+ },
1144
+ null,
1145
+ 2
1146
+ )}
1147
+ `;
1148
+ }
1057
1149
  function ensureGitignoreEntry(entry, comment) {
1058
1150
  const gitignorePath = path.join(process.cwd(), ".gitignore");
1059
1151
  if (fs.existsSync(gitignorePath)) {
@@ -1347,12 +1439,36 @@ function getClientGuidance(client) {
1347
1439
  "Use the companion CLI only for explicit upload, planning, chunk lookup, doctor, and task commit workflows outside the editor UI."
1348
1440
  ];
1349
1441
  }
1442
+ if (client === "windsurf") {
1443
+ return [
1444
+ "Windsurf should use the hosted MCP surface plus generated Windsurf automation bundles when available.",
1445
+ "Use snipara-companion automations install --client windsurf when you want dashboard-managed hook files in the local project."
1446
+ ];
1447
+ }
1350
1448
  if (client === "codex") {
1351
1449
  return [
1352
1450
  "Codex should use the hosted MCP surface plus AGENTS.md as the canonical project instruction file.",
1353
1451
  "The generated .snipara/templates/codex-config.toml is a merge-ready snippet for ~/.codex/config.toml if your Codex app does not read project .codex/config.toml."
1354
1452
  ];
1355
1453
  }
1454
+ if (client === "gemini") {
1455
+ return [
1456
+ "Gemini should use Hosted MCP plus the generated AGENTS.md rules; no local shell hooks are assumed.",
1457
+ "Use .snipara/templates/gemini-mcp-reference.json as a field reference for the client's MCP settings."
1458
+ ];
1459
+ }
1460
+ if (client === "vscode") {
1461
+ return [
1462
+ "VS Code and Copilot-style clients should use Hosted MCP plus AGENTS.md for project workflow rules.",
1463
+ "Use .snipara/templates/vscode-mcp-reference.json as the Snipara server reference when adding an MCP server."
1464
+ ];
1465
+ }
1466
+ if (client === "continue") {
1467
+ return [
1468
+ "Continue should use Hosted MCP for Snipara tools and keep AGENTS.md as the shared project instruction source.",
1469
+ "Use .snipara/templates/continue-mcp-reference.json as the Snipara server reference when wiring MCP."
1470
+ ];
1471
+ }
1356
1472
  if (client === "chatgpt") {
1357
1473
  return [
1358
1474
  "ChatGPT and OpenAI-compatible MCP clients should use the direct hosted MCP endpoint.",
@@ -1366,13 +1482,13 @@ function getClientGuidance(client) {
1366
1482
  ];
1367
1483
  }
1368
1484
  return [
1369
- "The generated pack assumes Hosted MCP for agents and API / SDK for product integrations.",
1370
- "Use the companion CLI only when local planning, upload, doctor, or task commit flows help."
1485
+ "The generated pack assumes a generic streamable HTTP MCP client plus AGENTS.md for shared workflow rules.",
1486
+ "Use .snipara/templates/custom-mcp-reference.json as the server reference and use companion only when local planning, upload, doctor, or task commit flows help."
1371
1487
  ];
1372
1488
  }
1373
1489
  function getCompanionCommands(answers) {
1374
1490
  const projectIdFlag = answers.projectId ? ` --project-id ${answers.projectId}` : "";
1375
- const apiKeyFlag = answers.apiKeyType === "none" || answers.apiKey.includes("YOUR_") ? " --api-key <rlm-key>" : ` --api-key ${answers.apiKey}`;
1491
+ const apiKeyFlag = " --api-key <snipara-key>";
1376
1492
  const clientFlag = getCompanionInitClientFlag(answers.aiClient);
1377
1493
  const businessOnboardingCommands = answers.installCompanion ? [
1378
1494
  {
@@ -1447,6 +1563,11 @@ function getCompanionCommands(answers) {
1447
1563
  command: `${COMPANION_COMMAND_NAME} code impact --changed-files src/api/webhooks.ts tests/webhooks.test.ts --diff-summary "webhook retry hardening"`,
1448
1564
  purpose: "Use paid Context code impact analysis to surface likely tests, docs, routes, config, and risks."
1449
1565
  },
1566
+ {
1567
+ title: answers.installOrchestrator ? "Run an explicit production orchestration gate" : "Enable explicit production orchestration",
1568
+ command: answers.installOrchestrator ? `${ORCHESTRATOR_COMMAND_NAME} check-drift --route /api/health` : "npx create-snipara repair --with-orchestrator",
1569
+ purpose: answers.installOrchestrator ? "Use snipara-orchestrator only for proof-based validation, drift checks, htasks, or multi-agent coordination." : "Install snipara-orchestrator only when production gates, drift checks, htasks, or multi-agent coordination are required."
1570
+ },
1450
1571
  githubAnswerPacksCommand,
1451
1572
  {
1452
1573
  title: "Upload or refresh a doc",
@@ -1496,12 +1617,118 @@ function getCompanionCommands(answers) {
1496
1617
  }
1497
1618
  ];
1498
1619
  }
1620
+ function getClientDisplayName(client) {
1621
+ const names = {
1622
+ "claude-code": "Claude Code",
1623
+ cursor: "Cursor",
1624
+ windsurf: "Windsurf",
1625
+ codex: "OpenAI Codex",
1626
+ gemini: "Gemini",
1627
+ chatgpt: "ChatGPT / OpenAI MCP",
1628
+ vscode: "VS Code",
1629
+ continue: "Continue",
1630
+ "claude-desktop": "Claude Desktop",
1631
+ other: "Custom MCP client"
1632
+ };
1633
+ return names[client];
1634
+ }
1635
+ function getClientPackFilename(client) {
1636
+ const names = {
1637
+ "claude-code": "CLAUDE_CODE.md",
1638
+ cursor: "CURSOR.md",
1639
+ windsurf: "WINDSURF.md",
1640
+ codex: "CODEX.md",
1641
+ gemini: "GEMINI.md",
1642
+ chatgpt: "CHATGPT.md",
1643
+ vscode: "VSCODE.md",
1644
+ continue: "CONTINUE.md",
1645
+ "claude-desktop": "CLAUDE_DESKTOP.md",
1646
+ other: "CUSTOM_MCP.md"
1647
+ };
1648
+ return names[client];
1649
+ }
1650
+ function getClientConfigArtifacts(client) {
1651
+ if (client === "claude-code") {
1652
+ return ["AGENTS.md", "CLAUDE.md", ".claude/settings.json when hooks are installed"];
1653
+ }
1654
+ if (client === "cursor") {
1655
+ return [".mcp.json", ".cursor/rules/snipara.mdc", "dashboard automation bundle when installed"];
1656
+ }
1657
+ if (client === "windsurf") {
1658
+ return [".mcp.json", "dashboard automation bundle when installed"];
1659
+ }
1660
+ if (client === "codex") {
1661
+ return ["AGENTS.md", ".codex/config.toml", ".snipara/templates/codex-config.toml"];
1662
+ }
1663
+ if (client === "gemini") {
1664
+ return ["AGENTS.md", ".snipara/templates/gemini-mcp-reference.json"];
1665
+ }
1666
+ if (client === "vscode") {
1667
+ return ["AGENTS.md", ".snipara/templates/vscode-mcp-reference.json"];
1668
+ }
1669
+ if (client === "continue") {
1670
+ return ["AGENTS.md", ".snipara/templates/continue-mcp-reference.json"];
1671
+ }
1672
+ if (client === "chatgpt") {
1673
+ return ["AGENTS.md", ".snipara/templates/chatgpt-openai-mcp.json"];
1674
+ }
1675
+ if (client === "claude-desktop") {
1676
+ return ["AGENTS.md", "Claude Desktop MCP config"];
1677
+ }
1678
+ return ["AGENTS.md", ".snipara/templates/custom-mcp-reference.json"];
1679
+ }
1680
+ function getClientAutomationCommand(client) {
1681
+ const companionClient = getCompanionInitClientFlag(client).match(/--client\s+(\S+)/)?.[1];
1682
+ return companionClient ? `${COMPANION_COMMAND_NAME} automations install --client ${companionClient}` : null;
1683
+ }
1684
+ function buildClientPackMarkdown(answers, commands, guidance) {
1685
+ const clientName = getClientDisplayName(answers.aiClient);
1686
+ const automationCommand = getClientAutomationCommand(answers.aiClient);
1687
+ const bootstrapCommand = commands.find(
1688
+ (command) => command.title === "Bootstrap local companion"
1689
+ );
1690
+ return `# Snipara Pack: ${clientName}
1691
+
1692
+ This pack is the client-specific overlay for the generated Snipara project setup.
1693
+ Use \`AGENTS.md\` as the shared source of agent behavior, then apply the client-specific files below.
1694
+
1695
+ ## Hosted MCP
1696
+
1697
+ - Endpoint: \`${buildHostedMcpEndpoint(answers)}\`
1698
+ - Auth: \`SNIPARA_API_KEY\` from the environment or local client secret store
1699
+ - Do not commit API keys or bearer tokens.
1700
+
1701
+ ## Client Files
1702
+
1703
+ ${getClientConfigArtifacts(answers.aiClient).map((item) => `- \`${item}\``).join("\n")}
1704
+
1705
+ ## Recommended Setup
1706
+
1707
+ ${bootstrapCommand ? `1. Bootstrap companion: \`${bootstrapCommand.command}\`` : "1. Bootstrap companion with `snipara-companion init`."}
1708
+ 2. Confirm the client can list or call the \`snipara_*\` MCP tools.
1709
+ 3. Keep exact edits, tests, and dirty working-tree checks local; use Snipara for memory, source truth, and indexed code graph context.
1710
+ ${automationCommand ? `4. For generated local automations, run \`${automationCommand}\` when that client exposes usable automation files.` : "4. This client is treated as MCP-first; no local hook surface is assumed."}
1711
+
1712
+ ## Client Guidance
1713
+
1714
+ ${guidance.map((line) => `- ${line}`).join("\n")}
1715
+
1716
+ ## Agent Workflow
1717
+
1718
+ - Start substantial work with \`snipara_recall\` and \`snipara_context_query\`.
1719
+ - Use \`answer_pack\` facts, caveats, source maps, and verification checks before making claims.
1720
+ - Use \`snipara_code_symbol_card\` and \`snipara_code_impact\` for important symbols or risky multi-file changes when available.
1721
+ - Use \`snipara-companion workflow start\`, \`phase-start\`, \`phase-commit\`, \`workflow resume\`, and \`final-commit\` for multi-phase work.
1722
+ - Persist only durable decisions, learnings, preferences, workflows, and troubleshooting outcomes. Never persist secrets.
1723
+ `;
1724
+ }
1499
1725
  async function createCompanionPack(answers) {
1500
1726
  console.log(chalk.bold("\n\u{1F5C2}\uFE0F Generating Companion Pack\n"));
1501
1727
  const packDir = path.join(process.cwd(), ".snipara", "companion");
1502
1728
  const commands = getCompanionCommands(answers);
1503
1729
  const guidance = getClientGuidance(answers.aiClient);
1504
1730
  const detection = detectEnvironment();
1731
+ const clientPackFilename = getClientPackFilename(answers.aiClient);
1505
1732
  fs.mkdirSync(packDir, { recursive: true });
1506
1733
  const readme = `# Snipara Companion Pack
1507
1734
 
@@ -1513,10 +1740,12 @@ This project uses Snipara as a hosted-first context and memory layer with local
1513
1740
  - Project slug: \`${answers.projectSlug}\`
1514
1741
  - Project id: \`${answers.projectId || "not-set"}\`
1515
1742
  - AI client: \`${answers.aiClient}\`
1743
+ - Client pack: \`${clientPackFilename}\`
1516
1744
  - Installed local companion: \`${answers.installCompanion ? "yes" : "no"}\`
1517
1745
  - Generated hosted MCP config: \`${answers.profile !== "runtime-only" ? "yes" : "no"}\`
1518
1746
  - Installed local snipara-mcp package: \`${answers.installMcp ? "yes" : "no"}\`
1519
1747
  - Installed Snipara Sandbox: \`${answers.installRuntime ? "yes" : "no"}\`
1748
+ - Installed Snipara Orchestrator: \`${answers.installOrchestrator ? "yes" : "no"}\`
1520
1749
  - Generated hooks: \`${answers.installHooks ? "yes" : "no"}\`
1521
1750
  - GitHub repository: \`${answers.githubRepo ? answers.githubRepo.fullName : "not-detected"}\`
1522
1751
 
@@ -1527,6 +1756,7 @@ This project uses Snipara as a hosted-first context and memory layer with local
1527
1756
  - .env.local present: \`${detection.files.envLocal ? "yes" : "no"}\`
1528
1757
  - Companion CLI on PATH: \`${detection.tooling.companionCli ? "yes" : "no"}\`
1529
1758
  - Snipara Sandbox CLI on PATH: \`${detection.tooling.runtimeCli ? "yes" : "no"}\`
1759
+ - Snipara Orchestrator CLI on PATH: \`${detection.tooling.orchestratorCli ? "yes" : "no"}\`
1530
1760
 
1531
1761
  ## Client Guidance
1532
1762
 
@@ -1592,15 +1822,22 @@ ${item.purpose}`
1592
1822
  ai_client: answers.aiClient,
1593
1823
  profile: answers.profile,
1594
1824
  llm_provider: answers.llmProvider || null,
1825
+ install_orchestrator: answers.installOrchestrator,
1595
1826
  github_repository: answers.githubRepo || null,
1596
1827
  github_automation_url: answers.githubRepo ? buildGitHubAutomationUrl(answers) : null,
1828
+ client_pack: clientPackFilename,
1597
1829
  commands,
1598
1830
  guidance,
1599
1831
  detection
1600
1832
  };
1601
1833
  fs.writeFileSync(path.join(packDir, "README.md"), readme + "\n");
1834
+ fs.writeFileSync(
1835
+ path.join(packDir, clientPackFilename),
1836
+ buildClientPackMarkdown(answers, commands, guidance) + "\n"
1837
+ );
1602
1838
  fs.writeFileSync(path.join(packDir, "commands.json"), JSON.stringify(pack, null, 2) + "\n");
1603
1839
  console.log(chalk.green(" \u2713 Created .snipara/companion/README.md"));
1840
+ console.log(chalk.green(` \u2713 Created .snipara/companion/${clientPackFilename}`));
1604
1841
  console.log(chalk.green(" \u2713 Created .snipara/companion/commands.json"));
1605
1842
  }
1606
1843
  async function runSandboxInit() {
@@ -1691,6 +1928,11 @@ async function runValidation(answers, includeHostedCheck) {
1691
1928
  status: answers.installRuntime ? detection.tooling.runtimeCli ? "pass" : "warn" : "pass",
1692
1929
  detail: answers.installRuntime && !detection.tooling.runtimeCli ? `${SANDBOX_COMMAND_NAME} CLI not found on PATH` : "Snipara Sandbox CLI ready or not requested"
1693
1930
  });
1931
+ checks.push({
1932
+ name: "orchestrator_cli",
1933
+ status: answers.installOrchestrator ? detection.tooling.orchestratorCli ? "pass" : "warn" : "pass",
1934
+ detail: answers.installOrchestrator && !detection.tooling.orchestratorCli ? `${ORCHESTRATOR_COMMAND_NAME} CLI not found on PATH` : "Snipara Orchestrator ready or not requested"
1935
+ });
1694
1936
  checks.push({
1695
1937
  name: "companion_pack",
1696
1938
  status: detection.files.sniparaCompanionPack ? "pass" : "warn",
@@ -1892,6 +2134,11 @@ function printSuccess(answers, report) {
1892
2134
  chalk.green(` \u2713 ${stripExtras(SANDBOX_PACKAGE_NAME)}`) + chalk.dim(" - Safe code execution")
1893
2135
  );
1894
2136
  }
2137
+ if (answers.installOrchestrator) {
2138
+ console.log(
2139
+ chalk.green(` \u2713 ${ORCHESTRATOR_PACKAGE_NAME}`) + chalk.dim(" - Production gates, drift checks, and htask workflows")
2140
+ );
2141
+ }
1895
2142
  if (answers.installCompanion) {
1896
2143
  console.log(
1897
2144
  chalk.green(` \u2713 ${COMPANION_PACKAGE_NAME}`) + chalk.dim(" - Local companion workflows and hook bootstrap")
@@ -1943,6 +2190,11 @@ function printSuccess(answers, report) {
1943
2190
  `Run ${SANDBOX_COMMAND_NAME} init when you want to choose sandbox/docker/local execution.`
1944
2191
  );
1945
2192
  }
2193
+ if (answers.installOrchestrator) {
2194
+ printNextStep(
2195
+ `Use ${ORCHESTRATOR_COMMAND_NAME} explicitly for production proof gates, drift checks, or htask coordination.`
2196
+ );
2197
+ }
1946
2198
  if (answers.githubRepo) {
1947
2199
  printNextStep(
1948
2200
  `Connect GitHub automation for ${answers.githubRepo.fullName} from the generated Snipara link.`
@@ -2009,7 +2261,8 @@ function detectEnvironment() {
2009
2261
  docker: commandExists("docker"),
2010
2262
  git: commandExists("git"),
2011
2263
  companionCli: Boolean(detectCompanionCommand()),
2012
- runtimeCli: Boolean(detectSandboxCommand())
2264
+ runtimeCli: Boolean(detectSandboxCommand()),
2265
+ orchestratorCli: Boolean(detectOrchestratorCommand())
2013
2266
  },
2014
2267
  existingConfig: {
2015
2268
  slug: existingConfig?.slug,
@@ -2039,6 +2292,7 @@ function loadExistingAnswers(options) {
2039
2292
  skipCompanion: options.withCompanion === true ? false : !detection.tooling.companionCli && effectiveProfile !== "hosted-companion" && effectiveProfile !== "full-stack",
2040
2293
  skipMcp: options.withMcp === true ? false : !detection.existingConfig.hasSniparaServer && effectiveProfile === "runtime-only",
2041
2294
  skipRuntime: options.withRuntime === true ? false : !detection.existingConfig.hasRuntimeServer && effectiveProfile !== "full-stack" && effectiveProfile !== "runtime-only",
2295
+ withOrchestrator: Boolean(options.withOrchestrator || detection.tooling.orchestratorCli),
2042
2296
  skipHooks: options.withHooks ? false : detection.aiClient !== "claude-code"
2043
2297
  });
2044
2298
  }
@@ -2143,12 +2397,36 @@ function detectAiClient() {
2143
2397
  if (fs.existsSync(path.join(process.cwd(), ".codex"))) {
2144
2398
  return "codex";
2145
2399
  }
2400
+ if (fs.existsSync(path.join(process.cwd(), ".cursor"))) {
2401
+ return "cursor";
2402
+ }
2403
+ if (fs.existsSync(path.join(process.cwd(), ".windsurf"))) {
2404
+ return "windsurf";
2405
+ }
2406
+ if (fs.existsSync(path.join(process.cwd(), ".gemini"))) {
2407
+ return "gemini";
2408
+ }
2409
+ if (fs.existsSync(path.join(process.cwd(), ".continue"))) {
2410
+ return "continue";
2411
+ }
2412
+ if (fs.existsSync(path.join(process.cwd(), ".vscode"))) {
2413
+ return "vscode";
2414
+ }
2146
2415
  if (fs.existsSync(path.join(homedir(), ".claude")) || process.env.CLAUDE_CODE) {
2147
2416
  return "claude-code";
2148
2417
  }
2149
2418
  if (fs.existsSync(path.join(homedir(), ".cursor")) || process.env.CURSOR_EDITOR) {
2150
2419
  return "cursor";
2151
2420
  }
2421
+ if (fs.existsSync(path.join(homedir(), ".windsurf")) || process.env.WINDSURF_EDITOR) {
2422
+ return "windsurf";
2423
+ }
2424
+ if (fs.existsSync(path.join(homedir(), ".gemini")) || process.env.GEMINI_CLI) {
2425
+ return "gemini";
2426
+ }
2427
+ if (fs.existsSync(path.join(homedir(), ".continue")) || process.env.CONTINUE_GLOBAL_DIR) {
2428
+ return "continue";
2429
+ }
2152
2430
  const claudeDesktopPath = process.platform === "darwin" ? path.join(homedir(), "Library", "Application Support", "Claude") : process.platform === "win32" ? path.join(homedir(), "AppData", "Roaming", "Claude") : path.join(homedir(), ".config", "claude");
2153
2431
  if (fs.existsSync(claudeDesktopPath)) {
2154
2432
  return "claude-desktop";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snipara",
3
- "version": "1.3.16",
3
+ "version": "1.3.18",
4
4
  "description": "Onboard Snipara Hosted MCP Context + Memory with auth, companion workflows, and optional Snipara Sandbox",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -32,6 +32,10 @@
32
32
  "chatgpt",
33
33
  "openai",
34
34
  "cursor",
35
+ "windsurf",
36
+ "gemini",
37
+ "vscode",
38
+ "continue",
35
39
  "claude-desktop"
36
40
  ],
37
41
  "author": "Snipara",