create-snipara 2.0.9 → 2.0.10

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 +183 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -26,7 +26,7 @@ Use it for:
26
26
  - free account signup with reviewed Context + Memory
27
27
  - local project wiring, `doctor`, `repair`, and `upgrade`
28
28
  - local source activation without GitHub, plus optional GitHub repository sync and PR Answer Packs approval when the current folder is a GitHub repo
29
- - day-zero Project Intelligence proof: a First Work Brief, a ready-to-run `snipara_context_query`, review-only decision archaeology candidates, possible doc-staleness findings, and an estimated context economy report from the user's own repository
29
+ - day-zero Project Intelligence proof: a First Work Brief, a ready-to-run `snipara_context_query`, a small hosted README/docs seed sync for virgin projects, review-only decision archaeology candidates, possible doc-staleness findings, and an estimated context economy report from the user's own repository
30
30
 
31
31
  ## Why It Exists
32
32
 
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.9",
16
+ version: "2.0.10",
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",
@@ -104,6 +104,9 @@ var SANDBOX_COMMAND_NAME = "snipara-sandbox";
104
104
  var LEGACY_SANDBOX_COMMAND_NAME = "rlm";
105
105
  var ORCHESTRATOR_COMMAND_NAME = "snipara-orchestrator";
106
106
  var DEVICE_CLIENT_ID = "create-snipara";
