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,215 @@
1
+ /**
2
+ * Git integration commands
3
+ * chainlesschain git status|auto-commit|hooks|history-analyze
4
+ */
5
+
6
+ import chalk from "chalk";
7
+ import { resolve } from "path";
8
+ import { logger } from "../lib/logger.js";
9
+ import {
10
+ gitStatus,
11
+ gitAutoCommit,
12
+ gitLog,
13
+ gitHistoryAnalyze,
14
+ gitInit,
15
+ isGitRepo,
16
+ } from "../lib/git-integration.js";
17
+
18
+ export function registerGitCommand(program) {
19
+ const git = program
20
+ .command("git")
21
+ .description("Git integration for knowledge base versioning");
22
+
23
+ // git status
24
+ git
25
+ .command("status")
26
+ .description("Show git status of the knowledge base directory")
27
+ .option("-d, --dir <dir>", "Target directory", ".")
28
+ .option("--json", "Output as JSON")
29
+ .action(async (options) => {
30
+ try {
31
+ const dir = resolve(options.dir);
32
+ const status = gitStatus(dir);
33
+
34
+ if (options.json) {
35
+ console.log(JSON.stringify(status, null, 2));
36
+ return;
37
+ }
38
+
39
+ if (!status.isRepo) {
40
+ logger.info(
41
+ `Not a git repository: ${dir}\n Run ${chalk.cyan("chainlesschain git init")} to initialize.`,
42
+ );
43
+ return;
44
+ }
45
+
46
+ logger.log(chalk.bold(`Branch: ${chalk.cyan(status.branch)}`));
47
+
48
+ if (status.clean) {
49
+ logger.log(chalk.green("Working tree clean"));
50
+ } else {
51
+ logger.log(`\n${status.files.length} changed file(s):\n`);
52
+ for (const f of status.files) {
53
+ const statusColor =
54
+ f.status === "M"
55
+ ? chalk.yellow
56
+ : f.status === "A" || f.status === "??"
57
+ ? chalk.green
58
+ : f.status === "D"
59
+ ? chalk.red
60
+ : chalk.white;
61
+ logger.log(` ${statusColor(f.status.padEnd(3))} ${f.file}`);
62
+ }
63
+ }
64
+ } catch (err) {
65
+ logger.error(`Git status failed: ${err.message}`);
66
+ process.exit(1);
67
+ }
68
+ });
69
+
70
+ // git init
71
+ git
72
+ .command("init")
73
+ .description("Initialize a git repository")
74
+ .option("-d, --dir <dir>", "Target directory", ".")
75
+ .action(async (options) => {
76
+ try {
77
+ const dir = resolve(options.dir);
78
+ const result = gitInit(dir);
79
+ if (result.initialized) {
80
+ logger.success(`Initialized git repository in ${chalk.gray(dir)}`);
81
+ } else {
82
+ logger.info(result.message);
83
+ }
84
+ } catch (err) {
85
+ logger.error(`Git init failed: ${err.message}`);
86
+ process.exit(1);
87
+ }
88
+ });
89
+
90
+ // git auto-commit
91
+ git
92
+ .command("auto-commit")
93
+ .description("Auto-commit all changes with a generated message")
94
+ .option("-d, --dir <dir>", "Target directory", ".")
95
+ .option("-m, --message <msg>", "Custom commit message")
96
+ .option("--json", "Output as JSON")
97
+ .action(async (options) => {
98
+ try {
99
+ const dir = resolve(options.dir);
100
+ const result = gitAutoCommit(dir, options.message);
101
+
102
+ if (options.json) {
103
+ console.log(JSON.stringify(result, null, 2));
104
+ return;
105
+ }
106
+
107
+ if (!result.committed) {
108
+ logger.info(result.message);
109
+ } else {
110
+ logger.success(
111
+ `Committed ${chalk.cyan(result.hash)}: ${result.message}`,
112
+ );
113
+ logger.log(chalk.gray(` ${result.filesChanged} file(s) changed`));
114
+ }
115
+ } catch (err) {
116
+ logger.error(`Auto-commit failed: ${err.message}`);
117
+ process.exit(1);
118
+ }
119
+ });
120
+
121
+ // git hooks
122
+ git
123
+ .command("hooks")
124
+ .description("Install git hooks for the knowledge base")
125
+ .option("-d, --dir <dir>", "Target directory", ".")
126
+ .option("--install", "Install hooks")
127
+ .action(async (options) => {
128
+ try {
129
+ const dir = resolve(options.dir);
130
+
131
+ if (!isGitRepo(dir)) {
132
+ logger.error("Not a git repository. Run 'git init' first.");
133
+ process.exit(1);
134
+ }
135
+
136
+ if (options.install) {
137
+ const { installHooks } = await import("../lib/git-integration.js");
138
+ const result = installHooks(dir);
139
+ logger.success(
140
+ `Installed ${chalk.cyan(result.hook)} hook at ${chalk.gray(result.path)}`,
141
+ );
142
+ } else {
143
+ logger.info(`Use ${chalk.cyan("--install")} to install git hooks`);
144
+ }
145
+ } catch (err) {
146
+ logger.error(`Hooks failed: ${err.message}`);
147
+ process.exit(1);
148
+ }
149
+ });
150
+
151
+ // git history-analyze
152
+ git
153
+ .command("history-analyze")
154
+ .description("Analyze repository history and statistics")
155
+ .option("-d, --dir <dir>", "Target directory", ".")
156
+ .option("-n, --limit <n>", "Recent commits to show", "10")
157
+ .option("--json", "Output as JSON")
158
+ .action(async (options) => {
159
+ try {
160
+ const dir = resolve(options.dir);
161
+
162
+ if (!isGitRepo(dir)) {
163
+ logger.error("Not a git repository");
164
+ process.exit(1);
165
+ }
166
+
167
+ const analysis = gitHistoryAnalyze(dir);
168
+ const recentLog = gitLog(dir, parseInt(options.limit));
169
+
170
+ if (options.json) {
171
+ console.log(
172
+ JSON.stringify({ ...analysis, recentCommits: recentLog }, null, 2),
173
+ );
174
+ return;
175
+ }
176
+
177
+ logger.log(chalk.bold("Repository Analysis\n"));
178
+ logger.log(
179
+ ` ${chalk.gray("Total commits:")} ${analysis.totalCommits}`,
180
+ );
181
+ logger.log(
182
+ ` ${chalk.gray("Tracked files:")} ${analysis.trackedFiles}`,
183
+ );
184
+ if (analysis.firstCommit) {
185
+ logger.log(
186
+ ` ${chalk.gray("First commit:")} ${analysis.firstCommit}`,
187
+ );
188
+ }
189
+ if (analysis.lastCommit) {
190
+ logger.log(` ${chalk.gray("Last commit:")} ${analysis.lastCommit}`);
191
+ }
192
+
193
+ if (analysis.contributors.length > 0) {
194
+ logger.log(chalk.bold("\nContributors:\n"));
195
+ for (const c of analysis.contributors) {
196
+ logger.log(
197
+ ` ${chalk.cyan(c.commits.toString().padStart(4))} ${c.author}`,
198
+ );
199
+ }
200
+ }
201
+
202
+ if (recentLog.length > 0) {
203
+ logger.log(chalk.bold("\nRecent Commits:\n"));
204
+ for (const c of recentLog) {
205
+ logger.log(
206
+ ` ${chalk.yellow(c.shortHash)} ${chalk.white(c.subject)} ${chalk.gray(c.date)}`,
207
+ );
208
+ }
209
+ }
210
+ } catch (err) {
211
+ logger.error(`Analysis failed: ${err.message}`);
212
+ process.exit(1);
213
+ }
214
+ });
215
+ }
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Hierarchical Memory 2.0 commands
3
+ * chainlesschain hmemory store|recall|consolidate|search|stats|share|prune
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
+ storeMemory,
12
+ recallMemory,
13
+ consolidateMemory,
14
+ searchEpisodic,
15
+ searchSemantic,
16
+ getMemoryStats,
17
+ shareMemory,
18
+ pruneMemory,
19
+ } from "../lib/hierarchical-memory.js";
20
+
21
+ export function registerHmemoryCommand(program) {
22
+ const hmemory = program
23
+ .command("hmemory")
24
+ .description("Hierarchical Memory 2.0 — four-layer memory system");
25
+
26
+ // hmemory store <content>
27
+ hmemory
28
+ .command("store")
29
+ .description("Store a memory at the appropriate layer")
30
+ .argument("<content>", "Memory content")
31
+ .option("--importance <n>", "Importance 0.0-1.0", "0.5")
32
+ .option("--type <type>", "Memory type (episodic|semantic)", "episodic")
33
+ .option("--core", "Force store as core memory (importance=1.0)")
34
+ .option("--json", "Output as JSON")
35
+ .action(async (content, 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 importance = options.core
44
+ ? 1.0
45
+ : parseFloat(options.importance) || 0.5;
46
+ const entry = storeMemory(db, content, {
47
+ importance,
48
+ type: options.type,
49
+ });
50
+
51
+ if (options.json) {
52
+ console.log(JSON.stringify(entry, null, 2));
53
+ } else {
54
+ logger.success(
55
+ `Memory stored: ${chalk.gray(entry.id.slice(0, 16))} → ${chalk.cyan(entry.layer)}`,
56
+ );
57
+ }
58
+
59
+ await shutdown();
60
+ } catch (err) {
61
+ logger.error(`Failed: ${err.message}`);
62
+ process.exit(1);
63
+ }
64
+ });
65
+
66
+ // hmemory recall <query>
67
+ hmemory
68
+ .command("recall")
69
+ .description("Recall memories with forgetting curve")
70
+ .argument("<query>", "Search query")
71
+ .option("-n, --limit <n>", "Max results", "20")
72
+ .option("--json", "Output as JSON")
73
+ .action(async (query, options) => {
74
+ try {
75
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
76
+ if (!ctx.db) {
77
+ logger.error("Database not available");
78
+ process.exit(1);
79
+ }
80
+ const db = ctx.db.getDatabase();
81
+ const results = recallMemory(db, query, {
82
+ limit: parseInt(options.limit) || 20,
83
+ });
84
+
85
+ if (options.json) {
86
+ console.log(JSON.stringify(results, null, 2));
87
+ } else if (results.length === 0) {
88
+ logger.info(`No memories matching "${query}" above recall threshold`);
89
+ } else {
90
+ logger.log(chalk.bold(`Recalled ${results.length} memories:\n`));
91
+ for (const r of results) {
92
+ const retention = (r.retention * 100).toFixed(0);
93
+ logger.log(
94
+ ` ${chalk.gray(r.id.slice(0, 16))} [${chalk.cyan(r.layer)}] retention=${chalk.yellow(retention + "%")}`,
95
+ );
96
+ logger.log(
97
+ ` ${chalk.white(r.content.substring(0, 120).replace(/\n/g, " "))}`,
98
+ );
99
+ }
100
+ }
101
+
102
+ await shutdown();
103
+ } catch (err) {
104
+ logger.error(`Failed: ${err.message}`);
105
+ process.exit(1);
106
+ }
107
+ });
108
+
109
+ // hmemory consolidate
110
+ hmemory
111
+ .command("consolidate")
112
+ .description("Promote and forget memories across layers")
113
+ .action(async () => {
114
+ try {
115
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
116
+ if (!ctx.db) {
117
+ logger.error("Database not available");
118
+ process.exit(1);
119
+ }
120
+ const db = ctx.db.getDatabase();
121
+ const spinner = ora("Consolidating memories...").start();
122
+ const result = consolidateMemory(db);
123
+ spinner.succeed(
124
+ `Consolidation complete: ${chalk.green(result.promoted)} promoted, ${chalk.red(result.forgotten)} forgotten`,
125
+ );
126
+
127
+ await shutdown();
128
+ } catch (err) {
129
+ logger.error(`Failed: ${err.message}`);
130
+ process.exit(1);
131
+ }
132
+ });
133
+
134
+ // hmemory search <query>
135
+ hmemory
136
+ .command("search")
137
+ .description("Search memories by type")
138
+ .argument("<query>", "Search query")
139
+ .option("--type <type>", "Memory type (episodic|semantic)", "episodic")
140
+ .option("-n, --limit <n>", "Max results", "20")
141
+ .option("--json", "Output as JSON")
142
+ .action(async (query, options) => {
143
+ try {
144
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
145
+ if (!ctx.db) {
146
+ logger.error("Database not available");
147
+ process.exit(1);
148
+ }
149
+ const db = ctx.db.getDatabase();
150
+ const searchFn =
151
+ options.type === "semantic" ? searchSemantic : searchEpisodic;
152
+ const results = searchFn(db, query, {
153
+ limit: parseInt(options.limit) || 20,
154
+ });
155
+
156
+ if (options.json) {
157
+ console.log(JSON.stringify(results, null, 2));
158
+ } else if (results.length === 0) {
159
+ logger.info(`No ${options.type} memories matching "${query}"`);
160
+ } else {
161
+ logger.log(
162
+ chalk.bold(`${options.type} search (${results.length} results):\n`),
163
+ );
164
+ for (const r of results) {
165
+ logger.log(
166
+ ` ${chalk.gray(r.id.slice(0, 16))} [${chalk.cyan(r.layer)}] importance=${chalk.yellow(r.importance)}`,
167
+ );
168
+ logger.log(
169
+ ` ${chalk.white(r.content.substring(0, 120).replace(/\n/g, " "))}`,
170
+ );
171
+ }
172
+ }
173
+
174
+ await shutdown();
175
+ } catch (err) {
176
+ logger.error(`Failed: ${err.message}`);
177
+ process.exit(1);
178
+ }
179
+ });
180
+
181
+ // hmemory stats
182
+ hmemory
183
+ .command("stats")
184
+ .description("Show memory statistics")
185
+ .option("--json", "Output as JSON")
186
+ .action(async (options) => {
187
+ try {
188
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
189
+ if (!ctx.db) {
190
+ logger.error("Database not available");
191
+ process.exit(1);
192
+ }
193
+ const db = ctx.db.getDatabase();
194
+ const stats = getMemoryStats(db);
195
+
196
+ if (options.json) {
197
+ console.log(JSON.stringify(stats, null, 2));
198
+ } else {
199
+ logger.log(chalk.bold("Hierarchical Memory Stats:\n"));
200
+ logger.log(` Working: ${chalk.yellow(stats.working)}`);
201
+ logger.log(` Short-term: ${chalk.yellow(stats.shortTerm)}`);
202
+ logger.log(` Long-term: ${chalk.yellow(stats.longTerm)}`);
203
+ logger.log(` Core: ${chalk.yellow(stats.core)}`);
204
+ logger.log(` Shared: ${chalk.yellow(stats.shared)}`);
205
+ logger.log(
206
+ ` ${chalk.bold("Total:")} ${chalk.green(stats.total)}`,
207
+ );
208
+ }
209
+
210
+ await shutdown();
211
+ } catch (err) {
212
+ logger.error(`Failed: ${err.message}`);
213
+ process.exit(1);
214
+ }
215
+ });
216
+
217
+ // hmemory share <id> <agent-id>
218
+ hmemory
219
+ .command("share")
220
+ .description("Share a memory with another agent")
221
+ .argument("<id>", "Memory ID")
222
+ .argument("<agent-id>", "Target agent ID")
223
+ .option("--privacy <level>", "Privacy level (full|filtered)", "filtered")
224
+ .option("--json", "Output as JSON")
225
+ .action(async (id, agentId, options) => {
226
+ try {
227
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
228
+ if (!ctx.db) {
229
+ logger.error("Database not available");
230
+ process.exit(1);
231
+ }
232
+ const db = ctx.db.getDatabase();
233
+ const result = shareMemory(db, id, agentId, options.privacy);
234
+
235
+ if (options.json) {
236
+ console.log(JSON.stringify(result, null, 2));
237
+ } else {
238
+ logger.success(
239
+ `Memory ${chalk.gray(id.slice(0, 16))} shared with ${chalk.cyan(agentId)} [${options.privacy}]`,
240
+ );
241
+ }
242
+
243
+ await shutdown();
244
+ } catch (err) {
245
+ logger.error(`Failed: ${err.message}`);
246
+ process.exit(1);
247
+ }
248
+ });
249
+
250
+ // hmemory prune
251
+ hmemory
252
+ .command("prune")
253
+ .description("Remove weak old memories")
254
+ .option("--max-age <hours>", "Maximum age in hours", "720")
255
+ .action(async (options) => {
256
+ try {
257
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
258
+ if (!ctx.db) {
259
+ logger.error("Database not available");
260
+ process.exit(1);
261
+ }
262
+ const db = ctx.db.getDatabase();
263
+ const spinner = ora("Pruning stale memories...").start();
264
+ const result = pruneMemory(db, { maxAge: options.maxAge });
265
+ spinner.succeed(`Pruned ${chalk.red(result.pruned)} stale memories`);
266
+
267
+ await shutdown();
268
+ } catch (err) {
269
+ logger.error(`Failed: ${err.message}`);
270
+ process.exit(1);
271
+ }
272
+ });
273
+ }