chainlesschain 0.37.9 → 0.37.11

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 (84) hide show
  1. package/README.md +309 -19
  2. package/bin/chainlesschain.js +4 -0
  3. package/package.json +1 -1
  4. package/src/commands/a2a.js +374 -0
  5. package/src/commands/audit.js +286 -0
  6. package/src/commands/auth.js +387 -0
  7. package/src/commands/bi.js +240 -0
  8. package/src/commands/browse.js +184 -0
  9. package/src/commands/cowork.js +317 -0
  10. package/src/commands/did.js +376 -0
  11. package/src/commands/economy.js +375 -0
  12. package/src/commands/encrypt.js +233 -0
  13. package/src/commands/evolution.js +398 -0
  14. package/src/commands/export.js +125 -0
  15. package/src/commands/git.js +215 -0
  16. package/src/commands/hmemory.js +273 -0
  17. package/src/commands/hook.js +260 -0
  18. package/src/commands/import.js +259 -0
  19. package/src/commands/init.js +184 -0
  20. package/src/commands/instinct.js +202 -0
  21. package/src/commands/llm.js +155 -4
  22. package/src/commands/lowcode.js +320 -0
  23. package/src/commands/mcp.js +302 -0
  24. package/src/commands/memory.js +282 -0
  25. package/src/commands/note.js +187 -0
  26. package/src/commands/org.js +505 -0
  27. package/src/commands/p2p.js +274 -0
  28. package/src/commands/plugin.js +451 -0
  29. package/src/commands/sandbox.js +366 -0
  30. package/src/commands/search.js +237 -0
  31. package/src/commands/session.js +238 -0
  32. package/src/commands/skill.js +254 -201
  33. package/src/commands/sync.js +249 -0
  34. package/src/commands/tokens.js +214 -0
  35. package/src/commands/wallet.js +416 -0
  36. package/src/commands/workflow.js +359 -0
  37. package/src/commands/zkp.js +277 -0
  38. package/src/index.js +93 -1
  39. package/src/lib/a2a-protocol.js +371 -0
  40. package/src/lib/agent-coordinator.js +273 -0
  41. package/src/lib/agent-economy.js +369 -0
  42. package/src/lib/app-builder.js +377 -0
  43. package/src/lib/audit-logger.js +364 -0
  44. package/src/lib/bi-engine.js +299 -0
  45. package/src/lib/bm25-search.js +322 -0
  46. package/src/lib/browser-automation.js +216 -0
  47. package/src/lib/cowork/ab-comparator-cli.js +180 -0
  48. package/src/lib/cowork/code-knowledge-graph-cli.js +232 -0
  49. package/src/lib/cowork/debate-review-cli.js +144 -0
  50. package/src/lib/cowork/decision-kb-cli.js +153 -0
  51. package/src/lib/cowork/project-style-analyzer-cli.js +168 -0
  52. package/src/lib/cowork-adapter.js +106 -0
  53. package/src/lib/crypto-manager.js +246 -0
  54. package/src/lib/did-manager.js +270 -0
  55. package/src/lib/ensure-utf8.js +59 -0
  56. package/src/lib/evolution-system.js +508 -0
  57. package/src/lib/git-integration.js +220 -0
  58. package/src/lib/hierarchical-memory.js +471 -0
  59. package/src/lib/hook-manager.js +387 -0
  60. package/src/lib/instinct-manager.js +190 -0
  61. package/src/lib/knowledge-exporter.js +302 -0
  62. package/src/lib/knowledge-importer.js +293 -0
  63. package/src/lib/llm-providers.js +325 -0
  64. package/src/lib/mcp-client.js +413 -0
  65. package/src/lib/memory-manager.js +211 -0
  66. package/src/lib/note-versioning.js +244 -0
  67. package/src/lib/org-manager.js +424 -0
  68. package/src/lib/p2p-manager.js +317 -0
  69. package/src/lib/pdf-parser.js +96 -0
  70. package/src/lib/permission-engine.js +374 -0
  71. package/src/lib/plan-mode.js +333 -0
  72. package/src/lib/plugin-manager.js +430 -0
  73. package/src/lib/project-detector.js +53 -0
  74. package/src/lib/response-cache.js +156 -0
  75. package/src/lib/sandbox-v2.js +503 -0
  76. package/src/lib/service-container.js +183 -0
  77. package/src/lib/session-manager.js +189 -0
  78. package/src/lib/skill-loader.js +274 -0
  79. package/src/lib/sync-manager.js +347 -0
  80. package/src/lib/token-tracker.js +200 -0
  81. package/src/lib/wallet-manager.js +348 -0
  82. package/src/lib/workflow-engine.js +503 -0
  83. package/src/lib/zkp-engine.js +241 -0
  84. package/src/repl/agent-repl.js +259 -124