107
+ var DAY_ZERO_CORPUS_MAX_FILES = 8;
108
+ var DAY_ZERO_CORPUS_MAX_FILE_CHARS = 12e3;
109
+ var DAY_ZERO_CORPUS_MAX_TOTAL_CHARS = 5e4;
107
110
  var EXPERIENCE_GOAL_SECTION = `## Experience Goal
108
111
 
109
112
  The target experience is outcome-first agent work across supported clients:
@@ -288,6 +291,63 @@ function readTextFileSnippet(relativePath, maxChars = 24e3) {
288
291
  return "";
289
292
  }
290
293
  }
294
+ function collectDayZeroCorpusDocuments(scan) {
295
+ const documents = [];
296
+ let totalChars = 0;
297
+ const cwd = process.cwd();
298
+ const rootReadmes = fs.existsSync(cwd) ? fs.readdirSync(cwd).filter((entry) => /^readme(?:\.[a-z0-9_-]+)?\.mdx?$/i.test(entry)).sort() : [];
299
+ const sources = [
300
+ ...rootReadmes,
301
+ ...listFilesUnder("docs", DAY_ZERO_CORPUS_MAX_FILES * 8),
302
+ ...scan.files.candidateDocs
303
+ ];
304
+ const seen = /* @__PURE__ */ new Set();
305
+ for (const source of sources) {
306
+ const normalized = source.replace(/\\/g, "/");
307
+ if (seen.has(normalized)) {
308
+ continue;
309
+ }
310
+ seen.add(normalized);
311
+ const lower = normalized.toLowerCase();
312
+ const isReadme = /^readme(?:\.[a-z0-9_-]+)?\.mdx?$/.test(lower);
313
+ const isDocsMarkdown = lower.startsWith("docs/") && /\.(?:md|mdx|markdown|txt|rst|adoc)$/.test(lower);
314
+ if (!isReadme && !isDocsMarkdown) {
315
+ continue;
316
+ }
317
+ if (documents.length >= DAY_ZERO_CORPUS_MAX_FILES) {
318
+ break;
319
+ }
320
+ if (totalChars >= DAY_ZERO_CORPUS_MAX_TOTAL_CHARS) {
321
+ break;
322
+ }
323
+ const remainingChars = DAY_ZERO_CORPUS_MAX_TOTAL_CHARS - totalChars;
324
+ const content = readTextFileSnippet(
325
+ source,
326
+ Math.min(DAY_ZERO_CORPUS_MAX_FILE_CHARS, remainingChars)
327
+ ).trim();
328
+ if (!content) {
329
+ continue;
330
+ }
331
+ documents.push({
332
+ path: normalized,
333
+ content
334
+ });
335
+ totalChars += content.length;
336
+ }
337
+ return documents;
338
+ }
339
+ function createDayZeroCorpusReport(status, documents, detail, options = {}) {
340
+ return {
341
+ status,
342
+ documents: documents.map((document) => ({
343
+ path: document.path,
344
+ chars: document.content.length
345
+ })),
346
+ detail,
347
+ ...options.tool ? { tool: options.tool } : {},
348
+ ...options.error ? { error: options.error.slice(0, 500) } : {}
349
+ };
350
+ }
291
351
  function buildStalenessFindings(scan) {
292
352
  const findings = [];
293
353
  const scriptSet = new Set(scan.scripts);
@@ -566,6 +626,11 @@ function createActivationManifest(answers, detection, mode = "default", scan) {
566
626
  query: dayZeroQuery,
567
627
  expectedOutcome: "First own-repo answer pack before the user reads product docs."
568
628
  },
629
+ dayZeroCorpus: createDayZeroCorpusReport(
630
+ "queued",
631
+ collectDayZeroCorpusDocuments(localScan),
632
+ "README and docs Markdown will be submitted to hosted context before the first day-zero query when live hosted checks are enabled."
633
+ ),
569
634
  agentReadiness: buildAgentReadinessReport(localScan),
570
635
  contextEconomy: buildContextEconomyReport(localScan, dayZeroQuery),
571
636
  projectSlug: answers.projectSlug,
@@ -593,8 +658,8 @@ function createActivationManifest(answers, detection, mode = "default", scan) {
593
658
  hasCompanion ? "Local source activation will create a repository snapshot." : "Install companion later to activate local source context."
594
659
  ),
595
660
  contextIndex: createActivationLane(
596
- hasCompanion ? "queued" : "skipped",
597
- hasCompanion ? "Context indexing starts from local docs and instruction files." : "Context indexing requires companion or hosted provider sync."
661
+ hasHostedConfig || hasCompanion ? "queued" : "skipped",
662
+ hasCompanion ? "Context indexing starts from local docs and instruction files." : hasHostedConfig ? "Day-zero README/docs sync will seed hosted context when live hosted checks run." : "Context indexing requires companion or hosted provider sync."
598
663
  ),
599
664
  codeGraph: createActivationLane(
600
665
  hasCompanion ? "queued" : "skipped",
@@ -698,6 +763,115 @@ function runLocalSourceActivation(answers, manifest) {
698
763
  }
699
764
  updateActivationManifest(manifest);
700
765
  }
766
+ async function runHostedDayZeroCorpusSync(answers, manifest, enabled) {
767
+ if (answers.profile === "runtime-only") {
768
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
769
+ "skipped",
770
+ [],
771
+ "Runtime-only profile skipped Hosted MCP config and hosted document sync."
772
+ );
773
+ updateActivationManifest(manifest);
774
+ return;
775
+ }
776
+ if (!enabled) {
777
+ const documents2 = collectDayZeroCorpusDocuments(manifest.localScan);
778
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
779
+ "skipped",
780
+ documents2,
781
+ "Skipped because hosted validation was disabled with --skip-test."
782
+ );
783
+ updateActivationManifest(manifest);
784
+ return;
785
+ }
786
+ if (answers.apiKeyType === "none" || answers.apiKey.includes("YOUR_")) {
787
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
788
+ "skipped",
789
+ [],
790
+ "Skipped because no live hosted API key was available."
791
+ );
792
+ updateActivationManifest(manifest);
793
+ return;
794
+ }
795
+ const documents = collectDayZeroCorpusDocuments(manifest.localScan);
796
+ if (documents.length === 0) {
797
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
798
+ "skipped",
799
+ [],
800
+ "No README or docs Markdown files were found to seed hosted context."
801
+ );
802
+ if (manifest.lanes.contextIndex.status === "queued") {
803
+ manifest.lanes.contextIndex = createActivationLane(
804
+ "skipped",
805
+ "No README or docs Markdown files were found to seed hosted context."
806
+ );
807
+ }
808
+ updateActivationManifest(manifest);
809
+ return;
810
+ }
811
+ const syncTool = "snipara_sync_documents";
812
+ const syncResponse = await callHostedMcp(answers, "tools/call", {
813
+ name: syncTool,
814
+ arguments: {
815
+ documents,
816
+ delete_missing: false
817
+ }
818
+ });
819
+ if (syncResponse.ok && !syncResponse.data.error) {
820
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
821
+ "submitted",
822
+ documents,
823
+ `Submitted ${documents.length} README/docs files to hosted context for the first day-zero answer pack.`,
824
+ { tool: syncTool }
825
+ );
826
+ manifest.lanes.contextIndex = createActivationLane(
827
+ "indexing",
828
+ "Day-zero README/docs corpus submitted to hosted context indexing.",
829
+ syncTool
830
+ );
831
+ updateActivationManifest(manifest);
832
+ return;
833
+ }
834
+ const uploadTool = "snipara_upload_document";
835
+ const uploadErrors = [];
836
+ for (const document of documents) {
837
+ const uploadResponse = await callHostedMcp(answers, "tools/call", {
838
+ name: uploadTool,
839
+ arguments: document
840
+ });
841
+ if (!uploadResponse.ok || uploadResponse.data.error) {
842
+ uploadErrors.push(
843
+ uploadResponse.ok ? describeJsonRpcError(uploadResponse.data) : describeHostedHttpFailure(uploadResponse.status, uploadResponse.bodyText)
844
+ );
845
+ break;
846
+ }
847
+ }
848
+ if (uploadErrors.length === 0) {
849
+ manifest.dayZeroCorpus = createDayZeroCorpusReport(
850
+ "submitted",
851
+ documents,
852
+ `Submitted ${documents.length} README/docs files to hosted context for the first day-zero answer pack.`,
853
+ { tool: uploadTool }
854
+ );
855
+ manifest.lanes.contextIndex = createActivationLane(
856
+ "indexing",
857
+ "Day-zero README/docs corpus submitted to hosted context indexing.",
858
+ uploadTool
859
+ );
860
+ } else {
861
+ const syncError = syncResponse.ok ? describeJsonRpcError(syncResponse.data) : describeHostedHttpFailure(syncResponse.status, syncResponse.bodyText);
862
+ const detail = `Could not submit the day-zero README/docs corpus. sync_documents: ${syncError}; upload_document: ${uploadErrors[0]}`;
863
+ manifest.dayZeroCorpus = createDayZeroCorpusReport("failed", documents, detail, {
864
+ tool: syncTool,
865
+ error: detail
866
+ });
867
+ manifest.lanes.contextIndex = failActivationLane(
868
+ "Hosted day-zero README/docs sync failed; the first answer may need GitHub, companion, or a later sync.",
869
+ syncTool,
870
+ new Error(detail)
871
+ );
872
+ }
873
+ updateActivationManifest(manifest);
874
+ }
701
875
  function createActivationArtifacts(answers, manifest) {
702
876
  const candidates = buildMemoryCandidatePreviews(manifest.localScan);
703
877
  writeMemoryCandidates(candidates);
@@ -1011,6 +1185,7 @@ async function runInit(options) {
1011
1185
  normalizedOptions.starter ? "starter" : "default",
1012
1186
  activationScan
1013
1187
  );
1188
+ await runHostedDayZeroCorpusSync(answers, activationManifest, !normalizedOptions.skipTest);
1014
1189
  runLocalSourceActivation(answers, activationManifest);
1015
1190
  createActivationArtifacts(answers, activationManifest);
1016
1191
  printSuccess(answers, validationReport, activationManifest);
@@ -4331,6 +4506,11 @@ function printActivationSummary(manifest) {
4331
4506
  ` Target: ${manifest.activationMetric.targetMinutes} minutes to a true, non-obvious own-repo answer.`
4332
4507
  )
4333
4508
  );
4509
+ console.log(
4510
+ chalk.dim(
4511
+ ` Day-zero corpus: ${manifest.dayZeroCorpus.status} - ${manifest.dayZeroCorpus.detail}`
4512
+ )
4513
+ );
4334
4514
  console.log(chalk.bold("\nAgent readiness:\n"));
4335
4515
  console.log(` ${manifest.agentReadiness.summary}`);
4336
4516
  for (const finding of manifest.agentReadiness.stalenessFindings.slice(0, 3)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-snipara",
3
- "version": "2.0.9",
3
+ "version": "2.0.10",
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",