create-snipara 1.3.32 → 1.3.34

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 +6 -1
  2. package/dist/index.js +48 -22
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -106,7 +106,8 @@ That distinction matters:
106
106
  - installs optional `snipara-orchestrator` for proof gates, drift checks, and htask workflows when requested
107
107
  - configures `.mcp.json`
108
108
  - generates merge-ready AI agent templates in `.snipara/templates/`, including Pro+ symbol-card, code-impact, and managed workflow guidance for paid Context plans
109
- - creates `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/snipara.mdc`, and `.codex/config.toml` when those files do not already exist
109
+ - creates `AGENTS.md` and `CLAUDE.md` when missing, or appends a marked Snipara section when those files already exist
110
+ - creates `.cursor/rules/snipara.mdc` and `.codex/config.toml` when those files do not already exist
110
111
  - writes client-specific companion packs such as `.snipara/companion/CODEX.md` or `.snipara/companion/GEMINI.md`
111
112
  - updates `.env`, `.env.local`, and `.env.example`
112
113
  - generates `.snipara/companion/README.md`
@@ -162,6 +163,10 @@ The generated agent templates cover:
162
163
  - ChatGPT/OpenAI HTTP MCP snippet
163
164
  - Gemini, VS Code, Continue, and custom HTTP MCP reference snippets
164
165
 
166
+ Existing root `AGENTS.md` and `CLAUDE.md` files are not replaced. The installer
167
+ adds or refreshes a marked Snipara section so project-specific instructions stay
168
+ intact.
169
+
165
170
  When `snipara-companion` is installed, the companion pack also includes the compaction-safe managed workflow:
166
171
 
