chainlesschain 0.47.9 → 0.51.0

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 (73) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AppLayout-6SPt_8Y_.js → AppLayout-Rvi759IS.js} +1 -1
  5. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +1 -0
  6. package/src/assets/web-panel/assets/{Dashboard-Br7kCwKJ.js → Dashboard-DBhFxXYQ.js} +2 -2
  7. package/src/assets/web-panel/assets/{index-tN-8TosE.js → index-uL0cZ8N_.js} +2 -2
  8. package/src/assets/web-panel/index.html +2 -2
  9. package/src/commands/codegen.js +303 -0
  10. package/src/commands/collab.js +482 -0
  11. package/src/commands/crosschain.js +382 -0
  12. package/src/commands/dbevo.js +388 -0
  13. package/src/commands/dev.js +411 -0
  14. package/src/commands/federation.js +427 -0
  15. package/src/commands/fusion.js +332 -0
  16. package/src/commands/governance.js +505 -0
  17. package/src/commands/hardening.js +110 -0
  18. package/src/commands/incentive.js +373 -0
  19. package/src/commands/inference.js +304 -0
  20. package/src/commands/infra.js +361 -0
  21. package/src/commands/ipfs.js +392 -0
  22. package/src/commands/kg.js +371 -0
  23. package/src/commands/marketplace.js +326 -0
  24. package/src/commands/mcp.js +97 -18
  25. package/src/commands/multimodal.js +404 -0
  26. package/src/commands/nlprog.js +329 -0
  27. package/src/commands/ops.js +408 -0
  28. package/src/commands/perception.js +385 -0
  29. package/src/commands/pqc.js +34 -0
  30. package/src/commands/privacy.js +345 -0
  31. package/src/commands/quantization.js +280 -0
  32. package/src/commands/recommend.js +336 -0
  33. package/src/commands/reputation.js +349 -0
  34. package/src/commands/runtime.js +500 -0
  35. package/src/commands/sla.js +352 -0
  36. package/src/commands/stress.js +252 -0
  37. package/src/commands/tech.js +268 -0
  38. package/src/commands/tenant.js +576 -0
  39. package/src/commands/trust.js +366 -0
  40. package/src/harness/mcp-client.js +330 -54
  41. package/src/index.js +118 -0
  42. package/src/lib/aiops.js +523 -0
  43. package/src/lib/autonomous-developer.js +524 -0
  44. package/src/lib/code-agent.js +442 -0
  45. package/src/lib/collaboration-governance.js +556 -0
  46. package/src/lib/community-governance.js +649 -0
  47. package/src/lib/content-recommendation.js +600 -0
  48. package/src/lib/cross-chain.js +669 -0
  49. package/src/lib/dbevo.js +669 -0
  50. package/src/lib/decentral-infra.js +445 -0
  51. package/src/lib/federation-hardening.js +587 -0
  52. package/src/lib/hardening-manager.js +409 -0
  53. package/src/lib/inference-network.js +407 -0
  54. package/src/lib/ipfs-storage.js +575 -0
  55. package/src/lib/knowledge-graph.js +530 -0
  56. package/src/lib/mcp-client.js +3 -0
  57. package/src/lib/multimodal.js +725 -0
  58. package/src/lib/nl-programming.js +595 -0
  59. package/src/lib/perception.js +500 -0
  60. package/src/lib/pqc-manager.js +141 -9
  61. package/src/lib/privacy-computing.js +575 -0
  62. package/src/lib/protocol-fusion.js +535 -0
  63. package/src/lib/quantization.js +362 -0
  64. package/src/lib/reputation-optimizer.js +509 -0
  65. package/src/lib/skill-marketplace.js +397 -0
  66. package/src/lib/sla-manager.js +484 -0
  67. package/src/lib/stress-tester.js +383 -0
  68. package/src/lib/tech-learning-engine.js +651 -0
  69. package/src/lib/tenant-saas.js +831 -0
  70. package/src/lib/token-incentive.js +513 -0
  71. package/src/lib/trust-security.js +473 -0
  72. package/src/lib/universal-runtime.js +771 -0
  73. package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +0 -1
