create-snipara 1.3.38 → 1.3.40

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 +1 -1
  2. package/dist/index.js +107 -50
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -208,7 +208,7 @@ Writes `.snipara/companion/doctor.json` and validates:
208
208
  For Claude-specific support, run:
209
209
 
210
210
  ```bash
211
- npx create-snipara doctor --client claude
211
+ npx create-snipara doctor --client claude-code
212
212
  ```
213
213
 
214
214
  This separates "Snipara config was written" from "Claude actually loaded the MCP
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.38",
16
+ version: "1.3.40",
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",
@@ -88,6 +88,8 @@ var BASE_URL = "https://www.snipara.com";
88
88
  var API_URL = "https://api.snipara.com";
89
89
  var COMPANION_PACKAGE_NAME = "snipara-companion";
90
90
  var COMPANION_COMMAND_NAME = "snipara-companion";
91
+ var COMPANION_NPX_COMMAND = "npx -y snipara-companion@latest";
92
+ var MIN_COMPANION_VERSION = "1.1.37";
91
93
  var GITHUB_ANSWER_PACKS_LABEL = "GitHub PR Answer Packs";
92
94
  var MCP_PACKAGE_NAME = "snipara-mcp";
93
95
  var SANDBOX_PACKAGE_NAME = "snipara-sandbox[all]";
