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.
- package/README.md +1 -1
- package/dist/index.js +183 -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.
|
|
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