agentvault 1.0.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/.dfx/local/network-id +4 -0
- package/.next/trace +2 -0
- package/.vercel/README.txt +11 -0
- package/.vercel/project.json +1 -0
- package/AGENTS.md +43 -0
- package/CHANGELOG.md +196 -0
- package/LICENSE +21 -0
- package/PLAN_VAULT_INTEGRATION.md +318 -0
- package/README.md +253 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T17-54-28-967Z.json +28 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T17-54-29-032Z.backup +1 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-373Z.json +28 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-428Z.backup +1 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-132Z.json +28 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-247Z.backup +1 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-216Z.json +28 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-283Z.backup +1 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-772Z.backup +1 -0
- package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-793Z.json +28 -0
- package/backups/test-backup.json +28 -0
- package/dist/cli/commands/approve.d.ts +4 -0
- package/dist/cli/commands/approve.js +232 -0
- package/dist/cli/commands/archive.d.ts +4 -0
- package/dist/cli/commands/archive.js +192 -0
- package/dist/cli/commands/backup.d.ts +4 -0
- package/dist/cli/commands/backup.js +164 -0
- package/dist/cli/commands/cloud-backup.d.ts +4 -0
- package/dist/cli/commands/cloud-backup.js +221 -0
- package/dist/cli/commands/cycles.d.ts +8 -0
- package/dist/cli/commands/cycles.js +83 -0
- package/dist/cli/commands/decrypt.d.ts +16 -0
- package/dist/cli/commands/decrypt.js +101 -0
- package/dist/cli/commands/deploy.d.ts +32 -0
- package/dist/cli/commands/deploy.js +208 -0
- package/dist/cli/commands/exec.d.ts +26 -0
- package/dist/cli/commands/exec.js +109 -0
- package/dist/cli/commands/fetch.d.ts +23 -0
- package/dist/cli/commands/fetch.js +164 -0
- package/dist/cli/commands/health.d.ts +8 -0
- package/dist/cli/commands/health.js +72 -0
- package/dist/cli/commands/identity.d.ts +8 -0
- package/dist/cli/commands/identity.js +140 -0
- package/dist/cli/commands/inference.d.ts +4 -0
- package/dist/cli/commands/inference.js +225 -0
- package/dist/cli/commands/info.d.ts +8 -0
- package/dist/cli/commands/info.js +59 -0
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.js +135 -0
- package/dist/cli/commands/instrument.d.ts +8 -0
- package/dist/cli/commands/instrument.js +35 -0
- package/dist/cli/commands/list.d.ts +36 -0
- package/dist/cli/commands/list.js +173 -0
- package/dist/cli/commands/logs.d.ts +8 -0
- package/dist/cli/commands/logs.js +96 -0
- package/dist/cli/commands/monitor.d.ts +8 -0
- package/dist/cli/commands/monitor.js +84 -0
- package/dist/cli/commands/network.d.ts +14 -0
- package/dist/cli/commands/network.js +258 -0
- package/dist/cli/commands/package.d.ts +36 -0
- package/dist/cli/commands/package.js +188 -0
- package/dist/cli/commands/profile.d.ts +8 -0
- package/dist/cli/commands/profile.js +76 -0
- package/dist/cli/commands/promote.d.ts +8 -0
- package/dist/cli/commands/promote.js +89 -0
- package/dist/cli/commands/rebuild.d.ts +21 -0
- package/dist/cli/commands/rebuild.js +140 -0
- package/dist/cli/commands/rollback.d.ts +8 -0
- package/dist/cli/commands/rollback.js +120 -0
- package/dist/cli/commands/show.d.ts +36 -0
- package/dist/cli/commands/show.js +200 -0
- package/dist/cli/commands/stats.d.ts +8 -0
- package/dist/cli/commands/stats.js +34 -0
- package/dist/cli/commands/status.d.ts +14 -0
- package/dist/cli/commands/status.js +83 -0
- package/dist/cli/commands/test.d.ts +8 -0
- package/dist/cli/commands/test.js +109 -0
- package/dist/cli/commands/tokens.d.ts +8 -0
- package/dist/cli/commands/tokens.js +62 -0
- package/dist/cli/commands/trace.d.ts +8 -0
- package/dist/cli/commands/trace.js +68 -0
- package/dist/cli/commands/wallet-export.d.ts +13 -0
- package/dist/cli/commands/wallet-export.js +140 -0
- package/dist/cli/commands/wallet-history.d.ts +10 -0
- package/dist/cli/commands/wallet-history.js +127 -0
- package/dist/cli/commands/wallet-import.d.ts +10 -0
- package/dist/cli/commands/wallet-import.js +209 -0
- package/dist/cli/commands/wallet-multi-send.d.ts +17 -0
- package/dist/cli/commands/wallet-multi-send.js +195 -0
- package/dist/cli/commands/wallet-process-queue.d.ts +19 -0
- package/dist/cli/commands/wallet-process-queue.js +209 -0
- package/dist/cli/commands/wallet-sign.d.ts +13 -0
- package/dist/cli/commands/wallet-sign.js +207 -0
- package/dist/cli/commands/wallet.d.ts +12 -0
- package/dist/cli/commands/wallet.js +794 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.js +96 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.js +14 -0
- package/fixup_1_0_OSS_release.md +136 -0
- package/fixup_REALEASE_PRD.md +136 -0
- package/package.json +79 -0
- package/pnpm-workspace.yaml +5 -0
- package/scripts/dev-dashboard.mjs +84 -0
- package/site/README.md +63 -0
- package/site/docusaurus.config.ts +148 -0
- package/site/package-lock.json +18383 -0
- package/site/package.json +47 -0
- package/site/sidebars.ts +86 -0
- package/site/static/.gitkeep +0 -0
- package/site/static/img/logo.svg +28 -0
- package/site/static/img/og-image.svg +35 -0
- package/src/archival/archive-manager.ts +372 -0
- package/src/archival/arweave-client.ts +289 -0
- package/src/archival/index.ts +8 -0
- package/src/backup/backup.ts +315 -0
- package/src/backup/index.ts +7 -0
- package/src/cloud-storage/cloud-sync.ts +461 -0
- package/src/cloud-storage/index.ts +11 -0
- package/src/cloud-storage/provider-detector.ts +198 -0
- package/src/cloud-storage/types.ts +104 -0
- package/src/debugging/index.ts +6 -0
- package/src/debugging/logs.ts +193 -0
- package/src/debugging/types.ts +100 -0
- package/src/deployment/deployer.ts +274 -0
- package/src/deployment/icpClient.ts +620 -0
- package/src/deployment/index.ts +46 -0
- package/src/deployment/promotion.ts +161 -0
- package/src/deployment/types.ts +111 -0
- package/src/icp/batch.ts +374 -0
- package/src/icp/cycles.ts +50 -0
- package/src/icp/environment.ts +215 -0
- package/src/icp/icpcli.ts +438 -0
- package/src/icp/icwasm.ts +222 -0
- package/src/icp/identity.ts +77 -0
- package/src/icp/index.ts +94 -0
- package/src/icp/optimization.ts +242 -0
- package/src/icp/tokens.ts +36 -0
- package/src/icp/tool-detector.ts +110 -0
- package/src/icp/types.ts +574 -0
- package/src/index.ts +25 -0
- package/src/inference/bittensor-client.ts +304 -0
- package/src/inference/index.ts +8 -0
- package/src/inference/inference-manager.ts +327 -0
- package/src/metrics/index.ts +7 -0
- package/src/metrics/metrics.ts +186 -0
- package/src/monitoring/alerting.ts +190 -0
- package/src/monitoring/health.ts +197 -0
- package/src/monitoring/index.ts +38 -0
- package/src/monitoring/info.ts +114 -0
- package/src/monitoring/types.ts +99 -0
- package/src/network/index.ts +5 -0
- package/src/network/network-config.ts +129 -0
- package/src/packaging/compiler.ts +647 -0
- package/src/packaging/config-persistence.ts +135 -0
- package/src/packaging/config-schemas.ts +156 -0
- package/src/packaging/detector.ts +220 -0
- package/src/packaging/index.ts +90 -0
- package/src/packaging/packager.ts +118 -0
- package/src/packaging/parsers/clawdbot.ts +278 -0
- package/src/packaging/parsers/cline.ts +223 -0
- package/src/packaging/parsers/generic.ts +266 -0
- package/src/packaging/parsers/goose.ts +214 -0
- package/src/packaging/parsers/index.ts +11 -0
- package/src/packaging/serializer.ts +260 -0
- package/src/packaging/types.ts +144 -0
- package/src/packaging/wasmedge-compiler.ts +406 -0
- package/src/security/index.ts +17 -0
- package/src/security/multisig.ts +415 -0
- package/src/security/types.ts +416 -0
- package/src/security/vetkeys.ts +655 -0
- package/src/testing/index.ts +6 -0
- package/src/testing/local-runner.ts +264 -0
- package/src/testing/types.ts +104 -0
- package/src/wallet/cbor-serializer.ts +323 -0
- package/src/wallet/chain-dispatcher.ts +313 -0
- package/src/wallet/cross-chain-aggregator.ts +346 -0
- package/src/wallet/index.ts +76 -0
- package/src/wallet/key-derivation.ts +425 -0
- package/src/wallet/providers/base-provider.ts +154 -0
- package/src/wallet/providers/cketh-provider.ts +434 -0
- package/src/wallet/providers/polkadot-provider.ts +503 -0
- package/src/wallet/providers/solana-provider.ts +490 -0
- package/src/wallet/transaction-queue.ts +284 -0
- package/src/wallet/types.ts +178 -0
- package/src/wallet/vetkeys-adapter.ts +431 -0
- package/src/wallet/wallet-manager.ts +597 -0
- package/src/wallet/wallet-storage.ts +380 -0
- package/vercel.json +8 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { detectProviders, detectAvailableProviders, createCustomProvider, resolveCloudBackupDir, archiveToCloud, listCloudArchives, restoreFromCloud, verifyCloudArchive, } from '../../src/cloud-storage/index.js';
|
|
5
|
+
import { formatBackupSize } from '../../src/backup/index.js';
|
|
6
|
+
const cloudBackupCmd = new Command('cloud-backup');
|
|
7
|
+
cloudBackupCmd
|
|
8
|
+
.description('Archive and restore SoulRecall data using cloud storage (Google Drive, iCloud, Dropbox, etc.)')
|
|
9
|
+
.action(async () => {
|
|
10
|
+
console.log(chalk.yellow('Please specify a subcommand: providers, archive, restore, list, or verify'));
|
|
11
|
+
console.log(chalk.gray(`
|
|
12
|
+
Examples:
|
|
13
|
+
${chalk.cyan('soulrecall cloud-backup providers')} List detected cloud providers
|
|
14
|
+
${chalk.cyan('soulrecall cloud-backup archive --provider dropbox')} Archive vault to Dropbox
|
|
15
|
+
${chalk.cyan('soulrecall cloud-backup list --provider dropbox')} List archives in Dropbox
|
|
16
|
+
${chalk.cyan('soulrecall cloud-backup restore <archive-path>')} Restore from archive
|
|
17
|
+
${chalk.cyan('soulrecall cloud-backup verify <archive-path>')} Verify archive integrity`));
|
|
18
|
+
});
|
|
19
|
+
// --- providers ---
|
|
20
|
+
cloudBackupCmd
|
|
21
|
+
.command('providers')
|
|
22
|
+
.description('Detect available cloud storage providers on this machine')
|
|
23
|
+
.action(async () => {
|
|
24
|
+
const spinner = ora('Scanning for cloud storage providers...').start();
|
|
25
|
+
const providers = detectProviders();
|
|
26
|
+
spinner.stop();
|
|
27
|
+
const available = providers.filter((p) => p.available);
|
|
28
|
+
const unavailable = providers.filter((p) => !p.available);
|
|
29
|
+
if (available.length > 0) {
|
|
30
|
+
console.log(chalk.green(`Found ${available.length} available provider(s):\n`));
|
|
31
|
+
for (const p of available) {
|
|
32
|
+
console.log(` ${chalk.cyan(p.label)}`);
|
|
33
|
+
console.log(` Path: ${chalk.gray(p.path)}`);
|
|
34
|
+
console.log(` ID: ${chalk.gray(p.provider)}`);
|
|
35
|
+
console.log();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log(chalk.yellow('No cloud storage providers detected. Use --path to specify a custom directory.'));
|
|
40
|
+
}
|
|
41
|
+
if (unavailable.length > 0) {
|
|
42
|
+
console.log(chalk.gray('Not detected:'));
|
|
43
|
+
for (const p of unavailable) {
|
|
44
|
+
console.log(chalk.gray(` - ${p.label}`));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// --- archive ---
|
|
49
|
+
cloudBackupCmd
|
|
50
|
+
.command('archive')
|
|
51
|
+
.description('Archive SoulRecall data to a cloud storage provider')
|
|
52
|
+
.option('-p, --provider <name>', 'Cloud provider (google-drive, icloud-drive, dropbox, onedrive)')
|
|
53
|
+
.option('--path <directory>', 'Custom directory path (overrides --provider)')
|
|
54
|
+
.option('-a, --agent <name>', 'Archive a specific agent only')
|
|
55
|
+
.option('--no-configs', 'Exclude agent configurations')
|
|
56
|
+
.option('--no-wallets', 'Exclude wallet data')
|
|
57
|
+
.option('--no-backups', 'Exclude existing backups')
|
|
58
|
+
.option('--no-networks', 'Exclude network configurations')
|
|
59
|
+
.option('--subdirectory <name>', 'Subdirectory name inside provider', 'SoulRecall-Backups')
|
|
60
|
+
.action(async (options) => {
|
|
61
|
+
// Resolve provider path
|
|
62
|
+
let providerPath;
|
|
63
|
+
let providerLabel;
|
|
64
|
+
if (options.path) {
|
|
65
|
+
const custom = createCustomProvider(options.path);
|
|
66
|
+
providerPath = custom.path;
|
|
67
|
+
providerLabel = `Custom (${options.path})`;
|
|
68
|
+
}
|
|
69
|
+
else if (options.provider) {
|
|
70
|
+
const providers = detectProviders();
|
|
71
|
+
const match = providers.find((p) => p.provider === options.provider);
|
|
72
|
+
if (!match) {
|
|
73
|
+
console.error(chalk.red(`Unknown provider "${options.provider}". Use "soulrecall cloud-backup providers" to see available options.`));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (!match.available) {
|
|
78
|
+
console.error(chalk.red(match.label + ' is not available on this machine. Expected path: ' + match.path));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
providerPath = match.path;
|
|
83
|
+
providerLabel = match.label;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Auto-detect: use first available
|
|
87
|
+
const available = detectAvailableProviders();
|
|
88
|
+
if (available.length === 0) {
|
|
89
|
+
console.error(chalk.red('No cloud provider detected. Use --provider or --path to specify a destination.'));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const first = available[0];
|
|
94
|
+
providerPath = first.path;
|
|
95
|
+
providerLabel = first.label;
|
|
96
|
+
console.log(chalk.gray(`Auto-detected provider: ${providerLabel}`));
|
|
97
|
+
}
|
|
98
|
+
const spinner = ora(`Archiving to ${providerLabel}...`).start();
|
|
99
|
+
const result = archiveToCloud(providerPath, {
|
|
100
|
+
agentName: options.agent,
|
|
101
|
+
includeConfigs: options.configs !== false,
|
|
102
|
+
includeWallets: options.wallets !== false,
|
|
103
|
+
includeBackups: options.backups !== false,
|
|
104
|
+
includeNetworks: options.networks !== false,
|
|
105
|
+
}, options.subdirectory);
|
|
106
|
+
if (result.success) {
|
|
107
|
+
spinner.succeed(chalk.green(`Archive created in ${providerLabel}`));
|
|
108
|
+
console.log(chalk.gray(` Path: ${result.archivePath}`));
|
|
109
|
+
console.log(chalk.gray(` Files: ${result.fileCount} (${formatBackupSize(result.totalBytes || 0)})`));
|
|
110
|
+
console.log(chalk.gray('\nYour cloud provider will sync this automatically.'));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
spinner.fail(chalk.red('Archive failed'));
|
|
114
|
+
console.error(chalk.red(result.error || 'Unknown error'));
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
// --- list ---
|
|
119
|
+
cloudBackupCmd
|
|
120
|
+
.command('list')
|
|
121
|
+
.description('List available archives in a cloud storage directory')
|
|
122
|
+
.option('-p, --provider <name>', 'Cloud provider (google-drive, icloud-drive, dropbox, onedrive)')
|
|
123
|
+
.option('--path <directory>', 'Custom directory path')
|
|
124
|
+
.option('--subdirectory <name>', 'Subdirectory name inside provider', 'SoulRecall-Backups')
|
|
125
|
+
.action(async (options) => {
|
|
126
|
+
let providerPath;
|
|
127
|
+
if (options.path) {
|
|
128
|
+
providerPath = options.path;
|
|
129
|
+
}
|
|
130
|
+
else if (options.provider) {
|
|
131
|
+
const providers = detectProviders();
|
|
132
|
+
const match = providers.find((p) => p.provider === options.provider);
|
|
133
|
+
if (!match || !match.available) {
|
|
134
|
+
console.error(chalk.red(`Provider "${options.provider}" not available. Run "soulrecall cloud-backup providers".`));
|
|
135
|
+
process.exit(1);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
providerPath = match.path;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const available = detectAvailableProviders();
|
|
142
|
+
if (available.length === 0) {
|
|
143
|
+
console.error(chalk.red('No cloud provider detected. Use --provider or --path.'));
|
|
144
|
+
process.exit(1);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const first = available[0];
|
|
148
|
+
providerPath = first.path;
|
|
149
|
+
console.log(chalk.gray('Auto-detected provider: ' + first.label));
|
|
150
|
+
}
|
|
151
|
+
const spinner = ora('Scanning for archives...').start();
|
|
152
|
+
const archives = listCloudArchives(providerPath, options.subdirectory);
|
|
153
|
+
spinner.stop();
|
|
154
|
+
if (archives.length === 0) {
|
|
155
|
+
console.log(chalk.yellow('No archives found.'));
|
|
156
|
+
console.log(chalk.gray(`Looked in: ${resolveCloudBackupDir(providerPath, options.subdirectory)}`));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log(chalk.green(`Found ${archives.length} archive(s):\n`));
|
|
160
|
+
for (const archive of archives) {
|
|
161
|
+
const m = archive.manifest;
|
|
162
|
+
const totalSize = m.files.reduce((s, f) => s + f.sizeBytes, 0);
|
|
163
|
+
const dateStr = new Date(m.createdAt).toLocaleString();
|
|
164
|
+
const nameStr = m.agentName || 'full-vault';
|
|
165
|
+
console.log(' ' + chalk.cyan(nameStr) + ' ' + chalk.gray('(' + dateStr + ')'));
|
|
166
|
+
console.log(chalk.gray(' Components: ' + m.components.join(', ')));
|
|
167
|
+
console.log(chalk.gray(' Files: ' + String(m.files.length) + ' (' + formatBackupSize(totalSize) + ')'));
|
|
168
|
+
console.log(chalk.gray(' Path: ' + archive.archivePath));
|
|
169
|
+
console.log();
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
// --- restore ---
|
|
173
|
+
cloudBackupCmd
|
|
174
|
+
.command('restore')
|
|
175
|
+
.description('Restore SoulRecall data from a cloud archive')
|
|
176
|
+
.argument('<archive-path>', 'Path to the archive directory')
|
|
177
|
+
.option('--overwrite', 'Overwrite existing files', false)
|
|
178
|
+
.action(async (archivePath, options) => {
|
|
179
|
+
const spinner = ora('Restoring from archive...').start();
|
|
180
|
+
const result = restoreFromCloud(archivePath, options.overwrite);
|
|
181
|
+
if (result.success) {
|
|
182
|
+
spinner.succeed(chalk.green(`Restored ${result.restoredFiles} file(s)`));
|
|
183
|
+
if (result.components && result.components.length > 0) {
|
|
184
|
+
console.log(chalk.gray(` Components: ${result.components.join(', ')}`));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
spinner.fail(chalk.red('Restore failed'));
|
|
189
|
+
console.error(chalk.red(result.error || 'Unknown error'));
|
|
190
|
+
}
|
|
191
|
+
if (result.warnings.length > 0) {
|
|
192
|
+
console.log(chalk.yellow('\nWarnings:'));
|
|
193
|
+
for (const w of result.warnings) {
|
|
194
|
+
console.log(chalk.yellow(` - ${w}`));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!result.success) {
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
// --- verify ---
|
|
202
|
+
cloudBackupCmd
|
|
203
|
+
.command('verify')
|
|
204
|
+
.description('Verify integrity of a cloud archive')
|
|
205
|
+
.argument('<archive-path>', 'Path to the archive directory')
|
|
206
|
+
.action(async (archivePath) => {
|
|
207
|
+
const spinner = ora('Verifying archive integrity...').start();
|
|
208
|
+
const result = verifyCloudArchive(archivePath);
|
|
209
|
+
if (result.valid) {
|
|
210
|
+
spinner.succeed(chalk.green('Archive integrity verified'));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
spinner.fail(chalk.red('Archive integrity check failed'));
|
|
214
|
+
for (const err of result.errors) {
|
|
215
|
+
console.error(chalk.red(` - ${err}`));
|
|
216
|
+
}
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
export { cloudBackupCmd };
|
|
221
|
+
//# sourceMappingURL=cloud-backup.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cycles Command
|
|
3
|
+
*
|
|
4
|
+
* Manage ICP cycles for canisters.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { checkBalance, mintCycles, transferCycles, } from '../../src/icp/cycles.js';
|
|
10
|
+
export function cyclesCommand() {
|
|
11
|
+
const command = new Command('cycles');
|
|
12
|
+
command
|
|
13
|
+
.description('Manage ICP cycles')
|
|
14
|
+
.action(() => {
|
|
15
|
+
command.outputHelp();
|
|
16
|
+
})
|
|
17
|
+
.addCommand(balanceSubcommand())
|
|
18
|
+
.addCommand(mintSubcommand())
|
|
19
|
+
.addCommand(transferSubcommand());
|
|
20
|
+
return command;
|
|
21
|
+
}
|
|
22
|
+
async function executeBalance(options) {
|
|
23
|
+
const { canister } = options;
|
|
24
|
+
const spinner = ora(`Checking cycles balance for ${canister}...`).start();
|
|
25
|
+
try {
|
|
26
|
+
const result = await checkBalance(canister);
|
|
27
|
+
spinner.succeed(`Cycles balance checked for ${canister}`);
|
|
28
|
+
console.log();
|
|
29
|
+
console.log(chalk.cyan('Balance:'), result.stdout || 'N/A');
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
spinner.fail(`Failed to check balance: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function executeMint(options) {
|
|
37
|
+
const { amount } = options;
|
|
38
|
+
const spinner = ora(`Minting ${amount} cycles...`).start();
|
|
39
|
+
try {
|
|
40
|
+
const result = await mintCycles(amount);
|
|
41
|
+
spinner.succeed(`${amount} cycles minted successfully`);
|
|
42
|
+
console.log();
|
|
43
|
+
console.log(chalk.cyan('Result:'), result.stdout || 'N/A');
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
spinner.fail(`Failed to mint cycles: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function executeTransfer(options) {
|
|
51
|
+
const { amount, to } = options;
|
|
52
|
+
const spinner = ora(`Transferring ${amount} cycles to ${to}...`).start();
|
|
53
|
+
try {
|
|
54
|
+
const result = await transferCycles(amount, to);
|
|
55
|
+
spinner.succeed(`${amount} cycles transferred successfully to ${to}`);
|
|
56
|
+
console.log();
|
|
57
|
+
console.log(chalk.cyan('Result:'), result.stdout || 'N/A');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
spinner.fail(`Failed to transfer cycles: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function balanceSubcommand() {
|
|
65
|
+
return new Command('balance')
|
|
66
|
+
.description('Check cycles balance of a canister')
|
|
67
|
+
.option('-c, --canister <canister-id>', 'Canister ID to check')
|
|
68
|
+
.action(executeBalance);
|
|
69
|
+
}
|
|
70
|
+
function mintSubcommand() {
|
|
71
|
+
return new Command('mint')
|
|
72
|
+
.description('Mint cycles to a canister')
|
|
73
|
+
.argument('<amount>', 'Amount to mint')
|
|
74
|
+
.action(executeMint);
|
|
75
|
+
}
|
|
76
|
+
function transferSubcommand() {
|
|
77
|
+
return new Command('transfer')
|
|
78
|
+
.description('Transfer cycles to a canister')
|
|
79
|
+
.argument('<amount>', 'Amount to transfer')
|
|
80
|
+
.argument('<to>', 'Recipient canister ID or principal')
|
|
81
|
+
.action(executeTransfer);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=cycles.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decrypt command - Decrypt agent state using seed phrase
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
export interface DecryptCommandOptions {
|
|
6
|
+
output?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Execute decrypt command
|
|
10
|
+
*/
|
|
11
|
+
export declare function executeDecrypt(filePath: string, options: DecryptCommandOptions): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Create decrypt command
|
|
14
|
+
*/
|
|
15
|
+
export declare function decryptCommand(): Command;
|
|
16
|
+
//# sourceMappingURL=decrypt.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decrypt command - Decrypt agent state using seed phrase
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { decryptJSON } from '../../src/security/vetkeys.js';
|
|
11
|
+
/**
|
|
12
|
+
* Execute decrypt command
|
|
13
|
+
*/
|
|
14
|
+
export async function executeDecrypt(filePath, options) {
|
|
15
|
+
const resolvedPath = path.resolve(filePath);
|
|
16
|
+
// Validate input file exists
|
|
17
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
18
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
19
|
+
}
|
|
20
|
+
// Read and parse file
|
|
21
|
+
const content = fs.readFileSync(resolvedPath, 'utf-8');
|
|
22
|
+
let data;
|
|
23
|
+
try {
|
|
24
|
+
data = JSON.parse(content);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error('Invalid JSON format');
|
|
28
|
+
}
|
|
29
|
+
// Check if already decrypted
|
|
30
|
+
if (!('encrypted' in data && data.encrypted)) {
|
|
31
|
+
console.log(chalk.yellow('State is already decrypted.'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Prompt for seed phrase
|
|
35
|
+
const { seedPhrase } = await inquirer.prompt([
|
|
36
|
+
{
|
|
37
|
+
type: 'password',
|
|
38
|
+
name: 'seedPhrase',
|
|
39
|
+
message: 'Enter your seed phrase:',
|
|
40
|
+
validate: (input) => {
|
|
41
|
+
if (!input.trim()) {
|
|
42
|
+
return 'Seed phrase is required';
|
|
43
|
+
}
|
|
44
|
+
const words = input.trim().split(/\s+/);
|
|
45
|
+
if (words.length !== 12 && words.length !== 24) {
|
|
46
|
+
return 'Seed phrase must be 12 or 24 words';
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
const spinner = ora('Decrypting agent state...').start();
|
|
53
|
+
try {
|
|
54
|
+
const encrypted = data;
|
|
55
|
+
// Decrypt using VetKeys
|
|
56
|
+
const decrypted = await decryptJSON(encrypted, seedPhrase);
|
|
57
|
+
spinner.succeed('State decrypted successfully!');
|
|
58
|
+
console.log();
|
|
59
|
+
console.log(chalk.cyan('Decryption Info:'));
|
|
60
|
+
console.log(` Algorithm: ${encrypted.algorithm}`);
|
|
61
|
+
console.log(` Encrypted at: ${encrypted.encryptedAt}`);
|
|
62
|
+
// Determine output path
|
|
63
|
+
const outputPath = options.output ?? resolvedPath.replace('.json', '.decrypted.json');
|
|
64
|
+
// Write decrypted state
|
|
65
|
+
fs.writeFileSync(outputPath, JSON.stringify(decrypted, null, 2), 'utf-8');
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.green('ā'), 'Decrypted state saved to:', chalk.bold(outputPath));
|
|
68
|
+
console.log();
|
|
69
|
+
console.log(chalk.cyan('Next steps:'));
|
|
70
|
+
console.log(' 1. Review the decrypted state');
|
|
71
|
+
console.log(' 2. Rebuild agent:', chalk.bold('soulrecall rebuild'));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
75
|
+
spinner.fail(`Decryption failed: ${message}`);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create decrypt command
|
|
81
|
+
*/
|
|
82
|
+
export function decryptCommand() {
|
|
83
|
+
const command = new Command('decrypt');
|
|
84
|
+
command
|
|
85
|
+
.description('Decrypt agent state using seed phrase')
|
|
86
|
+
.argument('<file>', 'encrypted state file to decrypt')
|
|
87
|
+
.option('-o, --output <path>', 'output file path')
|
|
88
|
+
.action(async (file, options) => {
|
|
89
|
+
console.log(chalk.bold('\nš SoulRecall Decrypt\n'));
|
|
90
|
+
try {
|
|
91
|
+
await executeDecrypt(file, options);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
95
|
+
console.error(chalk.red(`\nError: ${message}`));
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return command;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=decrypt.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy command - Deploy agent WASM to ICP canister
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { type DeployResult, type NetworkType } from '../../src/deployment/index.js';
|
|
6
|
+
export interface DeployCommandOptions {
|
|
7
|
+
network?: NetworkType;
|
|
8
|
+
canisterId?: string;
|
|
9
|
+
yes?: boolean;
|
|
10
|
+
dryRun?: boolean;
|
|
11
|
+
env?: string;
|
|
12
|
+
identity?: string;
|
|
13
|
+
cycles?: string;
|
|
14
|
+
mode?: 'auto' | 'install' | 'reinstall' | 'upgrade';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Display deployment preview (dry-run)
|
|
18
|
+
*/
|
|
19
|
+
export declare function displayPreview(wasmPath: string, options: DeployCommandOptions): void;
|
|
20
|
+
/**
|
|
21
|
+
* Display deployment result
|
|
22
|
+
*/
|
|
23
|
+
export declare function displayResult(result: DeployResult): void;
|
|
24
|
+
/**
|
|
25
|
+
* Execute the deploy command
|
|
26
|
+
*/
|
|
27
|
+
export declare function executeDeploy(wasmPath: string, options: DeployCommandOptions): Promise<DeployResult | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Create the deploy command
|
|
30
|
+
*/
|
|
31
|
+
export declare function deployCommand(): Command;
|
|
32
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy command - Deploy agent WASM to ICP canister
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { deployAgent, getDeploySummary, } from '../../src/deployment/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Format cycles for display
|
|
12
|
+
*/
|
|
13
|
+
function formatCycles(cycles) {
|
|
14
|
+
if (cycles >= BigInt(1_000_000_000_000)) {
|
|
15
|
+
return `${(Number(cycles) / 1_000_000_000_000).toFixed(2)} T`;
|
|
16
|
+
}
|
|
17
|
+
if (cycles >= BigInt(1_000_000_000)) {
|
|
18
|
+
return `${(Number(cycles) / 1_000_000_000).toFixed(2)} B`;
|
|
19
|
+
}
|
|
20
|
+
if (cycles >= BigInt(1_000_000)) {
|
|
21
|
+
return `${(Number(cycles) / 1_000_000).toFixed(2)} M`;
|
|
22
|
+
}
|
|
23
|
+
return `${cycles.toString()}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Format file size for display
|
|
27
|
+
*/
|
|
28
|
+
function formatSize(bytes) {
|
|
29
|
+
if (bytes < 1024) {
|
|
30
|
+
return `${bytes} B`;
|
|
31
|
+
}
|
|
32
|
+
if (bytes < 1024 * 1024) {
|
|
33
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
34
|
+
}
|
|
35
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Display deployment preview (dry-run)
|
|
39
|
+
*/
|
|
40
|
+
export function displayPreview(wasmPath, options) {
|
|
41
|
+
const summary = getDeploySummary({
|
|
42
|
+
wasmPath: path.resolve(wasmPath),
|
|
43
|
+
network: options.network ?? 'local',
|
|
44
|
+
canisterId: options.canisterId,
|
|
45
|
+
skipConfirmation: options.yes,
|
|
46
|
+
});
|
|
47
|
+
console.log(chalk.bold('\nDeployment Preview\n'));
|
|
48
|
+
console.log(chalk.cyan('Agent:'));
|
|
49
|
+
console.log(` Name: ${chalk.bold(summary.agentName)}`);
|
|
50
|
+
console.log(` WASM: ${summary.wasmPath}`);
|
|
51
|
+
console.log(` Size: ${formatSize(summary.wasmSize)}`);
|
|
52
|
+
if (summary.wasmHash) {
|
|
53
|
+
console.log(` Hash: ${summary.wasmHash.substring(0, 16)}...`);
|
|
54
|
+
}
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(chalk.cyan('Target:'));
|
|
57
|
+
console.log(` Network: ${chalk.bold(summary.network)}`);
|
|
58
|
+
console.log(` Operation: ${summary.isUpgrade ? chalk.yellow('Upgrade') : chalk.green('New Deploy')}`);
|
|
59
|
+
if (summary.canisterId) {
|
|
60
|
+
console.log(` Canister: ${summary.canisterId}`);
|
|
61
|
+
}
|
|
62
|
+
console.log();
|
|
63
|
+
if (summary.validation.warnings.length > 0) {
|
|
64
|
+
console.log(chalk.yellow('Warnings:'));
|
|
65
|
+
for (const warning of summary.validation.warnings) {
|
|
66
|
+
console.log(chalk.yellow(` ā ${warning}`));
|
|
67
|
+
}
|
|
68
|
+
console.log();
|
|
69
|
+
}
|
|
70
|
+
if (summary.validation.errors.length > 0) {
|
|
71
|
+
console.log(chalk.red('Errors:'));
|
|
72
|
+
for (const error of summary.validation.errors) {
|
|
73
|
+
console.log(chalk.red(` ā ${error.message}`));
|
|
74
|
+
}
|
|
75
|
+
console.log();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Display deployment result
|
|
80
|
+
*/
|
|
81
|
+
export function displayResult(result) {
|
|
82
|
+
console.log();
|
|
83
|
+
console.log(chalk.green('ā'), 'Agent deployed successfully!');
|
|
84
|
+
console.log();
|
|
85
|
+
console.log(chalk.cyan('Canister Info:'));
|
|
86
|
+
console.log(` Canister ID: ${chalk.bold(result.canister.canisterId)}`);
|
|
87
|
+
console.log(` Network: ${result.canister.network}`);
|
|
88
|
+
console.log(` Agent: ${result.canister.agentName}`);
|
|
89
|
+
console.log(` Deployed: ${result.canister.deployedAt.toISOString()}`);
|
|
90
|
+
if (result.canister.wasmHash) {
|
|
91
|
+
console.log(` WASM Hash: ${result.canister.wasmHash.substring(0, 16)}...`);
|
|
92
|
+
}
|
|
93
|
+
if (result.cyclesUsed) {
|
|
94
|
+
console.log(` Cycles Used: ${formatCycles(result.cyclesUsed)}`);
|
|
95
|
+
}
|
|
96
|
+
if (result.deployTool) {
|
|
97
|
+
console.log(` Deploy Tool: ${result.deployTool}`);
|
|
98
|
+
}
|
|
99
|
+
if (result.warnings.length > 0) {
|
|
100
|
+
console.log();
|
|
101
|
+
console.log(chalk.yellow('Warnings:'));
|
|
102
|
+
for (const warning of result.warnings) {
|
|
103
|
+
console.log(chalk.yellow(` ā ${warning}`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
console.log();
|
|
107
|
+
console.log(chalk.cyan('Next steps:'));
|
|
108
|
+
if (result.canister.network === 'local') {
|
|
109
|
+
console.log(' 1. Test your agent locally with dfx');
|
|
110
|
+
console.log(' 2. Deploy to IC mainnet with', chalk.bold('--network ic'));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.log(' 1. Interact with your canister at:');
|
|
114
|
+
console.log(` ${chalk.bold(`https://${result.canister.canisterId}.ic0.app`)}`);
|
|
115
|
+
console.log(' 2. Monitor cycles balance with', chalk.bold('dfx canister status'));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Prompt for deployment confirmation
|
|
120
|
+
*/
|
|
121
|
+
async function confirmDeployment(network, isUpgrade) {
|
|
122
|
+
const action = isUpgrade ? 'upgrade' : 'deploy';
|
|
123
|
+
const networkLabel = network === 'ic' ? 'IC mainnet' : 'local network';
|
|
124
|
+
const { confirmed } = await inquirer.prompt([
|
|
125
|
+
{
|
|
126
|
+
type: 'confirm',
|
|
127
|
+
name: 'confirmed',
|
|
128
|
+
message: `${action.charAt(0).toUpperCase() + action.slice(1)} to ${networkLabel}?`,
|
|
129
|
+
default: network === 'local',
|
|
130
|
+
},
|
|
131
|
+
]);
|
|
132
|
+
return confirmed;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Execute the deploy command
|
|
136
|
+
*/
|
|
137
|
+
export async function executeDeploy(wasmPath, options) {
|
|
138
|
+
const resolvedPath = path.resolve(wasmPath);
|
|
139
|
+
const network = options.network ?? 'local';
|
|
140
|
+
// Handle dry-run mode
|
|
141
|
+
if (options.dryRun) {
|
|
142
|
+
displayPreview(resolvedPath, options);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
// Confirm deployment unless --yes flag
|
|
146
|
+
if (!options.yes) {
|
|
147
|
+
const confirmed = await confirmDeployment(network, !!options.canisterId);
|
|
148
|
+
if (!confirmed) {
|
|
149
|
+
console.log(chalk.yellow('\nDeployment cancelled.'));
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const spinner = ora('Deploying agent to ICP...').start();
|
|
154
|
+
try {
|
|
155
|
+
// Prepare deploy options
|
|
156
|
+
const deployOptions = {
|
|
157
|
+
wasmPath: resolvedPath,
|
|
158
|
+
network,
|
|
159
|
+
canisterId: options.canisterId,
|
|
160
|
+
skipConfirmation: options.yes,
|
|
161
|
+
environment: options.env,
|
|
162
|
+
identity: options.identity,
|
|
163
|
+
cycles: options.cycles,
|
|
164
|
+
mode: options.mode,
|
|
165
|
+
};
|
|
166
|
+
// Execute deployment
|
|
167
|
+
const result = await deployAgent(deployOptions);
|
|
168
|
+
const action = result.isUpgrade ? 'upgraded' : 'deployed';
|
|
169
|
+
spinner.succeed(`Agent '${result.canister.agentName}' ${action} successfully!`);
|
|
170
|
+
displayResult(result);
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
175
|
+
spinner.fail(`Deployment failed: ${message}`);
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Create the deploy command
|
|
181
|
+
*/
|
|
182
|
+
export function deployCommand() {
|
|
183
|
+
const command = new Command('deploy');
|
|
184
|
+
command
|
|
185
|
+
.description('Deploy agent WASM to ICP canister')
|
|
186
|
+
.argument('<wasm>', 'path to compiled WASM file')
|
|
187
|
+
.option('-n, --network <network>', 'target network (local or ic)', 'local')
|
|
188
|
+
.option('-e, --env <environment>', 'named environment from icp.yaml (e.g. dev, staging, production)')
|
|
189
|
+
.option('-c, --canister-id <id>', 'existing canister ID (for upgrades)')
|
|
190
|
+
.option('-y, --yes', 'skip confirmation prompts')
|
|
191
|
+
.option('--dry-run', 'show what would be deployed without executing')
|
|
192
|
+
.option('--identity <name>', 'identity name for icp-cli')
|
|
193
|
+
.option('--cycles <amount>', 'cycles allocation (e.g. 100T)')
|
|
194
|
+
.option('--mode <mode>', 'deploy mode: auto, install, reinstall, upgrade')
|
|
195
|
+
.action(async (wasm, options) => {
|
|
196
|
+
console.log(chalk.bold('\nš SoulRecall Deploy\n'));
|
|
197
|
+
try {
|
|
198
|
+
await executeDeploy(wasm, options);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
202
|
+
console.error(chalk.red(`\nError: ${message}`));
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
return command;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=deploy.js.map
|