chainlesschain 0.37.10 → 0.37.12

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 (39) hide show
  1. package/README.md +166 -10
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +374 -0
  4. package/src/commands/bi.js +240 -0
  5. package/src/commands/cowork.js +317 -0
  6. package/src/commands/economy.js +375 -0
  7. package/src/commands/evolution.js +398 -0
  8. package/src/commands/hmemory.js +273 -0
  9. package/src/commands/hook.js +260 -0
  10. package/src/commands/init.js +184 -0
  11. package/src/commands/lowcode.js +320 -0
  12. package/src/commands/plugin.js +55 -2
  13. package/src/commands/sandbox.js +366 -0
  14. package/src/commands/skill.js +254 -201
  15. package/src/commands/workflow.js +359 -0
  16. package/src/commands/zkp.js +277 -0
  17. package/src/index.js +44 -0
  18. package/src/lib/a2a-protocol.js +371 -0
  19. package/src/lib/agent-coordinator.js +273 -0
  20. package/src/lib/agent-economy.js +369 -0
  21. package/src/lib/app-builder.js +377 -0
  22. package/src/lib/bi-engine.js +299 -0
  23. package/src/lib/cowork/ab-comparator-cli.js +180 -0
  24. package/src/lib/cowork/code-knowledge-graph-cli.js +232 -0
  25. package/src/lib/cowork/debate-review-cli.js +144 -0
  26. package/src/lib/cowork/decision-kb-cli.js +153 -0
  27. package/src/lib/cowork/project-style-analyzer-cli.js +168 -0
  28. package/src/lib/cowork-adapter.js +106 -0
  29. package/src/lib/evolution-system.js +508 -0
  30. package/src/lib/hierarchical-memory.js +471 -0
  31. package/src/lib/hook-manager.js +387 -0
  32. package/src/lib/plugin-manager.js +118 -0
  33. package/src/lib/project-detector.js +53 -0
  34. package/src/lib/sandbox-v2.js +503 -0
  35. package/src/lib/service-container.js +183 -0
  36. package/src/lib/skill-loader.js +274 -0
  37. package/src/lib/workflow-engine.js +503 -0
  38. package/src/lib/zkp-engine.js +241 -0
  39. package/src/repl/agent-repl.js +117 -112
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Low-Code Platform commands
3
+ * chainlesschain lowcode create|list|preview|publish|components|datasource|versions|rollback|export|deploy
4
+ */
5
+
6
+ import chalk from "chalk";
7
+ import ora from "ora";
8
+ import { logger } from "../lib/logger.js";
9
+ import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
+ import {
11
+ ensureLowcodeTables,
12
+ createApp,
13
+ saveDesign,
14
+ previewApp,
15
+ publishApp,
16
+ listComponents,
17
+ addDataSource,
18
+ getVersions,
19
+ rollbackApp,
20
+ exportApp,
21
+ listApps,
22
+ } from "../lib/app-builder.js";
23
+
24
+ export function registerLowcodeCommand(program) {
25
+ const lowcode = program
26
+ .command("lowcode")
27
+ .description("Low-code application platform");
28
+
29
+ // lowcode create <name>
30
+ lowcode
31
+ .command("create")
32
+ .description("Create a new low-code application")
33
+ .argument("<name>", "Application name")
34
+ .option("--description <desc>", "Application description", "")
35
+ .option(
36
+ "--platform <platform>",
37
+ "Target platform (web|desktop|mobile|all)",
38
+ "web",
39
+ )
40
+ .option("--json", "Output as JSON")
41
+ .action(async (name, options) => {
42
+ const spinner = ora("Creating application...").start();
43
+ try {
44
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
45
+ if (!ctx.db) {
46
+ spinner.fail("Database not available");
47
+ process.exit(1);
48
+ }
49
+ const db = ctx.db.getDatabase();
50
+ ensureLowcodeTables(db);
51
+
52
+ const result = createApp(db, {
53
+ name,
54
+ description: options.description,
55
+ platform: options.platform,
56
+ });
57
+
58
+ spinner.stop();
59
+
60
+ if (options.json) {
61
+ console.log(JSON.stringify(result, null, 2));
62
+ } else {
63
+ logger.log(
64
+ chalk.green(`Application created: ${chalk.bold(result.name)}`),
65
+ );
66
+ logger.log(` ID: ${chalk.cyan(result.id)}`);
67
+ logger.log(` Status: ${result.status}`);
68
+ }
69
+
70
+ await shutdown();
71
+ } catch (err) {
72
+ spinner.fail(`Failed: ${err.message}`);
73
+ process.exit(1);
74
+ }
75
+ });
76
+
77
+ // lowcode list
78
+ lowcode
79
+ .command("list")
80
+ .description("List all low-code applications")
81
+ .option("--json", "Output as JSON")
82
+ .action(async (options) => {
83
+ try {
84
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
85
+ if (!ctx.db) {
86
+ logger.error("Database not available");
87
+ process.exit(1);
88
+ }
89
+ const db = ctx.db.getDatabase();
90
+ ensureLowcodeTables(db);
91
+
92
+ const apps = listApps(db);
93
+
94
+ if (options.json) {
95
+ console.log(JSON.stringify(apps, null, 2));
96
+ } else if (apps.length === 0) {
97
+ logger.info(
98
+ 'No applications found. Create one with "chainlesschain lowcode create <name>"',
99
+ );
100
+ } else {
101
+ logger.log(chalk.bold(`Applications (${apps.length}):\n`));
102
+ for (const app of apps) {
103
+ const status =
104
+ app.status === "published"
105
+ ? chalk.green(app.status)
106
+ : chalk.yellow(app.status);
107
+ logger.log(
108
+ ` ${chalk.cyan(app.name)} [${status}] v${app.version} (${app.platform})`,
109
+ );
110
+ if (app.description)
111
+ logger.log(` ${chalk.gray(app.description)}`);
112
+ }
113
+ }
114
+
115
+ await shutdown();
116
+ } catch (err) {
117
+ logger.error(`Failed: ${err.message}`);
118
+ process.exit(1);
119
+ }
120
+ });
121
+
122
+ // lowcode preview <app-id>
123
+ lowcode
124
+ .command("preview")
125
+ .description("Preview application info")
126
+ .argument("<app-id>", "Application ID")
127
+ .action(async (appId) => {
128
+ try {
129
+ const preview = previewApp(appId);
130
+
131
+ logger.log(chalk.bold("Application Preview:"));
132
+ logger.log(` App ID: ${chalk.cyan(preview.appId)}`);
133
+ logger.log(` Platform: ${preview.platform}`);
134
+ logger.log(` Preview URL: ${chalk.underline(preview.previewUrl)}`);
135
+ logger.log(
136
+ ` Components: ${(preview.design.components || []).length}`,
137
+ );
138
+ } catch (err) {
139
+ logger.error(`Failed: ${err.message}`);
140
+ process.exit(1);
141
+ }
142
+ });
143
+
144
+ // lowcode publish <app-id>
145
+ lowcode
146
+ .command("publish")
147
+ .description("Publish an application")
148
+ .argument("<app-id>", "Application ID")
149
+ .action(async (appId) => {
150
+ const spinner = ora("Publishing application...").start();
151
+ try {
152
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
153
+ if (!ctx.db) {
154
+ spinner.fail("Database not available");
155
+ process.exit(1);
156
+ }
157
+ const db = ctx.db.getDatabase();
158
+ ensureLowcodeTables(db);
159
+
160
+ const result = publishApp(db, appId);
161
+ spinner.succeed(`Application ${chalk.cyan(appId)} published`);
162
+
163
+ await shutdown();
164
+ } catch (err) {
165
+ spinner.fail(`Failed: ${err.message}`);
166
+ process.exit(1);
167
+ }
168
+ });
169
+
170
+ // lowcode components
171
+ lowcode
172
+ .command("components")
173
+ .description("List available built-in components")
174
+ .option("--json", "Output as JSON")
175
+ .action((options) => {
176
+ const components = listComponents();
177
+
178
+ if (options.json) {
179
+ console.log(JSON.stringify(components, null, 2));
180
+ } else {
181
+ logger.log(chalk.bold(`Built-in Components (${components.length}):\n`));
182
+ const categories = [...new Set(components.map((c) => c.category))];
183
+ for (const cat of categories) {
184
+ logger.log(chalk.yellow(` [${cat}]`));
185
+ for (const comp of components.filter((c) => c.category === cat)) {
186
+ logger.log(
187
+ ` ${chalk.cyan(comp.name)} — props: ${comp.props.join(", ")}`,
188
+ );
189
+ }
190
+ }
191
+ }
192
+ });
193
+
194
+ // lowcode datasource <app-id> <name> <type>
195
+ lowcode
196
+ .command("datasource")
197
+ .description("Add a data source to an application")
198
+ .argument("<app-id>", "Application ID")
199
+ .argument("<name>", "Data source name")
200
+ .argument("<type>", "Data source type (rest|graphql|database|csv)")
201
+ .option("--config <json>", "Configuration as JSON string", "{}")
202
+ .action(async (appId, name, type, options) => {
203
+ const spinner = ora("Adding data source...").start();
204
+ try {
205
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
206
+ if (!ctx.db) {
207
+ spinner.fail("Database not available");
208
+ process.exit(1);
209
+ }
210
+ const db = ctx.db.getDatabase();
211
+ ensureLowcodeTables(db);
212
+
213
+ let config;
214
+ try {
215
+ config = JSON.parse(options.config);
216
+ } catch (_err) {
217
+ // Intentionally ignore parse error — use empty config
218
+ config = {};
219
+ }
220
+
221
+ const result = addDataSource(db, appId, name, type, config);
222
+ spinner.succeed(`Data source "${chalk.cyan(name)}" added (${type})`);
223
+ logger.log(` ID: ${chalk.gray(result.id)}`);
224
+
225
+ await shutdown();
226
+ } catch (err) {
227
+ spinner.fail(`Failed: ${err.message}`);
228
+ process.exit(1);
229
+ }
230
+ });
231
+
232
+ // lowcode versions <app-id>
233
+ lowcode
234
+ .command("versions")
235
+ .description("Show version history for an application")
236
+ .argument("<app-id>", "Application ID")
237
+ .option("--json", "Output as JSON")
238
+ .action((appId, options) => {
239
+ const versions = getVersions(appId);
240
+
241
+ if (options.json) {
242
+ console.log(JSON.stringify(versions, null, 2));
243
+ } else if (versions.length === 0) {
244
+ logger.info("No versions found for this application");
245
+ } else {
246
+ logger.log(chalk.bold(`Version History (${versions.length}):\n`));
247
+ for (const v of versions) {
248
+ logger.log(` v${v.version} — ${v.created_at || "unknown date"}`);
249
+ }
250
+ }
251
+ });
252
+
253
+ // lowcode rollback <app-id> <version>
254
+ lowcode
255
+ .command("rollback")
256
+ .description("Rollback application to a previous version")
257
+ .argument("<app-id>", "Application ID")
258
+ .argument("<version>", "Version number to restore")
259
+ .action(async (appId, version) => {
260
+ const spinner = ora(`Rolling back to version ${version}...`).start();
261
+ try {
262
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
263
+ if (!ctx.db) {
264
+ spinner.fail("Database not available");
265
+ process.exit(1);
266
+ }
267
+ const db = ctx.db.getDatabase();
268
+ ensureLowcodeTables(db);
269
+
270
+ const result = rollbackApp(db, appId, parseInt(version, 10));
271
+
272
+ if (result.restored) {
273
+ spinner.succeed(`Rolled back to version ${version}`);
274
+ } else {
275
+ spinner.fail(`Version ${version} not found`);
276
+ }
277
+
278
+ await shutdown();
279
+ } catch (err) {
280
+ spinner.fail(`Failed: ${err.message}`);
281
+ process.exit(1);
282
+ }
283
+ });
284
+
285
+ // lowcode export <app-id>
286
+ lowcode
287
+ .command("export")
288
+ .description("Export application definition")
289
+ .argument("<app-id>", "Application ID")
290
+ .option("--json", "Output as JSON")
291
+ .action((appId, options) => {
292
+ const result = exportApp(appId);
293
+
294
+ if (options.json) {
295
+ console.log(JSON.stringify(result, null, 2));
296
+ } else {
297
+ logger.log(chalk.bold("Application Export:"));
298
+ logger.log(` App ID: ${chalk.cyan(result.appId)}`);
299
+ logger.log(
300
+ ` App: ${result.app ? result.app.name : "not found"}`,
301
+ );
302
+ logger.log(` Data Sources: ${result.dataSources.length}`);
303
+ logger.log(` Versions: ${result.versions.length}`);
304
+ }
305
+ });
306
+
307
+ // lowcode deploy <app-id>
308
+ lowcode
309
+ .command("deploy")
310
+ .description("Deploy application (placeholder)")
311
+ .argument("<app-id>", "Application ID")
312
+ .action(async (appId) => {
313
+ logger.log(
314
+ chalk.yellow(
315
+ `Deploy for app ${chalk.cyan(appId)} is a placeholder. ` +
316
+ "Full deployment support coming in a future release.",
317
+ ),
318
+ );
319
+ });
320
+ }
@@ -20,6 +20,9 @@ import {
20
20
  listRegistry,
21
21
  registerInMarketplace,
22
22
  getPluginSummary,
23
+ installPluginSkills,
24
+ removePluginSkills,
25
+ getPluginSkills,
23
26
  } from "../lib/plugin-manager.js";