@@ -0,0 +1,451 @@
1
+ /**
2
+ * Plugin management commands
3
+ * chainlesschain plugin list|install|remove|enable|disable|update|info|search|registry|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
+ installPlugin,
11
+ getPlugin,
12
+ listPlugins,
13
+ enablePlugin,
14
+ disablePlugin,
15
+ removePlugin,
16
+ updatePlugin,
17
+ getPluginSettings,
18
+ setPluginSetting,
19
+ searchRegistry,
20
+ listRegistry,
21
+ registerInMarketplace,
22
+ getPluginSummary,
23
+ installPluginSkills,
24
+ removePluginSkills,
25
+ getPluginSkills,
26
+ } from "../lib/plugin-manager.js";
27
+
28
+ export function registerPluginCommand(program) {
29
+ const plugin = program
30
+ .command("plugin")
31
+ .description("Plugin and marketplace management");
32
+
33
+ // plugin list
34
+ plugin
35
+ .command("list", { isDefault: true })
36
+ .description("List installed plugins")
37
+ .option("--enabled", "Show only enabled plugins")
38
+ .option("--json", "Output as JSON")
39
+ .action(async (options) => {
40
+ try {
41
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
42
+ if (!ctx.db) {
43
+ logger.error("Database not available");
44
+ process.exit(1);
45
+ }
46
+ const db = ctx.db.getDatabase();
47
+ const plugins = listPlugins(db, { enabledOnly: options.enabled });
48
+
49
+ if (options.json) {
50
+ console.log(
51
+ JSON.stringify(
52
+ plugins.map((p) => ({
53
+ name: p.name,
54
+ version: p.version,
55
+ enabled: p.enabled === 1,
56
+ status: p.status,
57
+ })),
58
+ null,
59
+ 2,
60
+ ),
61
+ );
62
+ } else if (plugins.length === 0) {
63
+ logger.info(
64
+ 'No plugins installed. Install one with "chainlesschain plugin install <name>"',
65
+ );
66
+ } else {
67
+ logger.log(chalk.bold(`Plugins (${plugins.length}):\n`));
68
+ for (const p of plugins) {
69
+ const status = p.enabled
70
+ ? chalk.green("enabled")
71
+ : chalk.gray("disabled");
72
+ logger.log(` ${chalk.cyan(p.name)} v${p.version} [${status}]`);
73
+ if (p.description) logger.log(` ${chalk.gray(p.description)}`);
74
+ }
75
+ }
76
+
77
+ await shutdown();
78
+ } catch (err) {
79
+ logger.error(`Failed: ${err.message}`);
80
+ process.exit(1);
81
+ }
82
+ });
83
+
84
+ // plugin install
85
+ plugin
86
+ .command("install")
87
+ .description("Install a plugin")
88
+ .argument("<name>", "Plugin name")
89
+ .option("--version <version>", "Plugin version", "1.0.0")
90
+ .option("--description <desc>", "Plugin description")
91
+ .option("--author <author>", "Plugin author")
92
+ .option("--manifest <path>", "Plugin manifest file with skill declarations")
93
+ .option("--json", "Output as JSON")
94
+ .action(async (name, options) => {
95
+ try {
96
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
97
+ if (!ctx.db) {
98
+ logger.error("Database not available");
99
+ process.exit(1);
100
+ }
101
+ const db = ctx.db.getDatabase();
102
+ const result = installPlugin(db, {
103
+ name,
104
+ version: options.version,
105
+ description: options.description,
106
+ author: options.author,
107
+ });
108
+
109
+ // Install plugin skills if manifest provided
110
+ let skillResult = { installed: [] };
111
+ if (options.manifest) {
112
+ try {
113
+ const fs = await import("fs");
114
+ const manifestContent = fs.readFileSync(options.manifest, "utf-8");
115
+ const manifest = JSON.parse(manifestContent);
116
+ if (manifest.skills && manifest.skills.length > 0) {
117
+ const path = await import("path");
118
+ const pluginPath = path.dirname(path.resolve(options.manifest));
119
+ skillResult = installPluginSkills(
120
+ db,
121
+ name,
122
+ pluginPath,
123
+ manifest.skills,
124
+ );
125
+ }
126
+ } catch (err) {
127
+ logger.warn(`Could not install plugin skills: ${err.message}`);
128
+ }
129
+ }
130
+
131
+ if (options.json) {
132
+ console.log(
133
+ JSON.stringify(
134
+ { ...result, skills: skillResult.installed },
135
+ null,
136
+ 2,
137
+ ),
138
+ );
139
+ } else {
140
+ logger.success(`Plugin installed: ${result.name} v${result.version}`);
141
+ if (skillResult.installed.length > 0) {
142
+ logger.info(
143
+ `Skills installed: ${skillResult.installed.join(", ")}`,
144
+ );
145
+ }
146
+ }
147
+
148
+ await shutdown();
149
+ } catch (err) {
150
+ logger.error(`Failed: ${err.message}`);
151
+ process.exit(1);
152
+ }
153
+ });
154
+
155
+ // plugin remove
156
+ plugin
157
+ .command("remove")
158
+ .description("Remove a plugin")
159
+ .argument("<name>", "Plugin name")
160
+ .option("--force", "Skip confirmation")
161
+ .action(async (name, options) => {
162
+ try {
163
+ if (!options.force) {
164
+ const { confirm } = await import("@inquirer/prompts");
165
+ const ok = await confirm({
166
+ message: `Remove plugin "${name}"?`,
167
+ });
168
+ if (!ok) {
169
+ logger.info("Cancelled");
170
+ return;
171
+ }
172
+ }
173
+
174
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
175
+ if (!ctx.db) {
176
+ logger.error("Database not available");
177
+ process.exit(1);
178
+ }
179
+ const db = ctx.db.getDatabase();
180
+
181
+ // Remove plugin skills first
182
+ const skillResult = removePluginSkills(db, name);
183
+ const ok = removePlugin(db, name);
184
+
185
+ if (ok) {
186
+ logger.success(`Plugin removed: ${name}`);
187
+ if (skillResult.removed.length > 0) {
188
+ logger.info(`Skills removed: ${skillResult.removed.join(", ")}`);
189
+ }
190
+ } else {
191
+ logger.error(`Plugin not found: ${name}`);
192
+ }
193
+
194
+ await shutdown();
195
+ } catch (err) {
196
+ logger.error(`Failed: ${err.message}`);
197
+ process.exit(1);
198
+ }
199
+ });
200
+
201
+ // plugin enable
202
+ plugin
203
+ .command("enable")
204
+ .description("Enable a plugin")
205
+ .argument("<name>", "Plugin name")
206
+ .action(async (name) => {
207
+ try {
208
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
209
+ if (!ctx.db) {
210
+ logger.error("Database not available");
211
+ process.exit(1);
212
+ }
213
+ const db = ctx.db.getDatabase();
214
+ const ok = enablePlugin(db, name);
215
+
216
+ if (ok) {
217
+ logger.success(`Plugin enabled: ${name}`);
218
+ } else {
219
+ logger.error(`Plugin not found: ${name}`);
220
+ }
221
+
222
+ await shutdown();
223
+ } catch (err) {
224
+ logger.error(`Failed: ${err.message}`);
225
+ process.exit(1);
226
+ }
227
+ });
228
+
229
+ // plugin disable
230
+ plugin
231
+ .command("disable")
232
+ .description("Disable a plugin")
233
+ .argument("<name>", "Plugin name")
234
+ .action(async (name) => {
235
+ try {
236
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
237
+ if (!ctx.db) {
238
+ logger.error("Database not available");
239
+ process.exit(1);
240
+ }
241
+ const db = ctx.db.getDatabase();
242
+ const ok = disablePlugin(db, name);
243
+
244
+ if (ok) {
245
+ logger.success(`Plugin disabled: ${name}`);
246
+ } else {
247
+ logger.error(`Plugin not found: ${name}`);
248
+ }
249
+
250
+ await shutdown();
251
+ } catch (err) {
252
+ logger.error(`Failed: ${err.message}`);
253
+ process.exit(1);
254
+ }
255
+ });
256
+
257
+ // plugin update
258
+ plugin
259
+ .command("update")
260
+ .description("Update a plugin version")
261
+ .argument("<name>", "Plugin name")
262
+ .argument("<version>", "New version")
263
+ .action(async (name, version) => {
264
+ try {
265
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
266
+ if (!ctx.db) {
267
+ logger.error("Database not available");
268
+ process.exit(1);
269
+ }
270
+ const db = ctx.db.getDatabase();
271
+ const ok = updatePlugin(db, name, version);
272
+
273
+ if (ok) {
274
+ logger.success(`Plugin updated: ${name} → v${version}`);
275
+ } else {
276
+ logger.error(`Plugin not found: ${name}`);
277
+ }
278
+
279
+ await shutdown();
280
+ } catch (err) {
281
+ logger.error(`Failed: ${err.message}`);
282
+ process.exit(1);
283
+ }
284
+ });
285
+
286
+ // plugin info
287
+ plugin
288
+ .command("info")
289
+ .description("Show plugin details")
290
+ .argument("<name>", "Plugin name")
291
+ .option("--json", "Output as JSON")
292
+ .action(async (name, options) => {
293
+ try {
294
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
295
+ if (!ctx.db) {
296
+ logger.error("Database not available");
297
+ process.exit(1);
298
+ }
299
+ const db = ctx.db.getDatabase();
300
+ const p = getPlugin(db, name);
301
+
302
+ if (!p) {
303
+ logger.error(`Plugin not found: ${name}`);
304
+ process.exit(1);
305
+ }
306
+
307
+ const settings = getPluginSettings(db, name);
308
+ const skills = getPluginSkills(db, name);
309
+
310
+ if (options.json) {
311
+ console.log(JSON.stringify({ ...p, settings, skills }, null, 2));
312
+ } else {
313
+ logger.log(chalk.bold("Plugin Info:\n"));
314
+ logger.log(` ${chalk.bold("Name:")} ${chalk.cyan(p.name)}`);
315
+ logger.log(` ${chalk.bold("Version:")} ${p.version}`);
316
+ logger.log(
317
+ ` ${chalk.bold("Description:")} ${p.description || chalk.gray("(none)")}`,
318
+ );
319
+ logger.log(
320
+ ` ${chalk.bold("Author:")} ${p.author || chalk.gray("(unknown)")}`,
321
+ );
322
+ logger.log(
323
+ ` ${chalk.bold("Enabled:")} ${p.enabled ? chalk.green("yes") : chalk.red("no")}`,
324
+ );
325
+ logger.log(` ${chalk.bold("Installed:")} ${p.installed_at}`);
326
+
327
+ if (skills.length > 0) {
328
+ logger.log(`\n ${chalk.bold("Skills:")}`);
329
+ for (const sk of skills) {
330
+ logger.log(
331
+ ` ${chalk.cyan(sk.skill_name)} → ${chalk.gray(sk.skill_path)}`,
332
+ );
333
+ }
334
+ }
335
+
336
+ if (Object.keys(settings).length > 0) {
337
+ logger.log(`\n ${chalk.bold("Settings:")}`);
338
+ for (const [k, v] of Object.entries(settings)) {
339
+ logger.log(` ${k}: ${v}`);
340
+ }
341
+ }
342
+ }
343
+
344
+ await shutdown();
345
+ } catch (err) {
346
+ logger.error(`Failed: ${err.message}`);
347
+ process.exit(1);
348
+ }
349
+ });
350
+
351
+ // plugin search
352
+ plugin
353
+ .command("search")
354
+ .description("Search plugin registry")
355
+ .argument("<query>", "Search query")
356
+ .option("--json", "Output as JSON")
357
+ .action(async (query, options) => {
358
+ try {
359
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
360
+ if (!ctx.db) {
361
+ logger.error("Database not available");
362
+ process.exit(1);
363
+ }
364
+ const db = ctx.db.getDatabase();
365
+ const results = searchRegistry(db, query);
366
+
367
+ if (options.json) {
368
+ console.log(JSON.stringify(results, null, 2));
369
+ } else if (results.length === 0) {
370
+ logger.info(`No plugins found for "${query}"`);
371
+ } else {
372
+ logger.log(chalk.bold(`Registry Results (${results.length}):\n`));
373
+ for (const r of results) {
374
+ logger.log(` ${chalk.cyan(r.name)} v${r.latest_version}`);
375
+ if (r.description) logger.log(` ${chalk.gray(r.description)}`);
376
+ }
377
+ }
378
+
379
+ await shutdown();
380
+ } catch (err) {
381
+ logger.error(`Failed: ${err.message}`);
382
+ process.exit(1);
383
+ }
384
+ });
385
+
386
+ // plugin registry
387
+ plugin
388
+ .command("registry")
389
+ .description("List all plugins in registry")
390
+ .option("--json", "Output as JSON")
391
+ .action(async (options) => {
392
+ try {
393
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
394
+ if (!ctx.db) {
395
+ logger.error("Database not available");
396
+ process.exit(1);
397
+ }
398
+ const db = ctx.db.getDatabase();
399
+ const registry = listRegistry(db);
400
+
401
+ if (options.json) {
402
+ console.log(JSON.stringify(registry, null, 2));
403
+ } else if (registry.length === 0) {
404
+ logger.info("Registry is empty");
405
+ } else {
406
+ logger.log(chalk.bold(`Plugin Registry (${registry.length}):\n`));
407
+ for (const r of registry) {
408
+ logger.log(
409
+ ` ${chalk.cyan(r.name)} v${r.latest_version} - ${r.description || ""}`,
410
+ );
411
+ }
412
+ }
413
+
414
+ await shutdown();
415
+ } catch (err) {
416
+ logger.error(`Failed: ${err.message}`);
417
+ process.exit(1);
418
+ }
419
+ });
420
+
421
+ // plugin summary
422
+ plugin
423
+ .command("summary")
424
+ .description("Show plugin summary statistics")
425
+ .option("--json", "Output as JSON")
426
+ .action(async (options) => {
427
+ try {
428
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
429
+ if (!ctx.db) {
430
+ logger.error("Database not available");
431
+ process.exit(1);
432
+ }
433
+ const db = ctx.db.getDatabase();
434
+ const summary = getPluginSummary(db);
435
+
436
+ if (options.json) {
437
+ console.log(JSON.stringify(summary, null, 2));
438
+ } else {
439
+ logger.log(chalk.bold("Plugin Summary:\n"));
440
+ logger.log(` ${chalk.bold("Installed:")} ${summary.installed}`);
441
+ logger.log(` ${chalk.bold("Enabled:")} ${summary.enabled}`);
442
+ logger.log(` ${chalk.bold("Registry:")} ${summary.registryCount}`);
443
+ }
444
+
445
+ await shutdown();
446
+ } catch (err) {
447
+ logger.error(`Failed: ${err.message}`);
448
+ process.exit(1);
449
+ }
450
+ });
451
+ }