create-snipara 2.0.11 → 2.0.12

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 (2) hide show
  1. package/dist/index.js +154 -7
  2. package/package.json +1 -1
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: "2.0.11",
16
+ version: "2.0.12",
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",
@@ -107,6 +107,8 @@ var DEVICE_CLIENT_ID = "create-snipara";
107
107
  var DAY_ZERO_CORPUS_MAX_FILES = 8;
108
108
  var DAY_ZERO_CORPUS_MAX_FILE_CHARS = 12e3;
109
109
  var DAY_ZERO_CORPUS_MAX_TOTAL_CHARS = 5e4;
110
+ var ACTIVATION_MANIFEST_SCHEMA_VERSION = "snipara.activation.manifest.v1";
111
+ var ACTIVATION_CONSUMER_CONTRACT_VERSION = "snipara.editor.activation.v1";
110
112
  var EXPERIENCE_GOAL_SECTION = `## Experience Goal
111
113
 
112
114
  The target experience is outcome-first agent work across supported clients:
@@ -140,15 +142,23 @@ function getActivationDir() {
140
142
  function getActivationManifestPath() {
141
143
  return path.join(getActivationDir(), "manifest.json");
142
144
  }
145
+ function getStableActivationManifestPath() {
146
+ return path.join(getActivationDir(), "activation-manifest.json");
147
+ }
143
148
  function getActivationHandoffPath() {
144
149
  return path.join(getActivationDir(), "handoff.md");
145
150
  }
151
+ function getFirstWorkBriefPath() {
152
+ return path.join(getActivationDir(), "first-brief.md");
153
+ }
146
154
  function getMemoryCandidatesPath() {
147
155
  return path.join(getActivationDir(), "memory-candidates.json");
148
156
  }
149
157
  function writeActivationManifest(manifest) {
150
158
  fs.mkdirSync(getActivationDir(), { recursive: true });
151
- fs.writeFileSync(getActivationManifestPath(), JSON.stringify(manifest, null, 2) + "\n", "utf8");
159
+ const payload = JSON.stringify(manifest, null, 2) + "\n";
160
+ fs.writeFileSync(getActivationManifestPath(), payload, "utf8");
161
+ fs.writeFileSync(getStableActivationManifestPath(), payload, "utf8");
152
162
  }
153
163
  function updateActivationManifest(manifest) {
154
164
  manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -451,6 +461,24 @@ function writeInitialHandoff(answers, manifest) {
451
461
  ];
452
462
  fs.writeFileSync(getActivationHandoffPath(), lines.join("\n"), "utf8");
453
463
  }
464
+ function writeFirstWorkBrief(manifest) {
465
+ fs.mkdirSync(getActivationDir(), { recursive: true });
466
+ const lines = [
467
+ `# ${manifest.firstBrief.title}`,
468
+ "",
469
+ `Status: ${manifest.firstBrief.status}`,
470
+ `Activation: ${manifest.activationId}`,
471
+ `Client: ${getClientDisplayName(manifest.aiClient)}`,
472
+ "",
473
+ ...manifest.firstBrief.sections.flatMap((section) => [
474
+ `## ${section.title}`,
475
+ "",
476
+ ...section.lines.map((line) => `- ${line}`),
477
+ ""
478
+ ])
479
+ ];
480
+ fs.writeFileSync(getFirstWorkBriefPath(), lines.join("\n"), "utf8");
481
+ }
454
482
  function detectLocalActivationScan(detection) {
455
483
  const cwd = process.cwd();
456
484
  const exists = (relativePath) => fs.existsSync(path.join(cwd, relativePath));
@@ -624,9 +652,11 @@ function createActivationManifest(answers, detection, mode = "default", scan) {
624
652
  const surfaceContract = buildActivationSurfaceContract(answers.aiClient);
625
653
  return {
626
654
  version: "create-snipara-activation-v1",
655
+ schemaVersion: ACTIVATION_MANIFEST_SCHEMA_VERSION,
627
656
  activationId: buildActivationId(),
628
657
  mode,
629
658
  surfaceContract,
659
+ consumerContract: buildEditorActivationConsumerContract(answers.aiClient),
630
660
  activationMetric: {
631
661
  name: "time_to_how_did_it_know_that",
632
662
  targetMinutes: 5,
@@ -694,9 +724,13 @@ function createActivationManifest(answers, detection, mode = "default", scan) {
694
724
  )
695
725
  },
696
726
  artifacts: {
727
+ activationManifestPath: path.relative(process.cwd(), getStableActivationManifestPath()),
728
+ legacyManifestPath: path.relative(process.cwd(), getActivationManifestPath()),
729
+ firstBriefPath: null,
697
730
  handoffPath: null,
698
731
  memoryCandidatesPath: null
699
732
  },
733
+ nextActions: buildActivationNextActions(surfaceContract, answers),
700
734
  firstBrief: createInitialFirstWorkBrief(answers, detection, localScan),
701
735
  createdAt: now,
702
736
  updatedAt: now
@@ -899,10 +933,12 @@ function createActivationArtifacts(answers, manifest) {
899
933
  "Initial local handoff created.",
900
934
  manifest.artifacts.handoffPath
901
935
  );
936
+ writeFirstWorkBrief(manifest);
937
+ manifest.artifacts.firstBriefPath = path.relative(process.cwd(), getFirstWorkBriefPath());
902
938
  manifest.lanes.firstBrief = createActivationLane(
903
939
  "ready",
904
940
  "First Work Brief generated from local setup and scan signals.",
905
- path.relative(process.cwd(), getActivationManifestPath())
941
+ manifest.artifacts.firstBriefPath
906
942
  );
907
943
  updateActivationManifest(manifest);
908
944
  }
@@ -995,7 +1031,7 @@ function buildProgram() {
995
1031
  ).option("--advanced", "Show advanced profile, project id, hooks, GitHub, and sandbox prompts").option(
996
1032
  "--profile <profile>",
997
1033
  "Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
998
- ).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("--starter", "Mark this run as a starter activation and print dashboard-first guidance").option("--runtime-only", "Install only Snipara Sandbox").addOption(new Option("--full", "Legacy alias for --profile full-stack").hideHelp()).option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
1034
+ ).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("--starter", "Mark this run as a starter activation and print dashboard-first guidance").option("--json", "Print a machine-readable activation summary after setup").option("--runtime-only", "Install only Snipara Sandbox").addOption(new Option("--full", "Legacy alias for --profile full-stack").hideHelp()).option("-y, --yes", "Accept defaults without prompting").action(async (options) => {
999
1035
  printBanner();
1000
1036
  await runInit(options);
1001
1037
  });
@@ -1036,7 +1072,7 @@ function addSharedRootOptions(program) {
1036
1072
  ).option("--advanced", "Show advanced profile, project id, hooks, GitHub, and sandbox prompts").option(
1037
1073
  "--profile <profile>",
1038
1074
  "Install profile: hosted-only, hosted-companion, full-stack, runtime-only"
1039
- ).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("--starter", "Mark this run as a starter activation and print dashboard-first guidance").option("--runtime-only", "Install only Snipara Sandbox").addOption(new Option("--full", "Legacy alias for --profile full-stack").hideHelp()).option("-y, --yes", "Accept defaults without prompting");
1075
+ ).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("--starter", "Mark this run as a starter activation and print dashboard-first guidance").option("--json", "Print a machine-readable activation summary after setup").option("--runtime-only", "Install only Snipara Sandbox").addOption(new Option("--full", "Legacy alias for --profile full-stack").hideHelp()).option("-y, --yes", "Accept defaults without prompting");
1040
1076
  }
