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.
Files changed (67) hide show
  1. package/bootstrap/agents/dnacloud-installer.md +41 -0
  2. package/bootstrap/agents/dnacloud-market-researcher.md +44 -0
  3. package/bootstrap/commands/dna-create.md +69 -0
  4. package/bootstrap/commands/dna-earnings.md +21 -0
  5. package/bootstrap/commands/dna-install.md +24 -0
  6. package/bootstrap/commands/dna-packages.md +21 -0
  7. package/bootstrap/commands/dna-status.md +16 -0
  8. package/bootstrap/commands/dna-upload.md +26 -0
  9. package/bootstrap/commands/dna.md +19 -0
  10. package/bootstrap/skills/dnacloud/SKILL.md +178 -0
  11. package/dist/commands/creator.d.ts +10 -0
  12. package/dist/commands/creator.d.ts.map +1 -0
  13. package/dist/commands/creator.js +122 -0
  14. package/dist/commands/creator.js.map +1 -0
  15. package/dist/commands/init.d.ts +6 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +114 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/install.d.ts +9 -0
  20. package/dist/commands/install.d.ts.map +1 -0
  21. package/dist/commands/install.js +187 -0
  22. package/dist/commands/install.js.map +1 -0
  23. package/dist/commands/rollback.d.ts +6 -0
  24. package/dist/commands/rollback.d.ts.map +1 -0
  25. package/dist/commands/rollback.js +34 -0
  26. package/dist/commands/rollback.js.map +1 -0
  27. package/dist/commands/status.d.ts +2 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +42 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/commands/upload.d.ts +11 -0
  32. package/dist/commands/upload.d.ts.map +1 -0
  33. package/dist/commands/upload.js +174 -0
  34. package/dist/commands/upload.js.map +1 -0
  35. package/dist/commands/verify.d.ts +4 -0
  36. package/dist/commands/verify.d.ts.map +1 -0
  37. package/dist/commands/verify.js +57 -0
  38. package/dist/commands/verify.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +84 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/installer/Installer.d.ts +21 -0
  44. package/dist/installer/Installer.d.ts.map +1 -0
  45. package/dist/installer/Installer.js +143 -0
  46. package/dist/installer/Installer.js.map +1 -0
  47. package/dist/installer/Rollback.d.ts +6 -0
  48. package/dist/installer/Rollback.d.ts.map +1 -0
  49. package/dist/installer/Rollback.js +43 -0
  50. package/dist/installer/Rollback.js.map +1 -0
  51. package/dist/installer/Verifier.d.ts +13 -0
  52. package/dist/installer/Verifier.d.ts.map +1 -0
  53. package/dist/installer/Verifier.js +114 -0
  54. package/dist/installer/Verifier.js.map +1 -0
  55. package/dist/installer/paths.d.ts +5 -0
  56. package/dist/installer/paths.d.ts.map +1 -0
  57. package/dist/installer/paths.js +5 -0
  58. package/dist/installer/paths.js.map +1 -0
  59. package/dist/marketplace/MarketplaceClient.d.ts +62 -0
  60. package/dist/marketplace/MarketplaceClient.d.ts.map +1 -0
  61. package/dist/marketplace/MarketplaceClient.js +72 -0
  62. package/dist/marketplace/MarketplaceClient.js.map +1 -0
  63. package/dist/marketplace/PaymentClient.d.ts +18 -0
  64. package/dist/marketplace/PaymentClient.d.ts.map +1 -0
  65. package/dist/marketplace/PaymentClient.js +45 -0
  66. package/dist/marketplace/PaymentClient.js.map +1 -0
  67. 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,6 @@
1
+ interface RollbackOptions {
2
+ version?: string;
3
+ }
4
+ export declare function rollbackCommand(packageId: string, options: RollbackOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=rollback.d.ts.map
@@ -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,2 @@
1
+ export declare function statusCommand(): Promise<void>;
2
+ //# sourceMappingURL=status.d.ts.map
@@ -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