skillpp 0.1.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/COMPATIBILITY.md +58 -0
- package/LICENSE +21 -0
- package/README.md +307 -0
- package/README.zh-CN.md +307 -0
- package/SKILL.md +490 -0
- package/adapters/binance-ai.md +22 -0
- package/adapters/claude.md +21 -0
- package/adapters/gemini.md +26 -0
- package/adapters/gpt.md +28 -0
- package/adapters/kimi.md +26 -0
- package/adapters/mimo.md +22 -0
- package/adapters/openclaw.md +29 -0
- package/assets/skillpp-banner.png +0 -0
- package/package.json +59 -0
- package/pipelines.md +310 -0
- package/prompts/newbie-mode.md +48 -0
- package/prompts/router-prompt.md +32 -0
- package/prompts/universal-system-prompt.md +41 -0
- package/registry.md +209 -0
- package/rules.md +323 -0
- package/schemas/audit.schema.json +67 -0
- package/schemas/checkpoint.schema.json +86 -0
- package/schemas/handoff.schema.json +82 -0
- package/schemas/token.schema.json +36 -0
- package/scripts/compatibility-check.mjs +130 -0
- package/scripts/selftest.mjs +384 -0
- package/scripts/skillpp.mjs +448 -0
- package/scripts/validate-skillpp.mjs +140 -0
- package/skillpp.manifest.json +714 -0
- package/skills/audit-plus/SKILL.md +612 -0
- package/skills/binance/binance/CHANGELOG.md +112 -0
- package/skills/binance/binance/LICENSE.md +9 -0
- package/skills/binance/binance/SKILL.md +69 -0
- package/skills/binance/binance/references/algo.md +21 -0
- package/skills/binance/binance/references/alpha.md +9 -0
- package/skills/binance/binance/references/auth.md +32 -0
- package/skills/binance/binance/references/c2c.md +5 -0
- package/skills/binance/binance/references/convert.md +19 -0
- package/skills/binance/binance/references/copy-trading.md +6 -0
- package/skills/binance/binance/references/crypto-loan.md +27 -0
- package/skills/binance/binance/references/derivatives-options-streams.md +25 -0
- package/skills/binance/binance/references/derivatives-options.md +85 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-pro-streams.md +5 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-pro.md +34 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-streams.md +5 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin.md +146 -0
- package/skills/binance/binance/references/dual-investment.md +15 -0
- package/skills/binance/binance/references/fiat.md +9 -0
- package/skills/binance/binance/references/futures-coin-streams.md +29 -0
- package/skills/binance/binance/references/futures-coin.md +109 -0
- package/skills/binance/binance/references/futures-usds-streams.md +35 -0
- package/skills/binance/binance/references/futures-usds.md +144 -0
- package/skills/binance/binance/references/gift-card.md +10 -0
- package/skills/binance/binance/references/margin-trading-streams.md +6 -0
- package/skills/binance/binance/references/margin-trading.md +101 -0
- package/skills/binance/binance/references/mining.md +17 -0
- package/skills/binance/binance/references/pay.md +5 -0
- package/skills/binance/binance/references/rebate.md +5 -0
- package/skills/binance/binance/references/simple-earn.md +56 -0
- package/skills/binance/binance/references/spot-streams.md +25 -0
- package/skills/binance/binance/references/spot.md +114 -0
- package/skills/binance/binance/references/staking.md +59 -0
- package/skills/binance/binance/references/sub-account.md +67 -0
- package/skills/binance/binance/references/vip-loan.md +27 -0
- package/skills/binance/binance/references/wallet.md +75 -0
- package/skills/binance/fiat/CHANGELOG.md +11 -0
- package/skills/binance/fiat/LICENSE.md +9 -0
- package/skills/binance/fiat/SKILL.md +169 -0
- package/skills/binance/fiat/references/authentication.md +126 -0
- package/skills/binance/fiat/references/sapi-endpoints.md +217 -0
- package/skills/binance/onchain-pay/.local.md.example +10 -0
- package/skills/binance/onchain-pay/CHANGELOG.md +20 -0
- package/skills/binance/onchain-pay/LICENSE.md +9 -0
- package/skills/binance/onchain-pay/SKILL.md +466 -0
- package/skills/binance/onchain-pay/references/authentication.md +92 -0
- package/skills/binance/onchain-pay/scripts/sign_and_call.sh +52 -0
- package/skills/binance/p2p/CHANGELOG.md +33 -0
- package/skills/binance/p2p/LICENSE.md +9 -0
- package/skills/binance/p2p/SKILL.md +1082 -0
- package/skills/binance/p2p/references/agent-sapi-api.md +795 -0
- package/skills/binance/p2p/references/authentication.md +100 -0
- package/skills/binance/payment/SKILL.md +824 -0
- package/skills/binance/payment/common.py +560 -0
- package/skills/binance/payment/payment_skill.py +86 -0
- package/skills/binance/payment/receive.py +109 -0
- package/skills/binance/payment/references/setup-guide.md +77 -0
- package/skills/binance/payment/requirements.txt +4 -0
- package/skills/binance/payment/send.py +952 -0
- package/skills/binance/payment/send_extension/__init__.py +43 -0
- package/skills/binance/payment/send_extension/base.py +48 -0
- package/skills/binance/payment/send_extension/c2c.py +193 -0
- package/skills/binance/payment/send_extension/pix.py +316 -0
- package/skills/binance/square-post/README.md +62 -0
- package/skills/binance/square-post/SKILL.md +171 -0
- package/skills/binance/square-post/scripts/lib.mjs +175 -0
- package/skills/binance/square-post/scripts/post-image.mjs +80 -0
- package/skills/binance/square-post/scripts/post-text.mjs +41 -0
- package/skills/binance/square-post/scripts/post-video.mjs +110 -0
- package/skills/binance/square-post/scripts/save-key.mjs +34 -0
- package/skills/binance-web3/binance-agentic-wallet/SKILL.md +150 -0
- package/skills/binance-web3/binance-agentic-wallet/references/authentication.md +136 -0
- package/skills/binance-web3/binance-agentic-wallet/references/limit-order.md +204 -0
- package/skills/binance-web3/binance-agentic-wallet/references/market-order.md +179 -0
- package/skills/binance-web3/binance-agentic-wallet/references/prediction.md +489 -0
- package/skills/binance-web3/binance-agentic-wallet/references/preflight.md +66 -0
- package/skills/binance-web3/binance-agentic-wallet/references/security.md +47 -0
- package/skills/binance-web3/binance-agentic-wallet/references/send.md +53 -0
- package/skills/binance-web3/binance-agentic-wallet/references/wallet-setting.md +86 -0
- package/skills/binance-web3/binance-agentic-wallet/references/wallet-view.md +312 -0
- package/skills/binance-web3/binance-agentic-wallet/references/x402-payment.md +259 -0
- package/skills/binance-web3/binance-tokenized-securities-info/SKILL.md +613 -0
- package/skills/binance-web3/crypto-market-rank/SKILL.md +91 -0
- package/skills/binance-web3/crypto-market-rank/references/cli.md +219 -0
- package/skills/binance-web3/crypto-market-rank/scripts/cli.mjs +149 -0
- package/skills/binance-web3/meme-rush/SKILL.md +72 -0
- package/skills/binance-web3/meme-rush/references/cli.md +158 -0
- package/skills/binance-web3/meme-rush/scripts/cli.mjs +101 -0
- package/skills/binance-web3/query-address-info/SKILL.md +61 -0
- package/skills/binance-web3/query-address-info/references/cli.md +56 -0
- package/skills/binance-web3/query-address-info/scripts/cli.mjs +132 -0
- package/skills/binance-web3/query-token-audit/SKILL.md +162 -0
- package/skills/binance-web3/query-token-info/SKILL.md +83 -0
- package/skills/binance-web3/query-token-info/references/cli.md +135 -0
- package/skills/binance-web3/query-token-info/scripts/cli.mjs +112 -0
- package/skills/binance-web3/trading-signal/SKILL.md +66 -0
- package/skills/binance-web3/trading-signal/references/cli.md +90 -0
- package/skills/binance-web3/trading-signal/scripts/cli.mjs +92 -0
- package/skills/four-meme/four-guard/API-Contract-TaxToken.md +277 -0
- package/skills/four-meme/four-guard/API-CreateToken.02-02-2026.md +285 -0
- package/skills/four-meme/four-guard/API-Documents.03-03-2026.md +789 -0
- package/skills/four-meme/four-guard/AgentIdentifier.abi +585 -0
- package/skills/four-meme/four-guard/README.md +21 -0
- package/skills/four-meme/four-guard/SKILL.md +31 -0
- package/skills/four-meme/four-guard/TaxToken.abi +969 -0
- package/skills/four-meme/four-guard/TokenIdentifierSample.js_ +81 -0
- package/skills/four-meme/four-guard/TokenIdentifierSample.sol +69 -0
- package/skills/four-meme/four-guard/TokenManager.lite.abi +836 -0
- package/skills/four-meme/four-guard/TokenManager2.lite.abi +2325 -0
- package/skills/four-meme/four-guard/TokenManagerHelper3.abi +999 -0
- package/skills/four-meme/four-guard/go.mod +36 -0
- package/skills/four-meme/four-guard/go.sum +127 -0
- package/skills/four-meme/four-guard/main.go +183 -0
- package/skills/four-meme/four-meme-ai/SKILL.md +31 -0
- package/skills/four-meme/four-meme-ai/references/agent-creator-and-wallets.md +87 -0
- package/skills/four-meme/four-meme-ai/references/api-create-token.md +55 -0
- package/skills/four-meme/four-meme-ai/references/contract-addresses.md +47 -0
- package/skills/four-meme/four-meme-ai/references/create-token-scripts.md +131 -0
- package/skills/four-meme/four-meme-ai/references/errors.md +29 -0
- package/skills/four-meme/four-meme-ai/references/event-listening.md +75 -0
- package/skills/four-meme/four-meme-ai/references/execute-trade.md +31 -0
- package/skills/four-meme/four-meme-ai/references/tax-token-query.md +38 -0
- package/skills/four-meme/four-meme-ai/references/token-query-api.md +44 -0
- package/skills/four-meme/four-meme-ai/references/token-tax-info.md +77 -0
- package/skills/four-meme/four-meme-ai/scripts/8004-balance.ts +52 -0
- package/skills/four-meme/four-meme-ai/scripts/8004-register.ts +108 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-api.ts +321 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-chain.ts +102 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-instant.ts +106 -0
- package/skills/four-meme/four-meme-ai/scripts/execute-buy.ts +198 -0
- package/skills/four-meme/four-meme-ai/scripts/execute-sell.ts +150 -0
- package/skills/four-meme/four-meme-ai/scripts/get-public-config.ts +25 -0
- package/skills/four-meme/four-meme-ai/scripts/get-recent-events.ts +76 -0
- package/skills/four-meme/four-meme-ai/scripts/get-tax-token-info.ts +69 -0
- package/skills/four-meme/four-meme-ai/scripts/get-token-info.ts +94 -0
- package/skills/four-meme/four-meme-ai/scripts/quote-buy.ts +85 -0
- package/skills/four-meme/four-meme-ai/scripts/quote-sell.ts +66 -0
- package/skills/four-meme/four-meme-ai/scripts/send-token.ts +98 -0
- package/skills/four-meme/four-meme-ai/scripts/token-get.ts +31 -0
- package/skills/four-meme/four-meme-ai/scripts/token-list.ts +134 -0
- package/skills/four-meme/four-meme-ai/scripts/token-rankings.ts +162 -0
- package/skills/four-meme/four-meme-ai/scripts/verify-events.ts +47 -0
- package/skills/four-meme/four-meme-integration/SKILL.md +374 -0
- package/skills/four-meme/four-meme-integration/references/agent-creator-and-wallets.md +87 -0
- package/skills/four-meme/four-meme-integration/references/api-create-token.md +55 -0
- package/skills/four-meme/four-meme-integration/references/contract-addresses.md +47 -0
- package/skills/four-meme/four-meme-integration/references/create-token-scripts.md +131 -0
- package/skills/four-meme/four-meme-integration/references/errors.md +29 -0
- package/skills/four-meme/four-meme-integration/references/event-listening.md +75 -0
- package/skills/four-meme/four-meme-integration/references/execute-trade.md +31 -0
- package/skills/four-meme/four-meme-integration/references/tax-token-query.md +38 -0
- package/skills/four-meme/four-meme-integration/references/token-query-api.md +44 -0
- package/skills/four-meme/four-meme-integration/references/token-tax-info.md +77 -0
- package/skills/four-meme/four-meme-integration/scripts/8004-balance.ts +52 -0
- package/skills/four-meme/four-meme-integration/scripts/8004-register.ts +108 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-api.ts +321 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-chain.ts +102 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-instant.ts +106 -0
- package/skills/four-meme/four-meme-integration/scripts/execute-buy.ts +198 -0
- package/skills/four-meme/four-meme-integration/scripts/execute-sell.ts +150 -0
- package/skills/four-meme/four-meme-integration/scripts/get-public-config.ts +25 -0
- package/skills/four-meme/four-meme-integration/scripts/get-recent-events.ts +76 -0
- package/skills/four-meme/four-meme-integration/scripts/get-tax-token-info.ts +69 -0
- package/skills/four-meme/four-meme-integration/scripts/get-token-info.ts +94 -0
- package/skills/four-meme/four-meme-integration/scripts/quote-buy.ts +85 -0
- package/skills/four-meme/four-meme-integration/scripts/quote-sell.ts +66 -0
- package/skills/four-meme/four-meme-integration/scripts/send-token.ts +98 -0
- package/skills/four-meme/four-meme-integration/scripts/token-get.ts +31 -0
- package/skills/four-meme/four-meme-integration/scripts/token-list.ts +134 -0
- package/skills/four-meme/four-meme-integration/scripts/token-rankings.ts +162 -0
- package/skills/four-meme/four-meme-integration/scripts/verify-events.ts +47 -0
- package/skills/skillpp/contract-profiler/SKILL.md +118 -0
- package/skills/skillpp/newbie-tutor/SKILL.md +85 -0
- package/skills/skillpp/opportunity-board/SKILL.md +87 -0
- package/skills/skillpp/risk-fusion/SKILL.md +146 -0
- package/skills/skillpp/scam-pattern-lab/SKILL.md +115 -0
- package/skills/skillpp/wallet-doctor/SKILL.md +119 -0
- package/skills/skillpp/watchtower/SKILL.md +72 -0
- package/tests/compatibility/v0.1.0.json +117 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Skill++ self-test runner.
|
|
3
|
+
// Usage: node scripts/selftest.mjs [--verbose] [--integration]
|
|
4
|
+
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
6
|
+
import { join, resolve, dirname } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { execSync } from 'child_process';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const ROOT = resolve(__dirname, '..');
|
|
12
|
+
const VERBOSE = process.argv.includes('--verbose');
|
|
13
|
+
const INTEGRATION = process.argv.includes('--integration');
|
|
14
|
+
|
|
15
|
+
let passed = 0;
|
|
16
|
+
let failed = 0;
|
|
17
|
+
let skipped = 0;
|
|
18
|
+
|
|
19
|
+
function test(name, fn) {
|
|
20
|
+
try {
|
|
21
|
+
fn();
|
|
22
|
+
passed++;
|
|
23
|
+
if (VERBOSE) console.log(` PASS ${name}`);
|
|
24
|
+
} catch (e) {
|
|
25
|
+
failed++;
|
|
26
|
+
console.error(` FAIL ${name}: ${e.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function read(relPath) {
|
|
31
|
+
return readFileSync(join(ROOT, relPath), 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function run(command) {
|
|
35
|
+
return execSync(command, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function walkTextFiles(relPath) {
|
|
39
|
+
const abs = join(ROOT, relPath);
|
|
40
|
+
if (!existsSync(abs)) return [];
|
|
41
|
+
const stat = statSync(abs);
|
|
42
|
+
if (stat.isFile()) return [relPath];
|
|
43
|
+
const files = [];
|
|
44
|
+
for (const entry of readdirSync(abs, { withFileTypes: true })) {
|
|
45
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.git')) continue;
|
|
46
|
+
const childRel = `${relPath}/${entry.name}`;
|
|
47
|
+
if (entry.isDirectory()) files.push(...walkTextFiles(childRel));
|
|
48
|
+
else if (/\.(md|mjs|json|yml|yaml)$/.test(entry.name)) files.push(childRel);
|
|
49
|
+
}
|
|
50
|
+
return files;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function assertIncludes(text, required, label) {
|
|
54
|
+
for (const item of required) {
|
|
55
|
+
if (!text.includes(item)) throw new Error(`${label} missing ${item}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log('Skill++ Self-Test\n');
|
|
60
|
+
|
|
61
|
+
console.log('1. Structure');
|
|
62
|
+
test('root files exist', () => {
|
|
63
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'COMPATIBILITY.md', 'SKILL.md', 'registry.md', 'pipelines.md', 'rules.md', 'package.json', 'skillpp.manifest.json']) {
|
|
64
|
+
if (!existsSync(join(ROOT, f))) throw new Error(`missing ${f}`);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
test('manifest is valid JSON', () => {
|
|
68
|
+
JSON.parse(read('skillpp.manifest.json'));
|
|
69
|
+
});
|
|
70
|
+
test('root markdown files have no UTF-8 BOM', () => {
|
|
71
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'SKILL.md', 'registry.md', 'pipelines.md', 'rules.md']) {
|
|
72
|
+
const raw = readFileSync(join(ROOT, f));
|
|
73
|
+
if (raw[0] === 0xef && raw[1] === 0xbb && raw[2] === 0xbf) throw new Error(`BOM: ${f}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
test('schemas exist', () => {
|
|
77
|
+
for (const s of ['handoff', 'token', 'audit', 'checkpoint']) {
|
|
78
|
+
if (!existsSync(join(ROOT, 'schemas', `${s}.schema.json`))) throw new Error(`missing ${s}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
console.log('\n2. Runtime');
|
|
83
|
+
const ROUTE_TESTS = [
|
|
84
|
+
{ cmd: 'analyze', input: '0x55d398326f99059ff775485246999027b3197955', expectPipeline: 'P_TOKEN_ANALYSIS' },
|
|
85
|
+
{ cmd: 'scan', input: '56', expectPipeline: 'P_CHAIN_SCAN' },
|
|
86
|
+
{ cmd: 'trade', input: '0x55d398326f99059ff775485246999027b3197955', expectPipeline: 'P_TRADE_SAFETY' },
|
|
87
|
+
{ cmd: 'audit', input: '0x55d398326f99059ff775485246999027b3197955', expectPipeline: 'P_DEEP_AUDIT' },
|
|
88
|
+
{ cmd: 'wallet', input: '0x55d398326f99059ff775485246999027b3197955', expectPipeline: 'P_WALLET_XRAY' },
|
|
89
|
+
{ cmd: 'signals', input: '56', expectPipeline: 'P_SMART_MONEY' },
|
|
90
|
+
{ cmd: 'create', input: 'create a meme token on four.meme', expectPipeline: 'P_FOURMEME_CREATE' },
|
|
91
|
+
{ cmd: 'parse', input: 'https://bscscan.com/address/0x1234567890abcdef1234567890abcdef12345678#code', expectType: 'explorer_url' },
|
|
92
|
+
{ cmd: 'parse', input: 'CT_501', expectType: 'chain_id' },
|
|
93
|
+
];
|
|
94
|
+
for (const rt of ROUTE_TESTS) {
|
|
95
|
+
test(`route ${rt.cmd}`, () => {
|
|
96
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" ${rt.cmd} "${rt.input}" --dry-run`);
|
|
97
|
+
if (rt.expectType && !out.includes(`"type": "${rt.expectType}"`)) throw new Error(`expected type ${rt.expectType}`);
|
|
98
|
+
if (rt.expectPipeline && !out.includes(rt.expectPipeline)) throw new Error(`expected pipeline ${rt.expectPipeline}`);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
test('scan dry-run includes full chain scan subflow', () => {
|
|
102
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" scan "56" --dry-run`);
|
|
103
|
+
assertIncludes(out, ['meme-rush', 'topic-rush', 'token-rank', 'smart-money-inflow', 'risk-fusion', 'opportunity-board'], 'scan output');
|
|
104
|
+
});
|
|
105
|
+
test('doctor redacts local paths by default', () => {
|
|
106
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" doctor`);
|
|
107
|
+
assertIncludes(out, ['"command": "doctor"', '"packageRoot"', '"skillsDir"', '"skills": 25', '"pipelines": 7', '"externalCli"', '"baw"', '"binance-cli"', '"fourmeme"'], 'doctor output');
|
|
108
|
+
const report = JSON.parse(out);
|
|
109
|
+
if (report.packageRoot !== '<redacted>') throw new Error('packageRoot must be redacted');
|
|
110
|
+
if (!report.privacy?.includes('redacted')) throw new Error('missing redaction notice');
|
|
111
|
+
if (report.checks.skillsDir.path !== 'skills') throw new Error('skillsDir must be relative');
|
|
112
|
+
if ('absolutePath' in report.checks.skillsDir) throw new Error('absolute path leaked');
|
|
113
|
+
});
|
|
114
|
+
test('doctor shows local paths only with --show-paths', () => {
|
|
115
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" doctor --show-paths`);
|
|
116
|
+
const report = JSON.parse(out);
|
|
117
|
+
if (report.packageRoot !== ROOT) throw new Error('packageRoot mismatch');
|
|
118
|
+
if (report.checks.skillsDir.absolutePath !== join(ROOT, 'skills')) throw new Error('skillsDir absolutePath mismatch');
|
|
119
|
+
});
|
|
120
|
+
test('skills command lists manifest skills', () => {
|
|
121
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" skills`);
|
|
122
|
+
assertIncludes(out, ['"command": "skills"', '"count": 25', '"query-token-info"', '"risk-fusion"', '"opportunity-board"'], 'skills output');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
console.log('\n3. Bundled CLIs');
|
|
126
|
+
const CLIS = [
|
|
127
|
+
{ name: 'query-token-info', help: ['search', 'meta', 'dynamic', 'kline'] },
|
|
128
|
+
{ name: 'meme-rush', help: ['meme-rush', 'topic-rush'] },
|
|
129
|
+
{ name: 'trading-signal', help: ['smart-money'] },
|
|
130
|
+
{ name: 'crypto-market-rank', help: ['social-hype', 'token-rank'] },
|
|
131
|
+
{ name: 'query-address-info', help: ['positions'] },
|
|
132
|
+
];
|
|
133
|
+
for (const cli of CLIS) {
|
|
134
|
+
const p = join(ROOT, 'skills/binance-web3', cli.name, 'scripts/cli.mjs');
|
|
135
|
+
test(`${cli.name} --help`, () => {
|
|
136
|
+
const out = run(`node "${p}" --help`);
|
|
137
|
+
assertIncludes(out, cli.help, `${cli.name} help`);
|
|
138
|
+
});
|
|
139
|
+
test(`${cli.name} invalid command`, () => {
|
|
140
|
+
try {
|
|
141
|
+
run(`node "${p}" __nonexistent__`);
|
|
142
|
+
throw new Error('should fail');
|
|
143
|
+
} catch (e) {
|
|
144
|
+
if (!e.stderr && !e.stdout) throw new Error('no error output');
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log('\n4. Manifest');
|
|
150
|
+
const manifest = JSON.parse(read('skillpp.manifest.json'));
|
|
151
|
+
test('manifest counts are current', () => {
|
|
152
|
+
if (manifest.skills.length !== 25) throw new Error(`skills=${manifest.skills.length}`);
|
|
153
|
+
if (manifest.pipelines.length !== 7) throw new Error(`pipelines=${manifest.pipelines.length}`);
|
|
154
|
+
});
|
|
155
|
+
test('pipeline skill order is stable', () => {
|
|
156
|
+
const expected = {
|
|
157
|
+
P_TOKEN_ANALYSIS: ['query-token-info', 'query-token-audit', 'trading-signal', 'risk-fusion'],
|
|
158
|
+
P_CHAIN_SCAN: ['meme-rush', 'crypto-market-rank', 'risk-fusion', 'opportunity-board'],
|
|
159
|
+
P_TRADE_SAFETY: ['query-token-audit', 'audit-plus', 'risk-fusion'],
|
|
160
|
+
P_WALLET_XRAY: ['query-address-info', 'query-token-audit', 'wallet-doctor'],
|
|
161
|
+
P_SMART_MONEY: ['trading-signal', 'query-token-audit', 'risk-fusion'],
|
|
162
|
+
P_FOURMEME_CREATE: ['four-meme-integration'],
|
|
163
|
+
P_DEEP_AUDIT: ['query-token-info', 'query-token-audit', 'contract-profiler', 'audit-plus', 'risk-fusion'],
|
|
164
|
+
};
|
|
165
|
+
for (const [id, skills] of Object.entries(expected)) {
|
|
166
|
+
const pipeline = manifest.pipelines.find(p => p.id === id);
|
|
167
|
+
if (!pipeline) throw new Error(`missing ${id}`);
|
|
168
|
+
if (pipeline.skills.join(' -> ') !== skills.join(' -> ')) throw new Error(`${id} order drift`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
test('blocking checkpoints are defined', () => {
|
|
172
|
+
const blocking = manifest.checkpoints?.filter(c => c.securityLevel === 'BLOCKING') || [];
|
|
173
|
+
if (blocking.length < 4) throw new Error(`only ${blocking.length}`);
|
|
174
|
+
});
|
|
175
|
+
test('execCommand scripts exist', () => {
|
|
176
|
+
for (const s of manifest.skills) {
|
|
177
|
+
if (!s.execCommand?.startsWith('node ')) continue;
|
|
178
|
+
const rel = s.execCommand.replace('node ', '');
|
|
179
|
+
if (!existsSync(join(ROOT, rel))) throw new Error(`${s.name}: ${rel}`);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
test('write-operation skills include install guidance', () => {
|
|
183
|
+
for (const s of manifest.skills) {
|
|
184
|
+
if (['npx fourmeme', 'baw', 'binance-cli'].includes(s.execCommand) && !s.installCmd) {
|
|
185
|
+
throw new Error(`${s.name}: missing installCmd`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
test('skillpp modules all exist in manifest', () => {
|
|
190
|
+
for (const n of ['contract-profiler', 'risk-fusion', 'wallet-doctor', 'newbie-tutor', 'watchtower', 'opportunity-board', 'scam-pattern-lab']) {
|
|
191
|
+
if (!manifest.skills.find(s => s.name === n)) throw new Error(`missing ${n}`);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
console.log('\n5. Documentation');
|
|
196
|
+
test('README is English default and links Chinese version', () => {
|
|
197
|
+
const r = read('README.md');
|
|
198
|
+
assertIncludes(r, ['', '[简体中文](README.zh-CN.md)', 'Skill Plus Plus (Skill++)', 'img.shields.io/npm/v/skillpp', 'v0.1 public npm release', 'npm install -g skillpp', 'npm install -g github:skillpp/skillpp', 'protocol-first AI skill package', '25 coordinated skills', 'Privacy-Safe Doctor', '[MIT](LICENSE)'], 'README');
|
|
199
|
+
if (r.includes('## Skill++ 是什么')) throw new Error('README default should be English');
|
|
200
|
+
});
|
|
201
|
+
test('Chinese README exists and links English version', () => {
|
|
202
|
+
const r = read('README.zh-CN.md');
|
|
203
|
+
assertIncludes(r, ['', '[English](README.md)', 'Skill Plus Plus(Skill++)', 'img.shields.io/npm/v/skillpp', 'v0.1 公开 npm 发布版', 'npm install -g skillpp', 'npm install -g github:skillpp/skillpp', '协议优先的 AI skill 包', '25 个 skill 协同工作', '[MIT](LICENSE)'], 'README.zh-CN');
|
|
204
|
+
});
|
|
205
|
+
test('README lists supported AI agents', () => {
|
|
206
|
+
const r = read('README.md');
|
|
207
|
+
assertIncludes(r, ['BinanceAI', 'Claude', 'Claude Opus', 'GPT', 'Gemini', 'Mimo', 'Kimi', 'OpenClaw', 'Codex'], 'README AI list');
|
|
208
|
+
});
|
|
209
|
+
test('README has minimal CLI examples', () => {
|
|
210
|
+
const r = read('README.md');
|
|
211
|
+
assertIncludes(r, ['skillpp parse', 'skillpp analyze', 'skillpp scan', 'skillpp trade', 'skillpp create', 'P_TOKEN_ANALYSIS', 'AUDIT_RESULT'], 'README examples');
|
|
212
|
+
});
|
|
213
|
+
test('README documents external write CLI boundary', () => {
|
|
214
|
+
const r = read('README.md');
|
|
215
|
+
assertIncludes(r, ['does not silently install wallet, exchange, or Four.meme write-operation tools', 'Write-operation flows are checkpointed handoffs', '@binance/agentic-wallet', '@binance/binance-cli', '@four-meme/four-meme-ai'], 'README external CLI');
|
|
216
|
+
});
|
|
217
|
+
test('root SKILL.md release counts are current', () => {
|
|
218
|
+
const s = read('SKILL.md');
|
|
219
|
+
assertIncludes(s, ['25', '7', 'skillpp doctor', 'skillpp skills'], 'SKILL.md');
|
|
220
|
+
});
|
|
221
|
+
test('registry includes all manifest skills', () => {
|
|
222
|
+
const r = read('registry.md');
|
|
223
|
+
for (const s of manifest.skills) {
|
|
224
|
+
if (!r.includes(s.name)) throw new Error(`registry missing ${s.name}`);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
console.log('\n6. Release hygiene');
|
|
229
|
+
test('public files do not contain local private paths or secrets', () => {
|
|
230
|
+
const files = [
|
|
231
|
+
'README.md',
|
|
232
|
+
'README.zh-CN.md',
|
|
233
|
+
'COMPATIBILITY.md',
|
|
234
|
+
'SKILL.md',
|
|
235
|
+
'registry.md',
|
|
236
|
+
'pipelines.md',
|
|
237
|
+
'rules.md',
|
|
238
|
+
'package.json',
|
|
239
|
+
'skillpp.manifest.json',
|
|
240
|
+
...walkTextFiles('scripts'),
|
|
241
|
+
...walkTextFiles('adapters'),
|
|
242
|
+
...walkTextFiles('prompts'),
|
|
243
|
+
...walkTextFiles('.github'),
|
|
244
|
+
];
|
|
245
|
+
const forbidden = [
|
|
246
|
+
/(^|[^A-Za-z])[A-Za-z]:\\(?!\\?)/,
|
|
247
|
+
/(^|[^A-Za-z])[A-Za-z]:\//,
|
|
248
|
+
new RegExp('C:' + String.raw`\\Users\\`, 'i'),
|
|
249
|
+
new RegExp('App' + String.raw`Data\\`, 'i'),
|
|
250
|
+
new RegExp('Admin' + 'istrator', 'i'),
|
|
251
|
+
/PRIVATE_KEY\s*=/i,
|
|
252
|
+
/API_KEY\s*=/i,
|
|
253
|
+
/0x[a-fA-F0-9]{64}/,
|
|
254
|
+
new RegExp('mnemo' + 'nic', 'i'),
|
|
255
|
+
new RegExp('seed' + ' phrase', 'i'),
|
|
256
|
+
];
|
|
257
|
+
for (const f of files) {
|
|
258
|
+
const c = read(f);
|
|
259
|
+
for (const pattern of forbidden) {
|
|
260
|
+
if (pattern.test(c)) throw new Error(`${f}: ${pattern}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
test('public files do not contain placeholder repository URLs', () => {
|
|
265
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'package.json', 'skillpp.manifest.json', 'schemas/audit.schema.json', 'schemas/checkpoint.schema.json', 'schemas/handoff.schema.json', 'schemas/token.schema.json']) {
|
|
266
|
+
const c = read(f);
|
|
267
|
+
if (c.includes('github.com/' + '<owner>')) throw new Error(`${f}: placeholder owner URL`);
|
|
268
|
+
if (c.includes('github.com/' + '<org>')) throw new Error(`${f}: placeholder org URL`);
|
|
269
|
+
if (c.includes('skill-plus-plus.dev')) throw new Error(`${f}: stale domain`);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
test('public docs do not contain implementation-status artifacts', () => {
|
|
273
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'COMPATIBILITY.md', 'SKILL.md', 'registry.md', 'pipelines.md', 'rules.md']) {
|
|
274
|
+
const c = read(f);
|
|
275
|
+
const patterns = [
|
|
276
|
+
new RegExp('P' + '0\\b'),
|
|
277
|
+
new RegExp('P' + '1\\b'),
|
|
278
|
+
new RegExp('P' + '2\\b'),
|
|
279
|
+
new RegExp('P' + '3\\b'),
|
|
280
|
+
new RegExp('f' + 'ix', 'i'),
|
|
281
|
+
new RegExp('待' + '添加'),
|
|
282
|
+
new RegExp('计划' + '用途'),
|
|
283
|
+
];
|
|
284
|
+
for (const pattern of patterns) {
|
|
285
|
+
if (pattern.test(c)) throw new Error(`${f}: ${pattern}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
test('repository layout examples use skillpp folder name', () => {
|
|
290
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'SKILL.md']) {
|
|
291
|
+
const c = read(f);
|
|
292
|
+
if (c.includes('skill-plus' + '-plus/')) throw new Error(`${f}: stale folder name`);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
test('no sports in public docs', () => {
|
|
296
|
+
for (const f of ['README.md', 'README.zh-CN.md']) {
|
|
297
|
+
if (/sports-ai|体育|足球|世界杯/i.test(read(f))) throw new Error(`${f}: sports reference`);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
test('no stale pipeline numbers', () => {
|
|
301
|
+
for (const f of ['SKILL.md', 'pipelines.md', 'rules.md', 'registry.md', 'README.md', 'README.zh-CN.md', 'COMPATIBILITY.md']) {
|
|
302
|
+
if (/PIPELINE [0-9]/.test(read(f))) throw new Error(`${f}: stale PIPELINE N`);
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
test('no duplicate pipeline headings', () => {
|
|
306
|
+
const headings = read('pipelines.md').match(/^## P_\w+:/gm) || [];
|
|
307
|
+
const seen = new Set();
|
|
308
|
+
for (const h of headings) {
|
|
309
|
+
if (seen.has(h)) throw new Error(`duplicate ${h}`);
|
|
310
|
+
seen.add(h);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
test('npm package exposes expected files', () => {
|
|
314
|
+
const pkg = JSON.parse(read('package.json'));
|
|
315
|
+
if (pkg.name !== 'skillpp') throw new Error('package name must be skillpp');
|
|
316
|
+
if (pkg.version !== '0.1.0') throw new Error('package version must be 0.1.0 for first public npm release');
|
|
317
|
+
if (pkg.type !== 'module') throw new Error('package type must be module');
|
|
318
|
+
if (pkg.repository?.url !== 'git+https://github.com/skillpp/skillpp.git') throw new Error('missing repository URL');
|
|
319
|
+
if (pkg.homepage !== 'https://skillpp.ai') throw new Error('missing homepage');
|
|
320
|
+
if (pkg.bugs?.url !== 'https://github.com/skillpp/skillpp/issues') throw new Error('missing bugs URL');
|
|
321
|
+
if (pkg.publishConfig?.registry !== 'https://registry.npmjs.org/') throw new Error('missing npmjs publish registry');
|
|
322
|
+
if (pkg.publishConfig?.access !== 'public') throw new Error('missing public npm access');
|
|
323
|
+
if (pkg.license !== 'MIT') throw new Error('missing MIT license');
|
|
324
|
+
if (pkg.bin?.skillpp !== 'scripts/skillpp.mjs') throw new Error('missing bin.skillpp');
|
|
325
|
+
if (pkg.scripts?.test !== 'node scripts/selftest.mjs') throw new Error('missing npm test');
|
|
326
|
+
if (pkg.scripts?.validate !== 'node scripts/validate-skillpp.mjs --strict') throw new Error('missing npm validate');
|
|
327
|
+
if (pkg.scripts?.compatibility !== 'node scripts/compatibility-check.mjs') throw new Error('missing npm compatibility');
|
|
328
|
+
for (const f of ['README.md', 'README.zh-CN.md', 'COMPATIBILITY.md', 'SKILL.md', 'skills', 'adapters', 'prompts', 'schemas', 'scripts', 'assets', 'tests']) {
|
|
329
|
+
if (!pkg.files?.includes(f)) throw new Error(`package files missing ${f}`);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
test('compatibility baseline matches public package line', () => {
|
|
333
|
+
const pkg = JSON.parse(read('package.json'));
|
|
334
|
+
const manifest = JSON.parse(read('skillpp.manifest.json'));
|
|
335
|
+
const baselinePath = 'tests/compatibility/v0.1.0.json';
|
|
336
|
+
if (!existsSync(join(ROOT, baselinePath))) throw new Error(`missing ${baselinePath}`);
|
|
337
|
+
const baseline = JSON.parse(read(baselinePath));
|
|
338
|
+
if (baseline.major !== 0) throw new Error('baseline major must be 0');
|
|
339
|
+
if (pkg.version !== manifest.version) throw new Error('package and manifest versions diverged');
|
|
340
|
+
if (!read('COMPATIBILITY.md').includes(baselinePath)) throw new Error('COMPATIBILITY.md must name the active baseline');
|
|
341
|
+
});
|
|
342
|
+
test('GitHub Actions CI runs release checks', () => {
|
|
343
|
+
const ci = read('.github/workflows/ci.yml');
|
|
344
|
+
assertIncludes(ci, ['npm test', 'npm run validate', 'npm run compatibility', 'npm pack --dry-run'], 'CI');
|
|
345
|
+
assertIncludes(ci, ['actions/checkout@v6', 'actions/setup-node@v6'], 'CI actions');
|
|
346
|
+
});
|
|
347
|
+
test('runtime avoids shell-quoted JSON params', () => {
|
|
348
|
+
const s = read('scripts/skillpp.mjs');
|
|
349
|
+
if (s.includes('execSync' + '(cmdLine')) throw new Error('runtime still uses shell command string');
|
|
350
|
+
if (!s.includes('spawnSync')) throw new Error('runtime should use spawnSync argv');
|
|
351
|
+
});
|
|
352
|
+
test('public CLI scripts use ASCII-visible output', () => {
|
|
353
|
+
for (const f of [
|
|
354
|
+
'scripts/skillpp.mjs',
|
|
355
|
+
'scripts/validate-skillpp.mjs',
|
|
356
|
+
'scripts/compatibility-check.mjs',
|
|
357
|
+
'skills/binance-web3/query-token-info/scripts/cli.mjs',
|
|
358
|
+
'skills/binance-web3/query-address-info/scripts/cli.mjs',
|
|
359
|
+
'skills/binance-web3/trading-signal/scripts/cli.mjs',
|
|
360
|
+
'skills/binance-web3/crypto-market-rank/scripts/cli.mjs',
|
|
361
|
+
'skills/binance-web3/meme-rush/scripts/cli.mjs',
|
|
362
|
+
]) {
|
|
363
|
+
const c = read(f);
|
|
364
|
+
if (/[^\x00-\x7F]/.test(c)) throw new Error(`${f}: non-ASCII runtime script text`);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
if (INTEGRATION) {
|
|
369
|
+
console.log('\n7. Integration');
|
|
370
|
+
test('analyze USDT on BSC dry-run route', () => {
|
|
371
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" analyze "0x55d398326f99059ff775485246999027b3197955" --dry-run`);
|
|
372
|
+
if (!out.includes('P_TOKEN_ANALYSIS')) throw new Error('wrong pipeline');
|
|
373
|
+
});
|
|
374
|
+
test('parse BSCScan URL', () => {
|
|
375
|
+
const out = run(`node "${join(ROOT, 'scripts/skillpp.mjs')}" parse "https://bscscan.com/address/0x1234567890abcdef1234567890abcdef12345678#code"`);
|
|
376
|
+
assertIncludes(out, ['explorer_url', 'BSC', 'sourceAvailable'], 'parse output');
|
|
377
|
+
});
|
|
378
|
+
} else {
|
|
379
|
+
console.log('\n7. Integration skipped (use --integration to enable)');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
console.log('\nResult');
|
|
383
|
+
console.log(`Passed: ${passed}, Failed: ${failed}, Skipped: ${skipped}`);
|
|
384
|
+
process.exit(failed > 0 ? 1 : 0);
|