vanara 0.1.0 → 0.2.0
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 +14 -0
- package/bin/vanara.js +66 -2
- package/catalog/agents/api-designer/AGENT.md +140 -0
- package/catalog/agents/api-designer/examples/openapi-snippet.yaml +130 -0
- package/catalog/agents/api-designer/examples/review-notes.md +61 -0
- package/catalog/agents/api-designer/references/contract-and-openapi.md +82 -0
- package/catalog/agents/api-designer/references/design-checklist.md +68 -0
- package/catalog/agents/api-designer/references/versioning-and-evolution.md +63 -0
- package/catalog/agents/api-designer/scripts/lint-openapi.mjs +180 -0
- package/catalog/agents/code-reviewer/AGENT.md +168 -0
- package/catalog/agents/code-reviewer/examples/pr-comment-template.md +48 -0
- package/catalog/agents/code-reviewer/examples/sample-review-output.md +38 -0
- package/catalog/agents/code-reviewer/references/review-checklist.md +46 -0
- package/catalog/agents/code-reviewer/references/security-review.md +62 -0
- package/catalog/agents/code-reviewer/references/severity-rubric.md +63 -0
- package/catalog/agents/code-reviewer/scripts/review-guard.mjs +102 -0
- package/catalog/agents/debugger/AGENT.md +112 -0
- package/catalog/agents/debugger/examples/postmortem-template.md +59 -0
- package/catalog/agents/debugger/examples/repro-template.md +50 -0
- package/catalog/agents/debugger/references/bisection.md +63 -0
- package/catalog/agents/debugger/references/debugging-method.md +57 -0
- package/catalog/agents/debugger/references/observability.md +61 -0
- package/catalog/agents/debugger/scripts/parse-stacktrace.mjs +109 -0
- package/catalog/agents/pr-summarizer/AGENT.md +156 -0
- package/catalog/agents/pr-summarizer/examples/sample-pr-summary.md +46 -0
- package/catalog/agents/pr-summarizer/examples/weak-vs-strong-summary.md +68 -0
- package/catalog/agents/pr-summarizer/references/identifying-risk.md +68 -0
- package/catalog/agents/pr-summarizer/references/reading-the-diff.md +68 -0
- package/catalog/agents/pr-summarizer/references/test-plan-and-missing-tests.md +64 -0
- package/catalog/agents/pr-summarizer/references/writing-the-summary.md +63 -0
- package/catalog/agents/pr-summarizer/scripts/diff-risk.mjs +111 -0
- package/catalog/agents/refactoring-specialist/AGENT.md +185 -0
- package/catalog/agents/refactoring-specialist/examples/before-after.md +91 -0
- package/catalog/agents/refactoring-specialist/examples/refactor-plan.md +97 -0
- package/catalog/agents/refactoring-specialist/references/large-scale-refactor.md +50 -0
- package/catalog/agents/refactoring-specialist/references/safe-workflow.md +75 -0
- package/catalog/agents/refactoring-specialist/references/smell-catalog.md +76 -0
- package/catalog/agents/refactoring-specialist/scripts/detect-smells.mjs +150 -0
- package/catalog/agents/security-auditor/AGENT.md +168 -0
- package/catalog/agents/security-auditor/examples/audit-report.md +68 -0
- package/catalog/agents/security-auditor/examples/finding-template.md +31 -0
- package/catalog/agents/security-auditor/references/audit-workflow.md +116 -0
- package/catalog/agents/security-auditor/references/severity-and-reporting.md +56 -0
- package/catalog/agents/security-auditor/references/vuln-classes.md +129 -0
- package/catalog/agents/security-auditor/scripts/scan-secrets.mjs +86 -0
- package/catalog/agents/technical-writer/AGENT.md +163 -0
- package/catalog/agents/technical-writer/examples/how-to-example.md +76 -0
- package/catalog/agents/technical-writer/examples/reference-example.md +75 -0
- package/catalog/agents/technical-writer/references/clarity-and-style.md +52 -0
- package/catalog/agents/technical-writer/references/diataxis-and-doc-types.md +61 -0
- package/catalog/agents/technical-writer/references/structure-and-maintenance.md +59 -0
- package/catalog/agents/technical-writer/scripts/readability.mjs +103 -0
- package/catalog/agents/test-author/AGENT.md +177 -0
- package/catalog/agents/test-author/examples/test-plan.md +54 -0
- package/catalog/agents/test-author/examples/unit-test-example.ts +55 -0
- package/catalog/agents/test-author/references/aaa-and-naming.md +75 -0
- package/catalog/agents/test-author/references/mocking-and-fixtures.md +94 -0
- package/catalog/agents/test-author/references/test-types-and-pyramid.md +60 -0
- package/catalog/agents/test-author/scripts/check-coverage.mjs +145 -0
- package/catalog/agents/threat-modeler/AGENT.md +163 -0
- package/catalog/agents/threat-modeler/examples/dfd-example.md +55 -0
- package/catalog/agents/threat-modeler/examples/threat-model.md +81 -0
- package/catalog/agents/threat-modeler/references/dfd-and-trust-boundaries.md +76 -0
- package/catalog/agents/threat-modeler/references/mitigation-catalog.md +77 -0
- package/catalog/agents/threat-modeler/references/stride-method.md +68 -0
- package/catalog/agents/threat-modeler/scripts/stride-checklist.mjs +183 -0
- package/catalog/agents/vuln-scanner/AGENT.md +146 -0
- package/catalog/agents/vuln-scanner/examples/finding-template.md +57 -0
- package/catalog/agents/vuln-scanner/examples/scan-report.md +49 -0
- package/catalog/agents/vuln-scanner/references/remediation-and-severity.md +68 -0
- package/catalog/agents/vuln-scanner/references/scan-types-and-tools.md +83 -0
- package/catalog/agents/vuln-scanner/references/triage-and-false-positives.md +73 -0
- package/catalog/agents/vuln-scanner/scripts/parse-scan-results.mjs +133 -0
- package/catalog/packs/code-review-pack/PACK.md +100 -0
- package/catalog/packs/code-review-pack/examples/pr-flow-example.md +50 -0
- package/catalog/packs/code-review-pack/references/rollout-guide.md +40 -0
- package/catalog/packs/security-pack/PACK.md +128 -0
- package/catalog/packs/security-pack/examples/owasp-vuln-triage-and-fix.md +66 -0
- package/catalog/packs/security-pack/examples/threat-model-then-audit.md +77 -0
- package/catalog/packs/security-pack/references/choosing-the-right-tool.md +37 -0
- package/catalog/packs/security-pack/references/threat-model-to-remediation.md +69 -0
- package/catalog/packs/security-pack/references/workflow.md +56 -0
- package/catalog/skills/api-pagination/SKILL.md +83 -0
- package/catalog/skills/api-pagination/examples/keyset-queries.sql +38 -0
- package/catalog/skills/api-pagination/examples/response-shapes.md +51 -0
- package/catalog/skills/api-pagination/references/consuming-pages.md +39 -0
- package/catalog/skills/api-pagination/references/counting-and-totals.md +41 -0
- package/catalog/skills/api-pagination/references/cursor-encoding.md +34 -0
- package/catalog/skills/api-pagination/scripts/check-cursor.mjs +51 -0
- package/catalog/skills/caching-strategies/SKILL.md +180 -0
- package/catalog/skills/caching-strategies/examples/http-cache-headers.md +82 -0
- package/catalog/skills/caching-strategies/examples/redis-cache-aside.js +110 -0
- package/catalog/skills/caching-strategies/references/cache-patterns.md +93 -0
- package/catalog/skills/caching-strategies/references/eviction-and-ttl.md +67 -0
- package/catalog/skills/caching-strategies/references/invalidation-and-stampede.md +99 -0
- package/catalog/skills/caching-strategies/scripts/ttl-jitter.mjs +99 -0
- package/catalog/skills/conventional-commits/SKILL.md +135 -0
- package/catalog/skills/conventional-commits/examples/commit-examples.md +60 -0
- package/catalog/skills/conventional-commits/examples/commitlint.config.js +31 -0
- package/catalog/skills/conventional-commits/references/breaking-changes-semver.md +50 -0
- package/catalog/skills/conventional-commits/references/scoping-commits.md +42 -0
- package/catalog/skills/conventional-commits/references/spec.md +78 -0
- package/catalog/skills/conventional-commits/scripts/lint-commit.mjs +97 -0
- package/catalog/skills/database-migrations/SKILL.md +137 -0
- package/catalog/skills/database-migrations/examples/add-column-safe.sql +34 -0
- package/catalog/skills/database-migrations/examples/migration-config.example.json +27 -0
- package/catalog/skills/database-migrations/references/expand-contract.md +74 -0
- package/catalog/skills/database-migrations/references/rollback-and-safety.md +71 -0
- package/catalog/skills/database-migrations/references/zero-downtime-changes.md +84 -0
- package/catalog/skills/database-migrations/scripts/check-migration-reversible.mjs +139 -0
- package/catalog/skills/error-handling-patterns/SKILL.md +136 -0
- package/catalog/skills/error-handling-patterns/examples/express-error-middleware.js +93 -0
- package/catalog/skills/error-handling-patterns/examples/result-pattern.ts +81 -0
- package/catalog/skills/error-handling-patterns/references/error-taxonomy.md +91 -0
- package/catalog/skills/error-handling-patterns/references/language-patterns.md +102 -0
- package/catalog/skills/error-handling-patterns/references/retry-and-backoff.md +76 -0
- package/catalog/skills/error-handling-patterns/scripts/lint-empty-catch.mjs +113 -0
- package/catalog/skills/git-collaboration-workflows/SKILL.md +104 -0
- package/catalog/skills/git-collaboration-workflows/examples/branch-protection.md +48 -0
- package/catalog/skills/git-collaboration-workflows/examples/pr-review-playbook.md +48 -0
- package/catalog/skills/git-collaboration-workflows/references/branching-models.md +52 -0
- package/catalog/skills/git-collaboration-workflows/references/history-hygiene.md +44 -0
- package/catalog/skills/git-collaboration-workflows/scripts/check-branch-hygiene.mjs +62 -0
- package/catalog/skills/owasp-top10/SKILL.md +112 -0
- package/catalog/skills/owasp-top10/examples/sql-injection-fix.md +33 -0
- package/catalog/skills/owasp-top10/examples/xss-fix.md +27 -0
- package/catalog/skills/owasp-top10/references/access-control.md +36 -0
- package/catalog/skills/owasp-top10/references/crypto-failures.md +29 -0
- package/catalog/skills/owasp-top10/references/injection.md +39 -0
- package/catalog/skills/owasp-top10/references/ssrf-and-design.md +35 -0
- package/catalog/skills/owasp-top10/scripts/scan-injection.mjs +73 -0
- package/catalog/skills/prompt-engineering/SKILL.md +100 -0
- package/catalog/skills/prompt-engineering/examples/classification-prompt.md +29 -0
- package/catalog/skills/prompt-engineering/examples/extraction-prompt.md +25 -0
- package/catalog/skills/prompt-engineering/references/prompt-injection.md +34 -0
- package/catalog/skills/prompt-engineering/references/structured-output.md +34 -0
- package/catalog/skills/prompt-engineering/references/techniques.md +33 -0
- package/catalog/skills/prompt-engineering/scripts/validate-output.mjs +71 -0
- package/catalog/skills/readme-writing/SKILL.md +176 -0
- package/catalog/skills/readme-writing/examples/README.template.md +73 -0
- package/catalog/skills/readme-writing/examples/good-readme-example.md +95 -0
- package/catalog/skills/readme-writing/references/anatomy.md +107 -0
- package/catalog/skills/readme-writing/references/maintenance.md +68 -0
- package/catalog/skills/readme-writing/references/writing-style.md +79 -0
- package/catalog/skills/readme-writing/scripts/lint-readme.mjs +117 -0
- package/catalog/skills/refactoring-patterns/SKILL.md +178 -0
- package/catalog/skills/refactoring-patterns/examples/extract-function.before-after.js +57 -0
- package/catalog/skills/refactoring-patterns/examples/replace-conditional-with-polymorphism.before-after.ts +63 -0
- package/catalog/skills/refactoring-patterns/references/code-smells.md +92 -0
- package/catalog/skills/refactoring-patterns/references/refactoring-catalog.md +78 -0
- package/catalog/skills/refactoring-patterns/references/safe-workflow.md +74 -0
- package/catalog/skills/refactoring-patterns/scripts/detect-smells.mjs +137 -0
- package/catalog/skills/rest-api-design/SKILL.md +147 -0
- package/catalog/skills/rest-api-design/examples/error-envelope.json +26 -0
- package/catalog/skills/rest-api-design/examples/orders-api.openapi.yaml +106 -0
- package/catalog/skills/rest-api-design/references/error-handling.md +43 -0
- package/catalog/skills/rest-api-design/references/pagination.md +41 -0
- package/catalog/skills/rest-api-design/references/status-codes.md +32 -0
- package/catalog/skills/rest-api-design/references/versioning.md +31 -0
- package/catalog/skills/rest-api-design/scripts/check-envelope.mjs +62 -0
- package/catalog/skills/secrets-management/SKILL.md +134 -0
- package/catalog/skills/secrets-management/examples/env-example.md +41 -0
- package/catalog/skills/secrets-management/examples/rotation-runbook.md +50 -0
- package/catalog/skills/secrets-management/references/leak-response.md +47 -0
- package/catalog/skills/secrets-management/references/rotation.md +46 -0
- package/catalog/skills/secrets-management/references/secret-managers.md +52 -0
- package/catalog/skills/secrets-management/scripts/detect-hardcoded.mjs +96 -0
- package/catalog/skills/secure-auth/SKILL.md +135 -0
- package/catalog/skills/secure-auth/examples/auth-flow.md +60 -0
- package/catalog/skills/secure-auth/examples/jwt-verify.ts +89 -0
- package/catalog/skills/secure-auth/references/auth-attacks.md +76 -0
- package/catalog/skills/secure-auth/references/oauth2-oidc.md +65 -0
- package/catalog/skills/secure-auth/references/password-hashing.md +70 -0
- package/catalog/skills/secure-auth/references/sessions-vs-jwt.md +69 -0
- package/catalog/skills/secure-auth/scripts/check-password-policy.mjs +114 -0
- package/catalog/skills/sql-index-tuning/SKILL.md +171 -0
- package/catalog/skills/sql-index-tuning/examples/explain-walkthrough.sql +91 -0
- package/catalog/skills/sql-index-tuning/examples/index-ddl.sql +67 -0
- package/catalog/skills/sql-index-tuning/references/btree-internals.md +58 -0
- package/catalog/skills/sql-index-tuning/references/composite-and-covering.md +60 -0
- package/catalog/skills/sql-index-tuning/references/reading-explain.md +54 -0
- package/catalog/skills/sql-index-tuning/references/selectivity-and-cardinality.md +62 -0
- package/catalog/skills/sql-index-tuning/scripts/suggest-index.mjs +213 -0
- package/catalog/skills/test-plan-design/SKILL.md +154 -0
- package/catalog/skills/test-plan-design/examples/test-case-template.md +45 -0
- package/catalog/skills/test-plan-design/examples/test-plan.md +57 -0
- package/catalog/skills/test-plan-design/references/case-design.md +79 -0
- package/catalog/skills/test-plan-design/references/risk-prioritization.md +58 -0
- package/catalog/skills/test-plan-design/references/test-pyramid.md +58 -0
- package/catalog/skills/test-plan-design/scripts/coverage-gaps.mjs +109 -0
- package/free-tier.json +15 -0
- package/package.json +15 -4
- package/premium-index.json +1 -0
- package/src/config.js +31 -1
- package/src/license.js +143 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Runnable check: given a set of requirements and a set of test cases, report which
|
|
3
|
+
// requirements have NO covering test. Maps a traceability matrix to a build gate, so an
|
|
4
|
+
// untested requirement can fail CI instead of shipping silently.
|
|
5
|
+
//
|
|
6
|
+
// Input JSON shape:
|
|
7
|
+
// {
|
|
8
|
+
// "requirements": [ { "id": "R1", "title": "...", "priority": "high" }, ... ],
|
|
9
|
+
// "testCases": [ { "id": "t1", "requirement": "R1" }, ... ]
|
|
10
|
+
// }
|
|
11
|
+
// A test "covers" a requirement when its `requirement` field (string or array) matches the
|
|
12
|
+
// requirement's `id`.
|
|
13
|
+
//
|
|
14
|
+
// Usage:
|
|
15
|
+
// node coverage-gaps.mjs '<json>' # check a literal JSON string
|
|
16
|
+
// echo '<json>' | node coverage-gaps.mjs # check from stdin
|
|
17
|
+
// node coverage-gaps.mjs --selftest # run built-in test cases
|
|
18
|
+
//
|
|
19
|
+
// Exit code: 0 = every requirement is covered; 1 = gaps found / invalid input / selftest failed.
|
|
20
|
+
|
|
21
|
+
export function findCoverageGaps(model) {
|
|
22
|
+
const requirements = Array.isArray(model?.requirements) ? model.requirements : [];
|
|
23
|
+
const testCases = Array.isArray(model?.testCases) ? model.testCases : [];
|
|
24
|
+
|
|
25
|
+
const covered = new Set();
|
|
26
|
+
for (const tc of testCases) {
|
|
27
|
+
const refs = Array.isArray(tc?.requirement) ? tc.requirement : [tc?.requirement];
|
|
28
|
+
for (const r of refs) {
|
|
29
|
+
if (typeof r === 'string' && r.length > 0) covered.add(r);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const gaps = requirements
|
|
34
|
+
.filter((req) => typeof req?.id === 'string')
|
|
35
|
+
.filter((req) => !covered.has(req.id))
|
|
36
|
+
.map((req) => ({ id: req.id, title: req.title ?? '', priority: req.priority ?? 'unspecified' }));
|
|
37
|
+
|
|
38
|
+
return { total: requirements.length, coveredCount: requirements.length - gaps.length, gaps };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function report(label, json) {
|
|
42
|
+
let model;
|
|
43
|
+
try {
|
|
44
|
+
model = typeof json === 'string' ? JSON.parse(json) : json;
|
|
45
|
+
} catch {
|
|
46
|
+
console.error(`x ${label}: invalid JSON`);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const { total, coveredCount, gaps } = findCoverageGaps(model);
|
|
50
|
+
if (gaps.length === 0) {
|
|
51
|
+
console.log(`ok ${label}: all ${total} requirement(s) covered`);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
console.error(`x ${label}: ${gaps.length} of ${total} requirement(s) uncovered (${coveredCount} covered):`);
|
|
55
|
+
for (const g of gaps) {
|
|
56
|
+
console.error(` - ${g.id} [${g.priority}] ${g.title}`.trimEnd());
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function selftest() {
|
|
62
|
+
const fullCoverage = {
|
|
63
|
+
requirements: [
|
|
64
|
+
{ id: 'R1', title: 'Totals include tax', priority: 'high' },
|
|
65
|
+
{ id: 'R2', title: 'Expired coupons rejected', priority: 'medium' },
|
|
66
|
+
],
|
|
67
|
+
testCases: [
|
|
68
|
+
{ id: 't1', requirement: 'R1' },
|
|
69
|
+
{ id: 't2', requirement: ['R1', 'R2'] }, // array form also covers R2
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
const withGaps = {
|
|
73
|
+
requirements: [
|
|
74
|
+
{ id: 'R1', title: 'Totals include tax', priority: 'high' },
|
|
75
|
+
{ id: 'R2', title: 'Expired coupons rejected', priority: 'medium' },
|
|
76
|
+
{ id: 'R3', title: 'Coupon min cart $50', priority: 'high' },
|
|
77
|
+
],
|
|
78
|
+
testCases: [
|
|
79
|
+
{ id: 't1', requirement: 'R1' }, // R2 and R3 left uncovered
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const a = findCoverageGaps(fullCoverage);
|
|
84
|
+
const b = findCoverageGaps(withGaps);
|
|
85
|
+
|
|
86
|
+
const checks = [
|
|
87
|
+
['full-coverage reports zero gaps', a.gaps.length === 0],
|
|
88
|
+
['full-coverage counts all covered', a.coveredCount === 2 && a.total === 2],
|
|
89
|
+
['gaps case finds two gaps', b.gaps.length === 2],
|
|
90
|
+
['gaps case identifies R2 and R3', b.gaps.map((g) => g.id).join(',') === 'R2,R3'],
|
|
91
|
+
['gaps case counts one covered', b.coveredCount === 1 && b.total === 3],
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
let allPass = true;
|
|
95
|
+
for (const [name, ok] of checks) {
|
|
96
|
+
allPass &&= ok;
|
|
97
|
+
console.log(`${ok ? 'ok' : 'x'} selftest: ${name}`);
|
|
98
|
+
}
|
|
99
|
+
process.exit(allPass ? 0 : 1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const arg = process.argv[2];
|
|
103
|
+
if (arg === '--selftest') selftest();
|
|
104
|
+
else if (arg) process.exit(report('input', arg) ? 0 : 1);
|
|
105
|
+
else {
|
|
106
|
+
let buf = '';
|
|
107
|
+
process.stdin.on('data', (c) => (buf += c));
|
|
108
|
+
process.stdin.on('end', () => process.exit(report('stdin', buf) ? 0 : 1));
|
|
109
|
+
}
|
package/free-tier.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Items installable without a license. Everything else in the bundled catalog requires `vanara unlock <license-key>` (Pro subscription). Packs listed here imply their members are free too.",
|
|
3
|
+
"packs": ["code-review-pack", "security-pack"],
|
|
4
|
+
"agents": [
|
|
5
|
+
"code-reviewer", "pr-summarizer", "threat-modeler", "security-auditor", "vuln-scanner",
|
|
6
|
+
"debugger", "test-author", "api-designer", "refactoring-specialist", "technical-writer"
|
|
7
|
+
],
|
|
8
|
+
"skills": [
|
|
9
|
+
"git-collaboration-workflows", "conventional-commits", "sql-index-tuning",
|
|
10
|
+
"owasp-top10", "secure-auth", "secrets-management",
|
|
11
|
+
"rest-api-design", "api-pagination", "error-handling-patterns",
|
|
12
|
+
"test-plan-design", "readme-writing", "refactoring-patterns",
|
|
13
|
+
"caching-strategies", "database-migrations", "prompt-engineering"
|
|
14
|
+
]
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vanara",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Vanara — deploy packs of skilled AI agents. Install agents, skills, and packs into any project from the Vanara catalog.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"vanara": "bin/vanara.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "node --test"
|
|
10
|
+
"test": "node --test",
|
|
11
|
+
"stage-catalog": "node scripts/stage-catalog.mjs --premium",
|
|
12
|
+
"prepack": "node scripts/stage-catalog.mjs"
|
|
11
13
|
},
|
|
12
14
|
"engines": {
|
|
13
15
|
"node": ">=20"
|
|
@@ -29,10 +31,19 @@
|
|
|
29
31
|
"files": [
|
|
30
32
|
"bin/",
|
|
31
33
|
"src/",
|
|
34
|
+
"catalog/",
|
|
35
|
+
"free-tier.json",
|
|
32
36
|
"README.md",
|
|
33
|
-
"LICENSE"
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"premium-index.json"
|
|
34
39
|
],
|
|
35
40
|
"publishConfig": {
|
|
36
41
|
"access": "public"
|
|
37
|
-
}
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/vanara-agents/vanara.git",
|
|
46
|
+
"directory": "cli"
|
|
47
|
+
},
|
|
48
|
+
"bugs": "https://github.com/vanara-agents/vanara/issues"
|
|
38
49
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"kind":"agent","name":"accessibility-auditor","version":"2.0.0","description":"Use when auditing an existing UI for WCAG 2.2 A/AA conformance. Investigates semantics, keyboard operability, focus, color contrast, ARIA, forms, and reduced-mo"},{"kind":"agent","name":"ai-engineer","version":"2.0.0","description":"Use PROACTIVELY when building or hardening LLM-powered features (chatbots, RAG, agents, summarizers, extractors, classifiers). Picks the right pattern (prompt →"},{"kind":"agent","name":"api-documenter","version":"2.0.0","description":"Use when documenting an HTTP/REST or GraphQL API for external or internal consumers — turning routes, schemas, or an OpenAPI spec into accurate reference docs w"},{"kind":"agent","name":"app-release-manager","version":"2.0.0","description":"Use when preparing a mobile app release or store submission. Walks through versioning, build config, store metadata, and the review-readiness checklist to avoid"},{"kind":"agent","name":"budget-planner","version":"2.0.0","description":"Use when building, reviewing, or stress-testing a budget. Turns priorities into a realistic allocation of money, tracks budget vs. actuals, forecasts cash flow "},{"kind":"agent","name":"bug-reporter","version":"2.0.0","description":"Use when a vague problem report needs to become a clean, reproducible bug ticket with numbered steps, expected vs. actual behavior, environment, severity, and a"},{"kind":"agent","name":"business-data-analyst","version":"2.0.0","description":"Use when you need to analyze a dataset or metrics and explain what they mean for the business. Pins the decision, finds the signal, quantifies the effect size, "},{"kind":"agent","name":"cicd-engineer","version":"2.0.0","description":"Use when designing, hardening, or repairing a CI/CD pipeline — build→test→scan→deploy flows, environment promotion, deployment strategies, and rollback. Reach f"},{"kind":"agent","name":"competitive-analyst","version":"2.0.0","description":"Use when analyzing competitors or sizing a market. Maps the landscape, compares positioning, pricing, and features, and surfaces gaps and opportunities — every "},{"kind":"agent","name":"compliance-auditor","version":"2.0.0","description":"Use when preparing for or assessing security compliance (SOC 2, ISO 27001, GDPR, HIPAA). Maps required controls to concrete evidence, finds gaps where a control"},{"kind":"agent","name":"component-builder","version":"2.0.0","description":"Use PROACTIVELY when building UI components. Produces accessible, reusable, responsive components with full interaction states, a documented prop/slot API, and "},{"kind":"agent","name":"content-writer","version":"2.0.0","description":"Use PROACTIVELY when creating long-form content — blog posts, articles, guides, or landing-page copy. Produces structured, on-brand writing with a clear angle a"},{"kind":"agent","name":"contract-reviewer","version":"2.0.0","description":"Use when a non-lawyer needs to understand a business contract before signing or negotiating. Produces a plain-language summary, a clause-by-clause risk read (st"},{"kind":"agent","name":"customer-success-manager","version":"2.0.0","description":"Use when driving customer onboarding, adoption, retention, or renewals. Builds outcome-based success plans, computes account health, spots churn risk early, run"},{"kind":"agent","name":"data-modeler","version":"2.0.0","description":"Use when designing a database schema or data model from scratch or reshaping an existing one — turning entities, relationships, and real access patterns into no"},{"kind":"agent","name":"data-pipeline-engineer","version":"2.0.0","description":"Use when building, reviewing, or fixing a data pipeline (ETL/ELT, batch or streaming). Produces idempotent, observable pipelines with explicit schema contracts,"},{"kind":"agent","name":"data-quality-auditor","version":"2.0.0","description":"Use when validating a dataset before analysis, reporting, or model training. Profiles the data across six quality dimensions, applies explicit rules and thresho"},{"kind":"agent","name":"database-administrator","version":"2.0.0","description":"Use when operating, hardening, or troubleshooting a production database — backups and restore drills, replication and failover, slow-query and lock investigatio"},{"kind":"agent","name":"dependency-upgrader","version":"1.0.0","description":"Dependency upgrade specialist. Use PROACTIVELY on a schedule or when audits flag vulnerable/outdated packages. Scans the dependency tree, classifies upgrades by"},{"kind":"agent","name":"e2e-test-author","version":"2.0.0","description":"Use when you need to author or stabilize end-to-end tests for critical user journeys (login, signup, checkout). Selects which flows are worth the E2E cost, driv"},{"kind":"agent","name":"email-drafter","version":"2.0.0","description":"Use when drafting or improving a professional email. Produces clear, appropriately-toned messages with a strong subject line and a single clear ask — cold outre"},{"kind":"agent","name":"embedded-developer","version":"2.0.0","description":"Use when writing firmware or embedded software for microcontrollers/RTOS. Produces resource-efficient, reliable C/C++ that respects timing, memory, and power co"},{"kind":"agent","name":"feature-builder","version":"1.0.0","description":"Vertical-slice feature specialist. Use PROACTIVELY when a feature request spans layers — data model, API, business logic, UI, and tests. Builds the complete sli"},{"kind":"agent","name":"financial-analyst","version":"2.0.0","description":"Use when analyzing financials or building a model — forecasts, budgets, scenarios, and unit economics — to support a business decision. Reads statements, comput"},{"kind":"agent","name":"game-developer","version":"2.0.0","description":"Use when building gameplay features or systems — game loops, entity/scene state, input handling, movement/physics, and mechanics. Implements simulation code tha"},{"kind":"agent","name":"game-systems-designer","version":"2.0.0","description":"Use when designing game systems and mechanics — core loops, progression, economy, difficulty, and player motivation — for engagement and long-term balance. Turn"},{"kind":"agent","name":"hr-generalist","version":"2.0.0","description":"Use when drafting HR documents and running people processes — onboarding, handbook/policy sections, performance reviews, leave/accommodation guidance, and sensi"},{"kind":"agent","name":"iac-author","version":"2.0.0","description":"Use when provisioning or changing cloud infrastructure with Terraform/Pulumi/OpenTofu. Writes idempotent, modular IaC with least-privilege IAM, remote locked st"},{"kind":"agent","name":"incident-responder","version":"2.0.0","description":"Use when an active incident or outage is declared, a pager fires, or a production regression is under live triage. Drives a calm, structured response — detect, "},{"kind":"agent","name":"integration-engineer","version":"2.0.0","description":"Use when integrating a third-party API or service (payments, email, webhooks, data sync). Builds resilient integrations with retries, idempotency, dead-letter h"},{"kind":"agent","name":"iot-systems-engineer","version":"2.0.0","description":"Use when designing an IoT system end to end — device connectivity, telemetry, fleet management, and secure firmware updates from edge to cloud. Assumes flaky ne"},{"kind":"agent","name":"it-support-specialist","version":"2.0.0","description":"Use when triaging and resolving IT support requests. Diagnoses user problems methodically, gives clear step-by-step fixes, and knows when to escalate — turning "},{"kind":"agent","name":"llm-evaluator","version":"2.0.0","description":"Use when an LLM feature's quality must become a number you can defend. Designs eval criteria, builds datasets, picks scoring (deterministic vs LLM-as-judge vs p"},{"kind":"agent","name":"meeting-summarizer","version":"2.0.0","description":"Use when turning a meeting transcript or raw notes into a concise summary with decisions, action items, and owners. Captures what was decided, not every word sa"},{"kind":"agent","name":"ml-model-reviewer","version":"2.0.0","description":"Use when reviewing an ML model, training pipeline, or model card before it ships or is promoted. Audits for data leakage, evaluation soundness, reproducibility,"},{"kind":"agent","name":"mobile-app-builder","version":"2.0.0","description":"Use PROACTIVELY when building or extending a mobile app feature (iOS, Android, or cross-platform like React Native/Flutter). Builds idiomatic, performant screen"},{"kind":"agent","name":"mobile-perf-optimizer","version":"2.0.0","description":"Use when a mobile app is slow to start, janky while scrolling, drains battery, or grows memory without bound. Profiles first to find the real bottleneck, fixes "},{"kind":"agent","name":"network-engineer","version":"2.0.0","description":"Use when designing, segmenting, or troubleshooting network connectivity — VPCs, subnets, VLSM addressing, routing, switching, firewalls/security groups, DNS, an"},{"kind":"agent","name":"network-troubleshooter","version":"2.0.0","description":"Use when diagnosing a connectivity problem — timeouts, connection refused, DNS failures, TLS/cert errors, intermittent packet loss, or an unreachable service. W"},{"kind":"agent","name":"observability-engineer","version":"2.0.0","description":"Use when instrumenting a service for production, defining SLOs, designing alerts, or debugging a live incident. Designs the three pillars (logs, metrics, traces"},{"kind":"agent","name":"perf-optimizer","version":"2.0.0","description":"Use when a page, endpoint, query, or job is slow or a bundle is too large. Profiles first to locate the dominant cost, then proposes prioritized, measurable fix"},{"kind":"agent","name":"performance-engineer","version":"2.0.0","description":"Use when a backend, service, or job is slow, resource-heavy, or missing a latency/throughput SLO. Measures first, finds the dominant bottleneck, fixes it, and p"},{"kind":"agent","name":"policy-drafter","version":"2.0.0","description":"Use when drafting a first version of an internal business policy or governance document (acceptable use, information security, PTO, code of conduct). Produces a"},{"kind":"agent","name":"privacy-engineer","version":"2.0.0","description":"Use when handling personal data or implementing privacy requirements (GDPR, CCPA). Maps data flows, applies privacy-by-design and data minimization, classifies "},{"kind":"agent","name":"product-manager","version":"2.0.0","description":"Use when deciding what to build and why — turning user problems and business goals into a prioritized roadmap, a crisp PRD, and measurable success metrics. Best"},{"kind":"agent","name":"project-planner","version":"2.0.0","description":"Use PROACTIVELY when turning a goal into an executable project plan — when you need a scoped work breakdown, estimates, a dependency-aware schedule with a criti"},{"kind":"agent","name":"prompt-engineer","version":"2.0.0","description":"Use when a prompt is unreliable, inconsistent, or being written from scratch. Designs clear, structured prompts (role, task, constraints, few-shot, output schem"},{"kind":"agent","name":"proposal-writer","version":"2.0.0","description":"Use when writing a sales proposal, quote, or statement of work. Produces a clear, persuasive, buyer-centric document tied to the prospect's goals, scope, and va"},{"kind":"agent","name":"qa-strategist","version":"2.0.0","description":"Use when planning how to test a feature, sprint, or release — when you need a risk-based test strategy rather than just more tests. Designs coverage across unit"},{"kind":"agent","name":"recruiter","version":"2.0.0","description":"Use when hiring for a role — clarifying the req with the hiring manager, writing inclusive job descriptions, sourcing and outreach, and running a structured, bi"},{"kind":"agent","name":"requirements-analyst","version":"2.0.0","description":"Use when a request is vague, a feature is just starting, or stakeholders disagree on scope. Turns fuzzy asks into clear, testable requirements — problem stateme"},{"kind":"agent","name":"research-synthesizer","version":"2.0.0","description":"Use when you need to gather and synthesize information from multiple sources into a clear, cited, decision-ready brief. Triangulates across sources, surfaces wh"},{"kind":"agent","name":"sales-call-prepper","version":"2.0.0","description":"Use when preparing for a sales call, demo, or discovery meeting. Builds a complete call-prep brief — account research, a single call objective, discovery questi"},{"kind":"agent","name":"sales-outreach-writer","version":"2.0.0","description":"Use when writing cold outreach (email, LinkedIn) to prospects. Produces personalized, concise messages that lead with the prospect's problem, make a single low-"},{"kind":"agent","name":"seo-optimizer","version":"2.0.0","description":"Use when optimizing content or a page for search. Improves on-page SEO — title, meta, headings, internal links, and intent match — plus technical basics and str"},{"kind":"agent","name":"smart-contract-auditor","version":"2.0.0","description":"Use when reviewing a smart contract for security before deployment. Thinks adversarially about value and trust, hunts reentrancy, access-control flaws, overflow"},{"kind":"agent","name":"smart-contract-developer","version":"2.0.0","description":"Use when writing or modifying blockchain smart contracts (Solidity/EVM). Implements correct, gas-efficient contracts with security first — invariants, checks-ef"},{"kind":"agent","name":"social-media-manager","version":"2.0.0","description":"Use when planning or writing social posts across platforms. Adapts one message into platform-native posts (X, LinkedIn, Instagram, TikTok) with the right tone, "},{"kind":"agent","name":"solution-architect","version":"2.0.0","description":"Use when planning a new system or feature, evaluating architectural trade-offs between options, choosing technologies, or writing an ADR. Gathers functional + n"},{"kind":"agent","name":"support-responder","version":"2.0.0","description":"Use when drafting a reply to a customer support ticket. Writes clear, empathetic responses that acknowledge the person, deliver an accurate answer or fix, set h"},{"kind":"agent","name":"sysadmin-automator","version":"2.0.0","description":"Use when administering or automating servers and systems. Writes safe, idempotent shell/automation scripts for provisioning, maintenance, backups, scheduling, a"},{"kind":"agent","name":"tech-spec-writer","version":"2.0.0","description":"Use when a feature or change needs a written design before coding — to align a team, surface alternatives, and de-risk rollout. Produces a concise technical spe"},{"kind":"agent","name":"user-researcher","version":"2.0.0","description":"Use when you need to understand users — planning interviews, surveys, or usability tests, writing unbiased questions, recruiting representative participants, an"},{"kind":"skill","name":"app-store-optimization","version":"2.0.0","description":"How to optimize an app-store listing (ASO) for discovery and conversion — title, subtitle, keywords, screenshots, icon, ratings, and the metadata that drives in"},{"kind":"skill","name":"audit-logging","version":"2.0.0","description":"Design tamper-evident audit logs that satisfy security and compliance — what to record (who/what/when/where/outcome), what to never log (secrets/PII), structure"},{"kind":"skill","name":"background-jobs","version":"1.0.0","description":"Design background job systems that don't lose or double work — enqueue-after-commit, retry policies with jitter, idempotent handlers, visibility timeouts, prior"},{"kind":"skill","name":"backup-and-recovery","version":"2.0.0","description":"Design and operate a tested backup and disaster-recovery strategy — the 3-2-1 rule, RPO/RTO targets, full vs incremental vs differential, point-in-time recovery"},{"kind":"skill","name":"c4-diagramming","version":"2.0.0","description":"Document software architecture with the C4 model (Context, Container, Component, Code) as text-based diagrams in version control. Covers the four abstraction le"},{"kind":"skill","name":"changelog-writing","version":"2.0.0","description":"How to write and maintain a changelog humans actually read — Keep a Changelog structure, an Unreleased section, the six standard categories (Added/Changed/Depre"},{"kind":"skill","name":"churn-prevention","version":"2.0.0","description":"How to reduce customer churn — separating voluntary from involuntary churn, scoring account health from leading signals, running save and win-back plays, and fi"},{"kind":"skill","name":"ci-pipeline-design","version":"2.0.0","description":"Design fast, reliable CI/CD pipelines — fail-fast staged checks (lint→test→build→scan→deploy), dependency and build caching, artifact passing, matrix builds, me"},{"kind":"skill","name":"cloud-cost-optimization","version":"1.0.0","description":"Cut cloud spend without cutting reliability — rightsizing from utilization data, spot and commitment strategy, storage lifecycle rules, egress traps, tagging fo"},{"kind":"skill","name":"cold-outreach","version":"2.0.0","description":"How to write cold outreach that earns replies — relevance-first openers, specific personalization, one low-friction ask, tight subject lines, and a graceful fol"},{"kind":"skill","name":"content-calendar","version":"2.0.0","description":"How to plan and run a content calendar that balances pillars, formats, and channels around goals — cadence design, content mix, batching and repurposing, and a "},{"kind":"skill","name":"contract-review","version":"2.0.0","description":"How to read a business contract for the terms that matter most — liability, indemnity, IP, termination, payment, and auto-renewal — and spot red flags. Deep ref"},{"kind":"skill","name":"copywriting-frameworks","version":"2.0.0","description":"Proven copywriting frameworks (AIDA, PAS, BAB, FAB, the 4 Ps/4 Us) and when to use each to structure persuasive marketing copy. A deep reference with worked bef"},{"kind":"skill","name":"data-modeling","version":"2.0.0","description":"Design data models that make invalid states impossible — entities & relationships, normalization (1NF–3NF) vs deliberate denormalization, keys & indexing, relat"},{"kind":"skill","name":"data-storytelling","version":"2.0.0","description":"Turn data into a decision — lead with the insight, choose the right chart for the intent, frame it for the audience, and drive to an action. A deep reference wi"},{"kind":"skill","name":"data-validation","version":"2.0.0","description":"Validate untrusted data at boundaries with schema-based contracts — types, ranges, enums, regex, uniqueness, referential integrity, freshness — so bad input is "},{"kind":"skill","name":"database-scaling","version":"2.0.0","description":"Scale a relational database under growing load in the right order — query/index tuning, connection pooling, read replicas and replication lag, caching, table pa"},{"kind":"skill","name":"deployment-strategies","version":"1.0.0","description":"Deploy without fear — blue-green vs canary vs rolling trade-offs, database migrations during deploys (expand/contract), rollback design and its limits, smoke te"},{"kind":"skill","name":"dns-configuration","version":"2.0.0","description":"How DNS actually works and how to change it safely — record types (A/AAAA/CNAME/MX/TXT/NS/SOA/CAA), TTL and propagation, the CNAME-at-apex problem, email auth ("},{"kind":"skill","name":"dockerfile-authoring","version":"2.0.0","description":"Author small, secure, fast-building container images — multi-stage builds, layer caching, non-root/distroless hardening, .dockerignore, size optimization, and H"},{"kind":"skill","name":"documentation-structure","version":"2.0.0","description":"How to architect a documentation set with the Diátaxis framework — separating tutorials, how-to guides, reference, and explanation, then wiring information arch"},{"kind":"skill","name":"e2e-playwright","version":"2.0.0","description":"Deep reference for reliable Playwright E2E tests — role/accessible locators over CSS, web-first assertions and auto-waiting (no hard sleeps), fixtures and stora"},{"kind":"skill","name":"event-driven-architecture","version":"1.0.0","description":"Design event-driven systems that stay consistent — queues vs streams, pub/sub topology, idempotent consumers, the transactional outbox, sagas for multi-service "},{"kind":"skill","name":"feature-engineering","version":"2.0.0","description":"Engineer ML features safely and effectively — feature types, encoding (one-hot/target/ordinal), scaling, missing-value and outlier handling, feature selection, "},{"kind":"skill","name":"feature-flags-experimentation","version":"1.0.0","description":"Ship behind flags and learn from experiments — progressive rollouts, kill switches, deterministic bucketing, flag lifecycle and debt cleanup, A/B test design wi"},{"kind":"skill","name":"financial-modeling","version":"2.0.0","description":"How to build a clear, drivable financial model — three-statement linkage, driver-based forecasting, explicit assumptions, scenarios, sensitivity, and cash runwa"},{"kind":"skill","name":"frontend-state-management","version":"2.0.0","description":"Choose the right home for every piece of frontend state — server, client, URL, form, and derived — so React/TS apps stay predictable and never store the same tr"},{"kind":"skill","name":"game-loop-architecture","version":"2.0.0","description":"Structure a robust game loop — fixed vs variable timestep, the \"fix your timestep\" accumulator, decoupling update from render with interpolation, determinism fo"},{"kind":"skill","name":"game-performance","version":"2.0.0","description":"Keep games at a stable frame rate. Use when a game stutters, drops frames, or hitches — budgeting the 16.6ms frame, profiling CPU vs GPU bottlenecks, object poo"},{"kind":"skill","name":"gdpr-compliance","version":"2.0.0","description":"Build core GDPR obligations into software — lawful basis, data-subject rights (access/erasure/portability/rectification), consent, data minimization, processor/"},{"kind":"skill","name":"graphql-api-design","version":"1.0.0","description":"Design GraphQL APIs that survive production — schema modeling, resolver patterns, the N+1 problem and dataloaders, connection-style pagination, error handling, "},{"kind":"skill","name":"incident-management","version":"2.0.0","description":"Run a production incident from detection to postmortem — severity classification & SLAs, roles (Incident Commander, comms, ops), the detect→triage→mitigate→reso"},{"kind":"skill","name":"internationalization","version":"1.0.0","description":"Internationalize correctly from the start — ICU MessageFormat and plural rules, RTL layouts with logical CSS properties, locale-aware dates/numbers/currency via"},{"kind":"skill","name":"interview-design","version":"2.0.0","description":"Designing structured hiring interviews that predict job performance fairly — competency modeling, behavioral/STAR question design, consistent scoring rubrics, i"},{"kind":"skill","name":"iot-connectivity","version":"2.0.0","description":"Connect IoT fleets reliably — choosing MQTT/CoAP/HTTP/LoRaWAN, MQTT QoS and topic design, device provisioning and identity, OTA updates, surviving intermittent "},{"kind":"skill","name":"job-description-writing","version":"2.0.0","description":"How to write job descriptions that attract strong, diverse candidates — outcome-focused responsibilities, realistic must-have vs nice-to-have requirements, incl"},{"kind":"skill","name":"knowledge-base-writing","version":"2.0.0","description":"How to write self-service help articles that deflect tickets — task-focused titles, findable structure, clear steps, and maintenance loops. A deep reference wit"},{"kind":"skill","name":"kubernetes-manifests","version":"2.0.0","description":"Conventions for writing production-grade Kubernetes manifests — Deployments, Services, Ingress, liveness/readiness/startup probes, resource requests/limits and "},{"kind":"skill","name":"legacy-modernization","version":"1.0.0","description":"Modernize legacy systems without a rewrite bet — strangler-fig migration, finding seams, characterization tests before touching anything, anti-corruption layers"},{"kind":"skill","name":"linux-administration","version":"2.0.0","description":"Operating Linux servers with confidence — users/groups and octal permissions (setuid/setgid/sticky), systemd units and journald, process/disk/network triage (ps"},{"kind":"skill","name":"llm-evaluation","version":"2.0.0","description":"Deep, practical guide to evaluating LLM outputs — building eval datasets, choosing reference-based vs LLM-as-judge vs pairwise/Elo vs human scoring, picking met"},{"kind":"skill","name":"load-balancing","version":"2.0.0","description":"Distribute traffic across instances for scale and reliability — L4 vs L7, algorithms (round-robin, weighted, least-connections, consistent-hash), active/passive"},{"kind":"skill","name":"market-research","version":"2.0.0","description":"How to size and understand a market without fooling yourself — TAM/SAM/SOM sizing, customer segmentation, competitive analysis, and combining secondary and prim"},{"kind":"skill","name":"mcp-server-development","version":"1.0.0","description":"Build MCP servers agents can actually use — tool schema design that models route correctly, resources vs tools vs prompts, stdio and HTTP transports, auth patte"},{"kind":"skill","name":"meeting-notes-structure","version":"2.0.0","description":"How to structure meeting notes so they drive action afterward — separating decisions from discussion, capturing action items with an owner and due date every ti"},{"kind":"skill","name":"mobile-ui-patterns","version":"2.0.0","description":"Platform-aware mobile UI patterns for iOS and Android — navigation (tabs/stack/drawer), touch targets and thumb zones, gestures and feedback, safe areas and not"},{"kind":"skill","name":"model-evaluation","version":"2.0.0","description":"How to evaluate ML models honestly — task-appropriate metrics (classification vs regression), train/val/test splits and cross-validation, baselines, confusion m"},{"kind":"skill","name":"objection-handling","version":"2.0.0","description":"How to handle sales objections honestly and effectively — acknowledge, clarify the real concern, reframe with evidence, and confirm. Covers price, timing, trust"},{"kind":"skill","name":"offline-sync","version":"2.0.0","description":"Build offline-first apps that work without a connection — local-first reads, an outbox/mutation queue, optimistic UI, idempotent replay on reconnect, delta sync"},{"kind":"skill","name":"okr-writing","version":"2.0.0","description":"How to write effective OKRs — qualitative objectives paired with measurable key results — that drive focus instead of becoming a task list. A deep reference wit"},{"kind":"skill","name":"payment-integration","version":"1.0.0","description":"Integrate payments without losing money — idempotency keys on every charge, webhook-driven state (never redirect-driven), PCI scope boundaries, SCA/3DS flows, s"},{"kind":"skill","name":"performance-review-writing","version":"2.0.0","description":"How to write fair, useful performance reviews — specific evidence over vague impressions, behavior-based feedback (SBI/STAR), balanced strengths and growth area"},{"kind":"skill","name":"pricing-strategy","version":"2.0.0","description":"How to set and structure pricing — value-based pricing, good-better-best tiering and packaging, psychological anchoring, discounting, and price testing — to cap"},{"kind":"skill","name":"prioritization-frameworks","version":"2.0.0","description":"Decision frameworks for prioritizing product and engineering work — RICE, ICE, MoSCoW, Kano, weighted scoring, and Cost of Delay / WSJF — with guidance on which"},{"kind":"skill","name":"privacy-policy-drafting","version":"2.0.0","description":"How to draft a privacy policy that is accurate, readable, and covers the required elements — what data you collect, why, legal basis, sharing, retention, and us"},{"kind":"skill","name":"product-metrics","version":"2.0.0","description":"Choosing and operating product metrics that reflect real value — North Star definition, the AARRR pirate funnel, activation/retention/engagement, leading vs lag"},{"kind":"skill","name":"rag-patterns","version":"2.0.0","description":"Deep, practical guide to retrieval-augmented generation that actually grounds answers — chunking, embeddings, vector + hybrid/BM25 search, reranking, context as"},{"kind":"skill","name":"realtime-communication","version":"1.0.0","description":"Build realtime features that survive production — WebSockets vs SSE vs polling trade-offs, connection lifecycle, reconnect with backoff and event resume, heartb"},{"kind":"skill","name":"regression-strategy","version":"2.0.0","description":"Design a fast, trustworthy regression strategy — turn every fixed bug into a permanent test, tier suites (smoke/full/nightly), select only impacted tests via te"},{"kind":"skill","name":"responsive-layout","version":"2.0.0","description":"Build fluid, responsive web layouts from 320px to ultrawide with modern CSS — mobile-first, fluid type/space via clamp(), intrinsic CSS grid/flex, container que"},{"kind":"skill","name":"roadmap-planning","version":"2.0.0","description":"How to build a product roadmap that communicates strategy — outcome-based themes over feature lists, Now/Next/Later horizons, prioritization, and honest time fr"},{"kind":"skill","name":"rtos-firmware-patterns","version":"2.0.0","description":"RTOS firmware patterns — preemptive priority scheduling, ISR discipline (short handlers, deferred work, ISR-safe APIs), queues/semaphores/mutexes, priority inve"},{"kind":"skill","name":"runbook-writing","version":"2.0.0","description":"Write operational runbooks an on-call engineer can follow at 3am with zero context — exact triggers, preconditions, numbered copy-pasteable steps, per-step veri"},{"kind":"skill","name":"sales-discovery","version":"2.0.0","description":"How to run effective sales discovery — qualification frameworks (BANT, MEDDIC), SPIN questioning, quantifying pain, and mapping the decision process. A deep ref"},{"kind":"skill","name":"search-implementation","version":"1.0.0","description":"Implement search that finds things — full-text mechanics (analyzers, BM25), vector/semantic search and hybrid ranking with RRF, relevance evaluation with golden"},{"kind":"skill","name":"seo-on-page","version":"2.0.0","description":"On-page SEO — search-intent matching, title tags, meta descriptions, heading structure, internal linking, URLs, image alt text, and structured data that ranks w"},{"kind":"skill","name":"slo-error-budgets","version":"1.0.0","description":"Define reliability numerically — choosing SLIs users actually feel, setting SLO targets, error budgets and multi-window burn-rate alerting, latency percentiles "},{"kind":"skill","name":"smart-contract-security","version":"2.0.0","description":"Deep reference for securing Solidity/EVM smart contracts — reentrancy, access control, oracle/price manipulation, integer over/underflow, delegatecall, unchecke"},{"kind":"skill","name":"soc2-readiness","version":"2.0.0","description":"Get audit-ready for SOC 2 — scope the Trust Services Criteria, build a controls-to-evidence matrix, write the policies auditors check, choose Type I vs Type II,"},{"kind":"skill","name":"solidity-patterns","version":"2.0.0","description":"Battle-tested Solidity/EVM patterns for safe smart contracts — checks-effects-interactions, reentrancy guards, access control (Ownable/roles), pull-over-push pa"},{"kind":"skill","name":"source-evaluation","version":"2.0.0","description":"How to judge whether a source deserves trust before you cite it — authority, evidence, currency, bias, and corroboration — using the CRAAP test, primary-vs-seco"},{"kind":"skill","name":"support-response-writing","version":"2.0.0","description":"How to write support replies that resolve and reassure — acknowledgement and empathy, clear solutions or honest next steps, expectation-setting, de-escalation, "},{"kind":"skill","name":"system-design-patterns","version":"2.0.0","description":"Deep reference for scaling systems — load balancers, caches, queues, replicas, sharding, CDNs, CAP and consistency models, idempotency, and back-of-envelope cap"},{"kind":"skill","name":"tcp-ip-fundamentals","version":"2.0.0","description":"The networking fundamentals every engineer needs — the layered model and encapsulation, IPv4 addressing/subnetting/CIDR, TCP vs UDP, the 3-way handshake and con"},{"kind":"skill","name":"terms-of-service","version":"2.0.0","description":"How to draft terms of service covering the essentials — acceptable use, accounts, payment, liability limits, indemnification, termination, changes, governing la"},{"kind":"skill","name":"unit-economics","version":"2.0.0","description":"Analyze unit economics — CAC, LTV, contribution margin, and CAC payback — to judge whether a business model actually makes money per customer. A deep reference "},{"kind":"skill","name":"user-interview-design","version":"2.0.0","description":"How to design and run user (product/UX) research interviews that yield honest insight — non-leading questions, past-behavior focus, participant recruiting, bias"},{"kind":"skill","name":"user-story-writing","version":"2.0.0","description":"How to write user stories and acceptance criteria that are small, testable, and valuable — using INVEST, Given-When-Then, and disciplined story splitting. A dee"},{"kind":"skill","name":"wcag-accessibility","version":"2.0.0","description":"Deep, practical reference for building WCAG 2.2 AA-conformant web UIs — POUR principles, semantic HTML, keyboard operability and visible focus, ARIA done right,"},{"kind":"skill","name":"webhook-design","version":"2.0.0","description":"Design and consume webhooks reliably — HMAC signature verification, timestamp/replay protection, fast 2xx acknowledgement, consumer idempotency via event-id ded"},{"kind":"pack","name":"ai-llm-pack","version":"2.0.0","description":"Build reliable LLM-powered features — prompt engineering, RAG, agents, and evaluation — with quality and cost under control."},{"kind":"pack","name":"ai-product-builder-pack","version":"2.0.0","description":"A combo pack for shipping AI-powered products — decide the bet, engineer the prompt, ground it with retrieval, expose a clean API, and prove quality with evals."},{"kind":"pack","name":"architecture-analysis-pack","version":"2.0.0","description":"The front of the build pipeline — turn a fuzzy ask into testable requirements, a justified architecture, and a spec engineering can build from, before a line of"},{"kind":"pack","name":"backend-essentials-pack","version":"2.0.0","description":"Everything a backend developer needs to design, build, test, review, and ship server-side code with confidence — API design, safe migrations, and query performa"},{"kind":"pack","name":"business-ops-pack","version":"2.0.0","description":"Run the day-to-day better — set measurable goals, turn them into a prioritized plan, keep meetings decision-focused, and communicate clearly. Bundles the operat"},{"kind":"pack","name":"compliance-grc-pack","version":"2.0.0","description":"Get and stay compliant — SOC 2 and ISO readiness, GDPR/privacy engineering, and the tamper-evident audit logging that proves it. Sequences the agents and skills"},{"kind":"pack","name":"craftsmanship-pack","version":"2.0.0","description":"Keep a codebase healthy as it grows — safe refactoring, measured performance work, and resilient third-party integrations, sequenced so you change structure, sp"},{"kind":"pack","name":"customer-success-pack","version":"2.0.0","description":"Keep customers happy and retained — empathetic support replies, churn prevention, success management, and a self-service knowledge base, sequenced into one life"},{"kind":"pack","name":"data-ml-pack","version":"2.0.0","description":"Build trustworthy data and ML systems — reliable pipelines, validated data, leakage-free features, and honest model evaluation, sequenced from raw source to a m"},{"kind":"pack","name":"database-pack","version":"2.0.0","description":"Design and operate databases that stay correct, durable, and fast — schema modeling, tested backups and recovery, and scaling in the right order. Sequences the "},{"kind":"pack","name":"devops-cloud-pack","version":"2.0.0","description":"Everything between \"code is written\" and \"it runs reliably in production\" — containers, infrastructure-as-code, CI/CD pipelines, Kubernetes, and observability t"},{"kind":"pack","name":"embedded-iot-pack","version":"2.0.0","description":"Build connected devices end to end — resource-efficient firmware, real-time RTOS patterns, and reliable, secure IoT connectivity from the microcontroller to the"},{"kind":"pack","name":"finance-pack","version":"2.0.0","description":"Turn numbers into decisions — driver-based models, budgets and runway, unit economics, and pricing. Sequences finance agents and skills into one repeatable plan"},{"kind":"pack","name":"founder-operations-pack","version":"2.0.0","description":"A combo pack for running the business side of a startup — set product direction, keep the unit economics honest, price the product, hire well, and get a first-p"},{"kind":"pack","name":"frontend-essentials-pack","version":"2.0.0","description":"Everything a frontend developer needs to ship fast, accessible, responsive interfaces that look intentional — component design, state placement, WCAG audit, and"},{"kind":"pack","name":"full-stack-developer-pack","version":"2.0.0","description":"A combo pack for full-stack developers — design the API, build the UI, test-drive it, and ship it clean. Bundles the frontend and backend essentials with qualit"},{"kind":"pack","name":"game-dev-pack","version":"2.0.0","description":"Build games that play well and run smoothly — systems design, gameplay implementation, a solid game-loop architecture, and stable frame rate. Sequences design, "},{"kind":"pack","name":"go-to-market-pack","version":"2.0.0","description":"A combo pack to take a product to market — content and SEO, sales outreach and proposals, and customer success to retain what you win. Sequences attract, conver"},{"kind":"pack","name":"it-operations-pack","version":"2.0.0","description":"Keep systems running and users unblocked — incident response, server automation, and IT support, sequenced into repeatable ops workflows with runbooks that make"},{"kind":"pack","name":"knowledge-worker-pack","version":"2.0.0","description":"A combo pack for non-developers — set goals, plan the work, research and analyze to back decisions, write the output, and keep meetings tight. The essentials of"},{"kind":"pack","name":"legal-pack","version":"2.0.0","description":"Get a fast, clear first pass on everyday business legal documents — contract review, privacy policies, and terms of service — structured so you can hand a well-"},{"kind":"pack","name":"marketing-content-pack","version":"2.0.0","description":"Everything to plan, write, optimize, and distribute content that ranks and converts — a content engine that sequences long-form writing, on-page SEO, and platfo"},{"kind":"pack","name":"mobile-pack","version":"2.0.0","description":"Build, optimize, and ship mobile apps — native-feeling features, smooth performance, offline support, and a clean path through app-store review. Sequences the m"},{"kind":"pack","name":"networking-pack","version":"2.0.0","description":"Design and debug networks — topology and firewalls, DNS, load balancing, and methodical connectivity troubleshooting."},{"kind":"pack","name":"people-pack","version":"2.0.0","description":"Hire and manage people well — inclusive job descriptions, structured bias-resistant interviews, fair evidence-based performance reviews, and clear HR documents,"},{"kind":"pack","name":"product-management-pack","version":"2.0.0","description":"Decide what to build and why — user research, outcome-based roadmaps, and product metrics that focus the team on real value. Sequences discovery, prioritization"},{"kind":"pack","name":"qa-testing-pack","version":"2.0.0","description":"Catch bugs before users do — risk-based test strategy, reliable end-to-end tests, clean bug reports, and a regression suite that keeps main green. Sequences the"},{"kind":"pack","name":"research-analysis-pack","version":"2.0.0","description":"Turn questions into decisions — synthesize credible research, size markets, scan competitors, analyze your own metrics, and tell the story that drives action. O"},{"kind":"pack","name":"sales-pack","version":"2.0.0","description":"Win more deals — personalized cold outreach, effective discovery, prepared calls, confident objection handling, and persuasive proposals, sequenced into one rep"},{"kind":"pack","name":"secure-delivery-pack","version":"2.0.0","description":"A combo pack for shipping safely at speed — CI/CD, security auditing, dependency and secret scanning, risk-based test strategy, and observability, sequenced int"},{"kind":"pack","name":"sre-reliability-pack","version":"1.0.0","description":"Run production like an SRE team — SLOs and error budgets as the decision system, burn-rate alerting, canary deploys with rollback discipline, incident response "},{"kind":"pack","name":"startup-launch-pack","version":"2.0.0","description":"A combo pack for founders taking a product from idea to launch — scope it, architect it lean, build the UI and API, get auth right, and pass a security audit be"},{"kind":"pack","name":"technical-writing-pack","version":"2.0.0","description":"Produce documentation developers and users actually follow — structure the docs set, write task-oriented guides, document the API from source, and keep a clean "},{"kind":"pack","name":"web3-pack","version":"2.0.0","description":"Build and secure blockchain smart contracts — correct, gas-aware Solidity development paired with adversarial security auditing, sequenced from spec to audited "}]
|
package/src/config.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Central constants and source resolution. No hardcoded secrets, no network in v0.1.
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
5
|
+
import os from 'node:os';
|
|
4
6
|
|
|
5
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
8
|
export const CLI_ROOT = path.resolve(__dirname, '..');
|
|
@@ -12,10 +14,17 @@ export const LOCKFILE = '.vanara.json';
|
|
|
12
14
|
// 1. --source <dir> flag
|
|
13
15
|
// 2. VANARA_REGISTRY env var (a directory today; an https registry URL in v1
|
|
14
16
|
// once the hosted registry + entitlements exist — see OPEN-CORE-PLAN.md §3)
|
|
15
|
-
// 3.
|
|
17
|
+
// 3. the catalog bundled inside this npm package (works for ANY npx user)
|
|
18
|
+
// 4. dev default: the sibling forge catalog in this repo
|
|
19
|
+
export const PREMIUM_DIR = path.join(os.homedir(), '.vanara', 'catalog');
|
|
20
|
+
|
|
16
21
|
export function resolveSource(flagValue) {
|
|
17
22
|
if (flagValue) return flagValue;
|
|
18
23
|
if (process.env.VANARA_REGISTRY) return process.env.VANARA_REGISTRY;
|
|
24
|
+
// Unlocked subscribers have the full catalog synced locally (vanara unlock/sync).
|
|
25
|
+
if (existsSync(path.join(PREMIUM_DIR, 'packs'))) return PREMIUM_DIR;
|
|
26
|
+
const bundled = path.join(CLI_ROOT, 'catalog');
|
|
27
|
+
if (existsSync(path.join(bundled, 'packs'))) return bundled;
|
|
19
28
|
return path.resolve(CLI_ROOT, '..', 'forge', 'catalog');
|
|
20
29
|
}
|
|
21
30
|
|
|
@@ -25,3 +34,24 @@ export const CLAUDE_TARGET = {
|
|
|
25
34
|
agentsDir: path.join('.claude', 'agents'),
|
|
26
35
|
skillsDir: path.join('.claude', 'skills'),
|
|
27
36
|
};
|
|
37
|
+
|
|
38
|
+
// Pro subscription rail — Polar.sh (merchant of record; public license validation,
|
|
39
|
+
// so no secrets live in this CLI). organizationId + checkoutUrl are filled in
|
|
40
|
+
// when the store goes live; VANARA_POLAR_ORG env overrides for testing.
|
|
41
|
+
export const POLAR = {
|
|
42
|
+
apiBase: 'https://api.polar.sh',
|
|
43
|
+
organizationId: 'ede2a514-fe80-4b64-b9e6-ce7985c9fb91',
|
|
44
|
+
checkoutUrl: 'https://buy.polar.sh/polar_cl_nsNsLMyGBcKWwn3IWgCbvvFnFJePiDWZvSYd13zaosm',
|
|
45
|
+
// Gated premium-catalog endpoint (Cloudflare Worker in ../worker validates the
|
|
46
|
+
// license key server-side with Polar, then streams the tarball).
|
|
47
|
+
premiumUrl: 'https://get.vanaraagents.com/premium',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Free-tier manifest bundled with the package.
|
|
51
|
+
export function loadFreeTier() {
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(readFileSync(path.join(CLI_ROOT, 'free-tier.json'), 'utf8'));
|
|
54
|
+
} catch {
|
|
55
|
+
return { packs: [], agents: [], skills: [] };
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/license.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// Pro licensing — Polar.sh license keys as the rented entitlement service.
|
|
2
|
+
// Validation uses Polar's PUBLIC validate endpoint: no secrets ship in this CLI
|
|
3
|
+
// and no backend of ours exists. Free tier never touches this module.
|
|
4
|
+
// Mini version of OPEN-CORE-PLAN §3.2: cached validation, weekly re-check,
|
|
5
|
+
// 7-day offline grace. Client-side checks are honest friction by design —
|
|
6
|
+
// real enforcement arrives with the registry (Phase 3).
|
|
7
|
+
import { mkdir, readFile, writeFile, rm } from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { POLAR, PREMIUM_DIR } from './config.js';
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import { createWriteStream } from 'node:fs';
|
|
13
|
+
import { Readable } from 'node:stream';
|
|
14
|
+
import { pipeline } from 'node:stream/promises';
|
|
15
|
+
|
|
16
|
+
const DAY_MS = 86_400_000;
|
|
17
|
+
const REVALIDATE_AFTER_MS = 7 * DAY_MS; // check weekly when online
|
|
18
|
+
const OFFLINE_GRACE_MS = 7 * DAY_MS; // beyond revalidation window
|
|
19
|
+
|
|
20
|
+
export const licenseFilePath = (home = os.homedir()) =>
|
|
21
|
+
path.join(home, '.vanara', 'license.json');
|
|
22
|
+
|
|
23
|
+
/** Reject archives whose members escape the extraction dir (zip-slip). */
|
|
24
|
+
export function assertSafeTar(listing) {
|
|
25
|
+
for (const raw of listing.split(/\r?\n/)) {
|
|
26
|
+
const entry = raw.trim();
|
|
27
|
+
if (!entry) continue;
|
|
28
|
+
const unsafe =
|
|
29
|
+
entry.startsWith('/') ||
|
|
30
|
+
/^[A-Za-z]:/.test(entry) || // C:\ absolute
|
|
31
|
+
entry.split(/[\\/]/).some((seg) => seg === '..');
|
|
32
|
+
if (unsafe) {
|
|
33
|
+
throw new Error(`Refusing to extract unsafe archive path: ${entry}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function readLicense(fileOverride) {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(await readFile(fileOverride ?? licenseFilePath(), 'utf8'));
|
|
41
|
+
} catch (err) {
|
|
42
|
+
if (err.code === 'ENOENT') return null;
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function writeLicense(record, fileOverride) {
|
|
48
|
+
const file = fileOverride ?? licenseFilePath();
|
|
49
|
+
// The license key is a bearer credential — keep the dir + file owner-only
|
|
50
|
+
// (no-op on Windows ACLs, real protection on POSIX shared machines).
|
|
51
|
+
await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
52
|
+
await writeFile(file, `${JSON.stringify(record, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function clearLicense(fileOverride) {
|
|
56
|
+
await rm(fileOverride ?? licenseFilePath(), { force: true });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Validate a key against Polar's public endpoint. Returns { valid, error? }. */
|
|
60
|
+
export async function validateWithPolar(key, { fetchFn = fetch } = {}) {
|
|
61
|
+
const orgId = process.env.VANARA_POLAR_ORG ?? POLAR.organizationId;
|
|
62
|
+
if (!orgId) {
|
|
63
|
+
return { valid: false, error: 'Store not configured yet (missing Polar organization id).' };
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetchFn(`${POLAR.apiBase}/v1/customer-portal/license-keys/validate`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: { 'content-type': 'application/json' },
|
|
69
|
+
body: JSON.stringify({ key, organization_id: orgId }),
|
|
70
|
+
});
|
|
71
|
+
if (res.status === 404) return { valid: false, error: 'License key not found.' };
|
|
72
|
+
if (!res.ok) return { valid: false, error: `Validation service returned ${res.status}.`, transient: res.status >= 500 };
|
|
73
|
+
const data = await res.json();
|
|
74
|
+
const status = (data.status ?? '').toLowerCase();
|
|
75
|
+
if (['granted', 'active', 'valid'].includes(status)) return { valid: true };
|
|
76
|
+
return { valid: false, error: `License is ${status || 'not active'} (expired or cancelled subscription).` };
|
|
77
|
+
} catch (err) {
|
|
78
|
+
return { valid: false, error: `Could not reach the license service: ${err.message}`, transient: true };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** vanara unlock <key> — validate online, persist on success. */
|
|
83
|
+
export async function unlock(key, { fetchFn, fileOverride } = {}) {
|
|
84
|
+
const result = await validateWithPolar(key, { fetchFn });
|
|
85
|
+
if (!result.valid) return result;
|
|
86
|
+
await writeLicense({ key, validatedAt: new Date().toISOString(), plan: 'pro' }, fileOverride);
|
|
87
|
+
return { valid: true };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Is Pro currently unlocked? Uses the cached validation; revalidates in the
|
|
92
|
+
* background window; tolerates being offline for the grace period. Never
|
|
93
|
+
* blocks an install on a transient network failure inside the grace window.
|
|
94
|
+
*/
|
|
95
|
+
export async function isUnlocked({ fetchFn, fileOverride, now = Date.now() } = {}) {
|
|
96
|
+
const lic = await readLicense(fileOverride);
|
|
97
|
+
if (!lic?.key) return { unlocked: false };
|
|
98
|
+
const age = now - Date.parse(lic.validatedAt ?? 0);
|
|
99
|
+
if (age < REVALIDATE_AFTER_MS) return { unlocked: true, plan: lic.plan };
|
|
100
|
+
|
|
101
|
+
const result = await validateWithPolar(lic.key, { fetchFn });
|
|
102
|
+
if (result.valid) {
|
|
103
|
+
await writeLicense({ ...lic, validatedAt: new Date(now).toISOString() }, fileOverride);
|
|
104
|
+
return { unlocked: true, plan: lic.plan };
|
|
105
|
+
}
|
|
106
|
+
if (result.transient && age < REVALIDATE_AFTER_MS + OFFLINE_GRACE_MS) {
|
|
107
|
+
return { unlocked: true, plan: lic.plan, grace: true }; // offline grace
|
|
108
|
+
}
|
|
109
|
+
return { unlocked: false, reason: result.error };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Download the full premium catalog through the gated endpoint (server-side
|
|
114
|
+
* key check) and extract it to ~/.vanara/catalog. Requires a stored license.
|
|
115
|
+
*/
|
|
116
|
+
export async function syncPremium({ fetchFn = fetch, fileOverride, dirOverride } = {}) {
|
|
117
|
+
const lic = await readLicense(fileOverride);
|
|
118
|
+
if (!lic?.key) return { ok: false, error: 'No license — run: vanara unlock <license-key>' };
|
|
119
|
+
const base = process.env.VANARA_PREMIUM_URL ?? POLAR.premiumUrl;
|
|
120
|
+
if (!base) return { ok: false, error: 'Premium delivery not live yet — your license is saved; run `vanara sync` after launch.' };
|
|
121
|
+
|
|
122
|
+
const dir = dirOverride ?? PREMIUM_DIR;
|
|
123
|
+
// Send the key in the Authorization header, not the URL — query strings get
|
|
124
|
+
// retained in proxy/CDN/Worker request logs; headers generally do not.
|
|
125
|
+
const res = await fetchFn(base, { headers: { authorization: `Bearer ${lic.key}` } });
|
|
126
|
+
if (res.status === 402 || res.status === 403) return { ok: false, error: 'License not accepted by the catalog server (expired or cancelled?).' };
|
|
127
|
+
if (!res.ok) return { ok: false, error: `Catalog server returned ${res.status}.` };
|
|
128
|
+
|
|
129
|
+
await mkdir(dir, { recursive: true });
|
|
130
|
+
const tarball = path.join(dir, '.premium.tgz');
|
|
131
|
+
await pipeline(Readable.fromWeb(res.body), createWriteStream(tarball));
|
|
132
|
+
try {
|
|
133
|
+
// Defense-in-depth: the tarball is our own paid asset behind a license gate,
|
|
134
|
+
// but never trust downloaded archive contents. Inspect the member list and
|
|
135
|
+
// refuse absolute paths or `..` traversal (zip-slip) before extracting.
|
|
136
|
+
assertSafeTar(execFileSync('tar', ['-tzf', '.premium.tgz'], { cwd: dir, encoding: 'utf8' }));
|
|
137
|
+
// relative path + cwd: GNU tar on Windows misreads "C:" in absolute paths
|
|
138
|
+
execFileSync('tar', ['-xzf', '.premium.tgz'], { cwd: dir });
|
|
139
|
+
} finally {
|
|
140
|
+
await rm(tarball, { force: true });
|
|
141
|
+
}
|
|
142
|
+
return { ok: true, dir };
|
|
143
|
+
}
|