soldnacloud 0.6.7
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/bootstrap/agents/dnacloud-installer.md +41 -0
- package/bootstrap/agents/dnacloud-market-researcher.md +44 -0
- package/bootstrap/commands/dna-create.md +69 -0
- package/bootstrap/commands/dna-earnings.md +21 -0
- package/bootstrap/commands/dna-install.md +24 -0
- package/bootstrap/commands/dna-packages.md +21 -0
- package/bootstrap/commands/dna-status.md +16 -0
- package/bootstrap/commands/dna-upload.md +26 -0
- package/bootstrap/commands/dna.md +19 -0
- package/bootstrap/skills/dnacloud/SKILL.md +178 -0
- package/dist/commands/creator.d.ts +10 -0
- package/dist/commands/creator.d.ts.map +1 -0
- package/dist/commands/creator.js +122 -0
- package/dist/commands/creator.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +114 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.d.ts +9 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +187 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/rollback.d.ts +6 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +34 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +42 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/upload.d.ts +11 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +174 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/verify.d.ts +4 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +57 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/installer/Installer.d.ts +21 -0
- package/dist/installer/Installer.d.ts.map +1 -0
- package/dist/installer/Installer.js +143 -0
- package/dist/installer/Installer.js.map +1 -0
- package/dist/installer/Rollback.d.ts +6 -0
- package/dist/installer/Rollback.d.ts.map +1 -0
- package/dist/installer/Rollback.js +43 -0
- package/dist/installer/Rollback.js.map +1 -0
- package/dist/installer/Verifier.d.ts +13 -0
- package/dist/installer/Verifier.d.ts.map +1 -0
- package/dist/installer/Verifier.js +114 -0
- package/dist/installer/Verifier.js.map +1 -0
- package/dist/installer/paths.d.ts +5 -0
- package/dist/installer/paths.d.ts.map +1 -0
- package/dist/installer/paths.js +5 -0
- package/dist/installer/paths.js.map +1 -0
- package/dist/marketplace/MarketplaceClient.d.ts +62 -0
- package/dist/marketplace/MarketplaceClient.d.ts.map +1 -0
- package/dist/marketplace/MarketplaceClient.js +72 -0
- package/dist/marketplace/MarketplaceClient.js.map +1 -0
- package/dist/marketplace/PaymentClient.d.ts +18 -0
- package/dist/marketplace/PaymentClient.d.ts.map +1 -0
- package/dist/marketplace/PaymentClient.js +45 -0
- package/dist/marketplace/PaymentClient.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { DNACLOUD_DIR, CLAUDE_DIR } from '../installer/paths.js';
|
|
6
|
+
export async function initCommand(options) {
|
|
7
|
+
console.log(chalk.bold('\nDNAcloud Bootstrap 初始化\n'));
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
// 如果已有 config.json,且未显式指定 --marketplace-url,则沿用已有配置的 URL
|
|
10
|
+
const existingConfigPath = path.join(cwd, DNACLOUD_DIR, 'config.json');
|
|
11
|
+
if (fs.existsSync(existingConfigPath)) {
|
|
12
|
+
try {
|
|
13
|
+
const existing = JSON.parse(fs.readFileSync(existingConfigPath, 'utf-8'));
|
|
14
|
+
if (existing.marketplaceUrl && options.marketplaceUrl === process.env.DNACLOUD_MARKETPLACE_URL) {
|
|
15
|
+
options = { ...options, marketplaceUrl: existing.marketplaceUrl };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch { }
|
|
19
|
+
}
|
|
20
|
+
const spin = ora('检查 Claude Code 项目结构...').start();
|
|
21
|
+
const claudeDir = path.join(cwd, CLAUDE_DIR);
|
|
22
|
+
const dnaDir = path.join(cwd, DNACLOUD_DIR);
|
|
23
|
+
if (!fs.existsSync(claudeDir)) {
|
|
24
|
+
spin.warn('.claude/ 目录不存在,将创建');
|
|
25
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
spin.text = '创建 DNAcloud 目录结构...';
|
|
28
|
+
const dirs = [
|
|
29
|
+
path.join(dnaDir),
|
|
30
|
+
path.join(dnaDir, 'installed'),
|
|
31
|
+
path.join(dnaDir, 'snapshots'),
|
|
32
|
+
path.join(claudeDir, 'skills', 'dnacloud'),
|
|
33
|
+
path.join(claudeDir, 'agents'),
|
|
34
|
+
path.join(claudeDir, 'commands'),
|
|
35
|
+
];
|
|
36
|
+
for (const d of dirs) {
|
|
37
|
+
fs.mkdirSync(d, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
spin.text = '注册 dnacloud-marketplace MCP server...';
|
|
40
|
+
const mcpJsonPath = path.join(cwd, '.mcp.json');
|
|
41
|
+
const mcpConfig = fs.existsSync(mcpJsonPath)
|
|
42
|
+
? JSON.parse(fs.readFileSync(mcpJsonPath, 'utf-8'))
|
|
43
|
+
: {};
|
|
44
|
+
const servers = mcpConfig.mcpServers ?? {};
|
|
45
|
+
// 优先使用本地构建的 MCP server(本地开发/hackathon 场景)
|
|
46
|
+
const localMcpPath = path.resolve(import.meta.dirname, '../../../mcp-server/dist/index.js');
|
|
47
|
+
const mcpEntry = fs.existsSync(localMcpPath)
|
|
48
|
+
? { command: 'node', args: [localMcpPath], env: { DNACLOUD_MARKETPLACE_URL: options.marketplaceUrl } }
|
|
49
|
+
: { command: 'npx', args: ['-y', '@dnacloud/mcp-server'], env: { DNACLOUD_MARKETPLACE_URL: options.marketplaceUrl } };
|
|
50
|
+
servers['dnacloud-marketplace'] = mcpEntry;
|
|
51
|
+
mcpConfig.mcpServers = servers;
|
|
52
|
+
fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2) + '\n');
|
|
53
|
+
spin.text = '写入 DNAcloud 配置...';
|
|
54
|
+
const config = {
|
|
55
|
+
version: '1',
|
|
56
|
+
marketplaceUrl: options.marketplaceUrl,
|
|
57
|
+
initializedAt: new Date().toISOString(),
|
|
58
|
+
};
|
|
59
|
+
fs.writeFileSync(path.join(dnaDir, 'config.json'), JSON.stringify(config, null, 2) + '\n');
|
|
60
|
+
const sources = {
|
|
61
|
+
version: '1',
|
|
62
|
+
sources: [
|
|
63
|
+
{ id: 'marketplace', type: 'marketplace', url: options.marketplaceUrl, enabled: true },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
fs.writeFileSync(path.join(dnaDir, 'sources.json'), JSON.stringify(sources, null, 2) + '\n');
|
|
67
|
+
const lockFile = { version: '1', installed: {} };
|
|
68
|
+
const lockPath = path.join(dnaDir, 'lock.json');
|
|
69
|
+
if (!fs.existsSync(lockPath)) {
|
|
70
|
+
fs.writeFileSync(lockPath, JSON.stringify(lockFile, null, 2) + '\n');
|
|
71
|
+
}
|
|
72
|
+
spin.text = '安装 Bootstrap skill 文件...';
|
|
73
|
+
// 优先顺序:
|
|
74
|
+
// 1. npm 包内置 bootstrap/(生产:npm install -g @dnacloud/cli)
|
|
75
|
+
// 2. 本地 repo 的 dna-packages/bootstrap/.claude(开发模式)
|
|
76
|
+
const npmBuiltinBootstrap = path.resolve(import.meta.dirname, '../../bootstrap');
|
|
77
|
+
const repoBootstrap = path.resolve(import.meta.dirname, '../../../../dna-packages/bootstrap/.claude');
|
|
78
|
+
const bootstrapSrc = fs.existsSync(npmBuiltinBootstrap)
|
|
79
|
+
? npmBuiltinBootstrap
|
|
80
|
+
: fs.existsSync(repoBootstrap)
|
|
81
|
+
? repoBootstrap
|
|
82
|
+
: null;
|
|
83
|
+
if (bootstrapSrc) {
|
|
84
|
+
copyDir(bootstrapSrc, claudeDir);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
spin.warn('Bootstrap 文件未找到,跳过 skill/command 安装。请确认 CLI 已正确安装。');
|
|
88
|
+
}
|
|
89
|
+
spin.succeed('DNAcloud Bootstrap 初始化完成!');
|
|
90
|
+
console.log('\n' + chalk.green('✓') + ' DNAcloud Bootstrap 已安装到当前项目');
|
|
91
|
+
console.log(chalk.gray(' .dnacloud/config.json — DNAcloud 配置'));
|
|
92
|
+
console.log(chalk.gray(' .claude/skills/dnacloud/ — DNAcloud skill'));
|
|
93
|
+
console.log(chalk.gray(' .claude/agents/ — DNAcloud installer agent'));
|
|
94
|
+
console.log(chalk.gray(' .claude/commands/ — dna, dna-install, dna-status 命令'));
|
|
95
|
+
console.log('\n' + chalk.bold('现在你可以在 Claude Code 中说:'));
|
|
96
|
+
console.log(chalk.cyan(' "我要一个交易大师"'));
|
|
97
|
+
console.log(chalk.cyan(' "搜索 DNA marketplace"'));
|
|
98
|
+
console.log(chalk.cyan(' "/dna trading"') + '\n');
|
|
99
|
+
}
|
|
100
|
+
function copyDir(src, dest) {
|
|
101
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
102
|
+
for (const entry of entries) {
|
|
103
|
+
const srcPath = path.join(src, entry.name);
|
|
104
|
+
const destPath = path.join(dest, entry.name);
|
|
105
|
+
if (entry.isDirectory()) {
|
|
106
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
107
|
+
copyDir(srcPath, destPath);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
fs.copyFileSync(srcPath, destPath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface InstallOptions {
|
|
2
|
+
version: string;
|
|
3
|
+
marketplaceUrl: string;
|
|
4
|
+
yes?: boolean;
|
|
5
|
+
txHash?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function installCommand(packageId: string, options: InstallOptions): Promise<void>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAUA,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA0K9F"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import readline from 'node:readline';
|
|
6
|
+
import { MarketplaceClient, buildSolanaPaymentCredential } from '../marketplace/MarketplaceClient.js';
|
|
7
|
+
import { buildOnchainOsCommand } from '../marketplace/PaymentClient.js';
|
|
8
|
+
import { Installer } from '../installer/Installer.js';
|
|
9
|
+
import { Verifier } from '../installer/Verifier.js';
|
|
10
|
+
export async function installCommand(packageId, options) {
|
|
11
|
+
console.log(chalk.bold(`\nDNAcloud — 安装 ${packageId}\n`));
|
|
12
|
+
const marketplaceClient = new MarketplaceClient({ baseUrl: options.marketplaceUrl });
|
|
13
|
+
const spin = ora(`从 marketplace 获取 ${packageId} 信息...`).start();
|
|
14
|
+
let manifest;
|
|
15
|
+
try {
|
|
16
|
+
manifest = await marketplaceClient.getManifest(packageId);
|
|
17
|
+
spin.succeed(`找到: ${manifest.name} v${manifest.version}`);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
spin.fail(`获取包信息失败: ${err.message}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
console.log('\n' + chalk.bold('包信息:'));
|
|
24
|
+
console.log(` 名称: ${manifest.name}`);
|
|
25
|
+
console.log(` 版本: ${manifest.version}`);
|
|
26
|
+
console.log(` 类型: ${manifest.packageType}`);
|
|
27
|
+
console.log(` 目标: ${manifest.objective}`);
|
|
28
|
+
console.log(` 价格: ${manifest.price.amount} ${manifest.price.currency} (${manifest.price.network})`);
|
|
29
|
+
console.log(` 能力: ${manifest.capabilities.join(', ')}`);
|
|
30
|
+
console.log(` 不承诺: ${manifest.notGuaranteed.join(', ')}`);
|
|
31
|
+
const confirmed = options.yes || await confirm('\n确认购买并安装?(y/N) ');
|
|
32
|
+
if (!confirmed) {
|
|
33
|
+
console.log(chalk.yellow('已取消。'));
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
const version = options.version === 'latest' ? manifest.version : options.version;
|
|
37
|
+
// ── Step 1: Request artifact (triggers 402 if payment needed) ────────────
|
|
38
|
+
spin.start('请求 artifact...');
|
|
39
|
+
const probe = await marketplaceClient.requestArtifact(packageId, version);
|
|
40
|
+
let artifactData;
|
|
41
|
+
if (probe.type === 'success') {
|
|
42
|
+
spin.succeed('无需支付,artifact 已获取');
|
|
43
|
+
artifactData = probe.data;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Payment required — Solana USDC
|
|
47
|
+
spin.stop();
|
|
48
|
+
const req = probe.requirement;
|
|
49
|
+
console.log('\n' + chalk.bold('💳 需要支付:'));
|
|
50
|
+
console.log(` 金额: ${chalk.yellow(req.amount_display)}`);
|
|
51
|
+
console.log(` 网络: ${req.network}`);
|
|
52
|
+
console.log(` 收款方: ${req.payTo}`);
|
|
53
|
+
console.log(` 资产: USDC (${req.mint})`);
|
|
54
|
+
// ── Step 2: Get txHash ────────────────────────────────────────────────
|
|
55
|
+
let txHash = options.txHash?.trim() ?? '';
|
|
56
|
+
if (!txHash) {
|
|
57
|
+
// Check if running inside Claude Code with OnchainOS Agentic Wallet
|
|
58
|
+
const isAgentMode = process.env.ONCHAINOS_AGENT === 'true';
|
|
59
|
+
console.log('\n' + chalk.bold('支付方式 A — OKX OnchainOS Agentic Wallet(推荐):'));
|
|
60
|
+
console.log(chalk.cyan(' ' + buildOnchainOsCommand(req).replace(/\n/g, '\n ')));
|
|
61
|
+
console.log('\n' + chalk.bold('支付方式 B — 任意 Solana 钱包:'));
|
|
62
|
+
console.log(` 向地址 ${chalk.cyan(req.payTo)} 转账 ${chalk.yellow(req.amount_display)}`);
|
|
63
|
+
console.log(` 网络: ${req.network} Mint: ${req.mint}`);
|
|
64
|
+
if (isAgentMode) {
|
|
65
|
+
console.log(chalk.yellow('\n正在 Claude Code Agent 环境中,请由 Skill 完成支付...'));
|
|
66
|
+
process.exit(2); // Signal to Skill to handle payment
|
|
67
|
+
}
|
|
68
|
+
console.log('');
|
|
69
|
+
txHash = await promptInput('请输入转账 txHash(Solana tx signature):');
|
|
70
|
+
if (!txHash.trim()) {
|
|
71
|
+
console.log(chalk.yellow('未提供 txHash,安装已取消。'));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const payerAddress = process.env.SOLANA_PAYER_ADDRESS ?? 'unknown';
|
|
76
|
+
const credential = buildSolanaPaymentCredential({
|
|
77
|
+
txHash: txHash.trim(),
|
|
78
|
+
nonce: req.nonce,
|
|
79
|
+
network: req.network,
|
|
80
|
+
payer: payerAddress,
|
|
81
|
+
});
|
|
82
|
+
// ── Step 3: Retry with payment credential ────────────────────────────
|
|
83
|
+
const verifySpinner = ora('链上支付验证中(Solana RPC)...').start();
|
|
84
|
+
try {
|
|
85
|
+
artifactData = await marketplaceClient.getArtifactWithPayment(packageId, version, credential);
|
|
86
|
+
const txHashShort = txHash.slice(0, 12) + '...';
|
|
87
|
+
verifySpinner.succeed(`支付已验证 tx: ${chalk.green(txHashShort)}`);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
verifySpinner.fail(`支付验证失败: ${err.message}`);
|
|
91
|
+
console.log(chalk.yellow('\n提示:请确认转账已在链上确认(devnet 约需 2-5 秒),然后重试:'));
|
|
92
|
+
console.log(chalk.cyan(` dnacloud install ${packageId} --tx-hash ${txHash}`));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ── Step 4: Download and install ─────────────────────────────────────────
|
|
97
|
+
const tmpZip = path.join(process.cwd(), '.dnacloud', 'staging', `${packageId}-${version}.zip`);
|
|
98
|
+
fs.mkdirSync(path.dirname(tmpZip), { recursive: true });
|
|
99
|
+
const zipResponse = await fetch(artifactData.downloadUrl);
|
|
100
|
+
const buffer = Buffer.from(await zipResponse.arrayBuffer());
|
|
101
|
+
fs.writeFileSync(tmpZip, buffer);
|
|
102
|
+
const installer = new Installer(process.cwd());
|
|
103
|
+
const planPath = path.join(process.cwd(), '.dnacloud', 'staging', 'install-plan.json');
|
|
104
|
+
if (fs.existsSync(planPath)) {
|
|
105
|
+
const plan = JSON.parse(fs.readFileSync(planPath, 'utf-8'));
|
|
106
|
+
const preview = installer.generatePreview(plan);
|
|
107
|
+
console.log('\n' + chalk.bold('安装预览(将写入以下文件):'));
|
|
108
|
+
for (const op of preview.operations) {
|
|
109
|
+
console.log(` ${chalk.green('+')} ${op.destination} ${chalk.gray(op.description)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const confirmInstall = options.yes || await confirm('\n确认安装到当前项目?(y/N) ');
|
|
113
|
+
if (!confirmInstall) {
|
|
114
|
+
fs.rmSync(tmpZip, { force: true });
|
|
115
|
+
console.log(chalk.yellow('已取消。Artifact 已清理。'));
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
spin.start('安装中...');
|
|
119
|
+
try {
|
|
120
|
+
await installer.install(artifactData, tmpZip);
|
|
121
|
+
spin.succeed('安装完成');
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
spin.fail(`安装失败: ${err.message}`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
spin.start('验证安装...');
|
|
128
|
+
const verifier = new Verifier(process.cwd());
|
|
129
|
+
const verifyResult = verifier.verify(packageId);
|
|
130
|
+
if (verifyResult.status === 'active') {
|
|
131
|
+
spin.succeed(`验证通过 — 状态: ${chalk.green('active')}`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
spin.warn(`验证结果: ${chalk.yellow(verifyResult.status)}`);
|
|
135
|
+
}
|
|
136
|
+
console.log('\n' + chalk.bold('安装结果:'));
|
|
137
|
+
console.log(` 状态: ${badge(verifyResult.status)}`);
|
|
138
|
+
console.log(` Skills: ${tick(verifyResult.skillsInstalled)}`);
|
|
139
|
+
console.log(` Agents: ${tick(verifyResult.agentsInstalled)}`);
|
|
140
|
+
console.log(` Commands: ${tick(verifyResult.commandsInstalled)}`);
|
|
141
|
+
console.log(` MCP 配置: ${tick(verifyResult.mcpConfigured)}`);
|
|
142
|
+
console.log(` Hooks 配置: ${tick(verifyResult.hooksConfigured)}`);
|
|
143
|
+
console.log(` 真实交易就绪: ${tick(verifyResult.liveTradingReady)}`);
|
|
144
|
+
if (verifyResult.missingUserConfig.length > 0) {
|
|
145
|
+
console.log('\n' + chalk.yellow('⚠️ 需要配置以下环境变量才能进行真实交易:'));
|
|
146
|
+
for (const key of verifyResult.missingUserConfig) {
|
|
147
|
+
console.log(` export ${key}=<your-value>`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (verifyResult.capabilitiesAvailable.length > 0) {
|
|
151
|
+
console.log('\n' + chalk.green('✓') + ' 现在你可以在 Claude Code 中使用:');
|
|
152
|
+
console.log(' /trade-plan 制定交易计划');
|
|
153
|
+
console.log(' /risk-check 风险检查');
|
|
154
|
+
console.log(' /order-preview 订单预览');
|
|
155
|
+
console.log(' /portfolio-status 查看持仓');
|
|
156
|
+
console.log(' /daily-trade-review 日终复盘\n');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function confirm(question) {
|
|
160
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
161
|
+
return new Promise((resolve) => {
|
|
162
|
+
rl.question(question, (answer) => {
|
|
163
|
+
rl.close();
|
|
164
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async function promptInput(question) {
|
|
169
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
170
|
+
return new Promise((resolve) => {
|
|
171
|
+
rl.question(question, (answer) => {
|
|
172
|
+
rl.close();
|
|
173
|
+
resolve(answer.trim());
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function tick(v) {
|
|
178
|
+
return v ? chalk.green('✓') : chalk.red('✗');
|
|
179
|
+
}
|
|
180
|
+
function badge(status) {
|
|
181
|
+
if (status === 'active')
|
|
182
|
+
return chalk.green(status);
|
|
183
|
+
if (status === 'partial')
|
|
184
|
+
return chalk.yellow(status);
|
|
185
|
+
return chalk.red(status);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAKA,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import readline from 'node:readline';
|
|
4
|
+
import { Rollback } from '../installer/Rollback.js';
|
|
5
|
+
export async function rollbackCommand(packageId, options) {
|
|
6
|
+
console.log(chalk.bold(`\ndnacloud rollback — ${packageId}\n`));
|
|
7
|
+
console.log(chalk.yellow('⚠️ 警告:此操作将从当前项目中移除该 DNA 包的所有文件。'));
|
|
8
|
+
const confirmed = await confirm('确认回滚?(y/N) ');
|
|
9
|
+
if (!confirmed) {
|
|
10
|
+
console.log(chalk.gray('已取消。'));
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
const spin = ora(`正在回滚 ${packageId}...`).start();
|
|
14
|
+
const rollback = new Rollback(process.cwd());
|
|
15
|
+
try {
|
|
16
|
+
rollback.rollback(packageId);
|
|
17
|
+
spin.succeed(`${packageId} 已成功回滚`);
|
|
18
|
+
console.log(chalk.green('\n✓ 回滚完成。相关文件已移除,lock.json 已更新。\n'));
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
spin.fail(`回滚失败: ${err.message}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function confirm(question) {
|
|
26
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
rl.question(question, (answer) => {
|
|
29
|
+
rl.close();
|
|
30
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=rollback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAMpD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,OAAwB;IAC/E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,SAAS,IAAI,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAE9D,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,SAAS,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,SAAU,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,QAAgB;IACrC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAOA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CnD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { Verifier } from '../installer/Verifier.js';
|
|
5
|
+
import { LOCK_FILE } from '../installer/paths.js';
|
|
6
|
+
export async function statusCommand() {
|
|
7
|
+
console.log(chalk.bold('\ndnacloud status\n'));
|
|
8
|
+
const lockPath = path.join(process.cwd(), LOCK_FILE);
|
|
9
|
+
if (!fs.existsSync(lockPath)) {
|
|
10
|
+
console.log(chalk.gray('未找到安装记录。运行 dnacloud init 初始化,或 dnacloud install <packageId> 安装包。\n'));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
14
|
+
const installed = Object.keys(lock.installed);
|
|
15
|
+
if (installed.length === 0) {
|
|
16
|
+
console.log(chalk.gray('未安装任何 DNA 包。运行 dnacloud install <packageId> 安装。\n'));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const verifier = new Verifier(process.cwd());
|
|
20
|
+
console.log(`已安装 ${installed.length} 个 DNA 包:\n`);
|
|
21
|
+
for (const packageId of installed) {
|
|
22
|
+
const entry = lock.installed[packageId];
|
|
23
|
+
const result = verifier.verify(packageId);
|
|
24
|
+
const statusBadge = result.status === 'active'
|
|
25
|
+
? chalk.green('● active')
|
|
26
|
+
: result.status === 'partial'
|
|
27
|
+
? chalk.yellow('◐ partial')
|
|
28
|
+
: chalk.red('✗ failed');
|
|
29
|
+
const liveTrading = result.liveTradingReady
|
|
30
|
+
? chalk.green('真实交易: 就绪')
|
|
31
|
+
: chalk.yellow(`真实交易: 未就绪 (${result.missingUserConfig.length} 项配置缺失)`);
|
|
32
|
+
console.log(` ${statusBadge} ${chalk.bold(packageId)} v${entry.version}`);
|
|
33
|
+
console.log(` 安装时间: ${entry.installedAt}`);
|
|
34
|
+
console.log(` ${liveTrading}`);
|
|
35
|
+
if (result.missingUserConfig.length > 0) {
|
|
36
|
+
console.log(` 缺失: ${result.missingUserConfig.join(', ')}`);
|
|
37
|
+
}
|
|
38
|
+
console.log('');
|
|
39
|
+
}
|
|
40
|
+
console.log(chalk.gray('运行 dnacloud verify <packageId> 查看详细验证结果。'));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC,CAAC;QAC9F,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAgB,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE9C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAC,OAAO,SAAS,CAAC,MAAM,aAAa,CAAC,CAAC;IAClD,KAAK,MAAM,SAAS,IAAI,SAAS,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE1C,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,QAAQ;YAC5C,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;gBAC7B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;gBAC3B,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE1B,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB;YACzC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;YACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,MAAM,CAAC,iBAAiB,CAAC,MAAM,SAAS,CAAC,CAAC;QAEzE,OAAO,CAAC,GAAG,CAAC,KAAK,WAAW,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;QAE5C,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface UploadOptions {
|
|
2
|
+
payoutAddress: string;
|
|
3
|
+
price?: string;
|
|
4
|
+
currency?: string;
|
|
5
|
+
category?: string;
|
|
6
|
+
marketplaceUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function uploadCommand(packagePath: string, options: UploadOptions): Promise<void>;
|
|
9
|
+
export declare function validateLocalPackage(packagePath: string): Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AASA,UAAU,aAAa;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqG9F;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C7E"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import crypto from 'node:crypto';
|
|
6
|
+
import { createReadStream } from 'node:fs';
|
|
7
|
+
import { DNACLOUD_DIR } from '../installer/paths.js';
|
|
8
|
+
export async function uploadCommand(packagePath, options) {
|
|
9
|
+
const spin = ora('准备上传 DNA 包...').start();
|
|
10
|
+
const absPath = path.resolve(packagePath);
|
|
11
|
+
if (!fs.existsSync(absPath)) {
|
|
12
|
+
spin.fail(`包文件不存在: ${absPath}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
const configPath = path.join(cwd, DNACLOUD_DIR, 'config.json');
|
|
17
|
+
if (!fs.existsSync(configPath)) {
|
|
18
|
+
spin.fail(`未初始化 DNAcloud,请先在目标目录运行: dnacloud init\n 当前目录: ${cwd}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
22
|
+
const baseUrl = options.marketplaceUrl ?? config.marketplaceUrl ?? 'http://localhost:8080';
|
|
23
|
+
// 计算包 hash
|
|
24
|
+
spin.text = '计算包 SHA256...';
|
|
25
|
+
const packageHash = await computeFileSha256(absPath);
|
|
26
|
+
// 请求上传会话
|
|
27
|
+
spin.text = '请求上传会话...';
|
|
28
|
+
let session;
|
|
29
|
+
try {
|
|
30
|
+
const res = await fetch(`${baseUrl}/v1/creator/upload-session`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: { 'Content-Type': 'application/json' },
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
payout_address: options.payoutAddress,
|
|
35
|
+
package_hash: packageHash,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const err = await res.text();
|
|
40
|
+
spin.fail(`创建上传会话失败: ${res.status} ${err}`);
|
|
41
|
+
if (res.status === 405) {
|
|
42
|
+
console.log(chalk.yellow(' 提示:URL 路径可能缺少 /api,完整地址示例:https://finderfund.cn/dna/api'));
|
|
43
|
+
}
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
session = await res.json();
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
spin.fail(`无法连接到 DNAcloud 服务器: ${e instanceof Error ? e.message : e}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
spin.succeed(`上传会话已创建,收款地址: ${options.payoutAddress}`);
|
|
53
|
+
const uploadSpin = ora('上传 DNA 包到 DNAcloud...').start();
|
|
54
|
+
try {
|
|
55
|
+
const formData = new FormData();
|
|
56
|
+
const fileContent = fs.readFileSync(absPath);
|
|
57
|
+
formData.append('package', new Blob([fileContent], { type: 'application/zip' }), path.basename(absPath));
|
|
58
|
+
formData.append('upload_session_id', session.upload_session_id);
|
|
59
|
+
formData.append('payout_signature', 'none');
|
|
60
|
+
if (options.price)
|
|
61
|
+
formData.append('price', options.price);
|
|
62
|
+
if (options.currency)
|
|
63
|
+
formData.append('currency', options.currency);
|
|
64
|
+
if (options.category)
|
|
65
|
+
formData.append('category', options.category);
|
|
66
|
+
const res = await fetch(`${baseUrl}/v1/creator/packages/upload`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
body: formData,
|
|
69
|
+
});
|
|
70
|
+
const result = await res.json();
|
|
71
|
+
if (!res.ok) {
|
|
72
|
+
uploadSpin.fail(`上传失败: ${res.status} — ${result.error ?? JSON.stringify(result)}`);
|
|
73
|
+
printValidationReport(result.validation_report);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
if (result.validation_result === 'failed') {
|
|
77
|
+
uploadSpin.fail(`校验失败: ${result.status}`);
|
|
78
|
+
printValidationReport(result.validation_report);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
uploadSpin.succeed('DNA 包上传成功!');
|
|
82
|
+
console.log('');
|
|
83
|
+
console.log(chalk.green('✓') + ' 包已发布到 DNAcloud');
|
|
84
|
+
console.log(chalk.gray(` Package ID: ${result.package_id}`));
|
|
85
|
+
console.log(chalk.gray(` Status: ${result.status}`));
|
|
86
|
+
console.log(chalk.gray(` Validation: ${result.validation_result}`));
|
|
87
|
+
console.log(chalk.gray(` Marketplace URL: ${result.marketplace_url}`));
|
|
88
|
+
if (result.validation_report?.warnings?.length) {
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(chalk.yellow('⚠️ 校验警告:'));
|
|
91
|
+
for (const w of result.validation_report.warnings) {
|
|
92
|
+
console.log(chalk.yellow(` [${w.code}] ${w.message}`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
uploadSpin.fail(`上传异常: ${e instanceof Error ? e.message : e}`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function validateLocalPackage(packagePath) {
|
|
102
|
+
const spin = ora('验证 DNA 包结构...').start();
|
|
103
|
+
const absPath = path.resolve(packagePath);
|
|
104
|
+
if (!fs.existsSync(absPath)) {
|
|
105
|
+
spin.fail(`包文件不存在: ${absPath}`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
// 本地解压并验证
|
|
110
|
+
const { validateExtractedPackage } = await import('@dnacloud/validator');
|
|
111
|
+
const tmpDir = `/tmp/dnacloud-validate-${Date.now()}`;
|
|
112
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
113
|
+
// 解压 zip
|
|
114
|
+
const { execSync } = await import('node:child_process');
|
|
115
|
+
execSync(`unzip -q "${absPath}" -d "${tmpDir}"`, { stdio: 'pipe' });
|
|
116
|
+
const report = validateExtractedPackage(tmpDir, { requirePayout: true });
|
|
117
|
+
// 清理
|
|
118
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
119
|
+
if (report.result === 'failed') {
|
|
120
|
+
spin.fail(`校验失败 (score: ${report.score})`);
|
|
121
|
+
const hasMissingManifest = report.errors.some(e => e.code === 'MISSING_MANIFEST');
|
|
122
|
+
if (hasMissingManifest) {
|
|
123
|
+
console.log('');
|
|
124
|
+
console.log(chalk.yellow('提示:manifest.json 必须位于 zip 根目录,请使用以下方式打包:'));
|
|
125
|
+
console.log(chalk.cyan(' cd <package-dir> && zip -r ../<package>.zip .'));
|
|
126
|
+
console.log(chalk.red(' ✗ 错误方式:zip -r <package>.zip <package-dir>/'));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (report.result === 'passed_with_warnings') {
|
|
130
|
+
spin.warn(`校验通过(有警告)(score: ${report.score})`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
spin.succeed(`校验通过 (score: ${report.score})`);
|
|
134
|
+
}
|
|
135
|
+
printValidationReport(report);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
spin.fail(`校验异常: ${e instanceof Error ? e.message : e}`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function printValidationReport(report) {
|
|
143
|
+
if (!report)
|
|
144
|
+
return;
|
|
145
|
+
if (report.errors.length > 0) {
|
|
146
|
+
console.log('');
|
|
147
|
+
console.log(chalk.red('✗ 错误:'));
|
|
148
|
+
for (const err of report.errors) {
|
|
149
|
+
console.log(chalk.red(` [${err.code}] ${err.message}${err.file ? ` (${err.file})` : ''}`));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (report.warnings.length > 0) {
|
|
153
|
+
console.log('');
|
|
154
|
+
console.log(chalk.yellow('⚠ 警告:'));
|
|
155
|
+
for (const w of report.warnings) {
|
|
156
|
+
console.log(chalk.yellow(` [${w.code}] ${w.message}${w.file ? ` (${w.file})` : ''}`));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (report.capabilities) {
|
|
160
|
+
console.log('');
|
|
161
|
+
console.log(chalk.gray(' Capabilities:'));
|
|
162
|
+
console.log(chalk.gray(` Skills: ${report.capabilities.skills} | Agents: ${report.capabilities.agents} | Commands: ${report.capabilities.commands} | MCP: ${report.capabilities.mcp} | Hooks: ${report.capabilities.hooks}`));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function computeFileSha256(filePath) {
|
|
166
|
+
return new Promise((resolve, reject) => {
|
|
167
|
+
const hash = crypto.createHash('sha256');
|
|
168
|
+
const stream = createReadStream(filePath);
|
|
169
|
+
stream.on('data', chunk => hash.update(chunk));
|
|
170
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
171
|
+
stream.on('error', reject);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=upload.js.map
|