@@ -0,0 +1,445 @@
1
+ /**
2
+ * Decentralized Infrastructure — CLI port of Phase 74-75
3
+ * (docs/design/modules/41_去中心化基础设��系统.md).
4
+ *
5
+ * Desktop uses real Filecoin storage, IPLD content distribution,
6
+ * Tor hidden services, CDN domain fronting, and BLE/WiFi-Direct mesh.
7
+ * CLI port ships:
8
+ *
9
+ * - Filecoin deal CRUD (simulated storage deal lifecycle)
10
+ * - Content version tracking (IPLD-style versioning)
11
+ * - Anti-censorship route registry (Tor/domain-front/mesh simulation)
12
+ *
13
+ * What does NOT port: real Filecoin, IPFS/IPLD, Tor daemon,
14
+ * CDN domain fronting, BLE/WiFi-Direct mesh networking.
15
+ */
16
+
17
+ import crypto from "crypto";
18
+
19
+ /* ── Constants ────────────────��────────────────────────────── */
20
+
21
+ export const DEAL_STATUS = Object.freeze({
22
+ PENDING: "pending",
23
+ ACTIVE: "active",
24
+ EXPIRED: "expired",
25
+ FAILED: "failed",
26
+ });
27
+
28
+ export const ROUTE_TYPE = Object.freeze({
29
+ TOR: "tor",
30
+ DOMAIN_FRONT: "domain_front",
31
+ MESH_BLE: "mesh_ble",
32
+ MESH_WIFI: "mesh_wifi",
33
+ DIRECT: "direct",
34
+ });
35
+
36
+ export const ROUTE_STATUS = Object.freeze({
37
+ ACTIVE: "active",
38
+ INACTIVE: "inactive",
39
+ DEGRADED: "degraded",
40
+ });
41
+
42
+ /* ── State ─────────────��────────────────────────────��──── */
43
+
44
+ let _deals = new Map();
45
+ let _versions = new Map();
46
+ let _routes = new Map();
47
+
48
+ function _id() {
49
+ return crypto.randomUUID();
50
+ }
51
+ function _now() {
52
+ return Date.now();
53
+ }
54
+
55
+ function _strip(row) {
56
+ if (!row) return null;
57
+ const out = {};
58
+ for (const [k, v] of Object.entries(row)) {
59
+ if (k !== "_rowid_" && k !== "rowid") out[k] = v;
60
+ }
61
+ return out;
62
+ }
63
+
64
+ /* ── Schema ────────────────────────────────────────────── */
65
+
66
+ export function ensureDecentralInfraTables(db) {
67
+ db.exec(`CREATE TABLE IF NOT EXISTS filecoin_deals (
68
+ id TEXT PRIMARY KEY,
69
+ cid TEXT NOT NULL,
70
+ miner_id TEXT,
71
+ size_bytes INTEGER,
72
+ price_fil REAL,
73
+ duration_epochs INTEGER,
74
+ status TEXT DEFAULT 'pending',
75
+ verified INTEGER DEFAULT 0,
76
+ renewal_count INTEGER DEFAULT 0,
77
+ expires_at INTEGER,
78
+ created_at INTEGER
79
+ )`);
80
+
81
+ db.exec(`CREATE TABLE IF NOT EXISTS content_versions (
82
+ id TEXT PRIMARY KEY,
83
+ content_cid TEXT NOT NULL,
84
+ version INTEGER DEFAULT 1,
85
+ parent_cid TEXT,
86
+ dag_structure TEXT,
87
+ cached INTEGER DEFAULT 0,
88
+ peer_count INTEGER DEFAULT 0,
89
+ created_at INTEGER
90
+ )`);
91
+
92
+ db.exec(`CREATE TABLE IF NOT EXISTS anti_censorship_routes (
93
+ id TEXT PRIMARY KEY,
94
+ route_type TEXT NOT NULL,
95
+ endpoint TEXT,
96
+ status TEXT DEFAULT 'active',
97
+ latency_ms INTEGER,
98
+ reliability REAL DEFAULT 1.0,
99
+ last_used INTEGER,
100
+ created_at INTEGER
101
+ )`);
102
+
103
+ _loadAll(db);
104
+ }
105
+
106
+ function _loadAll(db) {
107
+ _deals.clear();
108
+ _versions.clear();
109
+ _routes.clear();
110
+
111
+ const tables = [
112
+ ["filecoin_deals", _deals],
113
+ ["content_versions", _versions],
114
+ ["anti_censorship_routes", _routes],
115
+ ];
116
+ for (const [table, map] of tables) {
117
+ try {
118
+ for (const row of db.prepare(`SELECT * FROM ${table}`).all()) {
119
+ const r = _strip(row);
120
+ map.set(r.id, r);
121
+ }
122
+ } catch (_e) {
123
+ /* table may not exist */
124
+ }
125
+ }
126
+ }
127
+
128
+ /* ── Phase 74: Filecoin Storage ──────────────────────────── */
129
+
130
+ export function createDeal(
131
+ db,
132
+ { cid, minerId, sizeBytes, priceFil, durationEpochs } = {},
133
+ ) {
134
+ if (!cid) return { dealId: null, reason: "missing_cid" };
135
+ if (!sizeBytes || sizeBytes <= 0)
136
+ return { dealId: null, reason: "invalid_size" };
137
+
138
+ const id = _id();
139
+ const now = _now();
140
+ const price = priceFil || 0;
141
+ const duration = durationEpochs || 518400; // ~180 days
142
+ const expiresAt = now + duration * 30000; // simulated epoch → ms
143
+
144
+ const deal = {
145
+ id,
146
+ cid,
147
+ miner_id: minerId || null,
148
+ size_bytes: sizeBytes,
149
+ price_fil: price,
150
+ duration_epochs: duration,
151
+ status: "pending",
152
+ verified: 0,
153
+ renewal_count: 0,
154
+ expires_at: expiresAt,
155
+ created_at: now,
156
+ };
157
+
158
+ db.prepare(
159
+ `INSERT INTO filecoin_deals (id, cid, miner_id, size_bytes, price_fil, duration_epochs, status, verified, renewal_count, expires_at, created_at)
160
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
161
+ ).run(
162
+ id,
163
+ cid,
164
+ deal.miner_id,
165
+ sizeBytes,
166
+ price,
167
+ duration,
168
+ "pending",
169
+ 0,
170
+ 0,
171
+ expiresAt,
172
+ now,
173
+ );
174
+
175
+ _deals.set(id, deal);
176
+ return { dealId: id };
177
+ }
178
+
179
+ export function updateDealStatus(db, id, status) {
180
+ const validTransitions = {
181
+ pending: ["active", "failed"],
182
+ active: ["expired", "failed"],
183
+ failed: ["pending"], // retry
184
+ };
185
+
186
+ const d = _deals.get(id);
187
+ if (!d) return { updated: false, reason: "not_found" };
188
+
189
+ const allowed = validTransitions[d.status];
190
+ if (!allowed || !allowed.includes(status))
191
+ return { updated: false, reason: "invalid_transition" };
192
+
193
+ d.status = status;
194
+ if (status === "active") d.verified = 1;
195
+
196
+ db.prepare(
197
+ "UPDATE filecoin_deals SET status = ?, verified = ? WHERE id = ?",
198
+ ).run(d.status, d.verified, id);
199
+
200
+ return { updated: true };
201
+ }
202
+
203
+ export function renewDeal(db, id) {
204
+ const d = _deals.get(id);
205
+ if (!d) return { renewed: false, reason: "not_found" };
206
+ if (d.status !== "active" && d.status !== "expired")
207
+ return { renewed: false, reason: "deal_not_renewable" };
208
+
209
+ d.renewal_count += 1;
210
+ d.status = "active";
211
+ d.expires_at = _now() + d.duration_epochs * 30000;
212
+
213
+ db.prepare(
214
+ "UPDATE filecoin_deals SET renewal_count = ?, status = ?, expires_at = ? WHERE id = ?",
215
+ ).run(d.renewal_count, d.status, d.expires_at, id);
216
+
217
+ return { renewed: true, renewalCount: d.renewal_count };
218
+ }
219
+
220
+ export function getDeal(db, id) {
221
+ const d = _deals.get(id);
222
+ return d ? { ...d } : null;
223
+ }
224
+
225
+ export function listDeals(db, { status, limit = 50 } = {}) {
226
+ let deals = [..._deals.values()];
227
+ if (status) deals = deals.filter((d) => d.status === status);
228
+ return deals
229
+ .sort((a, b) => b.created_at - a.created_at)
230
+ .slice(0, limit)
231
+ .map((d) => ({ ...d }));
232
+ }
233
+
234
+ /* ── Content Versions ────────────────────────────────────── */
235
+
236
+ export function addContentVersion(
237
+ db,
238
+ { contentCid, parentCid, dagStructure, peerCount } = {},
239
+ ) {
240
+ if (!contentCid) return { versionId: null, reason: "missing_content_cid" };
241
+
242
+ // Determine version number
243
+ const existing = [..._versions.values()].filter(
244
+ (v) => v.content_cid === contentCid || v.content_cid === parentCid,
245
+ );
246
+ const version =
247
+ existing.length > 0 ? Math.max(...existing.map((v) => v.version)) + 1 : 1;
248
+
249
+ const id = _id();
250
+ const now = _now();
251
+ const entry = {
252
+ id,
253
+ content_cid: contentCid,
254
+ version,
255
+ parent_cid: parentCid || null,
256
+ dag_structure: dagStructure || null,
257
+ cached: 0,
258
+ peer_count: peerCount || 0,
259
+ created_at: now,
260
+ };
261
+
262
+ db.prepare(
263
+ `INSERT INTO content_versions (id, content_cid, version, parent_cid, dag_structure, cached, peer_count, created_at)
264
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
265
+ ).run(
266
+ id,
267
+ contentCid,
268
+ version,
269
+ entry.parent_cid,
270
+ entry.dag_structure,
271
+ 0,
272
+ entry.peer_count,
273
+ now,
274
+ );
275
+
276
+ _versions.set(id, entry);
277
+ return { versionId: id, version };
278
+ }
279
+
280
+ export function getContentVersion(db, id) {
281
+ const v = _versions.get(id);
282
+ return v ? { ...v } : null;
283
+ }
284
+
285
+ export function listContentVersions(db, { contentCid, limit = 50 } = {}) {
286
+ let vers = [..._versions.values()];
287
+ if (contentCid) vers = vers.filter((v) => v.content_cid === contentCid);
288
+ return vers
289
+ .sort((a, b) => b.version - a.version)
290
+ .slice(0, limit)
291
+ .map((v) => ({ ...v }));
292
+ }
293
+
294
+ export function cacheVersion(db, id) {
295
+ const v = _versions.get(id);
296
+ if (!v) return { cached: false, reason: "not_found" };
297
+ v.cached = 1;
298
+ db.prepare("UPDATE content_versions SET cached = 1 WHERE id = ?").run(id);
299
+ return { cached: true };
300
+ }
301
+
302
+ /* ── Phase 75: Anti-Censorship Routes ────────────────────── */
303
+
304
+ const VALID_ROUTE_TYPES = new Set(Object.values(ROUTE_TYPE));
305
+
306
+ export function addRoute(
307
+ db,
308
+ { routeType, endpoint, latencyMs, reliability } = {},
309
+ ) {
310
+ if (!routeType || !VALID_ROUTE_TYPES.has(routeType))
311
+ return { routeId: null, reason: "invalid_route_type" };
312
+
313
+ const id = _id();
314
+ const now = _now();
315
+ const rel = reliability != null ? Math.max(0, Math.min(1, reliability)) : 1.0;
316
+
317
+ const route = {
318
+ id,
319
+ route_type: routeType,
320
+ endpoint: endpoint || null,
321
+ status: "active",
322
+ latency_ms: latencyMs || null,
323
+ reliability: rel,
324
+ last_used: null,
325
+ created_at: now,
326
+ };
327
+
328
+ db.prepare(
329
+ `INSERT INTO anti_censorship_routes (id, route_type, endpoint, status, latency_ms, reliability, last_used, created_at)
330
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
331
+ ).run(
332
+ id,
333
+ routeType,
334
+ route.endpoint,
335
+ "active",
336
+ route.latency_ms,
337
+ rel,
338
+ null,
339
+ now,
340
+ );
341
+
342
+ _routes.set(id, route);
343
+ return { routeId: id };
344
+ }
345
+
346
+ export function updateRouteStatus(db, id, status) {
347
+ const validStatuses = new Set(Object.values(ROUTE_STATUS));
348
+ if (!validStatuses.has(status))
349
+ return { updated: false, reason: "invalid_status" };
350
+
351
+ const r = _routes.get(id);
352
+ if (!r) return { updated: false, reason: "not_found" };
353
+
354
+ r.status = status;
355
+ r.last_used = _now();
356
+ db.prepare(
357
+ "UPDATE anti_censorship_routes SET status = ?, last_used = ? WHERE id = ?",
358
+ ).run(status, r.last_used, id);
359
+
360
+ return { updated: true };
361
+ }
362
+
363
+ export function removeRoute(db, id) {
364
+ const r = _routes.get(id);
365
+ if (!r) return { removed: false, reason: "not_found" };
366
+ db.prepare("DELETE FROM anti_censorship_routes WHERE id = ?").run(id);
367
+ _routes.delete(id);
368
+ return { removed: true };
369
+ }
370
+
371
+ export function getRoute(db, id) {
372
+ const r = _routes.get(id);
373
+ return r ? { ...r } : null;
374
+ }
375
+
376
+ export function listRoutes(db, { routeType, status, limit = 50 } = {}) {
377
+ let routes = [..._routes.values()];
378
+ if (routeType) routes = routes.filter((r) => r.route_type === routeType);
379
+ if (status) routes = routes.filter((r) => r.status === status);
380
+ return routes
381
+ .sort((a, b) => b.created_at - a.created_at)
382
+ .slice(0, limit)
383
+ .map((r) => ({ ...r }));
384
+ }
385
+
386
+ export function getConnectivityReport(db) {
387
+ const routes = [..._routes.values()];
388
+ const active = routes.filter((r) => r.status === "active");
389
+ const latencies = active
390
+ .filter((r) => r.latency_ms != null)
391
+ .map((r) => r.latency_ms);
392
+ const avgLatency =
393
+ latencies.length > 0
394
+ ? Math.round(latencies.reduce((s, l) => s + l, 0) / latencies.length)
395
+ : 0;
396
+ const avgReliability =
397
+ active.length > 0
398
+ ? Math.round(
399
+ (active.reduce((s, r) => s + r.reliability, 0) / active.length) * 100,
400
+ ) / 100
401
+ : 0;
402
+
403
+ return {
404
+ totalRoutes: routes.length,
405
+ activeRoutes: active.length,
406
+ byType: routes.reduce((acc, r) => {
407
+ acc[r.route_type] = (acc[r.route_type] || 0) + 1;
408
+ return acc;
409
+ }, {}),
410
+ avgLatencyMs: avgLatency,
411
+ avgReliability,
412
+ };
413
+ }
414
+
415
+ /* ── Stats ─────────���────────────────���──────────────────── */
416
+
417
+ export function getInfraStats(db) {
418
+ const deals = [..._deals.values()];
419
+ const versions = [..._versions.values()];
420
+
421
+ return {
422
+ storage: {
423
+ totalDeals: deals.length,
424
+ active: deals.filter((d) => d.status === "active").length,
425
+ totalSizeBytes: deals.reduce((s, d) => s + (d.size_bytes || 0), 0),
426
+ totalPriceFil:
427
+ Math.round(deals.reduce((s, d) => s + (d.price_fil || 0), 0) * 1000) /
428
+ 1000,
429
+ },
430
+ content: {
431
+ totalVersions: versions.length,
432
+ cached: versions.filter((v) => v.cached).length,
433
+ uniqueCids: new Set(versions.map((v) => v.content_cid)).size,
434
+ },
435
+ connectivity: getConnectivityReport(db),
436
+ };
437
+ }
438
+
439
+ /* ── Reset (tests) ─────────────────────────────────────── */
440
+
441
+ export function _resetState() {
442
+ _deals.clear();
443
+ _versions.clear();
444
+ _routes.clear();
445
+ }