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.
- package/README.md +166 -10
- package/package.json +1 -1
- package/src/commands/a2a.js +374 -0
- package/src/commands/bi.js +240 -0
- package/src/commands/cowork.js +317 -0
- package/src/commands/economy.js +375 -0
- package/src/commands/evolution.js +398 -0
- package/src/commands/hmemory.js +273 -0
- package/src/commands/hook.js +260 -0
- package/src/commands/init.js +184 -0
- package/src/commands/lowcode.js +320 -0
- package/src/commands/plugin.js +55 -2
- package/src/commands/sandbox.js +366 -0
- package/src/commands/skill.js +254 -201
- package/src/commands/workflow.js +359 -0
- package/src/commands/zkp.js +277 -0
- package/src/index.js +44 -0
- package/src/lib/a2a-protocol.js +371 -0
- package/src/lib/agent-coordinator.js +273 -0
- package/src/lib/agent-economy.js +369 -0
- package/src/lib/app-builder.js +377 -0
- package/src/lib/bi-engine.js +299 -0
- package/src/lib/cowork/ab-comparator-cli.js +180 -0
- package/src/lib/cowork/code-knowledge-graph-cli.js +232 -0
- package/src/lib/cowork/debate-review-cli.js +144 -0
- package/src/lib/cowork/decision-kb-cli.js +153 -0
- package/src/lib/cowork/project-style-analyzer-cli.js +168 -0
- package/src/lib/cowork-adapter.js +106 -0
- package/src/lib/evolution-system.js +508 -0
- package/src/lib/hierarchical-memory.js +471 -0
- package/src/lib/hook-manager.js +387 -0
- package/src/lib/plugin-manager.js +118 -0
- package/src/lib/project-detector.js +53 -0
- package/src/lib/sandbox-v2.js +503 -0
- package/src/lib/service-container.js +183 -0
- package/src/lib/skill-loader.js +274 -0
- package/src/lib/workflow-engine.js +503 -0
- package/src/lib/zkp-engine.js +241 -0
- 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
|
+
}
|
package/src/commands/plugin.js
CHANGED
|
@@ -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(
|
|
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)) {
|