24
27
 
25
28
  export function registerPluginCommand(program) {
@@ -86,6 +89,7 @@ export function registerPluginCommand(program) {
86
89
  .option("--version <version>", "Plugin version", "1.0.0")
87
90
  .option("--description <desc>", "Plugin description")
88
91
  .option("--author <author>", "Plugin author")
92
+ .option("--manifest <path>", "Plugin manifest file with skill declarations")
89
93
  .option("--json", "Output as JSON")
90
94
  .action(async (name, options) => {
91
95
  try {
@@ -102,10 +106,43 @@ export function registerPluginCommand(program) {
102
106
  author: options.author,
103
107
  });
104
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
+
105
131
  if (options.json) {
106
- console.log(JSON.stringify(result, null, 2));
132
+ console.log(
133
+ JSON.stringify(
134
+ { ...result, skills: skillResult.installed },
135
+ null,
136
+ 2,
137
+ ),
138
+ );
107
139
  } else {
108
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
+ }
109
146
  }
110
147
 
111
148
  await shutdown();
@@ -140,10 +177,16 @@ export function registerPluginCommand(program) {
140
177
  process.exit(1);
141
178
  }
142
179
  const db = ctx.db.getDatabase();
180
+
181
+ // Remove plugin skills first
182
+ const skillResult = removePluginSkills(db, name);
143
183
  const ok = removePlugin(db, name);
144
184
 
145
185
  if (ok) {
146
186
  logger.success(`Plugin removed: ${name}`);
187
+ if (skillResult.removed.length > 0) {
188
+ logger.info(`Skills removed: ${skillResult.removed.join(", ")}`);
189
+ }
147
190
  } else {
148
191
  logger.error(`Plugin not found: ${name}`);
149
192
  }
@@ -262,9 +305,10 @@ export function registerPluginCommand(program) {
262
305
  }
263
306
 
264
307
  const settings = getPluginSettings(db, name);
308
+ const skills = getPluginSkills(db, name);
265
309
 
266
310
  if (options.json) {
267
- console.log(JSON.stringify({ ...p, settings }, null, 2));
311
+ console.log(JSON.stringify({ ...p, settings, skills }, null, 2));
268
312
  } else {
269
313
  logger.log(chalk.bold("Plugin Info:\n"));
270
314
  logger.log(` ${chalk.bold("Name:")} ${chalk.cyan(p.name)}`);
@@ -280,6 +324,15 @@ export function registerPluginCommand(program) {
280
324
  );
281
325
  logger.log(` ${chalk.bold("Installed:")} ${p.installed_at}`);
282
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
+
283
336
  if (Object.keys(settings).length > 0) {
284
337
  logger.log(`\n ${chalk.bold("Settings:")}`);
285
338
  for (const [k, v] of Object.entries(settings)) {