chainlesschain 0.37.8 → 0.37.10

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 (59) hide show
  1. package/README.md +403 -8
  2. package/bin/chainlesschain.js +4 -0
  3. package/package.json +7 -2
  4. package/src/commands/agent.js +30 -0
  5. package/src/commands/ask.js +114 -0
  6. package/src/commands/audit.js +286 -0
  7. package/src/commands/auth.js +387 -0
  8. package/src/commands/browse.js +184 -0
  9. package/src/commands/chat.js +35 -0
  10. package/src/commands/db.js +152 -0
  11. package/src/commands/did.js +376 -0
  12. package/src/commands/encrypt.js +233 -0
  13. package/src/commands/export.js +125 -0
  14. package/src/commands/git.js +215 -0
  15. package/src/commands/import.js +259 -0
  16. package/src/commands/instinct.js +202 -0
  17. package/src/commands/llm.js +288 -0
  18. package/src/commands/mcp.js +302 -0
  19. package/src/commands/memory.js +282 -0
  20. package/src/commands/note.js +489 -0
  21. package/src/commands/org.js +505 -0
  22. package/src/commands/p2p.js +274 -0
  23. package/src/commands/plugin.js +398 -0
  24. package/src/commands/search.js +237 -0
  25. package/src/commands/session.js +238 -0
  26. package/src/commands/skill.js +479 -0
  27. package/src/commands/sync.js +249 -0
  28. package/src/commands/tokens.js +214 -0
  29. package/src/commands/wallet.js +416 -0
  30. package/src/index.js +65 -0
  31. package/src/lib/audit-logger.js +364 -0
  32. package/src/lib/bm25-search.js +322 -0
  33. package/src/lib/browser-automation.js +216 -0
  34. package/src/lib/crypto-manager.js +246 -0
  35. package/src/lib/did-manager.js +270 -0
  36. package/src/lib/ensure-utf8.js +59 -0
  37. package/src/lib/git-integration.js +220 -0
  38. package/src/lib/instinct-manager.js +190 -0
  39. package/src/lib/knowledge-exporter.js +302 -0
  40. package/src/lib/knowledge-importer.js +293 -0
  41. package/src/lib/llm-providers.js +325 -0
  42. package/src/lib/mcp-client.js +413 -0
  43. package/src/lib/memory-manager.js +211 -0
  44. package/src/lib/note-versioning.js +244 -0
  45. package/src/lib/org-manager.js +424 -0
  46. package/src/lib/p2p-manager.js +317 -0
  47. package/src/lib/pdf-parser.js +96 -0
  48. package/src/lib/permission-engine.js +374 -0
  49. package/src/lib/plan-mode.js +333 -0
  50. package/src/lib/platform.js +15 -0
  51. package/src/lib/plugin-manager.js +312 -0
  52. package/src/lib/response-cache.js +156 -0
  53. package/src/lib/session-manager.js +189 -0
  54. package/src/lib/sync-manager.js +347 -0
  55. package/src/lib/token-tracker.js +200 -0
  56. package/src/lib/wallet-manager.js +348 -0
  57. package/src/repl/agent-repl.js +912 -0
  58. package/src/repl/chat-repl.js +262 -0
  59. package/src/runtime/bootstrap.js +159 -0
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Wallet & asset commands
3
+ * chainlesschain wallet create|list|balance|set-default|delete|asset|transfer|history|summary
4
+ */
5
+
6
+ import chalk from "chalk";
7
+ import { logger } from "../lib/logger.js";
8
+ import { bootstrap, shutdown } from "../runtime/bootstrap.js";
9
+ import {
10
+ createWallet,
11
+ getAllWallets,
12
+ getBalance,
13
+ setDefaultWallet,
14
+ deleteWallet,
15
+ createAsset,
16
+ getAllAssets,
17
+ getAssets,
18
+ transferAsset,
19
+ getTransactions,
20
+ getWalletSummary,
21
+ } from "../lib/wallet-manager.js";
22
+
23
+ export function registerWalletCommand(program) {
24
+ const wallet = program
25
+ .command("wallet")
26
+ .description("Digital wallet and asset management");
27
+
28
+ // wallet create
29
+ wallet
30
+ .command("create")
31
+ .description("Create a new wallet")
32
+ .option("--name <name>", "Wallet name")
33
+ .option("--password <password>", "Encryption password")
34
+ .option("--json", "Output as JSON")
35
+ .action(async (options) => {
36
+ try {
37
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
38
+ if (!ctx.db) {
39
+ logger.error("Database not available");
40
+ process.exit(1);
41
+ }
42
+ const db = ctx.db.getDatabase();
43
+ const w = createWallet(db, options.name, options.password);
44
+
45
+ if (options.json) {
46
+ console.log(JSON.stringify(w, null, 2));
47
+ } else {
48
+ logger.success("Wallet created");
49
+ logger.log(` ${chalk.bold("Address:")} ${chalk.cyan(w.address)}`);
50
+ if (w.name) logger.log(` ${chalk.bold("Name:")} ${w.name}`);
51
+ logger.log(
52
+ ` ${chalk.bold("Default:")} ${w.isDefault ? chalk.green("yes") : "no"}`,
53
+ );
54
+ }
55
+
56
+ await shutdown();
57
+ } catch (err) {
58
+ logger.error(`Failed: ${err.message}`);
59
+ process.exit(1);
60
+ }
61
+ });
62
+
63
+ // wallet list
64
+ wallet
65
+ .command("list", { isDefault: true })
66
+ .description("List all wallets")
67
+ .option("--json", "Output as JSON")
68
+ .action(async (options) => {
69
+ try {
70
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
71
+ if (!ctx.db) {
72
+ logger.error("Database not available");
73
+ process.exit(1);
74
+ }
75
+ const db = ctx.db.getDatabase();
76
+ const wallets = getAllWallets(db);
77
+
78
+ if (options.json) {
79
+ console.log(
80
+ JSON.stringify(
81
+ wallets.map((w) => ({
82
+ address: w.address,
83
+ name: w.name,
84
+ balance: w.balance,
85
+ isDefault: w.is_default === 1,
86
+ })),
87
+ null,
88
+ 2,
89
+ ),
90
+ );
91
+ } else if (wallets.length === 0) {
92
+ logger.info(
93
+ 'No wallets. Create one with "chainlesschain wallet create"',
94
+ );
95
+ } else {
96
+ logger.log(chalk.bold(`Wallets (${wallets.length}):\n`));
97
+ for (const w of wallets) {
98
+ const def = w.is_default ? chalk.green(" [default]") : "";
99
+ const name = w.name ? ` (${w.name})` : "";
100
+ logger.log(` ${chalk.cyan(w.address)}${name}${def}`);
101
+ logger.log(` ${chalk.gray(`balance: ${w.balance}`)}`);
102
+ }
103
+ }
104
+
105
+ await shutdown();
106
+ } catch (err) {
107
+ logger.error(`Failed: ${err.message}`);
108
+ process.exit(1);
109
+ }
110
+ });
111
+
112
+ // wallet balance
113
+ wallet
114
+ .command("balance")
115
+ .description("Show wallet balance")
116
+ .argument("<address>", "Wallet address")
117
+ .option("--json", "Output as JSON")
118
+ .action(async (address, options) => {
119
+ try {
120
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
121
+ if (!ctx.db) {
122
+ logger.error("Database not available");
123
+ process.exit(1);
124
+ }
125
+ const db = ctx.db.getDatabase();
126
+ const result = getBalance(db, address);
127
+
128
+ if (!result) {
129
+ logger.error(`Wallet not found: ${address}`);
130
+ process.exit(1);
131
+ }
132
+
133
+ if (options.json) {
134
+ console.log(JSON.stringify(result, null, 2));
135
+ } else {
136
+ logger.log(
137
+ ` ${chalk.bold("Address:")} ${chalk.cyan(result.address)}`,
138
+ );
139
+ logger.log(
140
+ ` ${chalk.bold("Balance:")} ${chalk.green(result.balance)}`,
141
+ );
142
+ }
143
+
144
+ await shutdown();
145
+ } catch (err) {
146
+ logger.error(`Failed: ${err.message}`);
147
+ process.exit(1);
148
+ }
149
+ });
150
+
151
+ // wallet set-default
152
+ wallet
153
+ .command("set-default")
154
+ .description("Set a wallet as default")
155
+ .argument("<address>", "Wallet address")
156
+ .action(async (address) => {
157
+ try {
158
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
159
+ if (!ctx.db) {
160
+ logger.error("Database not available");
161
+ process.exit(1);
162
+ }
163
+ const db = ctx.db.getDatabase();
164
+ const ok = setDefaultWallet(db, address);
165
+
166
+ if (ok) {
167
+ logger.success("Default wallet updated");
168
+ } else {
169
+ logger.error(`Wallet not found: ${address}`);
170
+ }
171
+
172
+ await shutdown();
173
+ } catch (err) {
174
+ logger.error(`Failed: ${err.message}`);
175
+ process.exit(1);
176
+ }
177
+ });
178
+
179
+ // wallet delete
180
+ wallet
181
+ .command("delete")
182
+ .description("Delete a wallet")
183
+ .argument("<address>", "Wallet address")
184
+ .option("--force", "Skip confirmation")
185
+ .action(async (address, options) => {
186
+ try {
187
+ if (!options.force) {
188
+ const { confirm } = await import("@inquirer/prompts");
189
+ const ok = await confirm({
190
+ message: "Delete this wallet? The encrypted key will be lost.",
191
+ });
192
+ if (!ok) {
193
+ logger.info("Cancelled");
194
+ return;
195
+ }
196
+ }
197
+
198
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
199
+ if (!ctx.db) {
200
+ logger.error("Database not available");
201
+ process.exit(1);
202
+ }
203
+ const db = ctx.db.getDatabase();
204
+ const ok = deleteWallet(db, address);
205
+
206
+ if (ok) {
207
+ logger.success("Wallet deleted");
208
+ } else {
209
+ logger.error(`Wallet not found: ${address}`);
210
+ }
211
+
212
+ await shutdown();
213
+ } catch (err) {
214
+ logger.error(`Failed: ${err.message}`);
215
+ process.exit(1);
216
+ }
217
+ });
218
+
219
+ // wallet asset
220
+ wallet
221
+ .command("asset")
222
+ .description("Create a digital asset")
223
+ .argument("<name>", "Asset name")
224
+ .option("--address <address>", "Wallet address (default wallet if omitted)")
225
+ .option("--type <type>", "Asset type (token/nft/document)", "token")
226
+ .option("--description <desc>", "Asset description")
227
+ .option("--json", "Output as JSON")
228
+ .action(async (name, options) => {
229
+ try {
230
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
231
+ if (!ctx.db) {
232
+ logger.error("Database not available");
233
+ process.exit(1);
234
+ }
235
+ const db = ctx.db.getDatabase();
236
+
237
+ let address = options.address;
238
+ if (!address) {
239
+ const wallets = getAllWallets(db);
240
+ const def = wallets.find((w) => w.is_default === 1);
241
+ if (!def) {
242
+ logger.error("No wallets found. Create one first.");
243
+ process.exit(1);
244
+ }
245
+ address = def.address;
246
+ }
247
+
248
+ const asset = createAsset(
249
+ db,
250
+ address,
251
+ options.type,
252
+ name,
253
+ options.description,
254
+ );
255
+
256
+ if (options.json) {
257
+ console.log(JSON.stringify(asset, null, 2));
258
+ } else {
259
+ logger.success("Asset created");
260
+ logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(asset.id)}`);
261
+ logger.log(` ${chalk.bold("Name:")} ${asset.name}`);
262
+ logger.log(` ${chalk.bold("Type:")} ${asset.assetType}`);
263
+ logger.log(
264
+ ` ${chalk.bold("Wallet:")} ${chalk.gray(asset.walletAddress)}`,
265
+ );
266
+ }
267
+
268
+ await shutdown();
269
+ } catch (err) {
270
+ logger.error(`Failed: ${err.message}`);
271
+ process.exit(1);
272
+ }
273
+ });
274
+
275
+ // wallet assets
276
+ wallet
277
+ .command("assets")
278
+ .description("List digital assets")
279
+ .option("--address <address>", "Filter by wallet address")
280
+ .option("--json", "Output as JSON")
281
+ .action(async (options) => {
282
+ try {
283
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
284
+ if (!ctx.db) {
285
+ logger.error("Database not available");
286
+ process.exit(1);
287
+ }
288
+ const db = ctx.db.getDatabase();
289
+ const assets = options.address
290
+ ? getAssets(db, options.address)
291
+ : getAllAssets(db);
292
+
293
+ if (options.json) {
294
+ console.log(JSON.stringify(assets, null, 2));
295
+ } else if (assets.length === 0) {
296
+ logger.info("No assets found");
297
+ } else {
298
+ logger.log(chalk.bold(`Assets (${assets.length}):\n`));
299
+ for (const a of assets) {
300
+ logger.log(` ${chalk.cyan(a.id)} - ${a.name} (${a.asset_type})`);
301
+ logger.log(` ${chalk.gray(`wallet: ${a.wallet_address}`)}`);
302
+ }
303
+ }
304
+
305
+ await shutdown();
306
+ } catch (err) {
307
+ logger.error(`Failed: ${err.message}`);
308
+ process.exit(1);
309
+ }
310
+ });
311
+
312
+ // wallet transfer
313
+ wallet
314
+ .command("transfer")
315
+ .description("Transfer an asset")
316
+ .argument("<asset-id>", "Asset ID to transfer")
317
+ .argument("<to-address>", "Destination wallet address")
318
+ .option("--amount <amount>", "Amount to transfer")
319
+ .action(async (assetId, toAddress, options) => {
320
+ try {
321
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
322
+ if (!ctx.db) {
323
+ logger.error("Database not available");
324
+ process.exit(1);
325
+ }
326
+ const db = ctx.db.getDatabase();
327
+ const tx = transferAsset(db, assetId, toAddress, options.amount);
328
+
329
+ logger.success("Transfer complete");
330
+ logger.log(` ${chalk.bold("TX ID:")} ${chalk.cyan(tx.txId)}`);
331
+ logger.log(` ${chalk.bold("From:")} ${chalk.gray(tx.from)}`);
332
+ logger.log(` ${chalk.bold("To:")} ${chalk.gray(tx.to)}`);
333
+
334
+ await shutdown();
335
+ } catch (err) {
336
+ logger.error(`Failed: ${err.message}`);
337
+ process.exit(1);
338
+ }
339
+ });
340
+
341
+ // wallet history
342
+ wallet
343
+ .command("history")
344
+ .description("Show transaction history")
345
+ .option("--address <address>", "Filter by wallet address")
346
+ .option("--limit <n>", "Number of transactions", "20")
347
+ .option("--json", "Output as JSON")
348
+ .action(async (options) => {
349
+ try {
350
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
351
+ if (!ctx.db) {
352
+ logger.error("Database not available");
353
+ process.exit(1);
354
+ }
355
+ const db = ctx.db.getDatabase();
356
+ const txns = getTransactions(db, {
357
+ address: options.address,
358
+ limit: parseInt(options.limit),
359
+ });
360
+
361
+ if (options.json) {
362
+ console.log(JSON.stringify(txns, null, 2));
363
+ } else if (txns.length === 0) {
364
+ logger.info("No transactions");
365
+ } else {
366
+ logger.log(chalk.bold(`Transactions (${txns.length}):\n`));
367
+ for (const tx of txns) {
368
+ logger.log(
369
+ ` ${chalk.cyan(tx.id)} ${chalk.bold(tx.tx_type)} ${chalk.gray(tx.created_at)}`,
370
+ );
371
+ logger.log(
372
+ ` ${chalk.gray(`${tx.from_address} → ${tx.to_address}`)}`,
373
+ );
374
+ }
375
+ }
376
+
377
+ await shutdown();
378
+ } catch (err) {
379
+ logger.error(`Failed: ${err.message}`);
380
+ process.exit(1);
381
+ }
382
+ });
383
+
384
+ // wallet summary
385
+ wallet
386
+ .command("summary")
387
+ .description("Show wallet summary statistics")
388
+ .option("--json", "Output as JSON")
389
+ .action(async (options) => {
390
+ try {
391
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
392
+ if (!ctx.db) {
393
+ logger.error("Database not available");
394
+ process.exit(1);
395
+ }
396
+ const db = ctx.db.getDatabase();
397
+ const summary = getWalletSummary(db);
398
+
399
+ if (options.json) {
400
+ console.log(JSON.stringify(summary, null, 2));
401
+ } else {
402
+ logger.log(chalk.bold("Wallet Summary:\n"));
403
+ logger.log(` ${chalk.bold("Wallets:")} ${summary.walletCount}`);
404
+ logger.log(` ${chalk.bold("Assets:")} ${summary.assetCount}`);
405
+ logger.log(
406
+ ` ${chalk.bold("Transactions:")} ${summary.transactionCount}`,
407
+ );
408
+ }
409
+
410
+ await shutdown();
411
+ } catch (err) {
412
+ logger.error(`Failed: ${err.message}`);
413
+ process.exit(1);
414
+ }
415
+ });
416
+ }
package/src/index.js CHANGED
@@ -8,6 +8,32 @@ import { registerServicesCommand } from "./commands/services.js";
8
8
  import { registerConfigCommand } from "./commands/config.js";
9
9
  import { registerUpdateCommand } from "./commands/update.js";
10
10
  import { registerDoctorCommand } from "./commands/doctor.js";
11
+ import { registerDbCommand } from "./commands/db.js";
12
+ import { registerNoteCommand } from "./commands/note.js";
13
+ import { registerChatCommand } from "./commands/chat.js";
14
+ import { registerAskCommand } from "./commands/ask.js";
15
+ import { registerLlmCommand } from "./commands/llm.js";
16
+ import { registerAgentCommand } from "./commands/agent.js";
17
+ import { registerSkillCommand } from "./commands/skill.js";
18
+ import { registerSearchCommand } from "./commands/search.js";
19
+ import { registerTokensCommand } from "./commands/tokens.js";
20
+ import { registerMemoryCommand } from "./commands/memory.js";
21
+ import { registerSessionCommand } from "./commands/session.js";
22
+ import { registerImportCommand } from "./commands/import.js";
23
+ import { registerExportCommand } from "./commands/export.js";
24
+ import { registerGitCommand } from "./commands/git.js";
25
+ import { registerMcpCommand } from "./commands/mcp.js";
26
+ import { registerBrowseCommand } from "./commands/browse.js";
27
+ import { registerInstinctCommand } from "./commands/instinct.js";
28
+ import { registerDidCommand } from "./commands/did.js";
29
+ import { registerEncryptCommand } from "./commands/encrypt.js";
30
+ import { registerAuthCommand } from "./commands/auth.js";
31
+ import { registerAuditCommand } from "./commands/audit.js";
32
+ import { registerP2pCommand } from "./commands/p2p.js";
33
+ import { registerSyncCommand } from "./commands/sync.js";
34
+ import { registerWalletCommand } from "./commands/wallet.js";
35
+ import { registerOrgCommand } from "./commands/org.js";
36
+ import { registerPluginCommand } from "./commands/plugin.js";
11
37
 
12
38
  export function createProgram() {
13
39
  const program = new Command();
@@ -21,6 +47,7 @@ export function createProgram() {
21
47
  .option("--verbose", "Enable verbose output")
22
48
  .option("--quiet", "Suppress non-essential output");
23
49
 
50
+ // Existing commands
24
51
  registerSetupCommand(program);
25
52
  registerStartCommand(program);
26
53
  registerStopCommand(program);
@@ -30,5 +57,43 @@ export function createProgram() {
30
57
  registerUpdateCommand(program);
31
58
  registerDoctorCommand(program);
32
59
 
60
+ // Headless commands
61
+ registerDbCommand(program);
62
+ registerNoteCommand(program);
63
+ registerChatCommand(program);
64
+ registerAskCommand(program);
65
+ registerLlmCommand(program);
66
+ registerAgentCommand(program);
67
+ registerSkillCommand(program);
68
+
69
+ // Phase 1: AI intelligence layer
70
+ registerSearchCommand(program);
71
+ registerTokensCommand(program);
72
+ registerMemoryCommand(program);
73
+ registerSessionCommand(program);
74
+
75
+ // Phase 2: Knowledge & content management
76
+ registerImportCommand(program);
77
+ registerExportCommand(program);
78
+ registerGitCommand(program);
79
+
80
+ // Phase 3: MCP & external integration
81
+ registerMcpCommand(program);
82
+ registerBrowseCommand(program);
83
+ registerInstinctCommand(program);
84
+
85
+ // Phase 4: Security & identity
86
+ registerDidCommand(program);
87
+ registerEncryptCommand(program);
88
+ registerAuthCommand(program);
89
+ registerAuditCommand(program);
90
+
91
+ // Phase 5: P2P, blockchain & enterprise
92
+ registerP2pCommand(program);
93
+ registerSyncCommand(program);
94
+ registerWalletCommand(program);
95
+ registerOrgCommand(program);
96
+ registerPluginCommand(program);
97
+
33
98
  return program;
34
99
  }