@@ -605,7 +607,10 @@ async function gatherConfiguration(options) {
605
607
  let signupResult = null;
606
608
  if (!apiKey && response.profile !== "runtime-only") {
607
609
  if (response.apiKeyType === "signup") {
608
- signupResult = await handleSignup();
610
+ signupResult = await handleSignup({
611
+ projectHint: response.projectSlug,
612
+ repoHint: detectedGitRepo?.fullName
613
+ });
609
614
  apiKey = signupResult.apiKey;
610
615
  apiKeyType = "api";
611
616
  } else if (response.apiKeyType === "api") {
@@ -798,10 +803,10 @@ function buildAnswersFromProfile(input) {
798
803
  githubPath: input.githubPath
799
804
  };
800
805
  }
801
- async function handleSignup() {
806
+ async function handleSignup(hints = {}) {
802
807
  console.log(chalk.bold("\n\u{1F510} Browser Account Authorization\n"));
803
808
  try {
804
- return await runDeviceAuthorization();
809
+ return await runDeviceAuthorization(hints);
805
810
  } catch (error) {
806
811
  if (error instanceof DeviceAuthorizationAborted) {
807
812
  throw error;
@@ -829,7 +834,27 @@ async function handleManualSignup() {
829
834
  });
830
835
  return { apiKey: response.apiKey };
831
836
  }
832
- async function runDeviceAuthorization() {
837
+ function normalizeDeviceFlowHint(value) {
838
+ const normalized = value?.trim();
839
+ return normalized && !normalized.includes("<") && !normalized.includes(">") ? normalized : null;
840
+ }
841
+ function appendDeviceFlowHints(url, hints) {
842
+ try {
843
+ const parsed = new URL(url);
844
+ const projectHint = normalizeDeviceFlowHint(hints.projectHint);
845
+ const repoHint = normalizeDeviceFlowHint(hints.repoHint);
846
+ if (projectHint) {
847
+ parsed.searchParams.set("project_hint", projectHint);
848
+ }
849
+ if (repoHint) {
850
+ parsed.searchParams.set("repo_hint", repoHint);
851
+ }
852
+ return parsed.toString();
853
+ } catch {
854
+ return url;
855
+ }
856
+ }
857
+ async function runDeviceAuthorization(hints = {}) {
833
858
  const codeResponse = await postJson(`${BASE_URL}/api/oauth/device/code`, {
834
859
  client_id: DEVICE_CLIENT_ID,
835
860
  scope: "mcp:read mcp:write",
@@ -838,11 +863,10 @@ async function runDeviceAuthorization() {
838
863
  if (codeResponse.error) {
839
864
  throw new Error(codeResponse.error_description || codeResponse.error);
840
865
  }
841
- console.log(
842
- chalk.cyan(` Opening ${codeResponse.verification_uri_complete} in your browser...`)
843
- );
866
+ const verificationUrl = appendDeviceFlowHints(codeResponse.verification_uri_complete, hints);
867
+ console.log(chalk.cyan(` Opening ${verificationUrl} in your browser...`));
844
868
  console.log(chalk.dim(` Device code: ${codeResponse.user_code}`));
845
- openBrowser(codeResponse.verification_uri_complete);
869
+ openBrowser(verificationUrl);
846
870
  const spinner = ora("Waiting for Snipara authorization in the browser...").start();
847
871
  const startedAt = Date.now();
848
872
  let intervalMs = Math.max(1, codeResponse.interval || 5) * 1e3;
@@ -938,8 +962,40 @@ function isProvisionedApiKey(value) {
938
962
  function provisionedApiKeyValidationMessage() {
939
963
  return "New Snipara API keys should start with snp-";
940
964
  }
965
+ function normalizeSemver(value) {
966
+ const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
967
+ if (!match) {
968
+ return null;
969
+ }
970
+ return `${match[1]}.${match[2]}.${match[3]}`;
971
+ }
972
+ function getCompanionCommandVersion() {
973
+ if (!commandExists(COMPANION_COMMAND_NAME)) {
974
+ return null;
975
+ }
976
+ try {
977
+ return execSync(`${COMPANION_COMMAND_NAME} --version`, {
978
+ encoding: "utf-8",
979
+ stdio: ["ignore", "pipe", "ignore"],
980
+ timeout: 1e3
981
+ }).trim();
982
+ } catch {
983
+ return null;
984
+ }
985
+ }
986
+ function isSupportedCompanionVersion(version) {
987
+ const current = normalizeSemver(version);
988
+ return Boolean(current && compareSemver(current, MIN_COMPANION_VERSION) >= 0);
989
+ }
990
+ function getCompanionRequirementMessage() {
991
+ const version = getCompanionCommandVersion();
992
+ if (!version) {
993
+ return `${COMPANION_PACKAGE_NAME} not found on PATH`;
994
+ }
995
+ return `${COMPANION_PACKAGE_NAME} ${version} is older than required ${MIN_COMPANION_VERSION}`;
996
+ }
941
997
  function detectCompanionCommand() {
942
- if (commandExists(COMPANION_COMMAND_NAME)) {
998
+ if (isSupportedCompanionVersion(getCompanionCommandVersion())) {
943
999
  return COMPANION_COMMAND_NAME;
944
1000
  }
945
1001
  return null;
@@ -1033,11 +1089,11 @@ function detectNodePackageManagers() {
1033
1089
  }
1034
1090
  return managers;
1035
1091
  }
1036
- function getCompanionInstallCommand(packageManager, upgrade) {
1092
+ function getCompanionInstallCommand(packageManager, _upgrade) {
1037
1093
  if (packageManager === "pnpm") {
1038
- return `pnpm add -g ${upgrade ? "--latest " : ""}${COMPANION_PACKAGE_NAME}`;
1094
+ return `pnpm add -g ${COMPANION_PACKAGE_NAME}@latest`;
1039
1095
  }
1040
- return `npm install -g ${upgrade ? COMPANION_PACKAGE_NAME + "@latest" : COMPANION_PACKAGE_NAME}`;
1096
+ return `npm install -g ${COMPANION_PACKAGE_NAME}@latest`;
1041
1097
  }
1042
1098
  async function installNodeCompanion(upgrade) {
1043
1099
  console.log(chalk.bold(`
@@ -1046,7 +1102,7 @@ async function installNodeCompanion(upgrade) {
1046
1102
  const packageManagers = detectNodePackageManagers();
1047
1103
  if (packageManagers.length === 0) {
1048
1104
  console.log(chalk.yellow(" \u26A0\uFE0F npm/pnpm not found. Please install manually:\n"));
1049
- console.log(chalk.gray(` npm install -g ${COMPANION_PACKAGE_NAME}
1105
+ console.log(chalk.gray(` npm install -g ${COMPANION_PACKAGE_NAME}@latest
1050
1106
  `));
1051
1107
  return;
1052
1108
  }
@@ -1082,12 +1138,8 @@ async function installNodeCompanion(upgrade) {
1082
1138
  console.log(chalk.gray(` - ${failure}`));
1083
1139
  }
1084
1140
  console.log(chalk.yellow("\n Install manually with:"));
1085
- console.log(
1086
- chalk.gray(
1087
- ` npm install -g ${upgrade ? COMPANION_PACKAGE_NAME + "@latest" : COMPANION_PACKAGE_NAME}
1088
- `
1089
- )
1090
- );
1141
+ console.log(chalk.gray(` npm install -g ${COMPANION_PACKAGE_NAME}@latest
1142
+ `));
1091
1143
  }
1092
1144
  async function createMcpConfig(answers) {
1093
1145
  console.log(chalk.bold("\n\u2699\uFE0F Creating Configuration\n"));
@@ -1793,7 +1845,7 @@ function getClientGuidance(client) {
1793
1845
  if (client === "windsurf") {
1794
1846
  return [
1795
1847
  "Windsurf should use the hosted MCP surface plus generated Windsurf automation bundles when available.",
1796
- "Use snipara-companion automations install --client windsurf when you want dashboard-managed hook files in the local project."
1848
+ "Use npx -y snipara-companion@latest automations install --client windsurf when you want dashboard-managed hook files in the local project."
1797
1849
  ];
1798
1850
  }
1799
1851
  if (client === "codex") {
@@ -1843,19 +1895,19 @@ function getCompanionCommands(answers) {
1843
1895
  const businessOnboardingCommands = answers.installCompanion ? [
1844
1896
  {
1845
1897
  title: "Preview a business folder import",
1846
- command: `${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json`,
1898
+ command: `${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json`,
1847
1899
  purpose: "Classify a local or LLM-materialized business folder and review the Snipara sync manifest before upload."
1848
1900
  },
1849
1901
  {
1850
1902
  title: "Apply a business folder import",
1851
- command: `${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --apply`,
1903
+ command: `${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --apply`,
1852
1904
  purpose: "Upload approved business-context documents to hosted Snipara and trigger document reindexing."
1853
1905
  }
1854
1906
  ] : [
1855
1907
  {
1856
1908
  title: "Enable business folder onboarding",
1857
1909
  command: "npx create-snipara repair --with-companion",
1858
- purpose: `Install ${COMPANION_PACKAGE_NAME} so this project can run ${COMPANION_COMMAND_NAME} onboard-folder without using the dashboard.`
1910
+ purpose: `Install ${COMPANION_PACKAGE_NAME} so this project can run ${COMPANION_NPX_COMMAND} onboard-folder without using the dashboard.`
1859
1911
  }
1860
1912
  ];
1861
1913
  const githubAnswerPacksCommand = answers.githubRepo ? {
@@ -1870,7 +1922,7 @@ function getCompanionCommands(answers) {
1870
1922
  return [
1871
1923
  {
1872
1924
  title: "Bootstrap local companion",
1873
- command: `${COMPANION_COMMAND_NAME} init${clientFlag}${projectFlag}`,
1925
+ command: `${COMPANION_NPX_COMMAND} init${clientFlag}${projectFlag}`,
1874
1926
  purpose: "Re-run local companion setup if this workstation needs to refresh browser login or project selection."
1875
1927
  },
1876
1928
  {
@@ -1885,32 +1937,32 @@ function getCompanionCommands(answers) {
1885
1937
  },
1886
1938
  {
1887
1939
  title: "Run a focused hosted query",
1888
- command: `${COMPANION_COMMAND_NAME} query --query "how does auth middleware work?" --max-tokens 4000`,
1940
+ command: `${COMPANION_NPX_COMMAND} query --query "how does auth middleware work?" --max-tokens 4000`,
1889
1941
  purpose: "Pull ranked source context before editing, reviewing, or drafting."
1890
1942
  },
1891
1943
  {
1892
1944
  title: "Load linked standards only when needed",
1893
- command: `${COMPANION_COMMAND_NAME} shared-context --categories MANDATORY BEST_PRACTICES`,
1945
+ command: `${COMPANION_NPX_COMMAND} shared-context --categories MANDATORY BEST_PRACTICES`,
1894
1946
  purpose: "Fetch project-linked team or workspace guidance without treating it as memory."
1895
1947
  },
1896
1948
  {
1897
1949
  title: "Generate a hosted plan",
1898
- command: `${COMPANION_COMMAND_NAME} plan --query "Implement webhook retry hardening" --max-tokens 3000`,
1950
+ command: `${COMPANION_NPX_COMMAND} plan --query "Implement webhook retry hardening" --max-tokens 3000`,
1899
1951
  purpose: "Produce a structured execution plan against indexed project knowledge."
1900
1952
  },
1901
1953
  {
1902
1954
  title: "Start a managed workflow from the visible plan",
1903
- command: `${COMPANION_COMMAND_NAME} workflow start --goal "Implement webhook retry hardening" --plan-file ./plan.md`,
1955
+ command: `${COMPANION_NPX_COMMAND} workflow start --goal "Implement webhook retry hardening" --plan-file ./plan.md`,
1904
1956
  purpose: "Record the LLM-visible plan in .snipara/workflow/current.json so phase state survives compaction."
1905
1957
  },
1906
1958
  {
1907
1959
  title: "Start the current workflow phase",
1908
- command: `${COMPANION_COMMAND_NAME} workflow phase-start context`,
1960
+ command: `${COMPANION_NPX_COMMAND} workflow phase-start context`,
1909
1961
  purpose: "Mark a phase active and print the required Snipara context gate for the agent."
1910
1962
  },
1911
1963
  {
1912
1964
  title: "Analyze code impact before a risky change",
1913
- command: `${COMPANION_COMMAND_NAME} code impact --changed-files src/api/webhooks.ts tests/webhooks.test.ts --diff-summary "webhook retry hardening"`,
1965
+ command: `${COMPANION_NPX_COMMAND} code impact --changed-files src/api/webhooks.ts tests/webhooks.test.ts --diff-summary "webhook retry hardening"`,
1914
1966
  purpose: "Use paid Context code impact analysis to surface likely tests, docs, routes, config, and risks."
1915
1967
  },
1916
1968
  {
@@ -1921,48 +1973,48 @@ function getCompanionCommands(answers) {
1921
1973
  githubAnswerPacksCommand,
1922
1974
  {
1923
1975
  title: "Upload or refresh a doc",
1924
- command: `${COMPANION_COMMAND_NAME} upload --path docs/local-playbook.md --file ./docs/local-playbook.md`,
1976
+ command: `${COMPANION_NPX_COMMAND} upload --path docs/local-playbook.md --file ./docs/local-playbook.md`,
1925
1977
  purpose: "Push local notes or docs into hosted Snipara context."
1926
1978
  },
1927
1979
  ...businessOnboardingCommands,
1928
1980
  {
1929
1981
  title: "Inspect a specific chunk",
1930
- command: `${COMPANION_COMMAND_NAME} chunk get --chunk-id <chunk_id>`,
1982
+ command: `${COMPANION_NPX_COMMAND} chunk get --chunk-id <chunk_id>`,
1931
1983
  purpose: "Open an exact chunk returned by references-based search."
1932
1984
  },
1933
1985
  {
1934
1986
  title: "Bootstrap the session memory view",
1935
- command: `${COMPANION_COMMAND_NAME} session-bootstrap`,
1987
+ command: `${COMPANION_NPX_COMMAND} session-bootstrap`,
1936
1988
  purpose: "Load durable decisions, learnings, and optional short-lived carryover at session start."
1937
1989
  },
1938
1990
  {
1939
1991
  title: "Check Stuck Guard status",
1940
- command: `${COMPANION_COMMAND_NAME} stuck-guard status`,
1992
+ command: `${COMPANION_NPX_COMMAND} stuck-guard status`,
1941
1993
  purpose: "Inspect whether recent tool failures, empty searches, or risky workflow signals should trigger a Rescue Pack."
1942
1994
  },
1943
1995
  {
1944
1996
  title: "Simulate a Stuck Guard fixture",
1945
- command: `${COMPANION_COMMAND_NAME} stuck-guard simulate --fixture ./stuck-guard-fixture.json`,
1997
+ command: `${COMPANION_NPX_COMMAND} stuck-guard simulate --fixture ./stuck-guard-fixture.json`,
1946
1998
  purpose: "Replay canonical events against the hosted Stuck Guard decision API before enabling stricter modes."
1947
1999
  },
1948
2000
  {
1949
2001
  title: "Ask memory about past decisions",
1950
- command: `${COMPANION_COMMAND_NAME} recall --query "What did we decide about auth retries?" --type decision`,
2002
+ command: `${COMPANION_NPX_COMMAND} recall --query "What did we decide about auth retries?" --type decision`,
1951
2003
  purpose: "Query durable memory for past decisions, preferences, or validated learnings."
1952
2004
  },
1953
2005
  {
1954
2006
  title: "Commit durable task memory",
1955
- command: `${COMPANION_COMMAND_NAME} task-commit --summary "Hardened webhook retries and updated tests" --category engineering --outcome completed --files src/api/webhooks.ts tests/webhooks.test.ts`,
2007
+ command: `${COMPANION_NPX_COMMAND} task-commit --summary "Hardened webhook retries and updated tests" --category engineering --outcome completed --files src/api/webhooks.ts tests/webhooks.test.ts`,
1956
2008
  purpose: "Persist reusable outcomes back into hosted memory after the work is done."
1957
2009
  },
1958
2010
  {
1959
2011
  title: "Commit a managed workflow phase",
1960
- command: `${COMPANION_COMMAND_NAME} workflow phase-commit context --summary "Loaded context and mapped impacted files" --files src/api/webhooks.ts tests/webhooks.test.ts`,
2012
+ command: `${COMPANION_NPX_COMMAND} workflow phase-commit context --summary "Loaded context and mapped impacted files" --files src/api/webhooks.ts tests/webhooks.test.ts`,
1961
2013
  purpose: "Persist this phase through hosted memory and advance the local managed workflow state."
1962
2014
  },
1963
2015
  {
1964
2016
  title: "Commit the final managed workflow result",
1965
- command: `${COMPANION_COMMAND_NAME} final-commit --summary "Shipped webhook retry hardening and tests" --files src/api/webhooks.ts tests/webhooks.test.ts`,
2017
+ command: `${COMPANION_NPX_COMMAND} final-commit --summary "Shipped webhook retry hardening and tests" --files src/api/webhooks.ts tests/webhooks.test.ts`,
1966
2018
  purpose: "Persist the final workflow outcome and close the managed workflow after verification."
1967
2019
  }
1968
2020
  ];
@@ -2029,7 +2081,7 @@ function getClientConfigArtifacts(client) {
2029
2081
  }
2030
2082
  function getClientAutomationCommand(client) {
2031
2083
  const companionClient = getCompanionInitClientFlag(client).match(/--client\s+(\S+)/)?.[1];
2032
- return companionClient ? `${COMPANION_COMMAND_NAME} automations install --client ${companionClient}` : null;
2084
+ return companionClient ? `${COMPANION_NPX_COMMAND} automations install --client ${companionClient}` : null;
2033
2085
  }
2034
2086
  function buildClientPackMarkdown(answers, commands, guidance) {
2035
2087
  const clientName = getClientDisplayName(answers.aiClient);
@@ -2054,7 +2106,7 @@ ${getClientConfigArtifacts(answers.aiClient).map((item) => `- \`${item}\``).join
2054
2106
 
2055
2107
  ## Recommended Setup
2056
2108
 
2057
- ${bootstrapCommand ? `1. Bootstrap companion: \`${bootstrapCommand.command}\`` : "1. Bootstrap companion with `snipara-companion init`."}
2109
+ ${bootstrapCommand ? `1. Bootstrap companion: \`${bootstrapCommand.command}\`` : `1. Bootstrap companion with \`${COMPANION_NPX_COMMAND} init\`.`}
2058
2110
  2. Confirm the client can list or call the \`snipara_*\` MCP tools.
2059
2111
  3. Keep exact edits, tests, and dirty working-tree checks local; use Snipara for memory, source truth, and indexed code graph context.
2060
2112
  ${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."}
@@ -2068,6 +2120,7 @@ ${guidance.map((line) => `- ${line}`).join("\n")}
2068
2120
  - Start substantial work with \`snipara_recall\` and \`snipara_context_query\`.
2069
2121
  - Use \`answer_pack\` facts, caveats, source maps, and verification checks before making claims.
2070
2122
  - Use \`snipara_code_symbol_card\` and \`snipara_code_impact\` for important symbols or risky multi-file changes when available.
2123
+ - Use the installed \`snipara-companion\` binary for low-latency hooks; use \`${COMPANION_NPX_COMMAND}\` for one-off terminal commands when freshness matters.
2071
2124
  - Use \`snipara-companion workflow start\`, \`phase-start\`, \`phase-commit\`, \`workflow resume\`, and \`final-commit\` for multi-phase work.
2072
2125
  - Persist only durable decisions, learnings, preferences, workflows, and troubleshooting outcomes. Never persist secrets.
2073
2126
  `;
@@ -2118,11 +2171,11 @@ Use this when Claude, ChatGPT, Codex, or another LLM client has already material
2118
2171
 
2119
2172
  ${answers.installCompanion ? `Preview first:
2120
2173
 
2121
- \`${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json\`
2174
+ \`${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json\`
2122
2175
 
2123
2176
  Apply only after reviewing the manifest:
2124
2177
 
2125
- \`${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --apply\`` : `This setup did not install snipara-companion. Enable it before business folder imports:
2178
+ \`${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --apply\`` : `This setup did not install snipara-companion. Enable it before business folder imports:
2126
2179
 
2127
2180
  \`npx create-snipara repair --with-companion\``}
2128
2181
 
@@ -2427,7 +2480,7 @@ async function runValidation(answers, includeHostedCheck, options = {}) {
2427
2480
  checks.push({
2428
2481
  name: "companion_cli",
2429
2482
  status: answers.installCompanion ? detection.tooling.companionCli ? "pass" : "fail" : "pass",
2430
- detail: answers.installCompanion && !detection.tooling.companionCli ? `${COMPANION_PACKAGE_NAME} not found on PATH` : "Companion CLI ready or not requested"
2483
+ detail: answers.installCompanion && !detection.tooling.companionCli ? getCompanionRequirementMessage() : "Companion CLI ready or not requested"
2431
2484
  });
2432
2485
  checks.push({
2433
2486
  name: "sandbox_cli",
@@ -2735,7 +2788,9 @@ function printSuccess(answers, report) {
2735
2788
  printNextStep(
2736
2789
  "For Claude Code, start a new session and confirm Snipara appears in Settings -> MCP or ToolSearch."
2737
2790
  );
2738
- printNextStep("If Snipara tools are missing, run: npx create-snipara doctor --client claude");
2791
+ printNextStep(
2792
+ "If Snipara tools are missing, run: npx create-snipara doctor --client claude-code"
2793
+ );
2739
2794
  }
2740
2795
  if (answers.aiClient === "claude-desktop") {
2741
2796
  printNextStep(
@@ -2753,15 +2808,17 @@ function printSuccess(answers, report) {
2753
2808
  printNextStep("Open .snipara/companion/README.md for local commands and repair flow.");
2754
2809
  printNextStep("Run create-snipara doctor anytime you want a fresh local validation report.");
2755
2810
  if (answers.installCompanion) {
2756
- printNextStep(`${COMPANION_COMMAND_NAME} is the companion command for local workflow helpers.`);
2757
2811
  printNextStep(
2758
- `Use ${COMPANION_COMMAND_NAME} query / plan / upload / task-commit for explicit local workflows.`
2812
+ `${COMPANION_COMMAND_NAME} ${MIN_COMPANION_VERSION}+ is installed for low-latency local hooks.`
2813
+ );
2814
+ printNextStep(
2815
+ `Use ${COMPANION_NPX_COMMAND} query / plan / upload / task-commit for explicit local workflows.`
2759
2816
  );
2760
2817
  printNextStep(
2761
- `For business folders, preview with: ${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json`
2818
+ `For business folders, preview with: ${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --write-manifest ./snipara-onboard.json`
2762
2819
  );
2763
2820
  printNextStep(
2764
- `Apply after review with: ${COMPANION_COMMAND_NAME} onboard-folder ./client-export --source-provider local_folder --apply`
2821
+ `Apply after review with: ${COMPANION_NPX_COMMAND} onboard-folder ./client-export --source-provider local_folder --apply`
2765
2822
  );
2766
2823
  } else if (answers.profile !== "runtime-only") {
2767
2824
  printNextStep(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snipara",
3
- "version": "1.3.38",
3
+ "version": "1.3.40",
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",