167
172
  ```bash
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import { homedir } from "os";
13
13
  // package.json
14
14
  var package_default = {
15
15
  name: "create-snipara",
16
- version: "1.3.32",
16
+ version: "1.3.34",
17
17
  description: "Onboard Snipara Hosted MCP Context + Memory with auth, companion workflows, and optional Snipara Sandbox",
18
18
  main: "dist/index.js",
19
19
  type: "module",
@@ -1152,12 +1152,12 @@ async function createAgentTemplates(answers) {
1152
1152
  fs.writeFileSync(template.path, template.content);
1153
1153
  }
1154
1154
  console.log(chalk.green(" Created .snipara/templates agent snippets"));
1155
- writeIfMissing(
1155
+ writeOrMergeMarkdownInstructions(
1156
1156
  path.join(process.cwd(), "AGENTS.md"),
1157
1157
  buildAgentsMdTemplate(answers),
1158
1158
  "AGENTS.md"
1159
1159
  );
1160
- writeIfMissing(
1160
+ writeOrMergeMarkdownInstructions(
1161
1161
  path.join(process.cwd(), "CLAUDE.md"),
1162
1162
  buildClaudeMdTemplate(answers),
1163
1163
  "CLAUDE.md"
@@ -1186,6 +1186,45 @@ function writeIfMissing(filePath, content, label) {
1186
1186
  fs.writeFileSync(filePath, content);
1187
1187
  console.log(chalk.green(` Created ${label}`));
1188
1188
  }
1189
+ function markdownInstructionMarker(label, type) {
1190
+ return `<!-- snipara:instructions ${label}:${type} -->`;
1191
+ }
1192
+ function escapeRegExp(value) {
1193
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1194
+ }
1195
+ function ensureTrailingNewline(content) {
1196
+ return content.endsWith("\n") ? content : `${content}
1197
+ `;
1198
+ }
1199
+ function buildMarkdownInstructionBlock(label, content) {
1200
+ return [
1201
+ markdownInstructionMarker(label, "start"),
1202
+ content.trimEnd(),
1203
+ markdownInstructionMarker(label, "end"),
1204
+ ""
1205
+ ].join("\n");
1206
+ }
1207
+ function writeOrMergeMarkdownInstructions(filePath, content, label) {
1208
+ if (!fs.existsSync(filePath)) {
1209
+ fs.writeFileSync(filePath, content);
1210
+ console.log(chalk.green(` Created ${label}`));
1211
+ return;
1212
+ }
1213
+ const current = fs.readFileSync(filePath, "utf8");
1214
+ if (current.trim() === content.trim()) {
1215
+ console.log(chalk.dim(` ${label} already contains Snipara instructions`));
1216
+ return;
1217
+ }
1218
+ const block = buildMarkdownInstructionBlock(label, content);
1219
+ const start = markdownInstructionMarker(label, "start");
1220
+ const end = markdownInstructionMarker(label, "end");
1221
+ const existingBlockPattern = new RegExp(
1222
+ `${escapeRegExp(start)}[\\s\\S]*?${escapeRegExp(end)}\\n?`
1223
+ );
1224
+ const nextContent = existingBlockPattern.test(current) ? ensureTrailingNewline(current.replace(existingBlockPattern, block)) : `${current}${current.endsWith("\n\n") ? "" : current.endsWith("\n") ? "\n" : "\n\n"}${block}`;
1225
+ fs.writeFileSync(filePath, nextContent);
1226
+ console.log(chalk.green(` Updated ${label} with Snipara instructions`));
1227
+ }
1189
1228
  function buildHostedMcpEndpoint(answers) {
1190
1229
  return `${API_URL}/mcp/${answers.projectSlug}`;
1191
1230
  }
@@ -1641,31 +1680,18 @@ async function createCompanionConfig(answers) {
1641
1680
  }
1642
1681
  const configDir = path.join(process.cwd(), ".snipara", "companion");
1643
1682
  const configPath = path.join(configDir, "config.json");
1644
- const globalConfigPath = getGlobalCompanionConfigPath();
1645
1683
  fs.mkdirSync(configDir, { recursive: true });
1646
- fs.mkdirSync(path.dirname(globalConfigPath), { recursive: true });
1647
- const existingGlobalConfig = readCompanionConfigFile(globalConfigPath);
1648
1684
  const existingWorkspaceConfig = readCompanionConfigFile(configPath);
1649
- const globalConfig = {
1650
- ...existingGlobalConfig,
1651
- apiKey: answers.apiKey,
1652
- apiUrl: API_URL
1653
- };
1654
1685
  const workspaceConfig = {
1655
- projectId: answers.projectSlug,
1686
+ ...existingWorkspaceConfig,
1687
+ apiKey: answers.apiKey,
1688
+ apiUrl: API_URL,
1689
+ projectId: answers.projectId || answers.projectSlug,
1656
1690
  sessionId: typeof existingWorkspaceConfig.sessionId === "string" && existingWorkspaceConfig.sessionId ? existingWorkspaceConfig.sessionId : `sess_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
1657
1691
  };
1658
- fs.writeFileSync(globalConfigPath, JSON.stringify(globalConfig, null, 2) + "\n");
1659
1692
  fs.writeFileSync(configPath, JSON.stringify(workspaceConfig, null, 2) + "\n");
1660
- ensureGitignoreEntry(
1661
- ".snipara/companion/config.json",
1662
- "# Snipara local companion workspace config"
1663
- );
1664
- console.log(chalk.green(" \u2713 Configured global companion auth"));
1665
- console.log(chalk.green(" \u2713 Configured local companion workspace"));
1666
- }
1667
- function getGlobalCompanionConfigPath() {
1668
- return path.join(homedir(), ".rlmsaas", "config.json");
1693
+ ensureGitignoreEntry(".snipara/companion/config.json", "# Snipara local companion config");
1694
+ console.log(chalk.green(" \u2713 Configured local companion config"));
1669
1695
  }
1670
1696
  function readCompanionConfigFile(filePath) {
1671
1697
  if (!fs.existsSync(filePath)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snipara",
3
- "version": "1.3.32",
3
+ "version": "1.3.34",
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",