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,249 @@
1
+ /**
2
+ * Sync commands
3
+ * chainlesschain sync status|push|pull|conflicts|resolve|log|clear
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
+ getSyncStatus,
11
+ pushResources,
12
+ pullResources,
13
+ getConflicts,
14
+ resolveConflict,
15
+ getSyncLog,
16
+ clearSyncData,
17
+ registerResource,
18
+ getAllSyncStates,
19
+ } from "../lib/sync-manager.js";
20
+
21
+ export function registerSyncCommand(program) {
22
+ const sync = program
23
+ .command("sync")
24
+ .description("File and knowledge synchronization");
25
+
26
+ // sync status
27
+ sync
28
+ .command("status", { isDefault: true })
29
+ .description("Show sync status")
30
+ .option("--json", "Output as JSON")
31
+ .action(async (options) => {
32
+ try {
33
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
34
+ if (!ctx.db) {
35
+ logger.error("Database not available");
36
+ process.exit(1);
37
+ }
38
+ const db = ctx.db.getDatabase();
39
+ const status = getSyncStatus(db);
40
+
41
+ if (options.json) {
42
+ console.log(JSON.stringify(status, null, 2));
43
+ } else {
44
+ logger.log(chalk.bold("Sync Status:\n"));
45
+ logger.log(` ${chalk.bold("Resources:")} ${status.totalResources}`);
46
+ logger.log(
47
+ ` ${chalk.bold("Pending:")} ${chalk.yellow(status.pending)}`,
48
+ );
49
+ logger.log(
50
+ ` ${chalk.bold("Synced:")} ${chalk.green(status.synced)}`,
51
+ );
52
+ logger.log(
53
+ ` ${chalk.bold("Conflicts:")} ${status.conflicts > 0 ? chalk.red(status.conflicts) : "0"}`,
54
+ );
55
+ }
56
+
57
+ await shutdown();
58
+ } catch (err) {
59
+ logger.error(`Failed: ${err.message}`);
60
+ process.exit(1);
61
+ }
62
+ });
63
+
64
+ // sync push
65
+ sync
66
+ .command("push")
67
+ .description("Push local changes to remote")
68
+ .option("--type <type>", "Resource type to push")
69
+ .action(async (options) => {
70
+ try {
71
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
72
+ if (!ctx.db) {
73
+ logger.error("Database not available");
74
+ process.exit(1);
75
+ }
76
+ const db = ctx.db.getDatabase();
77
+ const result = pushResources(db, options.type);
78
+ logger.success(`Pushed ${result.pushed}/${result.total} resources`);
79
+ await shutdown();
80
+ } catch (err) {
81
+ logger.error(`Failed: ${err.message}`);
82
+ process.exit(1);
83
+ }
84
+ });
85
+
86
+ // sync pull
87
+ sync
88
+ .command("pull")
89
+ .description("Pull remote changes to local")
90
+ .option("--type <type>", "Resource type to pull")
91
+ .action(async (options) => {
92
+ try {
93
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
94
+ if (!ctx.db) {
95
+ logger.error("Database not available");
96
+ process.exit(1);
97
+ }
98
+ const db = ctx.db.getDatabase();
99
+ const result = pullResources(db, options.type);
100
+ logger.success(
101
+ `Checked ${result.checked} resources, updated ${result.updated}`,
102
+ );
103
+ await shutdown();
104
+ } catch (err) {
105
+ logger.error(`Failed: ${err.message}`);
106
+ process.exit(1);
107
+ }
108
+ });
109
+
110
+ // sync conflicts
111
+ sync
112
+ .command("conflicts")
113
+ .description("Show sync conflicts")
114
+ .option("--all", "Include resolved conflicts")
115
+ .option("--json", "Output as JSON")
116
+ .action(async (options) => {
117
+ try {
118
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
119
+ if (!ctx.db) {
120
+ logger.error("Database not available");
121
+ process.exit(1);
122
+ }
123
+ const db = ctx.db.getDatabase();
124
+ const conflicts = getConflicts(db, { resolved: options.all });
125
+
126
+ if (options.json) {
127
+ console.log(JSON.stringify(conflicts, null, 2));
128
+ } else if (conflicts.length === 0) {
129
+ logger.info("No conflicts");
130
+ } else {
131
+ logger.log(chalk.bold(`Conflicts (${conflicts.length}):\n`));
132
+ for (const c of conflicts) {
133
+ const resolved = c.resolution
134
+ ? chalk.green("[resolved]")
135
+ : chalk.red("[unresolved]");
136
+ logger.log(` ${chalk.cyan(c.id)} ${resolved}`);
137
+ logger.log(
138
+ ` ${chalk.gray(`${c.resource_type}/${c.resource_id}`)}`,
139
+ );
140
+ }
141
+ }
142
+
143
+ await shutdown();
144
+ } catch (err) {
145
+ logger.error(`Failed: ${err.message}`);
146
+ process.exit(1);
147
+ }
148
+ });
149
+
150
+ // sync resolve
151
+ sync
152
+ .command("resolve")
153
+ .description("Resolve a sync conflict")
154
+ .argument("<conflict-id>", "Conflict ID")
155
+ .option("--use <side>", "Use local or remote version", "local")
156
+ .action(async (conflictId, options) => {
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 = resolveConflict(db, conflictId, options.use);
165
+
166
+ if (ok) {
167
+ logger.success(`Conflict resolved (${options.use})`);
168
+ } else {
169
+ logger.error(`Conflict not found: ${conflictId}`);
170
+ }
171
+
172
+ await shutdown();
173
+ } catch (err) {
174
+ logger.error(`Failed: ${err.message}`);
175
+ process.exit(1);
176
+ }
177
+ });
178
+
179
+ // sync log
180
+ sync
181
+ .command("log")
182
+ .description("Show sync operation log")
183
+ .option("--limit <n>", "Number of entries", "20")
184
+ .option("--json", "Output as JSON")
185
+ .action(async (options) => {
186
+ try {
187
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
188
+ if (!ctx.db) {
189
+ logger.error("Database not available");
190
+ process.exit(1);
191
+ }
192
+ const db = ctx.db.getDatabase();
193
+ const entries = getSyncLog(db, { limit: parseInt(options.limit) });
194
+
195
+ if (options.json) {
196
+ console.log(JSON.stringify(entries, null, 2));
197
+ } else if (entries.length === 0) {
198
+ logger.info("No sync log entries");
199
+ } else {
200
+ logger.log(chalk.bold(`Sync Log (${entries.length}):\n`));
201
+ for (const e of entries) {
202
+ const statusColor =
203
+ e.status === "success" ? chalk.green : chalk.red;
204
+ logger.log(
205
+ ` ${chalk.gray(e.created_at)} ${chalk.bold(e.operation)} ${statusColor(e.status)}`,
206
+ );
207
+ }
208
+ }
209
+
210
+ await shutdown();
211
+ } catch (err) {
212
+ logger.error(`Failed: ${err.message}`);
213
+ process.exit(1);
214
+ }
215
+ });
216
+
217
+ // sync clear
218
+ sync
219
+ .command("clear")
220
+ .description("Clear all sync data")
221
+ .option("--force", "Skip confirmation")
222
+ .action(async (options) => {
223
+ try {
224
+ if (!options.force) {
225
+ const { confirm } = await import("@inquirer/prompts");
226
+ const ok = await confirm({
227
+ message: "Clear all sync data? This cannot be undone.",
228
+ });
229
+ if (!ok) {
230
+ logger.info("Cancelled");
231
+ return;
232
+ }
233
+ }
234
+
235
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
236
+ if (!ctx.db) {
237
+ logger.error("Database not available");
238
+ process.exit(1);
239
+ }
240
+ const db = ctx.db.getDatabase();
241
+ clearSyncData(db);
242
+ logger.success("Sync data cleared");
243
+ await shutdown();
244
+ } catch (err) {
245
+ logger.error(`Failed: ${err.message}`);
246
+ process.exit(1);
247
+ }
248
+ });
249
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Token usage tracking commands
3
+ * chainlesschain tokens [show|breakdown|recent|reset]
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
+ getUsageStats,
11
+ getTodayStats,
12
+ getCostBreakdown,
13
+ getRecentUsage,
14
+ } from "../lib/token-tracker.js";
15
+ import {
16
+ getCacheStats,
17
+ clearCache,
18
+ clearExpired,
19
+ } from "../lib/response-cache.js";
20
+
21
+ export function registerTokensCommand(program) {
22
+ const tokens = program
23
+ .command("tokens")
24
+ .description("LLM token usage tracking and response cache");
25
+
26
+ // tokens show (default)
27
+ tokens
28
+ .command("show", { isDefault: true })
29
+ .description("Show token usage summary")
30
+ .option("--period <period>", "Time period: today, week, month, all", "all")
31
+ .option("--json", "Output as JSON")
32
+ .action(async (options) => {
33
+ try {
34
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
35
+ if (!ctx.db) {
36
+ logger.error("Database not available");
37
+ process.exit(1);
38
+ }
39
+ const db = ctx.db.getDatabase();
40
+
41
+ let statsOptions = {};
42
+ const now = new Date();
43
+ if (options.period === "today") {
44
+ statsOptions.startDate = now.toISOString().slice(0, 10);
45
+ } else if (options.period === "week") {
46
+ const weekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000);
47
+ statsOptions.startDate = weekAgo.toISOString().slice(0, 10);
48
+ } else if (options.period === "month") {
49
+ const monthAgo = new Date(now - 30 * 24 * 60 * 60 * 1000);
50
+ statsOptions.startDate = monthAgo.toISOString().slice(0, 10);
51
+ }
52
+
53
+ const stats = getUsageStats(db, statsOptions);
54
+ const todayStats = getTodayStats(db);
55
+
56
+ if (options.json) {
57
+ console.log(JSON.stringify({ stats, today: todayStats }, null, 2));
58
+ } else {
59
+ logger.log(chalk.bold(`Token Usage (${options.period}):\n`));
60
+ logger.log(` Total calls: ${chalk.cyan(stats.total_calls)}`);
61
+ logger.log(
62
+ ` Input tokens: ${chalk.cyan(stats.total_input_tokens.toLocaleString())}`,
63
+ );
64
+ logger.log(
65
+ ` Output tokens: ${chalk.cyan(stats.total_output_tokens.toLocaleString())}`,
66
+ );
67
+ logger.log(
68
+ ` Total tokens: ${chalk.cyan(stats.total_tokens.toLocaleString())}`,
69
+ );
70
+ logger.log(
71
+ ` Total cost: ${chalk.yellow("$" + stats.total_cost_usd.toFixed(4))}`,
72
+ );
73
+ logger.log(
74
+ ` Avg response: ${chalk.gray(Math.round(stats.avg_response_time_ms) + "ms")}`,
75
+ );
76
+
77
+ if (options.period !== "today") {
78
+ logger.log(chalk.bold("\n Today:"));
79
+ logger.log(
80
+ ` Calls: ${chalk.cyan(todayStats.total_calls)} Tokens: ${chalk.cyan(todayStats.total_tokens.toLocaleString())} Cost: ${chalk.yellow("$" + todayStats.total_cost_usd.toFixed(4))}`,
81
+ );
82
+ }
83
+ }
84
+
85
+ await shutdown();
86
+ } catch (err) {
87
+ logger.error(`Failed to get token stats: ${err.message}`);
88
+ process.exit(1);
89
+ }
90
+ });
91
+
92
+ // tokens breakdown
93
+ tokens
94
+ .command("breakdown")
95
+ .description("Show cost breakdown by provider/model")
96
+ .option("--json", "Output as JSON")
97
+ .action(async (options) => {
98
+ try {
99
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
100
+ if (!ctx.db) {
101
+ logger.error("Database not available");
102
+ process.exit(1);
103
+ }
104
+ const db = ctx.db.getDatabase();
105
+ const breakdown = getCostBreakdown(db);
106
+
107
+ if (options.json) {
108
+ console.log(JSON.stringify(breakdown, null, 2));
109
+ } else if (breakdown.length === 0) {
110
+ logger.info("No usage data yet");
111
+ } else {
112
+ logger.log(chalk.bold("Cost Breakdown:\n"));
113
+ for (const row of breakdown) {
114
+ logger.log(
115
+ ` ${chalk.cyan(row.provider)}/${chalk.white(row.model)}`,
116
+ );
117
+ logger.log(
118
+ ` Calls: ${row.calls} Tokens: ${row.total_tokens.toLocaleString()} Cost: ${chalk.yellow("$" + row.cost_usd.toFixed(4))}`,
119
+ );
120
+ }
121
+ }
122
+
123
+ await shutdown();
124
+ } catch (err) {
125
+ logger.error(`Failed: ${err.message}`);
126
+ process.exit(1);
127
+ }
128
+ });
129
+
130
+ // tokens recent
131
+ tokens
132
+ .command("recent")
133
+ .description("Show recent LLM calls")
134
+ .option("-n, --limit <n>", "Number of entries", "10")
135
+ .option("--json", "Output as JSON")
136
+ .action(async (options) => {
137
+ try {
138
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
139
+ if (!ctx.db) {
140
+ logger.error("Database not available");
141
+ process.exit(1);
142
+ }
143
+ const db = ctx.db.getDatabase();
144
+ const entries = getRecentUsage(
145
+ db,
146
+ Math.max(1, parseInt(options.limit) || 10),
147
+ );
148
+
149
+ if (options.json) {
150
+ console.log(JSON.stringify(entries, null, 2));
151
+ } else if (entries.length === 0) {
152
+ logger.info("No recent usage");
153
+ } else {
154
+ logger.log(chalk.bold("Recent LLM Calls:\n"));
155
+ for (const e of entries) {
156
+ logger.log(
157
+ ` ${chalk.gray(e.created_at)} ${chalk.cyan(e.provider)}/${chalk.white(e.model)} ${e.total_tokens} tokens ${chalk.yellow("$" + e.cost_usd.toFixed(4))} ${chalk.gray(e.response_time_ms + "ms")}`,
158
+ );
159
+ }
160
+ }
161
+
162
+ await shutdown();
163
+ } catch (err) {
164
+ logger.error(`Failed: ${err.message}`);
165
+ process.exit(1);
166
+ }
167
+ });
168
+
169
+ // tokens cache
170
+ tokens
171
+ .command("cache")
172
+ .description("Show response cache statistics")
173
+ .option("--clear", "Clear all cached responses")
174
+ .option("--cleanup", "Remove expired entries only")
175
+ .option("--json", "Output as JSON")
176
+ .action(async (options) => {
177
+ try {
178
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
179
+ if (!ctx.db) {
180
+ logger.error("Database not available");
181
+ process.exit(1);
182
+ }
183
+ const db = ctx.db.getDatabase();
184
+
185
+ if (options.clear) {
186
+ clearCache(db);
187
+ logger.success("Response cache cleared");
188
+ } else if (options.cleanup) {
189
+ const removed = clearExpired(db);
190
+ logger.success(`Removed ${removed} expired cache entries`);
191
+ } else {
192
+ const stats = getCacheStats(db);
193
+ if (options.json) {
194
+ console.log(JSON.stringify(stats, null, 2));
195
+ } else {
196
+ logger.log(chalk.bold("Response Cache:\n"));
197
+ logger.log(` Entries: ${chalk.cyan(stats.total_entries)}`);
198
+ logger.log(` Total hits: ${chalk.cyan(stats.total_hits)}`);
199
+ logger.log(
200
+ ` Tokens saved: ${chalk.green(stats.total_tokens_saved.toLocaleString())}`,
201
+ );
202
+ logger.log(
203
+ ` Expired: ${chalk.gray(stats.expired_entries)}`,
204
+ );
205
+ }
206
+ }
207
+
208
+ await shutdown();
209
+ } catch (err) {
210
+ logger.error(`Failed: ${err.message}`);
211
+ process.exit(1);
212
+ }
213
+ });
214
+ }