1041
1077
  async function main() {
1042
1078
  const program = buildProgram();
@@ -1136,6 +1172,7 @@ function parseInitOptionsFromArgv(args) {
1136
1172
  "--github": "github",
1137
1173
  "--skip-github": "skipGithub",
1138
1174
  "--starter": "starter",
1175
+ "--json": "json",
1139
1176
  "--yes": "yes",
1140
1177
  "-y": "yes"
1141
1178
  };
@@ -1200,6 +1237,11 @@ async function runInit(options) {
1200
1237
  runLocalSourceActivation(answers, activationManifest);
1201
1238
  createActivationArtifacts(answers, activationManifest);
1202
1239
  printSuccess(answers, validationReport, activationManifest);
1240
+ if (normalizedOptions.json) {
1241
+ console.log(
1242
+ JSON.stringify(buildActivationJsonSummary(activationManifest, validationReport), null, 2)
1243
+ );
1244
+ }
1203
1245
  if (answers.configureGitHub && answers.githubRepo) {
1204
1246
  await openGitHubAutomation(answers);
1205
1247
  }
@@ -1207,6 +1249,35 @@ async function runInit(options) {
1207
1249
  await runSandboxInit();
1208
1250
  }
1209
1251
  }
1252
+ function buildActivationJsonSummary(manifest, validation) {
1253
+ const laneEntries = Object.entries(manifest.lanes);
1254
+ const failedLanes = laneEntries.filter(([, lane]) => lane.status === "failed").map(([name]) => name);
1255
+ const pendingLanes = laneEntries.filter(([, lane]) => lane.status === "queued" || lane.status === "indexing").map(([name]) => name);
1256
+ const activationStatus = failedLanes.length > 0 ? "partial" : pendingLanes.length > 0 ? "partial" : "complete";
1257
+ return {
1258
+ ok: true,
1259
+ activationStatus,
1260
+ activationId: manifest.activationId,
1261
+ schemaVersion: manifest.schemaVersion,
1262
+ consumerContractVersion: manifest.consumerContract.version,
1263
+ projectSlug: manifest.projectSlug,
1264
+ aiClient: manifest.aiClient,
1265
+ profile: validation.profile,
1266
+ artifacts: manifest.artifacts,
1267
+ lanes: Object.fromEntries(
1268
+ laneEntries.map(([name, lane]) => [
1269
+ name,
1270
+ {
1271
+ status: lane.status,
1272
+ detail: lane.detail,
1273
+ command: lane.command
1274
+ }
1275
+ ])
1276
+ ),
1277
+ nextActions: manifest.nextActions,
1278
+ exitCode: activationStatus === "complete" ? 0 : manifest.consumerContract.exitCodes.activation_partial
1279
+ };
1280
+ }
1210
1281
  async function runDoctor(options) {
1211
1282
  const normalizedOptions = normalizeMaintenanceOptions(options);
1212
1283
  const requestedClient = normalizeClientOption(normalizedOptions.client);
@@ -1290,11 +1361,12 @@ async function runUpgrade(options) {
1290
1361
  printDoctorReport(detectEnvironment(), report);
1291
1362
  }
1292
1363
  async function runPrintConfig(options) {
1364
+ const normalizedOptions = normalizeMaintenanceOptions(options);
1293
1365
  const detection = detectEnvironment();
1294
- const answers = loadExistingAnswers(options);
1366
+ const answers = loadExistingAnswers(normalizedOptions);
1295
1367
  const githubRepo = detectGitRepository();
1296
1368
  const githubAnswerPacks = githubRepo ? `${githubRepo.fullName} can be connected with npx create-snipara --github` : "requires a GitHub-backed git remote";
1297
- if (options.json) {
1369
+ if (normalizedOptions.json) {
1298
1370
  console.log(
1299
1371
  JSON.stringify(
1300
1372
  {
@@ -3384,6 +3456,81 @@ function buildActivationSurfaceContract(client) {
3384
3456
  nextSurfaceAction: "Restart or reload the client, verify Snipara tools, then ask the first grounded project question from the generated First Work Brief."
3385
3457
  };
3386
3458
  }
3459
+ function buildEditorActivationConsumerContract(client) {
3460
+ const secretRule = client === "vscode" ? "Use VS Code SecretStorage for SNIPARA_API_KEY and pass it to create-snipara through the child-process environment; never write raw secrets into extension settings or logs." : "Pass SNIPARA_API_KEY through the process environment or client secret store; never parse, log, or persist raw secrets from terminal output.";
3461
+ return {
3462
+ version: ACTIVATION_CONSUMER_CONTRACT_VERSION,
3463
+ audience: "editor_extension",
3464
+ stableFiles: {
3465
+ activationManifest: ".snipara/activation/activation-manifest.json",
3466
+ firstBrief: ".snipara/activation/first-brief.md",
3467
+ handoff: ".snipara/activation/handoff.md",
3468
+ memoryCandidates: ".snipara/activation/memory-candidates.json"
3469
+ },
3470
+ requiredManifestFields: [
3471
+ "schemaVersion",
3472
+ "consumerContract.version",
3473
+ "surfaceContract",
3474
+ "artifacts.activationManifestPath",
3475
+ "artifacts.firstBriefPath",
3476
+ "artifacts.handoffPath",
3477
+ "lanes.connection.status",
3478
+ "lanes.firstBrief.status",
3479
+ "nextActions"
3480
+ ],
3481
+ laneStatuses: ["ready", "indexing", "queued", "needs_review", "skipped", "failed"],
3482
+ exitCodes: {
3483
+ success: 0,
3484
+ activation_partial: 10,
3485
+ auth_required: 20,
3486
+ missing_api_key: 21,
3487
+ missing_node_or_npm: 30,
3488
+ activation_failed: 40
3489
+ },
3490
+ parseRule: "Read .snipara/activation/activation-manifest.json as the source of truth. If --json is used, parse the last JSON object from stdout as a summary pointer, not as the full durable state.",
3491
+ secretRule
3492
+ };
3493
+ }
3494
+ function buildActivationNextActions(surfaceContract, answers) {
3495
+ const actions = [
3496
+ {
3497
+ id: "open_first_work_brief",
3498
+ label: "Open First Work Brief",
3499
+ target: "editor",
3500
+ when: "artifacts.firstBriefPath is present and lanes.firstBrief.status is ready"
3501
+ },
3502
+ {
3503
+ id: "handoff_to_agent",
3504
+ label: "Hand off to the coding agent",
3505
+ target: "agent",
3506
+ when: "lanes.connection.status is ready and First Work Brief has been shown"
3507
+ },
3508
+ {
3509
+ id: "review_memory_candidates",
3510
+ label: "Review memory candidates",
3511
+ target: "editor",
3512
+ when: "lanes.memoryCandidates.status is needs_review"
3513
+ }
3514
+ ];
3515
+ if (answers.aiClient === "vscode") {
3516
+ actions.unshift({
3517
+ id: "vscode_activate_workspace",
3518
+ label: "Snipara: Activate Workspace",
3519
+ command: "Snipara: Activate Workspace",
3520
+ target: "editor",
3521
+ when: "VS Code extension command is available"
3522
+ });
3523
+ } else {
3524
+ actions.unshift({
3525
+ id: "verify_surface_activation",
3526
+ label: "Verify activation surface",
3527
+ command: surfaceContract.nextSurfaceAction,
3528
+ target: "agent",
3529
+ when: "editor-specific command is unavailable"
3530
+ });
3531
+ }
3532
+ return actions;
3533
+ }
3387
3534
  function getClientGuidance(client) {
3388
3535
  if (client === "claude-code") {
3389
3536
  return [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snipara",
3
- "version": "2.0.11",
3
+ "version": "2.0.12",
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",